Commit 3c3281de authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

vhost: added public documentation

parent df67486f
Loading
Loading
Loading
Loading
+177 −16
Original line number Diff line number Diff line
@@ -47,40 +47,202 @@ int spdk_vhost_init(void);
int spdk_vhost_fini(void);

/**
 * \param event event object. event arg1 is optional path to vhost socket.
 * Init vhost application.  This is called once by SPDK app layer.
 * \param arg1 optional path to directory where sockets will
 * be created
 * \param arg2 unused
 */
void spdk_vhost_startup(void *arg1, void *arg2);

/**
 * Deinit vhost application.  This is called once by SPDK app layer.
 */
void spdk_vhost_shutdown_cb(void);

/* Forward declaration */
/**
 * SPDK vhost device (vdev).  An equivalent of Virtio device.
 * Both virtio-blk and virtio-scsi devices are represented by this
 * struct. For virtio-scsi a single vhost device (also called SCSI
 * controller) may contain multiple devices (SCSI targets), each of
 * which may contain multiple logical units (SCSI LUNs). For now
 * only one LUN per device is available.
 *
 * All vdev-changing functions operate directly on this object.
 * Note that \c spdk_vhost_dev cannot be acquired. This object is
 * only accessible as a callback parameter via \c
 * spdk_vhost_call_external_event and it's derivatives. This ensures
 * that all access to the vdev is piped through a single,
 * thread-safe API.
 */
struct spdk_vhost_dev;

typedef int (*spdk_vhost_event_fn)(struct spdk_vhost_dev *, void *);
/**
 * Synchronized vhost event used for user callbacks.
 *
 * \param vdev vhost device
 * \param arg user-provided parameter
 * \return 0 on success, -1 on failure
 */
typedef int (*spdk_vhost_event_fn)(struct spdk_vhost_dev *vdev, void *arg);

/**
 * Get name of the vhost device.  This is equal to the filename
 * of socket file. The name is constant throughout the lifetime of
 * a vdev.
 *
 * \param vdev vhost device
 * \return name of the vdev
 */
const char *spdk_vhost_dev_get_name(struct spdk_vhost_dev *vdev);

const char *spdk_vhost_dev_get_name(struct spdk_vhost_dev *ctrl);
uint64_t spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *ctrl);
/**
 * Get cpumask of the vhost device.  The mask is constant
 * throughout the lifetime of a vdev. It is be a subset
 * of SPDK app cpumask vhost was started with.
 *
 * \param dev vhost device
 * \return cpumask of the vdev. The mask is constructed as:
 * ((1 << cpu0) | (1 << cpu1) | ... | (1 << cpuN)).
 */
uint64_t spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *vdev);

/**
 * Construct an empty vhost SCSI device.  This will create a
 * Unix domain socket together with a vhost-user slave server waiting
 * for a connection on this socket. Creating the vdev does not
 * start any I/O pollers and does not hog the CPU. I/O processing
 * starts after receiving proper message on the created socket.
 * See QEMU's vhost-user documentation for details.
 * All physical devices have to be separately attached to this
 * vdev via \c spdk_vhost_scsi_dev_add_dev().
 *
 * This function is thread-safe.
 *
 * \param name name of the vhost device. The name will also be used
 * for socket name, which is exactly \c socket_base_dir/name
 * \param mask string containing cpumask in hex. The leading *0x*
 * is allowed but not required. The mask itself can be constructed as:
 * ((1 << cpu0) | (1 << cpu1) | ... | (1 << cpuN)).
 * \return 0 on success, negative errno on error.
 */
int spdk_vhost_scsi_dev_construct(const char *name, const char *cpumask);

/**
 * Remove an empty vhost SCSI device.  The vdev must not
 * have any SCSI devices attached nor have any open connection on
 * it's socket.
 *
 * \param vdev vhost SCSI device
 * \return 0 on success, negative errno on error.
 */
int spdk_vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev);
struct spdk_scsi_dev *spdk_vhost_scsi_dev_get_dev(struct spdk_vhost_dev *ctrl, uint8_t num);

/**
 * Construct and attach new SCSI device to the vhost SCSI device
 * on given (unoccupied) slot.  The device will be created with a single
 * LUN0 associated with given SPDK bdev. Currently only one LUN per
 * device is supported.
 *
 * If vhost SCSI device has an active socket connection, it is
 * required that it has negotiated \c VIRTIO_SCSI_F_HOTPLUG feature
 * flag. Otherwise an -ENOTSUP error code is returned.
 *
 * \param vdev vhost SCSI device
 * \param scsi_dev_num slot to attach to
 * \param lun_name name of the SPDK bdev to associate with SCSI LUN0
 * \return 0 on success, negative errno on error.
 */
int spdk_vhost_scsi_dev_add_dev(struct spdk_vhost_dev *vdev, unsigned scsi_dev_num,
				const char *lun_name);

/**
 * Get SCSI device from vhost SCSI device on given slot.  Max
 * number of available slots is defined by
 * \c SPDK_VHOST_SCSI_CTRLR_MAX_DEVS.
 *
 * \param vdev vhost SCSI device
 * \param num slot id
 * \return SCSI device on given slot or NULL
 */
struct spdk_scsi_dev *spdk_vhost_scsi_dev_get_dev(struct spdk_vhost_dev *vdev, uint8_t num);

/**
 * Detach and destruct SCSI device from a vhost SCSI device.
 *
 * If vhost SCSI device has an active socket connection, it is
 * required that it has negotiated \c VIRTIO_SCSI_F_HOTPLUG feature
 * flag.Otherwise an -ENOTSUP error code is returned. If the flag has
 * been negotiated, the device will be marked to be deleted. Actual
 * deletion is deferred until after all pending I/O to this device
 * has finished.
 *
 * Once the device has been deleted (whether or not vhost SCSI
 * device is in use) given callback will be called.
 *
 * \param vdev vhost SCSI device
 * \param scsi_dev_num slot id to delete device from
 * \param cb_fn callback to be fired once device has been successfully
 * deleted. The first parameter of callback function is the vhost SCSI
 * device, the second is user provided argument *cb_arg*.
 * \param cb_arg parameter to be passed to *cb_fn*.
 * \return 0 on success, negative errno on error.
 */
int spdk_vhost_scsi_dev_remove_dev(struct spdk_vhost_dev *vdev, unsigned scsi_dev_num,
				   spdk_vhost_event_fn cb_fn, void *cb_arg);

/**
 * Construct a vhost blk device.  This will create a Unix domain
 * socket together with a vhost-user slave server waiting for a
 * connection on this socket. Creating the vdev does not start
 * any I/O pollers and does not hog the CPU. I/O processing starts
 * after receiving proper message on the created socket.
 * See QEMU's vhost-user documentation for details. Vhost blk
 * device is tightly associated with given SPDK bdev. Given
 * bdev can not be changed, unless it has been hotremoved. This
 * would result in all I/O failing with virtio \c VIRTIO_BLK_S_IOERR
 * error code.
 *
 * This function is thread-safe.
 *
 * \param name name of the vhost blk device. The name will also be
 * used for socket name, which is exactly \c socket_base_dir/name
 * \param mask string containing cpumask in hex. The leading *0x*
 * is allowed but not required. The mask itself can be constructed as:
 * ((1 << cpu0) | (1 << cpu1) | ... | (1 << cpuN)).
 * \param dev_name bdev name to associate with this vhost device
 * \param readonly if set, all writes to the device will fail with
 * \c VIRTIO_BLK_S_IOERR error code.
 * \return 0 on success, negative errno on error.
 */
int spdk_vhost_blk_construct(const char *name, const char *cpumask, const char *dev_name,
			     bool readonly);

/**
 * Remove a vhost blk device.  The device must not have any
 * open connections on it's socket.
 *
 * \param vdev vhost blk device
 * \return 0 on success, negative errno on error.
 */
int spdk_vhost_blk_destroy(struct spdk_vhost_dev *dev);

/**
 * Get underlying SPDK bdev from vhost blk device.  The
 * bdev might be NULL, as it could have been hotremoved.
 *
 * \param ctrl vhost blk device
 * \return SPDK bdev associated with given vdev
 */
struct spdk_bdev *spdk_vhost_blk_get_dev(struct spdk_vhost_dev *ctrlr);

/**
 * Call function on reactor of given vhost controller.
 * If controller is not in use, the event will be called
 * Call function on reactor of given vhost device.  If
 * device is not in use, the event will be called
 * right away on the caller's thread.
 *
 * This function is thread safe.
 *
 * \param ctrlr_name name of the vhost controller to run
 * \param vdev_name name of the vhost device to run
 * this event on
 * \param fn function to be called. The first parameter
 * of callback function is either actual spdk_vhost_dev
@@ -88,20 +250,19 @@ struct spdk_bdev *spdk_vhost_blk_get_dev(struct spdk_vhost_dev *ctrlr);
 * exist. The second param is user provided argument *arg*.
 * \param arg parameter to be passed to *fn*.
 */
void spdk_vhost_call_external_event(const char *ctrlr_name, spdk_vhost_event_fn fn, void *arg);
void spdk_vhost_call_external_event(const char *vdev_name, spdk_vhost_event_fn fn, void *arg);

/**
 * Call function for each available vhost controller on
 * Call function for each available vhost device on
 * it's reactor.  This will call given function in a chain,
 * meaning that each callback will be called after the
 * previous one has finished. After given function has
 * been called for all controllers, it will be called
 * once again with first param - vhost controller - set
 * to NULL.
 * been called for all vdevs, it will be called once
 * again with first param - vhost device- set to NULL.
 *
 * This function is thread safe.
 *
 * \param fn function to be called for each controller.
 * \param fn function to be called for each vdev.
 * The first param will be either vdev pointer or NULL.
 * The second param is user provided argument *arg*.
 * \param arg parameter to be passed to *fn*.