* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-13 8:35 ` [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost Nicholas A. Bellinger
@ 2012-08-13 8:53 ` Michael S. Tsirkin
2012-08-14 20:31 ` Nicholas A. Bellinger
2012-08-13 8:59 ` Michael S. Tsirkin
` (2 subsequent siblings)
3 siblings, 1 reply; 36+ messages in thread
From: Michael S. Tsirkin @ 2012-08-13 8:53 UTC (permalink / raw)
To: Nicholas A. Bellinger
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>
> This patch adds a new type of host device that drives the vhost_scsi
> device. The syntax to add vhost-scsi is:
>
> qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
>
> The virtio-scsi emulated device will make use of vhost-scsi to process
> virtio-scsi requests inside the kernel and hand them to the in-kernel
> SCSI target stack using the tcm_vhost fabric driver.
>
> The tcm_vhost driver was merged into the upstream linux kernel for 3.6-rc2,
> and the commit can be found here:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=057cbf49a1f08297
>
> Changelog v1 -> v2:
>
> - Expose ABI version via VHOST_SCSI_GET_ABI_VERSION + use Rev 0 as
> starting point for v3.6-rc code (Stefan + ALiguori + nab)
> - Fix upstream qemu conflict in hw/qdev-properties.c
> - Make GET_ABI_VERSION use int (nab + mst)
> - Fix vhost-scsi case lables in configure (reported by paolo)
> - Convert qdev_prop_vhost_scsi to use ->get() + ->set() following
> qdev_prop_netdev (reported by paolo)
> - Fix typo in qemu-options.hx definition of vhost-scsi (reported by paolo)
>
> Changelog v0 -> v1:
>
> - Add VHOST_SCSI_SET_ENDPOINT call (stefan)
> - Enable vhost notifiers for multiple queues (Zhi)
> - clear vhost-scsi endpoint on stopped (Zhi)
> - Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
> - Rename vhost_vring_target -> vhost_scsi_target (mst + nab)
> - Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)
>
> Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> Cc: Anthony Liguori <aliguori@us.ibm.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
> ---
> configure | 10 +++
> hw/Makefile.objs | 1 +
> hw/qdev-properties.c | 40 ++++++++++++
> hw/qdev.h | 3 +
> hw/vhost-scsi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/vhost-scsi.h | 50 +++++++++++++++
> qemu-common.h | 1 +
> qemu-config.c | 16 +++++
> qemu-options.hx | 4 +
> vl.c | 18 +++++
> 10 files changed, 313 insertions(+), 0 deletions(-)
> create mode 100644 hw/vhost-scsi.c
> create mode 100644 hw/vhost-scsi.h
>
> diff --git a/configure b/configure
> index f0dbc03..1f03202 100755
> --- a/configure
> +++ b/configure
> @@ -168,6 +168,7 @@ libattr=""
> xfs=""
>
> vhost_net="no"
> +vhost_scsi="no"
> kvm="no"
> gprof="no"
> debug_tcg="no"
> @@ -513,6 +514,7 @@ Haiku)
> usb="linux"
> kvm="yes"
> vhost_net="yes"
> + vhost_scsi="yes"
> if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
> audio_possible_drivers="$audio_possible_drivers fmod"
> fi
> @@ -818,6 +820,10 @@ for opt do
> ;;
> --enable-vhost-net) vhost_net="yes"
> ;;
> + --disable-vhost-scsi) vhost_scsi="no"
> + ;;
> + --enable-vhost-scsi) vhost_scsi="yes"
> + ;;
> --disable-opengl) opengl="no"
> ;;
> --enable-opengl) opengl="yes"
> @@ -3116,6 +3122,7 @@ echo "posix_madvise $posix_madvise"
> echo "uuid support $uuid"
> echo "libcap-ng support $cap_ng"
> echo "vhost-net support $vhost_net"
> +echo "vhost-scsi support $vhost_scsi"
> echo "Trace backend $trace_backend"
> echo "Trace output file $trace_file-<pid>"
> echo "spice support $spice"
> @@ -3828,6 +3835,9 @@ case "$target_arch2" in
> if test "$vhost_net" = "yes" ; then
> echo "CONFIG_VHOST_NET=y" >> $config_target_mak
> fi
> + if test "$vhost_scsi" = "yes" ; then
> + echo "CONFIG_VHOST_SCSI=y" >> $config_target_mak
> + fi
> fi
> esac
> case "$target_arch2" in
> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> index 3ba5dd0..6ab75ec 100644
> --- a/hw/Makefile.objs
> +++ b/hw/Makefile.objs
> @@ -169,6 +169,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
> obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o
> obj-$(CONFIG_SOFTMMU) += vhost_net.o
> obj-$(CONFIG_VHOST_NET) += vhost.o
> +obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
> obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
> obj-$(CONFIG_NO_PCI) += pci-stub.o
> obj-$(CONFIG_VGA) += vga.o
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 8aca0d4..0266266 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -4,6 +4,7 @@
> #include "blockdev.h"
> #include "hw/block-common.h"
> #include "net/hub.h"
> +#include "vhost-scsi.h"
>
> void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
> {
> @@ -696,6 +697,45 @@ PropertyInfo qdev_prop_vlan = {
> .set = set_vlan,
> };
>
> +/* --- vhost-scsi --- */
> +
> +static int parse_vhost_scsi_dev(DeviceState *dev, const char *str, void **ptr)
> +{
> + VHostSCSI *p;
> +
> + p = find_vhost_scsi(str);
> + if (p == NULL)
> + return -ENOENT;
> +
> + *ptr = p;
> + return 0;
> +}
> +
> +static const char *print_vhost_scsi_dev(void *ptr)
> +{
> + VHostSCSI *p = ptr;
> +
> + return (p) ? vhost_scsi_get_id(p) : "<null>";
> +}
> +
> +static void get_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + get_pointer(obj, v, opaque, print_vhost_scsi_dev, name, errp);
> +}
> +
> +static void set_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + set_pointer(obj, v, opaque, parse_vhost_scsi_dev, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_vhost_scsi = {
> + .name = "vhost-scsi",
> + .get = get_vhost_scsi_dev,
> + .set = set_vhost_scsi_dev,
> +};
> +
> /* --- pointer --- */
>
> /* Not a proper property, just for dirty hacks. TODO Remove it! */
> diff --git a/hw/qdev.h b/hw/qdev.h
> index d699194..d5873bb 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
> extern PropertyInfo qdev_prop_pci_devfn;
> extern PropertyInfo qdev_prop_blocksize;
> extern PropertyInfo qdev_prop_pci_host_devaddr;
> +extern PropertyInfo qdev_prop_vhost_scsi;
>
> #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
> .name = (_name), \
> @@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
> DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
> #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
> +#define DEFINE_PROP_VHOST_SCSI(_n, _s, _f) \
> + DEFINE_PROP(_n, _s, _f, qdev_prop_vhost_scsi, VHostSCSI*)
>
> #define DEFINE_PROP_END_OF_LIST() \
> {}
> diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> new file mode 100644
> index 0000000..7145b2d
> --- /dev/null
> +++ b/hw/vhost-scsi.c
> @@ -0,0 +1,170 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include <sys/ioctl.h>
> +#include "config.h"
> +#include "qemu-queue.h"
> +#include "vhost-scsi.h"
> +#include "vhost.h"
> +
> +struct VHostSCSI {
> + const char *id;
> + const char *wwpn;
> + uint16_t tpgt;
> + struct vhost_dev dev;
> + struct vhost_virtqueue vqs[3];
> + QLIST_ENTRY(VHostSCSI) list;
> +};
> +
> +static QLIST_HEAD(, VHostSCSI) vhost_scsi_list =
> + QLIST_HEAD_INITIALIZER(vhost_scsi_list);
> +
> +VHostSCSI *find_vhost_scsi(const char *id)
> +{
> + VHostSCSI *vs;
> +
> + QLIST_FOREACH(vs, &vhost_scsi_list, list) {
> + if (strcmp(id, vs->id) == 0) {
> + return vs;
> + }
> + }
> + return NULL;
> +}
> +
> +const char *vhost_scsi_get_id(VHostSCSI *vs)
> +{
> + return vs->id;
> +}
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret, abi_version;
> + struct vhost_scsi_target backend;
> +
> + if (!vhost_dev_query(&vs->dev, vdev)) {
> + return -ENOTSUP;
> + }
> +
> + vs->dev.nvqs = 3;
> + vs->dev.vqs = vs->vqs;
> +
> + ret = vhost_dev_enable_notifiers(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + ret = vhost_dev_start(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + memset(&backend, 0, sizeof(backend));
> + ret = ioctl(vs->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + if (abi_version > VHOST_SCSI_ABI_VERSION) {
> + fprintf(stderr, "The running tcm_vhost kernel abi_version: %d is greater"
> + " than vhost_scsi userspace supports: %d\n", abi_version,
> + VHOST_SCSI_ABI_VERSION);
> + ret = -ENOSYS;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + fprintf(stdout, "TCM_vHost ABI version: %d\n", abi_version);
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret;
> + struct vhost_scsi_target backend;
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
> + if (ret < 0) {
> + fprintf(stderr, "Failed to clear endpoint\n");
> + }
> +
> + vhost_dev_stop(&vs->dev, vdev);
> +}
> +
> +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> + uint16_t tpgt)
> +{
> + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> + int ret;
> +
> + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> +
> + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
This -1 is a hack. You need to support passing in fd from
the monitor, and pass it here.
> + if (ret < 0) {
> + fprintf(stderr, "vhost-scsi: vhost initialization failed: %s\n",
> + strerror(-ret));
> + return NULL;
> + }
> + vs->dev.backend_features = 0;
> + vs->dev.acked_features = 0;
> +
> + vs->id = g_strdup(id);
> + vs->wwpn = g_strdup(wwpn);
> + vs->tpgt = tpgt;
> + QLIST_INSERT_HEAD(&vhost_scsi_list, vs, list);
> +
> + return vs;
> +}
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
> +{
> + const char *id;
> + const char *wwpn;
> + uint64_t tpgt;
> +
> + id = qemu_opts_id(opts);
> + if (!id) {
> + fprintf(stderr, "vhost-scsi: no id specified\n");
> + return NULL;
> + }
> + if (find_vhost_scsi(id)) {
> + fprintf(stderr, "duplicate vhost-scsi: \"%s\"\n", id);
> + return NULL;
> + }
> +
> + wwpn = qemu_opt_get(opts, "wwpn");
> + if (!wwpn) {
> + fprintf(stderr, "vhost-scsi: \"%s\" missing wwpn\n", id);
> + return NULL;
> + }
> +
> + tpgt = qemu_opt_get_number(opts, "tpgt", UINT64_MAX);
> + if (tpgt > UINT16_MAX) {
> + fprintf(stderr, "vhost-scsi: \"%s\" needs a 16-bit tpgt\n", id);
> + return NULL;
> + }
> +
> + return vhost_scsi_add(id, wwpn, tpgt);
> +}
> diff --git a/hw/vhost-scsi.h b/hw/vhost-scsi.h
> new file mode 100644
> index 0000000..f3096dc
> --- /dev/null
> +++ b/hw/vhost-scsi.h
> @@ -0,0 +1,50 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#ifndef VHOST_SCSI_H
> +#define VHOST_SCSI_H
> +
> +#include "qemu-common.h"
> +#include "qemu-option.h"
> +
> +/*
> + * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
> + *
> + * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate +
> + * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage
> + */
> +
> +#define VHOST_SCSI_ABI_VERSION 0
> +
> +/* TODO #include <linux/vhost.h> properly */
> +/* For VHOST_SCSI_SET_ENDPOINT/VHOST_SCSI_CLEAR_ENDPOINT ioctl */
> +struct vhost_scsi_target {
> + int abi_version;
> + unsigned char vhost_wwpn[224];
> + unsigned short vhost_tpgt;
> +};
> +
> +#define VHOST_VIRTIO 0xAF
> +#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
> +#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
> +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct vhost_scsi_target)
> +
> +VHostSCSI *find_vhost_scsi(const char *id);
> +const char *vhost_scsi_get_id(VHostSCSI *vs);
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts);
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev);
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev);
> +
> +#endif
> diff --git a/qemu-common.h b/qemu-common.h
> index f9deca6..ec36002 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -280,6 +280,7 @@ typedef struct EventNotifier EventNotifier;
> typedef struct VirtIODevice VirtIODevice;
> typedef struct QEMUSGList QEMUSGList;
> typedef struct SHPCDevice SHPCDevice;
> +typedef struct VHostSCSI VHostSCSI;
>
> typedef uint64_t pcibus_t;
>
> diff --git a/qemu-config.c b/qemu-config.c
> index 5c3296b..33399ea 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -626,6 +626,21 @@ QemuOptsList qemu_boot_opts = {
> },
> };
>
> +QemuOptsList qemu_vhost_scsi_opts = {
> + .name = "vhost-scsi",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_vhost_scsi_opts.head),
> + .desc = {
> + {
> + .name = "wwpn",
> + .type = QEMU_OPT_STRING,
> + }, {
> + .name = "tpgt",
> + .type = QEMU_OPT_NUMBER,
> + },
> + { /* end of list */ }
> + },
> +};
> +
> static QemuOptsList *vm_config_groups[32] = {
> &qemu_drive_opts,
> &qemu_chardev_opts,
> @@ -641,6 +656,7 @@ static QemuOptsList *vm_config_groups[32] = {
> &qemu_machine_opts,
> &qemu_boot_opts,
> &qemu_iscsi_opts,
> + &qemu_vhost_scsi_opts,
> NULL,
> };
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 47cb5bd..4e7a03c 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -565,6 +565,10 @@ possible drivers and properties, use @code{-device ?} and
> ETEXI
>
> DEFHEADING()
> +DEF("vhost-scsi", HAS_ARG, QEMU_OPTION_vhost_scsi,
> + "-vhost-scsi wwpn=string0,tpgt=number0\n"
> + " add vhost-scsi device\n",
> + QEMU_ARCH_ALL)
>
> DEFHEADING(File system options:)
>
> diff --git a/vl.c b/vl.c
> index 91076f0..61c8284 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -144,6 +144,7 @@ int main(int argc, char **argv)
> #include "qemu-options.h"
> #include "qmp-commands.h"
> #include "main-loop.h"
> +#include "hw/vhost-scsi.h"
> #ifdef CONFIG_VIRTFS
> #include "fsdev/qemu-fsdev.h"
> #endif
> @@ -1858,6 +1859,14 @@ static int fsdev_init_func(QemuOpts *opts, void *opaque)
> }
> #endif
>
> +static int vhost_scsi_init_func(QemuOpts *opts, void *opaque)
> +{
> + if (!vhost_scsi_add_opts(opts)) {
> + return -1;
> + }
> + return 0;
> +}
> +
> static int mon_init_func(QemuOpts *opts, void *opaque)
> {
> CharDriverState *chr;
> @@ -2617,6 +2626,11 @@ int main(int argc, char **argv, char **envp)
> }
> break;
> #endif
> + case QEMU_OPTION_vhost_scsi:
> + if (!qemu_opts_parse(qemu_find_opts("vhost-scsi"), optarg, 0)) {
> + exit(1);
> + }
> + break;
> #ifdef CONFIG_SLIRP
> case QEMU_OPTION_tftp:
> legacy_tftp_prefix = optarg;
> @@ -3337,6 +3351,10 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> }
> #endif
> + if (qemu_opts_foreach(qemu_find_opts("vhost-scsi"),
> + vhost_scsi_init_func, NULL, 1)) {
> + exit(1);
> + }
>
> os_daemonize();
>
> --
> 1.7.2.5
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-13 8:53 ` Michael S. Tsirkin
@ 2012-08-14 20:31 ` Nicholas A. Bellinger
2012-08-18 19:12 ` Michael S. Tsirkin
0 siblings, 1 reply; 36+ messages in thread
From: Nicholas A. Bellinger @ 2012-08-14 20:31 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Mon, 2012-08-13 at 11:53 +0300, Michael S. Tsirkin wrote:
> On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> >
> > This patch adds a new type of host device that drives the vhost_scsi
> > device. The syntax to add vhost-scsi is:
> >
> > qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
> >
> > The virtio-scsi emulated device will make use of vhost-scsi to process
> > virtio-scsi requests inside the kernel and hand them to the in-kernel
> > SCSI target stack using the tcm_vhost fabric driver.
<SNIP>
> > +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> > + uint16_t tpgt)
> > +{
> > + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> > + int ret;
> > +
> > + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> > + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> > +
> > + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
>
> This -1 is a hack. You need to support passing in fd from
> the monitor, and pass it here.
>
Mmm, looking at how vhost_net_init + tap.c does this, but am not quite
what fd needs to be propagated up for virtio-scsi -> vhost-scsi..
Can you please elaborate on this one a bit more..?
--nab
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-14 20:31 ` Nicholas A. Bellinger
@ 2012-08-18 19:12 ` Michael S. Tsirkin
2012-08-19 0:36 ` Nicholas A. Bellinger
0 siblings, 1 reply; 36+ messages in thread
From: Michael S. Tsirkin @ 2012-08-18 19:12 UTC (permalink / raw)
To: Nicholas A. Bellinger
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Tue, Aug 14, 2012 at 01:31:14PM -0700, Nicholas A. Bellinger wrote:
> On Mon, 2012-08-13 at 11:53 +0300, Michael S. Tsirkin wrote:
> > On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> > > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > >
> > > This patch adds a new type of host device that drives the vhost_scsi
> > > device. The syntax to add vhost-scsi is:
> > >
> > > qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
> > >
> > > The virtio-scsi emulated device will make use of vhost-scsi to process
> > > virtio-scsi requests inside the kernel and hand them to the in-kernel
> > > SCSI target stack using the tcm_vhost fabric driver.
>
> <SNIP>
>
> > > +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> > > + uint16_t tpgt)
> > > +{
> > > + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> > > + int ret;
> > > +
> > > + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> > > + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> > > +
> > > + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
> >
> > This -1 is a hack. You need to support passing in fd from
> > the monitor, and pass it here.
> >
>
> Mmm, looking at how vhost_net_init + tap.c does this, but am not quite
> what fd needs to be propagated up for virtio-scsi -> vhost-scsi..
>
> Can you please elaborate on this one a bit more..?
>
> --nab
>
The idea is to allow running as a user without access to
/dev/vhost-scsi.
For this, allow passing in the fd of /dev/vhost-scsi through unix domain sockets.
--
MST
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-18 19:12 ` Michael S. Tsirkin
@ 2012-08-19 0:36 ` Nicholas A. Bellinger
2012-08-19 8:44 ` Michael S. Tsirkin
0 siblings, 1 reply; 36+ messages in thread
From: Nicholas A. Bellinger @ 2012-08-19 0:36 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Sat, 2012-08-18 at 22:12 +0300, Michael S. Tsirkin wrote:
> On Tue, Aug 14, 2012 at 01:31:14PM -0700, Nicholas A. Bellinger wrote:
> > On Mon, 2012-08-13 at 11:53 +0300, Michael S. Tsirkin wrote:
> > > On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> > > > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
<SNIP>
> > > > +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> > > > + uint16_t tpgt)
> > > > +{
> > > > + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> > > > + int ret;
> > > > +
> > > > + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> > > > + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> > > > +
> > > > + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
> > >
> > > This -1 is a hack. You need to support passing in fd from
> > > the monitor, and pass it here.
> > >
> >
> > Mmm, looking at how vhost_net_init + tap.c does this, but am not quite
> > what fd needs to be propagated up for virtio-scsi -> vhost-scsi..
> >
> > Can you please elaborate on this one a bit more..?
> >
>
> The idea is to allow running as a user without access to
> /dev/vhost-scsi.
> For this, allow passing in the fd of /dev/vhost-scsi through unix domain sockets.
>
Ah, that is a pretty neat trick.. So for vhost-scsi code, this would
mean something along the lines of the following, yes..?
Thanks MST!
diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
index 4206a75..8af8758 100644
--- a/hw/vhost-scsi.c
+++ b/hw/vhost-scsi.c
@@ -21,6 +21,7 @@ struct VHostSCSI {
const char *id;
const char *wwpn;
uint16_t tpgt;
+ int vhostfd;
struct vhost_dev dev;
struct vhost_virtqueue vqs[VHOST_SCSI_VQ_NUM];
QLIST_ENTRY(VHostSCSI) list;
@@ -114,13 +115,32 @@ void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
}
static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
- uint16_t tpgt)
+ uint16_t tpgt, const char *vhostfd_str)
{
- VHostSCSI *vs = g_malloc0(sizeof(*vs));
+ VHostSCSI *vs;
int ret;
+ vs = g_malloc0(sizeof(*vs));
+ if (!vs) {
+ error_report("vhost-scsi: unable to allocate *vs\n");
+ return NULL;
+ }
+ vs->vhostfd = -1;
+
+ if (vhostfd_str) {
+ if (!qemu_isdigit(vhostfd_str[0])) {
+ error_report("vhost-scsi: passed vhostfd value is not a digit\n");
+ return NULL;
+ }
+
+ vs->vhostfd = qemu_parse_fd(vhostfd_str);
+ if (vs->vhostfd == -1) {
+ error_report("vhost-scsi: unable to parse vs->vhostfd\n");
+ return NULL;
+ }
+ }
/* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
- ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
+ ret = vhost_dev_init(&vs->dev, vs->vhostfd, "/dev/vhost-scsi", false);
if (ret < 0) {
error_report("vhost-scsi: vhost initialization failed: %s\n",
strerror(-ret));
@@ -140,7 +160,7 @@ static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
{
const char *id;
- const char *wwpn;
+ const char *wwpn, *vhostfd;
uint64_t tpgt;
id = qemu_opts_id(opts);
@@ -164,6 +184,7 @@ VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
error_report("vhost-scsi: \"%s\" needs a 16-bit tpgt\n", id);
return NULL;
}
+ vhostfd = qemu_opt_get(opts, "vhostfd");
- return vhost_scsi_add(id, wwpn, tpgt);
+ return vhost_scsi_add(id, wwpn, tpgt, vhostfd);
}
diff --git a/qemu-config.c b/qemu-config.c
index 33399ea..2d4884c 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -636,6 +636,9 @@ QemuOptsList qemu_vhost_scsi_opts = {
}, {
.name = "tpgt",
.type = QEMU_OPT_NUMBER,
+ }, {
+ .name = "vhostfd",
+ .type = QEMU_OPT_STRING,
},
{ /* end of list */ }
},
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-19 0:36 ` Nicholas A. Bellinger
@ 2012-08-19 8:44 ` Michael S. Tsirkin
2012-08-20 22:24 ` Nicholas A. Bellinger
0 siblings, 1 reply; 36+ messages in thread
From: Michael S. Tsirkin @ 2012-08-19 8:44 UTC (permalink / raw)
To: Nicholas A. Bellinger
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Sat, Aug 18, 2012 at 05:36:26PM -0700, Nicholas A. Bellinger wrote:
> On Sat, 2012-08-18 at 22:12 +0300, Michael S. Tsirkin wrote:
> > On Tue, Aug 14, 2012 at 01:31:14PM -0700, Nicholas A. Bellinger wrote:
> > > On Mon, 2012-08-13 at 11:53 +0300, Michael S. Tsirkin wrote:
> > > > On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> > > > > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>
> <SNIP>
>
> > > > > +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> > > > > + uint16_t tpgt)
> > > > > +{
> > > > > + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> > > > > + int ret;
> > > > > +
> > > > > + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> > > > > + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> > > > > +
> > > > > + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
> > > >
> > > > This -1 is a hack. You need to support passing in fd from
> > > > the monitor, and pass it here.
> > > >
> > >
> > > Mmm, looking at how vhost_net_init + tap.c does this, but am not quite
> > > what fd needs to be propagated up for virtio-scsi -> vhost-scsi..
> > >
> > > Can you please elaborate on this one a bit more..?
> > >
> >
> > The idea is to allow running as a user without access to
> > /dev/vhost-scsi.
> > For this, allow passing in the fd of /dev/vhost-scsi through unix domain sockets.
> >
>
> Ah, that is a pretty neat trick.. So for vhost-scsi code, this would
> mean something along the lines of the following, yes..?
Yes but with one correction. See below.
> Thanks MST!
> diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> index 4206a75..8af8758 100644
> --- a/hw/vhost-scsi.c
> +++ b/hw/vhost-scsi.c
> @@ -21,6 +21,7 @@ struct VHostSCSI {
> const char *id;
> const char *wwpn;
> uint16_t tpgt;
> + int vhostfd;
> struct vhost_dev dev;
> struct vhost_virtqueue vqs[VHOST_SCSI_VQ_NUM];
> QLIST_ENTRY(VHostSCSI) list;
> @@ -114,13 +115,32 @@ void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> }
>
> static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> - uint16_t tpgt)
> + uint16_t tpgt, const char *vhostfd_str)
> {
> - VHostSCSI *vs = g_malloc0(sizeof(*vs));
> + VHostSCSI *vs;
> int ret;
>
> + vs = g_malloc0(sizeof(*vs));
> + if (!vs) {
> + error_report("vhost-scsi: unable to allocate *vs\n");
> + return NULL;
> + }
> + vs->vhostfd = -1;
> +
> + if (vhostfd_str) {
> + if (!qemu_isdigit(vhostfd_str[0])) {
> + error_report("vhost-scsi: passed vhostfd value is not a digit\n");
> + return NULL;
This let you use an fd which was open at exec
but does not allow for fd to be open later in
case device is hot-plugged.
See net_handle_fd_param - I think you can just rename it
qemu_handle_fd_param to avoid code duplication.
> + }
> +
> + vs->vhostfd = qemu_parse_fd(vhostfd_str);
> + if (vs->vhostfd == -1) {
> + error_report("vhost-scsi: unable to parse vs->vhostfd\n");
> + return NULL;
> + }
> + }
> /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> - ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
> + ret = vhost_dev_init(&vs->dev, vs->vhostfd, "/dev/vhost-scsi", false);
> if (ret < 0) {
> error_report("vhost-scsi: vhost initialization failed: %s\n",
> strerror(-ret));
> @@ -140,7 +160,7 @@ static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
> {
> const char *id;
> - const char *wwpn;
> + const char *wwpn, *vhostfd;
> uint64_t tpgt;
>
> id = qemu_opts_id(opts);
> @@ -164,6 +184,7 @@ VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
> error_report("vhost-scsi: \"%s\" needs a 16-bit tpgt\n", id);
> return NULL;
> }
> + vhostfd = qemu_opt_get(opts, "vhostfd");
>
> - return vhost_scsi_add(id, wwpn, tpgt);
> + return vhost_scsi_add(id, wwpn, tpgt, vhostfd);
> }
> diff --git a/qemu-config.c b/qemu-config.c
> index 33399ea..2d4884c 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -636,6 +636,9 @@ QemuOptsList qemu_vhost_scsi_opts = {
> }, {
> .name = "tpgt",
> .type = QEMU_OPT_NUMBER,
> + }, {
> + .name = "vhostfd",
> + .type = QEMU_OPT_STRING,
> },
> { /* end of list */ }
> },
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-19 8:44 ` Michael S. Tsirkin
@ 2012-08-20 22:24 ` Nicholas A. Bellinger
0 siblings, 0 replies; 36+ messages in thread
From: Nicholas A. Bellinger @ 2012-08-20 22:24 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Sun, 2012-08-19 at 11:44 +0300, Michael S. Tsirkin wrote:
> On Sat, Aug 18, 2012 at 05:36:26PM -0700, Nicholas A. Bellinger wrote:
> > On Sat, 2012-08-18 at 22:12 +0300, Michael S. Tsirkin wrote:
> > > On Tue, Aug 14, 2012 at 01:31:14PM -0700, Nicholas A. Bellinger wrote:
> > > > On Mon, 2012-08-13 at 11:53 +0300, Michael S. Tsirkin wrote:
> > > > > On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> > > > > > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
<SNIP>
> > > > Mmm, looking at how vhost_net_init + tap.c does this, but am not quite
> > > > what fd needs to be propagated up for virtio-scsi -> vhost-scsi..
> > > >
> > > > Can you please elaborate on this one a bit more..?
> > > >
> > >
> > > The idea is to allow running as a user without access to
> > > /dev/vhost-scsi.
> > > For this, allow passing in the fd of /dev/vhost-scsi through unix domain sockets.
> > >
> >
> > Ah, that is a pretty neat trick.. So for vhost-scsi code, this would
> > mean something along the lines of the following, yes..?
>
> Yes but with one correction. See below.
>
> > Thanks MST!
>
> > diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> > index 4206a75..8af8758 100644
> > --- a/hw/vhost-scsi.c
> > +++ b/hw/vhost-scsi.c
> > @@ -21,6 +21,7 @@ struct VHostSCSI {
> > const char *id;
> > const char *wwpn;
> > uint16_t tpgt;
> > + int vhostfd;
> > struct vhost_dev dev;
> > struct vhost_virtqueue vqs[VHOST_SCSI_VQ_NUM];
> > QLIST_ENTRY(VHostSCSI) list;
> > @@ -114,13 +115,32 @@ void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> > }
> >
> > static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> > - uint16_t tpgt)
> > + uint16_t tpgt, const char *vhostfd_str)
> > {
> > - VHostSCSI *vs = g_malloc0(sizeof(*vs));
> > + VHostSCSI *vs;
> > int ret;
> >
> > + vs = g_malloc0(sizeof(*vs));
> > + if (!vs) {
> > + error_report("vhost-scsi: unable to allocate *vs\n");
> > + return NULL;
> > + }
> > + vs->vhostfd = -1;
> > +
> > + if (vhostfd_str) {
> > + if (!qemu_isdigit(vhostfd_str[0])) {
> > + error_report("vhost-scsi: passed vhostfd value is not a digit\n");
> > + return NULL;
>
> This let you use an fd which was open at exec
> but does not allow for fd to be open later in
> case device is hot-plugged.
>
> See net_handle_fd_param - I think you can just rename it
> qemu_handle_fd_param to avoid code duplication.
>
OK, so monitor_get_fd() will set this up for the case where the device
is hot-plugged. That makes alot more sense now..
So renaming net_handle_fd_param -> qemu_handle_fd_param + moving into
cutils.c, and will include as a leading patch for RFC-v3.
Thanks MST!
--nab
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-13 8:35 ` [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost Nicholas A. Bellinger
2012-08-13 8:53 ` Michael S. Tsirkin
@ 2012-08-13 8:59 ` Michael S. Tsirkin
2012-08-14 21:12 ` Nicholas A. Bellinger
2012-08-13 19:47 ` Blue Swirl
2012-08-20 9:02 ` Paolo Bonzini
3 siblings, 1 reply; 36+ messages in thread
From: Michael S. Tsirkin @ 2012-08-13 8:59 UTC (permalink / raw)
To: Nicholas A. Bellinger
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>
> This patch adds a new type of host device that drives the vhost_scsi
> device. The syntax to add vhost-scsi is:
>
> qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
>
> The virtio-scsi emulated device will make use of vhost-scsi to process
> virtio-scsi requests inside the kernel and hand them to the in-kernel
> SCSI target stack using the tcm_vhost fabric driver.
>
> The tcm_vhost driver was merged into the upstream linux kernel for 3.6-rc2,
> and the commit can be found here:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=057cbf49a1f08297
>
> Changelog v1 -> v2:
>
> - Expose ABI version via VHOST_SCSI_GET_ABI_VERSION + use Rev 0 as
> starting point for v3.6-rc code (Stefan + ALiguori + nab)
> - Fix upstream qemu conflict in hw/qdev-properties.c
> - Make GET_ABI_VERSION use int (nab + mst)
> - Fix vhost-scsi case lables in configure (reported by paolo)
> - Convert qdev_prop_vhost_scsi to use ->get() + ->set() following
> qdev_prop_netdev (reported by paolo)
> - Fix typo in qemu-options.hx definition of vhost-scsi (reported by paolo)
>
> Changelog v0 -> v1:
>
> - Add VHOST_SCSI_SET_ENDPOINT call (stefan)
> - Enable vhost notifiers for multiple queues (Zhi)
> - clear vhost-scsi endpoint on stopped (Zhi)
> - Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
> - Rename vhost_vring_target -> vhost_scsi_target (mst + nab)
> - Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)
>
> Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> Cc: Anthony Liguori <aliguori@us.ibm.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Sent mail too fast, sorry. More comments below.
> ---
> configure | 10 +++
> hw/Makefile.objs | 1 +
> hw/qdev-properties.c | 40 ++++++++++++
> hw/qdev.h | 3 +
> hw/vhost-scsi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/vhost-scsi.h | 50 +++++++++++++++
> qemu-common.h | 1 +
> qemu-config.c | 16 +++++
> qemu-options.hx | 4 +
> vl.c | 18 +++++
> 10 files changed, 313 insertions(+), 0 deletions(-)
> create mode 100644 hw/vhost-scsi.c
> create mode 100644 hw/vhost-scsi.h
>
> diff --git a/configure b/configure
> index f0dbc03..1f03202 100755
> --- a/configure
> +++ b/configure
> @@ -168,6 +168,7 @@ libattr=""
> xfs=""
>
> vhost_net="no"
> +vhost_scsi="no"
> kvm="no"
> gprof="no"
> debug_tcg="no"
> @@ -513,6 +514,7 @@ Haiku)
> usb="linux"
> kvm="yes"
> vhost_net="yes"
> + vhost_scsi="yes"
> if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
> audio_possible_drivers="$audio_possible_drivers fmod"
> fi
> @@ -818,6 +820,10 @@ for opt do
> ;;
> --enable-vhost-net) vhost_net="yes"
> ;;
> + --disable-vhost-scsi) vhost_scsi="no"
> + ;;
> + --enable-vhost-scsi) vhost_scsi="yes"
> + ;;
> --disable-opengl) opengl="no"
> ;;
> --enable-opengl) opengl="yes"
> @@ -3116,6 +3122,7 @@ echo "posix_madvise $posix_madvise"
> echo "uuid support $uuid"
> echo "libcap-ng support $cap_ng"
> echo "vhost-net support $vhost_net"
> +echo "vhost-scsi support $vhost_scsi"
> echo "Trace backend $trace_backend"
> echo "Trace output file $trace_file-<pid>"
> echo "spice support $spice"
> @@ -3828,6 +3835,9 @@ case "$target_arch2" in
> if test "$vhost_net" = "yes" ; then
> echo "CONFIG_VHOST_NET=y" >> $config_target_mak
> fi
> + if test "$vhost_scsi" = "yes" ; then
> + echo "CONFIG_VHOST_SCSI=y" >> $config_target_mak
> + fi
> fi
> esac
> case "$target_arch2" in
> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> index 3ba5dd0..6ab75ec 100644
> --- a/hw/Makefile.objs
> +++ b/hw/Makefile.objs
> @@ -169,6 +169,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
> obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o
> obj-$(CONFIG_SOFTMMU) += vhost_net.o
> obj-$(CONFIG_VHOST_NET) += vhost.o
> +obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
> obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
> obj-$(CONFIG_NO_PCI) += pci-stub.o
> obj-$(CONFIG_VGA) += vga.o
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 8aca0d4..0266266 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -4,6 +4,7 @@
> #include "blockdev.h"
> #include "hw/block-common.h"
> #include "net/hub.h"
> +#include "vhost-scsi.h"
>
> void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
> {
> @@ -696,6 +697,45 @@ PropertyInfo qdev_prop_vlan = {
> .set = set_vlan,
> };
>
> +/* --- vhost-scsi --- */
> +
> +static int parse_vhost_scsi_dev(DeviceState *dev, const char *str, void **ptr)
> +{
> + VHostSCSI *p;
> +
> + p = find_vhost_scsi(str);
> + if (p == NULL)
> + return -ENOENT;
> +
> + *ptr = p;
> + return 0;
> +}
> +
> +static const char *print_vhost_scsi_dev(void *ptr)
> +{
> + VHostSCSI *p = ptr;
> +
> + return (p) ? vhost_scsi_get_id(p) : "<null>";
> +}
> +
> +static void get_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + get_pointer(obj, v, opaque, print_vhost_scsi_dev, name, errp);
> +}
> +
> +static void set_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + set_pointer(obj, v, opaque, parse_vhost_scsi_dev, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_vhost_scsi = {
> + .name = "vhost-scsi",
> + .get = get_vhost_scsi_dev,
> + .set = set_vhost_scsi_dev,
> +};
> +
> /* --- pointer --- */
>
> /* Not a proper property, just for dirty hacks. TODO Remove it! */
Why does this make sense in the generic qdev-properties?
There's exactly one device that can use this, no?
> diff --git a/hw/qdev.h b/hw/qdev.h
> index d699194..d5873bb 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
> extern PropertyInfo qdev_prop_pci_devfn;
> extern PropertyInfo qdev_prop_blocksize;
> extern PropertyInfo qdev_prop_pci_host_devaddr;
> +extern PropertyInfo qdev_prop_vhost_scsi;
>
> #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
> .name = (_name), \
> @@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
> DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
> #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
> +#define DEFINE_PROP_VHOST_SCSI(_n, _s, _f) \
> + DEFINE_PROP(_n, _s, _f, qdev_prop_vhost_scsi, VHostSCSI*)
>
Can this move to vhost-scsi.c?
> #define DEFINE_PROP_END_OF_LIST() \
> {}
> diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> new file mode 100644
> index 0000000..7145b2d
> --- /dev/null
> +++ b/hw/vhost-scsi.c
> @@ -0,0 +1,170 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include <sys/ioctl.h>
> +#include "config.h"
> +#include "qemu-queue.h"
> +#include "vhost-scsi.h"
> +#include "vhost.h"
> +
> +struct VHostSCSI {
> + const char *id;
> + const char *wwpn;
> + uint16_t tpgt;
> + struct vhost_dev dev;
> + struct vhost_virtqueue vqs[3];
Could you add enum for vq numbers pls?
> + QLIST_ENTRY(VHostSCSI) list;
> +};
> +
> +static QLIST_HEAD(, VHostSCSI) vhost_scsi_list =
> + QLIST_HEAD_INITIALIZER(vhost_scsi_list);
> +
> +VHostSCSI *find_vhost_scsi(const char *id)
> +{
> + VHostSCSI *vs;
> +
> + QLIST_FOREACH(vs, &vhost_scsi_list, list) {
> + if (strcmp(id, vs->id) == 0) {
!strcmp
> + return vs;
> + }
> + }
> + return NULL;
> +}
> +
> +const char *vhost_scsi_get_id(VHostSCSI *vs)
> +{
> + return vs->id;
> +}
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret, abi_version;
> + struct vhost_scsi_target backend;
> +
> + if (!vhost_dev_query(&vs->dev, vdev)) {
> + return -ENOTSUP;
> + }
> +
> + vs->dev.nvqs = 3;
> + vs->dev.vqs = vs->vqs;
> +
> + ret = vhost_dev_enable_notifiers(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + ret = vhost_dev_start(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + memset(&backend, 0, sizeof(backend));
> + ret = ioctl(vs->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + if (abi_version > VHOST_SCSI_ABI_VERSION) {
> + fprintf(stderr, "The running tcm_vhost kernel abi_version: %d is greater"
> + " than vhost_scsi userspace supports: %d\n", abi_version,
> + VHOST_SCSI_ABI_VERSION);
> + ret = -ENOSYS;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + fprintf(stdout, "TCM_vHost ABI version: %d\n", abi_version);
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret;
> + struct vhost_scsi_target backend;
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
> + if (ret < 0) {
> + fprintf(stderr, "Failed to clear endpoint\n");
> + }
> +
> + vhost_dev_stop(&vs->dev, vdev);
> +}
> +
> +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> + uint16_t tpgt)
> +{
> + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> + int ret;
> +
> + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> +
Please do not keep debugging fprintfs around.
> + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
commented on this separately
> + if (ret < 0) {
> + fprintf(stderr, "vhost-scsi: vhost initialization failed: %s\n",
> + strerror(-ret));
errors should go to monitor, here and elsewhere.
> + return NULL;
> + }
> + vs->dev.backend_features = 0;
> + vs->dev.acked_features = 0;
> +
> + vs->id = g_strdup(id);
> + vs->wwpn = g_strdup(wwpn);
> + vs->tpgt = tpgt;
> + QLIST_INSERT_HEAD(&vhost_scsi_list, vs, list);
> +
> + return vs;
> +}
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
> +{
> + const char *id;
> + const char *wwpn;
> + uint64_t tpgt;
> +
> + id = qemu_opts_id(opts);
> + if (!id) {
> + fprintf(stderr, "vhost-scsi: no id specified\n");
> + return NULL;
> + }
> + if (find_vhost_scsi(id)) {
> + fprintf(stderr, "duplicate vhost-scsi: \"%s\"\n", id);
> + return NULL;
> + }
> +
> + wwpn = qemu_opt_get(opts, "wwpn");
> + if (!wwpn) {
> + fprintf(stderr, "vhost-scsi: \"%s\" missing wwpn\n", id);
> + return NULL;
> + }
> +
> + tpgt = qemu_opt_get_number(opts, "tpgt", UINT64_MAX);
> + if (tpgt > UINT16_MAX) {
> + fprintf(stderr, "vhost-scsi: \"%s\" needs a 16-bit tpgt\n", id);
> + return NULL;
> + }
> +
> + return vhost_scsi_add(id, wwpn, tpgt);
> +}
> diff --git a/hw/vhost-scsi.h b/hw/vhost-scsi.h
> new file mode 100644
> index 0000000..f3096dc
> --- /dev/null
> +++ b/hw/vhost-scsi.h
> @@ -0,0 +1,50 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#ifndef VHOST_SCSI_H
> +#define VHOST_SCSI_H
> +
> +#include "qemu-common.h"
> +#include "qemu-option.h"
> +
> +/*
> + * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
> + *
> + * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate +
> + * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage
> + */
> +
> +#define VHOST_SCSI_ABI_VERSION 0
> +
> +/* TODO #include <linux/vhost.h> properly */
> +/* For VHOST_SCSI_SET_ENDPOINT/VHOST_SCSI_CLEAR_ENDPOINT ioctl */
> +struct vhost_scsi_target {
> + int abi_version;
> + unsigned char vhost_wwpn[224];
> + unsigned short vhost_tpgt;
> +};
> +
> +#define VHOST_VIRTIO 0xAF
> +#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
> +#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
> +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct vhost_scsi_target)
> +
> +VHostSCSI *find_vhost_scsi(const char *id);
> +const char *vhost_scsi_get_id(VHostSCSI *vs);
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts);
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev);
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev);
> +
> +#endif
> diff --git a/qemu-common.h b/qemu-common.h
> index f9deca6..ec36002 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -280,6 +280,7 @@ typedef struct EventNotifier EventNotifier;
> typedef struct VirtIODevice VirtIODevice;
> typedef struct QEMUSGList QEMUSGList;
> typedef struct SHPCDevice SHPCDevice;
> +typedef struct VHostSCSI VHostSCSI;
>
> typedef uint64_t pcibus_t;
>
> diff --git a/qemu-config.c b/qemu-config.c
> index 5c3296b..33399ea 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -626,6 +626,21 @@ QemuOptsList qemu_boot_opts = {
> },
> };
>
> +QemuOptsList qemu_vhost_scsi_opts = {
> + .name = "vhost-scsi",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_vhost_scsi_opts.head),
> + .desc = {
> + {
> + .name = "wwpn",
> + .type = QEMU_OPT_STRING,
> + }, {
> + .name = "tpgt",
> + .type = QEMU_OPT_NUMBER,
> + },
> + { /* end of list */ }
> + },
> +};
> +
> static QemuOptsList *vm_config_groups[32] = {
> &qemu_drive_opts,
> &qemu_chardev_opts,
> @@ -641,6 +656,7 @@ static QemuOptsList *vm_config_groups[32] = {
> &qemu_machine_opts,
> &qemu_boot_opts,
> &qemu_iscsi_opts,
> + &qemu_vhost_scsi_opts,
> NULL,
> };
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 47cb5bd..4e7a03c 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -565,6 +565,10 @@ possible drivers and properties, use @code{-device ?} and
> ETEXI
>
> DEFHEADING()
> +DEF("vhost-scsi", HAS_ARG, QEMU_OPTION_vhost_scsi,
> + "-vhost-scsi wwpn=string0,tpgt=number0\n"
> + " add vhost-scsi device\n",
> + QEMU_ARCH_ALL)
>
> DEFHEADING(File system options:)
>
> diff --git a/vl.c b/vl.c
> index 91076f0..61c8284 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -144,6 +144,7 @@ int main(int argc, char **argv)
> #include "qemu-options.h"
> #include "qmp-commands.h"
> #include "main-loop.h"
> +#include "hw/vhost-scsi.h"
> #ifdef CONFIG_VIRTFS
> #include "fsdev/qemu-fsdev.h"
> #endif
> @@ -1858,6 +1859,14 @@ static int fsdev_init_func(QemuOpts *opts, void *opaque)
> }
> #endif
>
> +static int vhost_scsi_init_func(QemuOpts *opts, void *opaque)
> +{
> + if (!vhost_scsi_add_opts(opts)) {
> + return -1;
> + }
> + return 0;
> +}
> +
> static int mon_init_func(QemuOpts *opts, void *opaque)
> {
> CharDriverState *chr;
> @@ -2617,6 +2626,11 @@ int main(int argc, char **argv, char **envp)
> }
> break;
> #endif
> + case QEMU_OPTION_vhost_scsi:
> + if (!qemu_opts_parse(qemu_find_opts("vhost-scsi"), optarg, 0)) {
> + exit(1);
> + }
> + break;
> #ifdef CONFIG_SLIRP
> case QEMU_OPTION_tftp:
> legacy_tftp_prefix = optarg;
> @@ -3337,6 +3351,10 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> }
> #endif
> + if (qemu_opts_foreach(qemu_find_opts("vhost-scsi"),
> + vhost_scsi_init_func, NULL, 1)) {
> + exit(1);
> + }
>
> os_daemonize();
>
> --
> 1.7.2.5
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-13 8:59 ` Michael S. Tsirkin
@ 2012-08-14 21:12 ` Nicholas A. Bellinger
2012-08-18 19:10 ` Michael S. Tsirkin
0 siblings, 1 reply; 36+ messages in thread
From: Nicholas A. Bellinger @ 2012-08-14 21:12 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Mon, 2012-08-13 at 11:59 +0300, Michael S. Tsirkin wrote:
> On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> >
> > This patch adds a new type of host device that drives the vhost_scsi
> > device. The syntax to add vhost-scsi is:
> >
> > qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
> >
> > The virtio-scsi emulated device will make use of vhost-scsi to process
> > virtio-scsi requests inside the kernel and hand them to the in-kernel
> > SCSI target stack using the tcm_vhost fabric driver.
> >
> > The tcm_vhost driver was merged into the upstream linux kernel for 3.6-rc2,
> > and the commit can be found here:
> >
> > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=057cbf49a1f08297
> >
> > Changelog v1 -> v2:
> >
> > - Expose ABI version via VHOST_SCSI_GET_ABI_VERSION + use Rev 0 as
> > starting point for v3.6-rc code (Stefan + ALiguori + nab)
> > - Fix upstream qemu conflict in hw/qdev-properties.c
> > - Make GET_ABI_VERSION use int (nab + mst)
> > - Fix vhost-scsi case lables in configure (reported by paolo)
> > - Convert qdev_prop_vhost_scsi to use ->get() + ->set() following
> > qdev_prop_netdev (reported by paolo)
> > - Fix typo in qemu-options.hx definition of vhost-scsi (reported by paolo)
> >
> > Changelog v0 -> v1:
> >
> > - Add VHOST_SCSI_SET_ENDPOINT call (stefan)
> > - Enable vhost notifiers for multiple queues (Zhi)
> > - clear vhost-scsi endpoint on stopped (Zhi)
> > - Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
> > - Rename vhost_vring_target -> vhost_scsi_target (mst + nab)
> > - Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)
> >
> > Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> > Cc: Anthony Liguori <aliguori@us.ibm.com>
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: Michael S. Tsirkin <mst@redhat.com>
> > Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
>
>
> Sent mail too fast, sorry. More comments below.
>
> > ---
> > configure | 10 +++
> > hw/Makefile.objs | 1 +
> > hw/qdev-properties.c | 40 ++++++++++++
> > hw/qdev.h | 3 +
> > hw/vhost-scsi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > hw/vhost-scsi.h | 50 +++++++++++++++
> > qemu-common.h | 1 +
> > qemu-config.c | 16 +++++
> > qemu-options.hx | 4 +
> > vl.c | 18 +++++
> > 10 files changed, 313 insertions(+), 0 deletions(-)
> > create mode 100644 hw/vhost-scsi.c
> > create mode 100644 hw/vhost-scsi.h
> >
> > diff --git a/configure b/configure
> > index f0dbc03..1f03202 100755
> > --- a/configure
> > +++ b/configure
> > @@ -168,6 +168,7 @@ libattr=""
> > xfs=""
> >
> > vhost_net="no"
> > +vhost_scsi="no"
> > kvm="no"
> > gprof="no"
> > debug_tcg="no"
> > @@ -513,6 +514,7 @@ Haiku)
> > usb="linux"
> > kvm="yes"
> > vhost_net="yes"
> > + vhost_scsi="yes"
> > if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
> > audio_possible_drivers="$audio_possible_drivers fmod"
> > fi
> > @@ -818,6 +820,10 @@ for opt do
> > ;;
> > --enable-vhost-net) vhost_net="yes"
> > ;;
> > + --disable-vhost-scsi) vhost_scsi="no"
> > + ;;
> > + --enable-vhost-scsi) vhost_scsi="yes"
> > + ;;
> > --disable-opengl) opengl="no"
> > ;;
> > --enable-opengl) opengl="yes"
> > @@ -3116,6 +3122,7 @@ echo "posix_madvise $posix_madvise"
> > echo "uuid support $uuid"
> > echo "libcap-ng support $cap_ng"
> > echo "vhost-net support $vhost_net"
> > +echo "vhost-scsi support $vhost_scsi"
> > echo "Trace backend $trace_backend"
> > echo "Trace output file $trace_file-<pid>"
> > echo "spice support $spice"
> > @@ -3828,6 +3835,9 @@ case "$target_arch2" in
> > if test "$vhost_net" = "yes" ; then
> > echo "CONFIG_VHOST_NET=y" >> $config_target_mak
> > fi
> > + if test "$vhost_scsi" = "yes" ; then
> > + echo "CONFIG_VHOST_SCSI=y" >> $config_target_mak
> > + fi
> > fi
> > esac
> > case "$target_arch2" in
> > diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> > index 3ba5dd0..6ab75ec 100644
> > --- a/hw/Makefile.objs
> > +++ b/hw/Makefile.objs
> > @@ -169,6 +169,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
> > obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o
> > obj-$(CONFIG_SOFTMMU) += vhost_net.o
> > obj-$(CONFIG_VHOST_NET) += vhost.o
> > +obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
> > obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
> > obj-$(CONFIG_NO_PCI) += pci-stub.o
> > obj-$(CONFIG_VGA) += vga.o
> > diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> > index 8aca0d4..0266266 100644
> > --- a/hw/qdev-properties.c
> > +++ b/hw/qdev-properties.c
> > @@ -4,6 +4,7 @@
> > #include "blockdev.h"
> > #include "hw/block-common.h"
> > #include "net/hub.h"
> > +#include "vhost-scsi.h"
> >
> > void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
> > {
> > @@ -696,6 +697,45 @@ PropertyInfo qdev_prop_vlan = {
> > .set = set_vlan,
> > };
> >
> > +/* --- vhost-scsi --- */
> > +
> > +static int parse_vhost_scsi_dev(DeviceState *dev, const char *str, void **ptr)
> > +{
> > + VHostSCSI *p;
> > +
> > + p = find_vhost_scsi(str);
> > + if (p == NULL)
> > + return -ENOENT;
> > +
> > + *ptr = p;
> > + return 0;
> > +}
> > +
> > +static const char *print_vhost_scsi_dev(void *ptr)
> > +{
> > + VHostSCSI *p = ptr;
> > +
> > + return (p) ? vhost_scsi_get_id(p) : "<null>";
> > +}
> > +
> > +static void get_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> > + const char *name, Error **errp)
> > +{
> > + get_pointer(obj, v, opaque, print_vhost_scsi_dev, name, errp);
> > +}
> > +
> > +static void set_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> > + const char *name, Error **errp)
> > +{
> > + set_pointer(obj, v, opaque, parse_vhost_scsi_dev, name, errp);
> > +}
> > +
> > +PropertyInfo qdev_prop_vhost_scsi = {
> > + .name = "vhost-scsi",
> > + .get = get_vhost_scsi_dev,
> > + .set = set_vhost_scsi_dev,
> > +};
> > +
> > /* --- pointer --- */
> >
> > /* Not a proper property, just for dirty hacks. TODO Remove it! */
>
> Why does this make sense in the generic qdev-properties?
> There's exactly one device that can use this, no?
>
Mmmm, not sure on this one either.. Stefan..?
> > diff --git a/hw/qdev.h b/hw/qdev.h
> > index d699194..d5873bb 100644
> > --- a/hw/qdev.h
> > +++ b/hw/qdev.h
> > @@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
> > extern PropertyInfo qdev_prop_pci_devfn;
> > extern PropertyInfo qdev_prop_blocksize;
> > extern PropertyInfo qdev_prop_pci_host_devaddr;
> > +extern PropertyInfo qdev_prop_vhost_scsi;
> >
> > #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
> > .name = (_name), \
> > @@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
> > DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
> > #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> > DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
> > +#define DEFINE_PROP_VHOST_SCSI(_n, _s, _f) \
> > + DEFINE_PROP(_n, _s, _f, qdev_prop_vhost_scsi, VHostSCSI*)
> >
>
> Can this move to vhost-scsi.c?
>
Done
> > #define DEFINE_PROP_END_OF_LIST() \
> > {}
> > diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> > new file mode 100644
> > index 0000000..7145b2d
> > --- /dev/null
> > +++ b/hw/vhost-scsi.c
> > @@ -0,0 +1,170 @@
> > +/*
> > + * vhost_scsi host device
> > + *
> > + * Copyright IBM, Corp. 2011
> > + *
> > + * Authors:
> > + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> > + * See the COPYING.LIB file in the top-level directory.
> > + *
> > + */
> > +
> > +#include <sys/ioctl.h>
> > +#include "config.h"
> > +#include "qemu-queue.h"
> > +#include "vhost-scsi.h"
> > +#include "vhost.h"
> > +
> > +struct VHostSCSI {
> > + const char *id;
> > + const char *wwpn;
> > + uint16_t tpgt;
> > + struct vhost_dev dev;
> > + struct vhost_virtqueue vqs[3];
>
> Could you add enum for vq numbers pls?
>
Done
> > + QLIST_ENTRY(VHostSCSI) list;
> > +};
> > +
> > +static QLIST_HEAD(, VHostSCSI) vhost_scsi_list =
> > + QLIST_HEAD_INITIALIZER(vhost_scsi_list);
> > +
> > +VHostSCSI *find_vhost_scsi(const char *id)
> > +{
> > + VHostSCSI *vs;
> > +
> > + QLIST_FOREACH(vs, &vhost_scsi_list, list) {
> > + if (strcmp(id, vs->id) == 0) {
>
> !strcmp
>
Done
> > + return vs;
> > + }
> > + }
> > + return NULL;
> > +}
> > +
> > +const char *vhost_scsi_get_id(VHostSCSI *vs)
> > +{
> > + return vs->id;
> > +}
> > +
> > +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev)
> > +{
> > + int ret, abi_version;
> > + struct vhost_scsi_target backend;
> > +
> > + if (!vhost_dev_query(&vs->dev, vdev)) {
> > + return -ENOTSUP;
> > + }
> > +
> > + vs->dev.nvqs = 3;
> > + vs->dev.vqs = vs->vqs;
> > +
> > + ret = vhost_dev_enable_notifiers(&vs->dev, vdev);
> > + if (ret < 0) {
> > + return ret;
> > + }
> > +
> > + ret = vhost_dev_start(&vs->dev, vdev);
> > + if (ret < 0) {
> > + return ret;
> > + }
> > +
> > + memset(&backend, 0, sizeof(backend));
> > + ret = ioctl(vs->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> > + if (ret < 0) {
> > + ret = -errno;
> > + vhost_dev_stop(&vs->dev, vdev);
> > + return ret;
> > + }
> > + if (abi_version > VHOST_SCSI_ABI_VERSION) {
> > + fprintf(stderr, "The running tcm_vhost kernel abi_version: %d is greater"
> > + " than vhost_scsi userspace supports: %d\n", abi_version,
> > + VHOST_SCSI_ABI_VERSION);
> > + ret = -ENOSYS;
> > + vhost_dev_stop(&vs->dev, vdev);
> > + return ret;
> > + }
> > + fprintf(stdout, "TCM_vHost ABI version: %d\n", abi_version);
> > +
> > + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> > + backend.vhost_tpgt = vs->tpgt;
> > + ret = ioctl(vs->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
> > + if (ret < 0) {
> > + ret = -errno;
> > + vhost_dev_stop(&vs->dev, vdev);
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> > +{
> > + int ret;
> > + struct vhost_scsi_target backend;
> > +
> > + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> > + backend.vhost_tpgt = vs->tpgt;
> > + ret = ioctl(vs->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
> > + if (ret < 0) {
> > + fprintf(stderr, "Failed to clear endpoint\n");
> > + }
> > +
> > + vhost_dev_stop(&vs->dev, vdev);
> > +}
> > +
> > +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> > + uint16_t tpgt)
> > +{
> > + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> > + int ret;
> > +
> > + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> > + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> > +
>
> Please do not keep debugging fprintfs around.
>
Dropped
> > + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
>
> commented on this separately
>
...
> > + if (ret < 0) {
> > + fprintf(stderr, "vhost-scsi: vhost initialization failed: %s\n",
> > + strerror(-ret));
>
> errors should go to monitor, here and elsewhere.
>
I think this means using monitor_printf() right..?
Looking at that now..
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-14 21:12 ` Nicholas A. Bellinger
@ 2012-08-18 19:10 ` Michael S. Tsirkin
2012-08-18 23:38 ` Nicholas A. Bellinger
0 siblings, 1 reply; 36+ messages in thread
From: Michael S. Tsirkin @ 2012-08-18 19:10 UTC (permalink / raw)
To: Nicholas A. Bellinger
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Tue, Aug 14, 2012 at 02:12:29PM -0700, Nicholas A. Bellinger wrote:
> On Mon, 2012-08-13 at 11:59 +0300, Michael S. Tsirkin wrote:
> > On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
> > > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > >
> > > This patch adds a new type of host device that drives the vhost_scsi
> > > device. The syntax to add vhost-scsi is:
> > >
> > > qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
> > >
> > > The virtio-scsi emulated device will make use of vhost-scsi to process
> > > virtio-scsi requests inside the kernel and hand them to the in-kernel
> > > SCSI target stack using the tcm_vhost fabric driver.
> > >
> > > The tcm_vhost driver was merged into the upstream linux kernel for 3.6-rc2,
> > > and the commit can be found here:
> > >
> > > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=057cbf49a1f08297
> > >
> > > Changelog v1 -> v2:
> > >
> > > - Expose ABI version via VHOST_SCSI_GET_ABI_VERSION + use Rev 0 as
> > > starting point for v3.6-rc code (Stefan + ALiguori + nab)
> > > - Fix upstream qemu conflict in hw/qdev-properties.c
> > > - Make GET_ABI_VERSION use int (nab + mst)
> > > - Fix vhost-scsi case lables in configure (reported by paolo)
> > > - Convert qdev_prop_vhost_scsi to use ->get() + ->set() following
> > > qdev_prop_netdev (reported by paolo)
> > > - Fix typo in qemu-options.hx definition of vhost-scsi (reported by paolo)
> > >
> > > Changelog v0 -> v1:
> > >
> > > - Add VHOST_SCSI_SET_ENDPOINT call (stefan)
> > > - Enable vhost notifiers for multiple queues (Zhi)
> > > - clear vhost-scsi endpoint on stopped (Zhi)
> > > - Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
> > > - Rename vhost_vring_target -> vhost_scsi_target (mst + nab)
> > > - Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)
> > >
> > > Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > > Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> > > Cc: Anthony Liguori <aliguori@us.ibm.com>
> > > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > > Cc: Michael S. Tsirkin <mst@redhat.com>
> > > Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
> >
> >
> > Sent mail too fast, sorry. More comments below.
> >
> > > ---
> > > configure | 10 +++
> > > hw/Makefile.objs | 1 +
> > > hw/qdev-properties.c | 40 ++++++++++++
> > > hw/qdev.h | 3 +
> > > hw/vhost-scsi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > > hw/vhost-scsi.h | 50 +++++++++++++++
> > > qemu-common.h | 1 +
> > > qemu-config.c | 16 +++++
> > > qemu-options.hx | 4 +
> > > vl.c | 18 +++++
> > > 10 files changed, 313 insertions(+), 0 deletions(-)
> > > create mode 100644 hw/vhost-scsi.c
> > > create mode 100644 hw/vhost-scsi.h
> > >
> > > diff --git a/configure b/configure
> > > index f0dbc03..1f03202 100755
> > > --- a/configure
> > > +++ b/configure
> > > @@ -168,6 +168,7 @@ libattr=""
> > > xfs=""
> > >
> > > vhost_net="no"
> > > +vhost_scsi="no"
> > > kvm="no"
> > > gprof="no"
> > > debug_tcg="no"
> > > @@ -513,6 +514,7 @@ Haiku)
> > > usb="linux"
> > > kvm="yes"
> > > vhost_net="yes"
> > > + vhost_scsi="yes"
> > > if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
> > > audio_possible_drivers="$audio_possible_drivers fmod"
> > > fi
> > > @@ -818,6 +820,10 @@ for opt do
> > > ;;
> > > --enable-vhost-net) vhost_net="yes"
> > > ;;
> > > + --disable-vhost-scsi) vhost_scsi="no"
> > > + ;;
> > > + --enable-vhost-scsi) vhost_scsi="yes"
> > > + ;;
> > > --disable-opengl) opengl="no"
> > > ;;
> > > --enable-opengl) opengl="yes"
> > > @@ -3116,6 +3122,7 @@ echo "posix_madvise $posix_madvise"
> > > echo "uuid support $uuid"
> > > echo "libcap-ng support $cap_ng"
> > > echo "vhost-net support $vhost_net"
> > > +echo "vhost-scsi support $vhost_scsi"
> > > echo "Trace backend $trace_backend"
> > > echo "Trace output file $trace_file-<pid>"
> > > echo "spice support $spice"
> > > @@ -3828,6 +3835,9 @@ case "$target_arch2" in
> > > if test "$vhost_net" = "yes" ; then
> > > echo "CONFIG_VHOST_NET=y" >> $config_target_mak
> > > fi
> > > + if test "$vhost_scsi" = "yes" ; then
> > > + echo "CONFIG_VHOST_SCSI=y" >> $config_target_mak
> > > + fi
> > > fi
> > > esac
> > > case "$target_arch2" in
> > > diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> > > index 3ba5dd0..6ab75ec 100644
> > > --- a/hw/Makefile.objs
> > > +++ b/hw/Makefile.objs
> > > @@ -169,6 +169,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
> > > obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o
> > > obj-$(CONFIG_SOFTMMU) += vhost_net.o
> > > obj-$(CONFIG_VHOST_NET) += vhost.o
> > > +obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
> > > obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
> > > obj-$(CONFIG_NO_PCI) += pci-stub.o
> > > obj-$(CONFIG_VGA) += vga.o
> > > diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> > > index 8aca0d4..0266266 100644
> > > --- a/hw/qdev-properties.c
> > > +++ b/hw/qdev-properties.c
> > > @@ -4,6 +4,7 @@
> > > #include "blockdev.h"
> > > #include "hw/block-common.h"
> > > #include "net/hub.h"
> > > +#include "vhost-scsi.h"
> > >
> > > void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
> > > {
> > > @@ -696,6 +697,45 @@ PropertyInfo qdev_prop_vlan = {
> > > .set = set_vlan,
> > > };
> > >
> > > +/* --- vhost-scsi --- */
> > > +
> > > +static int parse_vhost_scsi_dev(DeviceState *dev, const char *str, void **ptr)
> > > +{
> > > + VHostSCSI *p;
> > > +
> > > + p = find_vhost_scsi(str);
> > > + if (p == NULL)
> > > + return -ENOENT;
> > > +
> > > + *ptr = p;
> > > + return 0;
> > > +}
> > > +
> > > +static const char *print_vhost_scsi_dev(void *ptr)
> > > +{
> > > + VHostSCSI *p = ptr;
> > > +
> > > + return (p) ? vhost_scsi_get_id(p) : "<null>";
> > > +}
> > > +
> > > +static void get_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> > > + const char *name, Error **errp)
> > > +{
> > > + get_pointer(obj, v, opaque, print_vhost_scsi_dev, name, errp);
> > > +}
> > > +
> > > +static void set_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> > > + const char *name, Error **errp)
> > > +{
> > > + set_pointer(obj, v, opaque, parse_vhost_scsi_dev, name, errp);
> > > +}
> > > +
> > > +PropertyInfo qdev_prop_vhost_scsi = {
> > > + .name = "vhost-scsi",
> > > + .get = get_vhost_scsi_dev,
> > > + .set = set_vhost_scsi_dev,
> > > +};
> > > +
> > > /* --- pointer --- */
> > >
> > > /* Not a proper property, just for dirty hacks. TODO Remove it! */
> >
> > Why does this make sense in the generic qdev-properties?
> > There's exactly one device that can use this, no?
> >
>
> Mmmm, not sure on this one either.. Stefan..?
>
> > > diff --git a/hw/qdev.h b/hw/qdev.h
> > > index d699194..d5873bb 100644
> > > --- a/hw/qdev.h
> > > +++ b/hw/qdev.h
> > > @@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
> > > extern PropertyInfo qdev_prop_pci_devfn;
> > > extern PropertyInfo qdev_prop_blocksize;
> > > extern PropertyInfo qdev_prop_pci_host_devaddr;
> > > +extern PropertyInfo qdev_prop_vhost_scsi;
> > >
> > > #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
> > > .name = (_name), \
> > > @@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
> > > DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
> > > #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> > > DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
> > > +#define DEFINE_PROP_VHOST_SCSI(_n, _s, _f) \
> > > + DEFINE_PROP(_n, _s, _f, qdev_prop_vhost_scsi, VHostSCSI*)
> > >
> >
> > Can this move to vhost-scsi.c?
> >
>
> Done
>
> > > #define DEFINE_PROP_END_OF_LIST() \
> > > {}
> > > diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> > > new file mode 100644
> > > index 0000000..7145b2d
> > > --- /dev/null
> > > +++ b/hw/vhost-scsi.c
> > > @@ -0,0 +1,170 @@
> > > +/*
> > > + * vhost_scsi host device
> > > + *
> > > + * Copyright IBM, Corp. 2011
> > > + *
> > > + * Authors:
> > > + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > > + *
> > > + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> > > + * See the COPYING.LIB file in the top-level directory.
> > > + *
> > > + */
> > > +
> > > +#include <sys/ioctl.h>
> > > +#include "config.h"
> > > +#include "qemu-queue.h"
> > > +#include "vhost-scsi.h"
> > > +#include "vhost.h"
> > > +
> > > +struct VHostSCSI {
> > > + const char *id;
> > > + const char *wwpn;
> > > + uint16_t tpgt;
> > > + struct vhost_dev dev;
> > > + struct vhost_virtqueue vqs[3];
> >
> > Could you add enum for vq numbers pls?
> >
>
> Done
>
> > > + QLIST_ENTRY(VHostSCSI) list;
> > > +};
> > > +
> > > +static QLIST_HEAD(, VHostSCSI) vhost_scsi_list =
> > > + QLIST_HEAD_INITIALIZER(vhost_scsi_list);
> > > +
> > > +VHostSCSI *find_vhost_scsi(const char *id)
> > > +{
> > > + VHostSCSI *vs;
> > > +
> > > + QLIST_FOREACH(vs, &vhost_scsi_list, list) {
> > > + if (strcmp(id, vs->id) == 0) {
> >
> > !strcmp
> >
>
> Done
>
> > > + return vs;
> > > + }
> > > + }
> > > + return NULL;
> > > +}
> > > +
> > > +const char *vhost_scsi_get_id(VHostSCSI *vs)
> > > +{
> > > + return vs->id;
> > > +}
> > > +
> > > +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev)
> > > +{
> > > + int ret, abi_version;
> > > + struct vhost_scsi_target backend;
> > > +
> > > + if (!vhost_dev_query(&vs->dev, vdev)) {
> > > + return -ENOTSUP;
> > > + }
> > > +
> > > + vs->dev.nvqs = 3;
> > > + vs->dev.vqs = vs->vqs;
> > > +
> > > + ret = vhost_dev_enable_notifiers(&vs->dev, vdev);
> > > + if (ret < 0) {
> > > + return ret;
> > > + }
> > > +
> > > + ret = vhost_dev_start(&vs->dev, vdev);
> > > + if (ret < 0) {
> > > + return ret;
> > > + }
> > > +
> > > + memset(&backend, 0, sizeof(backend));
> > > + ret = ioctl(vs->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> > > + if (ret < 0) {
> > > + ret = -errno;
> > > + vhost_dev_stop(&vs->dev, vdev);
> > > + return ret;
> > > + }
> > > + if (abi_version > VHOST_SCSI_ABI_VERSION) {
> > > + fprintf(stderr, "The running tcm_vhost kernel abi_version: %d is greater"
> > > + " than vhost_scsi userspace supports: %d\n", abi_version,
> > > + VHOST_SCSI_ABI_VERSION);
> > > + ret = -ENOSYS;
> > > + vhost_dev_stop(&vs->dev, vdev);
> > > + return ret;
> > > + }
> > > + fprintf(stdout, "TCM_vHost ABI version: %d\n", abi_version);
> > > +
> > > + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> > > + backend.vhost_tpgt = vs->tpgt;
> > > + ret = ioctl(vs->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
> > > + if (ret < 0) {
> > > + ret = -errno;
> > > + vhost_dev_stop(&vs->dev, vdev);
> > > + return ret;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> > > +{
> > > + int ret;
> > > + struct vhost_scsi_target backend;
> > > +
> > > + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> > > + backend.vhost_tpgt = vs->tpgt;
> > > + ret = ioctl(vs->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
> > > + if (ret < 0) {
> > > + fprintf(stderr, "Failed to clear endpoint\n");
> > > + }
> > > +
> > > + vhost_dev_stop(&vs->dev, vdev);
> > > +}
> > > +
> > > +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> > > + uint16_t tpgt)
> > > +{
> > > + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> > > + int ret;
> > > +
> > > + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> > > + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> > > +
> >
> > Please do not keep debugging fprintfs around.
> >
>
> Dropped
>
> > > + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
> >
> > commented on this separately
> >
>
> ...
>
> > > + if (ret < 0) {
> > > + fprintf(stderr, "vhost-scsi: vhost initialization failed: %s\n",
> > > + strerror(-ret));
> >
> > errors should go to monitor, here and elsewhere.
> >
>
> I think this means using monitor_printf() right..?
>
> Looking at that now..
error_report is handier.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-18 19:10 ` Michael S. Tsirkin
@ 2012-08-18 23:38 ` Nicholas A. Bellinger
0 siblings, 0 replies; 36+ messages in thread
From: Nicholas A. Bellinger @ 2012-08-18 23:38 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Stefan Hajnoczi, kvm-devel, qemu-devel, Zhi Yong Wu,
Anthony Liguori, target-devel, Paolo Bonzini, lf-virt
On Sat, 2012-08-18 at 22:10 +0300, Michael S. Tsirkin wrote:
> On Tue, Aug 14, 2012 at 02:12:29PM -0700, Nicholas A. Bellinger wrote:
> > On Mon, 2012-08-13 at 11:59 +0300, Michael S. Tsirkin wrote:
> > > On Mon, Aug 13, 2012 at 08:35:14AM +0000, Nicholas A. Bellinger wrote:
<SNIP>
> >
> > > > + if (ret < 0) {
> > > > + fprintf(stderr, "vhost-scsi: vhost initialization failed: %s\n",
> > > > + strerror(-ret));
> > >
> > > errors should go to monitor, here and elsewhere.
> > >
> >
> > I think this means using monitor_printf() right..?
> >
> > Looking at that now..
>
>
> error_report is handier.
>
Converted all fprintf(stderr, ...) -> error_report() usage for RFC-v3.
Thanks MST!
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-13 8:35 ` [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost Nicholas A. Bellinger
2012-08-13 8:53 ` Michael S. Tsirkin
2012-08-13 8:59 ` Michael S. Tsirkin
@ 2012-08-13 19:47 ` Blue Swirl
2012-08-14 21:17 ` Nicholas A. Bellinger
2012-08-20 9:02 ` Paolo Bonzini
3 siblings, 1 reply; 36+ messages in thread
From: Blue Swirl @ 2012-08-13 19:47 UTC (permalink / raw)
To: Nicholas A. Bellinger
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Michael S. Tsirkin,
Jan Kiszka, Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Mon, Aug 13, 2012 at 8:35 AM, Nicholas A. Bellinger
<nab@linux-iscsi.org> wrote:
> From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>
> This patch adds a new type of host device that drives the vhost_scsi
> device. The syntax to add vhost-scsi is:
>
> qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
>
> The virtio-scsi emulated device will make use of vhost-scsi to process
> virtio-scsi requests inside the kernel and hand them to the in-kernel
> SCSI target stack using the tcm_vhost fabric driver.
>
> The tcm_vhost driver was merged into the upstream linux kernel for 3.6-rc2,
> and the commit can be found here:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=057cbf49a1f08297
>
> Changelog v1 -> v2:
>
> - Expose ABI version via VHOST_SCSI_GET_ABI_VERSION + use Rev 0 as
> starting point for v3.6-rc code (Stefan + ALiguori + nab)
> - Fix upstream qemu conflict in hw/qdev-properties.c
> - Make GET_ABI_VERSION use int (nab + mst)
> - Fix vhost-scsi case lables in configure (reported by paolo)
> - Convert qdev_prop_vhost_scsi to use ->get() + ->set() following
> qdev_prop_netdev (reported by paolo)
> - Fix typo in qemu-options.hx definition of vhost-scsi (reported by paolo)
>
> Changelog v0 -> v1:
>
> - Add VHOST_SCSI_SET_ENDPOINT call (stefan)
> - Enable vhost notifiers for multiple queues (Zhi)
> - clear vhost-scsi endpoint on stopped (Zhi)
> - Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
> - Rename vhost_vring_target -> vhost_scsi_target (mst + nab)
> - Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)
>
> Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> Cc: Anthony Liguori <aliguori@us.ibm.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
> ---
> configure | 10 +++
> hw/Makefile.objs | 1 +
> hw/qdev-properties.c | 40 ++++++++++++
> hw/qdev.h | 3 +
> hw/vhost-scsi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/vhost-scsi.h | 50 +++++++++++++++
> qemu-common.h | 1 +
> qemu-config.c | 16 +++++
> qemu-options.hx | 4 +
> vl.c | 18 +++++
> 10 files changed, 313 insertions(+), 0 deletions(-)
> create mode 100644 hw/vhost-scsi.c
> create mode 100644 hw/vhost-scsi.h
>
> diff --git a/configure b/configure
> index f0dbc03..1f03202 100755
> --- a/configure
> +++ b/configure
> @@ -168,6 +168,7 @@ libattr=""
> xfs=""
>
> vhost_net="no"
> +vhost_scsi="no"
> kvm="no"
> gprof="no"
> debug_tcg="no"
> @@ -513,6 +514,7 @@ Haiku)
> usb="linux"
> kvm="yes"
> vhost_net="yes"
> + vhost_scsi="yes"
> if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
> audio_possible_drivers="$audio_possible_drivers fmod"
> fi
> @@ -818,6 +820,10 @@ for opt do
> ;;
> --enable-vhost-net) vhost_net="yes"
> ;;
> + --disable-vhost-scsi) vhost_scsi="no"
> + ;;
> + --enable-vhost-scsi) vhost_scsi="yes"
> + ;;
> --disable-opengl) opengl="no"
> ;;
> --enable-opengl) opengl="yes"
> @@ -3116,6 +3122,7 @@ echo "posix_madvise $posix_madvise"
> echo "uuid support $uuid"
> echo "libcap-ng support $cap_ng"
> echo "vhost-net support $vhost_net"
> +echo "vhost-scsi support $vhost_scsi"
> echo "Trace backend $trace_backend"
> echo "Trace output file $trace_file-<pid>"
> echo "spice support $spice"
> @@ -3828,6 +3835,9 @@ case "$target_arch2" in
> if test "$vhost_net" = "yes" ; then
> echo "CONFIG_VHOST_NET=y" >> $config_target_mak
> fi
> + if test "$vhost_scsi" = "yes" ; then
> + echo "CONFIG_VHOST_SCSI=y" >> $config_target_mak
> + fi
> fi
> esac
> case "$target_arch2" in
> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> index 3ba5dd0..6ab75ec 100644
> --- a/hw/Makefile.objs
> +++ b/hw/Makefile.objs
> @@ -169,6 +169,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
> obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o
> obj-$(CONFIG_SOFTMMU) += vhost_net.o
> obj-$(CONFIG_VHOST_NET) += vhost.o
> +obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
> obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
> obj-$(CONFIG_NO_PCI) += pci-stub.o
> obj-$(CONFIG_VGA) += vga.o
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 8aca0d4..0266266 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -4,6 +4,7 @@
> #include "blockdev.h"
> #include "hw/block-common.h"
> #include "net/hub.h"
> +#include "vhost-scsi.h"
>
> void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
> {
> @@ -696,6 +697,45 @@ PropertyInfo qdev_prop_vlan = {
> .set = set_vlan,
> };
>
> +/* --- vhost-scsi --- */
> +
> +static int parse_vhost_scsi_dev(DeviceState *dev, const char *str, void **ptr)
> +{
> + VHostSCSI *p;
> +
> + p = find_vhost_scsi(str);
> + if (p == NULL)
> + return -ENOENT;
Braces, please.
> +
> + *ptr = p;
> + return 0;
> +}
> +
> +static const char *print_vhost_scsi_dev(void *ptr)
> +{
> + VHostSCSI *p = ptr;
> +
> + return (p) ? vhost_scsi_get_id(p) : "<null>";
> +}
> +
> +static void get_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + get_pointer(obj, v, opaque, print_vhost_scsi_dev, name, errp);
> +}
> +
> +static void set_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + set_pointer(obj, v, opaque, parse_vhost_scsi_dev, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_vhost_scsi = {
> + .name = "vhost-scsi",
> + .get = get_vhost_scsi_dev,
> + .set = set_vhost_scsi_dev,
> +};
> +
> /* --- pointer --- */
>
> /* Not a proper property, just for dirty hacks. TODO Remove it! */
> diff --git a/hw/qdev.h b/hw/qdev.h
> index d699194..d5873bb 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
> extern PropertyInfo qdev_prop_pci_devfn;
> extern PropertyInfo qdev_prop_blocksize;
> extern PropertyInfo qdev_prop_pci_host_devaddr;
> +extern PropertyInfo qdev_prop_vhost_scsi;
>
> #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
> .name = (_name), \
> @@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
> DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
> #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
> +#define DEFINE_PROP_VHOST_SCSI(_n, _s, _f) \
> + DEFINE_PROP(_n, _s, _f, qdev_prop_vhost_scsi, VHostSCSI*)
>
> #define DEFINE_PROP_END_OF_LIST() \
> {}
> diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> new file mode 100644
> index 0000000..7145b2d
> --- /dev/null
> +++ b/hw/vhost-scsi.c
> @@ -0,0 +1,170 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include <sys/ioctl.h>
> +#include "config.h"
> +#include "qemu-queue.h"
> +#include "vhost-scsi.h"
> +#include "vhost.h"
> +
> +struct VHostSCSI {
> + const char *id;
> + const char *wwpn;
> + uint16_t tpgt;
> + struct vhost_dev dev;
> + struct vhost_virtqueue vqs[3];
> + QLIST_ENTRY(VHostSCSI) list;
> +};
> +
> +static QLIST_HEAD(, VHostSCSI) vhost_scsi_list =
> + QLIST_HEAD_INITIALIZER(vhost_scsi_list);
> +
> +VHostSCSI *find_vhost_scsi(const char *id)
> +{
> + VHostSCSI *vs;
> +
> + QLIST_FOREACH(vs, &vhost_scsi_list, list) {
> + if (strcmp(id, vs->id) == 0) {
> + return vs;
> + }
> + }
> + return NULL;
> +}
> +
> +const char *vhost_scsi_get_id(VHostSCSI *vs)
> +{
> + return vs->id;
> +}
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret, abi_version;
> + struct vhost_scsi_target backend;
> +
> + if (!vhost_dev_query(&vs->dev, vdev)) {
> + return -ENOTSUP;
> + }
> +
> + vs->dev.nvqs = 3;
> + vs->dev.vqs = vs->vqs;
> +
> + ret = vhost_dev_enable_notifiers(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + ret = vhost_dev_start(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + memset(&backend, 0, sizeof(backend));
> + ret = ioctl(vs->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + if (abi_version > VHOST_SCSI_ABI_VERSION) {
> + fprintf(stderr, "The running tcm_vhost kernel abi_version: %d is greater"
> + " than vhost_scsi userspace supports: %d\n", abi_version,
> + VHOST_SCSI_ABI_VERSION);
> + ret = -ENOSYS;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + fprintf(stdout, "TCM_vHost ABI version: %d\n", abi_version);
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
Please change vhost_wwpn to plain char *, then the cast can be removed.
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret;
> + struct vhost_scsi_target backend;
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
Also here.
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
> + if (ret < 0) {
> + fprintf(stderr, "Failed to clear endpoint\n");
> + }
> +
> + vhost_dev_stop(&vs->dev, vdev);
> +}
> +
> +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> + uint16_t tpgt)
> +{
> + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> + int ret;
> +
> + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> +
> + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
> + if (ret < 0) {
> + fprintf(stderr, "vhost-scsi: vhost initialization failed: %s\n",
> + strerror(-ret));
> + return NULL;
> + }
> + vs->dev.backend_features = 0;
> + vs->dev.acked_features = 0;
> +
> + vs->id = g_strdup(id);
> + vs->wwpn = g_strdup(wwpn);
> + vs->tpgt = tpgt;
> + QLIST_INSERT_HEAD(&vhost_scsi_list, vs, list);
> +
> + return vs;
> +}
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
> +{
> + const char *id;
> + const char *wwpn;
> + uint64_t tpgt;
> +
> + id = qemu_opts_id(opts);
> + if (!id) {
> + fprintf(stderr, "vhost-scsi: no id specified\n");
> + return NULL;
> + }
> + if (find_vhost_scsi(id)) {
> + fprintf(stderr, "duplicate vhost-scsi: \"%s\"\n", id);
> + return NULL;
> + }
> +
> + wwpn = qemu_opt_get(opts, "wwpn");
> + if (!wwpn) {
> + fprintf(stderr, "vhost-scsi: \"%s\" missing wwpn\n", id);
> + return NULL;
> + }
> +
> + tpgt = qemu_opt_get_number(opts, "tpgt", UINT64_MAX);
> + if (tpgt > UINT16_MAX) {
> + fprintf(stderr, "vhost-scsi: \"%s\" needs a 16-bit tpgt\n", id);
> + return NULL;
> + }
> +
> + return vhost_scsi_add(id, wwpn, tpgt);
> +}
> diff --git a/hw/vhost-scsi.h b/hw/vhost-scsi.h
> new file mode 100644
> index 0000000..f3096dc
> --- /dev/null
> +++ b/hw/vhost-scsi.h
> @@ -0,0 +1,50 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#ifndef VHOST_SCSI_H
> +#define VHOST_SCSI_H
> +
> +#include "qemu-common.h"
> +#include "qemu-option.h"
> +
> +/*
> + * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
> + *
> + * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate +
> + * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage
> + */
> +
> +#define VHOST_SCSI_ABI_VERSION 0
> +
> +/* TODO #include <linux/vhost.h> properly */
> +/* For VHOST_SCSI_SET_ENDPOINT/VHOST_SCSI_CLEAR_ENDPOINT ioctl */
> +struct vhost_scsi_target {
> + int abi_version;
> + unsigned char vhost_wwpn[224];
> + unsigned short vhost_tpgt;
> +};
> +
> +#define VHOST_VIRTIO 0xAF
> +#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
> +#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
> +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct vhost_scsi_target)
> +
> +VHostSCSI *find_vhost_scsi(const char *id);
> +const char *vhost_scsi_get_id(VHostSCSI *vs);
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts);
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev);
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev);
> +
> +#endif
> diff --git a/qemu-common.h b/qemu-common.h
> index f9deca6..ec36002 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -280,6 +280,7 @@ typedef struct EventNotifier EventNotifier;
> typedef struct VirtIODevice VirtIODevice;
> typedef struct QEMUSGList QEMUSGList;
> typedef struct SHPCDevice SHPCDevice;
> +typedef struct VHostSCSI VHostSCSI;
>
> typedef uint64_t pcibus_t;
>
> diff --git a/qemu-config.c b/qemu-config.c
> index 5c3296b..33399ea 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -626,6 +626,21 @@ QemuOptsList qemu_boot_opts = {
> },
> };
>
> +QemuOptsList qemu_vhost_scsi_opts = {
> + .name = "vhost-scsi",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_vhost_scsi_opts.head),
> + .desc = {
> + {
> + .name = "wwpn",
> + .type = QEMU_OPT_STRING,
> + }, {
> + .name = "tpgt",
> + .type = QEMU_OPT_NUMBER,
> + },
> + { /* end of list */ }
> + },
> +};
> +
> static QemuOptsList *vm_config_groups[32] = {
> &qemu_drive_opts,
> &qemu_chardev_opts,
> @@ -641,6 +656,7 @@ static QemuOptsList *vm_config_groups[32] = {
> &qemu_machine_opts,
> &qemu_boot_opts,
> &qemu_iscsi_opts,
> + &qemu_vhost_scsi_opts,
> NULL,
> };
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 47cb5bd..4e7a03c 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -565,6 +565,10 @@ possible drivers and properties, use @code{-device ?} and
> ETEXI
>
> DEFHEADING()
> +DEF("vhost-scsi", HAS_ARG, QEMU_OPTION_vhost_scsi,
> + "-vhost-scsi wwpn=string0,tpgt=number0\n"
> + " add vhost-scsi device\n",
> + QEMU_ARCH_ALL)
>
> DEFHEADING(File system options:)
>
> diff --git a/vl.c b/vl.c
> index 91076f0..61c8284 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -144,6 +144,7 @@ int main(int argc, char **argv)
> #include "qemu-options.h"
> #include "qmp-commands.h"
> #include "main-loop.h"
> +#include "hw/vhost-scsi.h"
> #ifdef CONFIG_VIRTFS
> #include "fsdev/qemu-fsdev.h"
> #endif
> @@ -1858,6 +1859,14 @@ static int fsdev_init_func(QemuOpts *opts, void *opaque)
> }
> #endif
>
> +static int vhost_scsi_init_func(QemuOpts *opts, void *opaque)
> +{
> + if (!vhost_scsi_add_opts(opts)) {
> + return -1;
> + }
> + return 0;
> +}
> +
> static int mon_init_func(QemuOpts *opts, void *opaque)
> {
> CharDriverState *chr;
> @@ -2617,6 +2626,11 @@ int main(int argc, char **argv, char **envp)
> }
> break;
> #endif
> + case QEMU_OPTION_vhost_scsi:
> + if (!qemu_opts_parse(qemu_find_opts("vhost-scsi"), optarg, 0)) {
> + exit(1);
> + }
> + break;
> #ifdef CONFIG_SLIRP
> case QEMU_OPTION_tftp:
> legacy_tftp_prefix = optarg;
> @@ -3337,6 +3351,10 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> }
> #endif
> + if (qemu_opts_foreach(qemu_find_opts("vhost-scsi"),
> + vhost_scsi_init_func, NULL, 1)) {
> + exit(1);
> + }
>
> os_daemonize();
>
> --
> 1.7.2.5
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-13 19:47 ` Blue Swirl
@ 2012-08-14 21:17 ` Nicholas A. Bellinger
0 siblings, 0 replies; 36+ messages in thread
From: Nicholas A. Bellinger @ 2012-08-14 21:17 UTC (permalink / raw)
To: Blue Swirl
Cc: Anthony Liguori, Stefan Hajnoczi, kvm-devel, Michael S. Tsirkin,
Jan Kiszka, Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, Paolo Bonzini, lf-virt,
Christoph Hellwig
On Mon, 2012-08-13 at 19:47 +0000, Blue Swirl wrote:
> On Mon, Aug 13, 2012 at 8:35 AM, Nicholas A. Bellinger
> <nab@linux-iscsi.org> wrote:
> > From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> >
> > This patch adds a new type of host device that drives the vhost_scsi
> > device. The syntax to add vhost-scsi is:
> >
> > qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
> >
> > The virtio-scsi emulated device will make use of vhost-scsi to process
> > virtio-scsi requests inside the kernel and hand them to the in-kernel
> > SCSI target stack using the tcm_vhost fabric driver.
> >
> > The tcm_vhost driver was merged into the upstream linux kernel for 3.6-rc2,
> > and the commit can be found here:
> >
> > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=057cbf49a1f08297
> >
> > Changelog v1 -> v2:
> >
> > - Expose ABI version via VHOST_SCSI_GET_ABI_VERSION + use Rev 0 as
> > starting point for v3.6-rc code (Stefan + ALiguori + nab)
> > - Fix upstream qemu conflict in hw/qdev-properties.c
> > - Make GET_ABI_VERSION use int (nab + mst)
> > - Fix vhost-scsi case lables in configure (reported by paolo)
> > - Convert qdev_prop_vhost_scsi to use ->get() + ->set() following
> > qdev_prop_netdev (reported by paolo)
> > - Fix typo in qemu-options.hx definition of vhost-scsi (reported by paolo)
> >
> > Changelog v0 -> v1:
> >
> > - Add VHOST_SCSI_SET_ENDPOINT call (stefan)
> > - Enable vhost notifiers for multiple queues (Zhi)
> > - clear vhost-scsi endpoint on stopped (Zhi)
> > - Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
> > - Rename vhost_vring_target -> vhost_scsi_target (mst + nab)
> > - Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)
> >
> > Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> > Cc: Anthony Liguori <aliguori@us.ibm.com>
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: Michael S. Tsirkin <mst@redhat.com>
> > Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
> > ---
> > configure | 10 +++
> > hw/Makefile.objs | 1 +
> > hw/qdev-properties.c | 40 ++++++++++++
> > hw/qdev.h | 3 +
> > hw/vhost-scsi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > hw/vhost-scsi.h | 50 +++++++++++++++
> > qemu-common.h | 1 +
> > qemu-config.c | 16 +++++
> > qemu-options.hx | 4 +
> > vl.c | 18 +++++
> > 10 files changed, 313 insertions(+), 0 deletions(-)
> > create mode 100644 hw/vhost-scsi.c
> > create mode 100644 hw/vhost-scsi.h
> >
<SNIP>
> >
> > +/* --- vhost-scsi --- */
> > +
> > +static int parse_vhost_scsi_dev(DeviceState *dev, const char *str, void **ptr)
> > +{
> > + VHostSCSI *p;
> > +
> > + p = find_vhost_scsi(str);
> > + if (p == NULL)
> > + return -ENOENT;
>
> Braces, please.
>
Fixed
> > +
> > + *ptr = p;
> > + return 0;
> > +}
> > +
> > +static const char *print_vhost_scsi_dev(void *ptr)
> > +{
> > + VHostSCSI *p = ptr;
> > +
> > + return (p) ? vhost_scsi_get_id(p) : "<null>";
> > +}
> > +
> > +static void get_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> > + const char *name, Error **errp)
> > +{
> > + get_pointer(obj, v, opaque, print_vhost_scsi_dev, name, errp);
> > +}
> > +
> > +static void set_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> > + const char *name, Error **errp)
> > +{
> > + set_pointer(obj, v, opaque, parse_vhost_scsi_dev, name, errp);
> > +}
> > +
> > +PropertyInfo qdev_prop_vhost_scsi = {
> > + .name = "vhost-scsi",
> > + .get = get_vhost_scsi_dev,
> > + .set = set_vhost_scsi_dev,
> > +};
> > +
> > /* --- pointer --- */
> >
> > /* Not a proper property, just for dirty hacks. TODO Remove it! */
> > diff --git a/hw/qdev.h b/hw/qdev.h
> > index d699194..d5873bb 100644
> > --- a/hw/qdev.h
> > +++ b/hw/qdev.h
> > @@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
> > extern PropertyInfo qdev_prop_pci_devfn;
> > extern PropertyInfo qdev_prop_blocksize;
> > extern PropertyInfo qdev_prop_pci_host_devaddr;
> > +extern PropertyInfo qdev_prop_vhost_scsi;
> >
> > #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
> > .name = (_name), \
> > @@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
> > DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
> > #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> > DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
> > +#define DEFINE_PROP_VHOST_SCSI(_n, _s, _f) \
> > + DEFINE_PROP(_n, _s, _f, qdev_prop_vhost_scsi, VHostSCSI*)
> >
> > #define DEFINE_PROP_END_OF_LIST() \
> > {}
> > diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> > new file mode 100644
> > index 0000000..7145b2d
> > --- /dev/null
> > +++ b/hw/vhost-scsi.c
> > @@ -0,0 +1,170 @@
> > +/*
> > + * vhost_scsi host device
> > + *
> > + * Copyright IBM, Corp. 2011
> > + *
> > + * Authors:
> > + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> > + * See the COPYING.LIB file in the top-level directory.
> > + *
> > + */
> > +
> > +#include <sys/ioctl.h>
> > +#include "config.h"
> > +#include "qemu-queue.h"
> > +#include "vhost-scsi.h"
> > +#include "vhost.h"
> > +
> > +struct VHostSCSI {
> > + const char *id;
> > + const char *wwpn;
> > + uint16_t tpgt;
> > + struct vhost_dev dev;
> > + struct vhost_virtqueue vqs[3];
> > + QLIST_ENTRY(VHostSCSI) list;
> > +};
> > +
> > +static QLIST_HEAD(, VHostSCSI) vhost_scsi_list =
> > + QLIST_HEAD_INITIALIZER(vhost_scsi_list);
> > +
> > +VHostSCSI *find_vhost_scsi(const char *id)
> > +{
> > + VHostSCSI *vs;
> > +
> > + QLIST_FOREACH(vs, &vhost_scsi_list, list) {
> > + if (strcmp(id, vs->id) == 0) {
> > + return vs;
> > + }
> > + }
> > + return NULL;
> > +}
> > +
> > +const char *vhost_scsi_get_id(VHostSCSI *vs)
> > +{
> > + return vs->id;
> > +}
> > +
> > +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev)
> > +{
> > + int ret, abi_version;
> > + struct vhost_scsi_target backend;
> > +
> > + if (!vhost_dev_query(&vs->dev, vdev)) {
> > + return -ENOTSUP;
> > + }
> > +
> > + vs->dev.nvqs = 3;
> > + vs->dev.vqs = vs->vqs;
> > +
> > + ret = vhost_dev_enable_notifiers(&vs->dev, vdev);
> > + if (ret < 0) {
> > + return ret;
> > + }
> > +
> > + ret = vhost_dev_start(&vs->dev, vdev);
> > + if (ret < 0) {
> > + return ret;
> > + }
> > +
> > + memset(&backend, 0, sizeof(backend));
> > + ret = ioctl(vs->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> > + if (ret < 0) {
> > + ret = -errno;
> > + vhost_dev_stop(&vs->dev, vdev);
> > + return ret;
> > + }
> > + if (abi_version > VHOST_SCSI_ABI_VERSION) {
> > + fprintf(stderr, "The running tcm_vhost kernel abi_version: %d is greater"
> > + " than vhost_scsi userspace supports: %d\n", abi_version,
> > + VHOST_SCSI_ABI_VERSION);
> > + ret = -ENOSYS;
> > + vhost_dev_stop(&vs->dev, vdev);
> > + return ret;
> > + }
> > + fprintf(stdout, "TCM_vHost ABI version: %d\n", abi_version);
> > +
> > + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
>
> Please change vhost_wwpn to plain char *, then the cast can be removed.
>
<nod>, changed to char *, and updating tcm_vhost on the kernel side to
do the same.
> > + backend.vhost_tpgt = vs->tpgt;
> > + ret = ioctl(vs->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
> > + if (ret < 0) {
> > + ret = -errno;
> > + vhost_dev_stop(&vs->dev, vdev);
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> > +{
> > + int ret;
> > + struct vhost_scsi_target backend;
> > +
> > + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
>
> Also here.
>
Done
Thanks for your review Blue!
--nab
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost
2012-08-13 8:35 ` [Qemu-devel] [RFC-v2 3/6] vhost-scsi: add -vhost-scsi host device for use with tcm-vhost Nicholas A. Bellinger
` (2 preceding siblings ...)
2012-08-13 19:47 ` Blue Swirl
@ 2012-08-20 9:02 ` Paolo Bonzini
3 siblings, 0 replies; 36+ messages in thread
From: Paolo Bonzini @ 2012-08-20 9:02 UTC (permalink / raw)
To: Nicholas A. Bellinger, Anthony Liguori
Cc: Stefan Hajnoczi, kvm-devel, Michael S. Tsirkin, Jan Kiszka,
Zhi Yong Wu, qemu-devel, Zhi Yong Wu, Anthony Liguori,
target-devel, Hannes Reinecke, lf-virt, Christoph Hellwig
Il 13/08/2012 10:35, Nicholas A. Bellinger ha scritto:
> From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>
> This patch adds a new type of host device that drives the vhost_scsi
> device. The syntax to add vhost-scsi is:
>
> qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123
>
> The virtio-scsi emulated device will make use of vhost-scsi to process
> virtio-scsi requests inside the kernel and hand them to the in-kernel
> SCSI target stack using the tcm_vhost fabric driver.
>
> The tcm_vhost driver was merged into the upstream linux kernel for 3.6-rc2,
> and the commit can be found here:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=057cbf49a1f08297
>
> Changelog v1 -> v2:
>
> - Expose ABI version via VHOST_SCSI_GET_ABI_VERSION + use Rev 0 as
> starting point for v3.6-rc code (Stefan + ALiguori + nab)
> - Fix upstream qemu conflict in hw/qdev-properties.c
> - Make GET_ABI_VERSION use int (nab + mst)
> - Fix vhost-scsi case lables in configure (reported by paolo)
> - Convert qdev_prop_vhost_scsi to use ->get() + ->set() following
> qdev_prop_netdev (reported by paolo)
> - Fix typo in qemu-options.hx definition of vhost-scsi (reported by paolo)
>
> Changelog v0 -> v1:
>
> - Add VHOST_SCSI_SET_ENDPOINT call (stefan)
> - Enable vhost notifiers for multiple queues (Zhi)
> - clear vhost-scsi endpoint on stopped (Zhi)
> - Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
> - Rename vhost_vring_target -> vhost_scsi_target (mst + nab)
> - Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)
>
> Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Cc: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> Cc: Anthony Liguori <aliguori@us.ibm.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
> ---
> configure | 10 +++
> hw/Makefile.objs | 1 +
> hw/qdev-properties.c | 40 ++++++++++++
> hw/qdev.h | 3 +
> hw/vhost-scsi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/vhost-scsi.h | 50 +++++++++++++++
> qemu-common.h | 1 +
> qemu-config.c | 16 +++++
> qemu-options.hx | 4 +
> vl.c | 18 +++++
> 10 files changed, 313 insertions(+), 0 deletions(-)
> create mode 100644 hw/vhost-scsi.c
> create mode 100644 hw/vhost-scsi.h
>
> diff --git a/configure b/configure
> index f0dbc03..1f03202 100755
> --- a/configure
> +++ b/configure
> @@ -168,6 +168,7 @@ libattr=""
> xfs=""
>
> vhost_net="no"
> +vhost_scsi="no"
> kvm="no"
> gprof="no"
> debug_tcg="no"
> @@ -513,6 +514,7 @@ Haiku)
> usb="linux"
> kvm="yes"
> vhost_net="yes"
> + vhost_scsi="yes"
> if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
> audio_possible_drivers="$audio_possible_drivers fmod"
> fi
> @@ -818,6 +820,10 @@ for opt do
> ;;
> --enable-vhost-net) vhost_net="yes"
> ;;
> + --disable-vhost-scsi) vhost_scsi="no"
> + ;;
> + --enable-vhost-scsi) vhost_scsi="yes"
> + ;;
> --disable-opengl) opengl="no"
> ;;
> --enable-opengl) opengl="yes"
> @@ -3116,6 +3122,7 @@ echo "posix_madvise $posix_madvise"
> echo "uuid support $uuid"
> echo "libcap-ng support $cap_ng"
> echo "vhost-net support $vhost_net"
> +echo "vhost-scsi support $vhost_scsi"
> echo "Trace backend $trace_backend"
> echo "Trace output file $trace_file-<pid>"
> echo "spice support $spice"
> @@ -3828,6 +3835,9 @@ case "$target_arch2" in
> if test "$vhost_net" = "yes" ; then
> echo "CONFIG_VHOST_NET=y" >> $config_target_mak
> fi
> + if test "$vhost_scsi" = "yes" ; then
> + echo "CONFIG_VHOST_SCSI=y" >> $config_target_mak
> + fi
> fi
> esac
> case "$target_arch2" in
> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> index 3ba5dd0..6ab75ec 100644
> --- a/hw/Makefile.objs
> +++ b/hw/Makefile.objs
> @@ -169,6 +169,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
> obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o
> obj-$(CONFIG_SOFTMMU) += vhost_net.o
> obj-$(CONFIG_VHOST_NET) += vhost.o
> +obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
> obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
> obj-$(CONFIG_NO_PCI) += pci-stub.o
> obj-$(CONFIG_VGA) += vga.o
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 8aca0d4..0266266 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -4,6 +4,7 @@
> #include "blockdev.h"
> #include "hw/block-common.h"
> #include "net/hub.h"
> +#include "vhost-scsi.h"
>
> void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
> {
> @@ -696,6 +697,45 @@ PropertyInfo qdev_prop_vlan = {
> .set = set_vlan,
> };
>
> +/* --- vhost-scsi --- */
> +
> +static int parse_vhost_scsi_dev(DeviceState *dev, const char *str, void **ptr)
> +{
> + VHostSCSI *p;
> +
> + p = find_vhost_scsi(str);
> + if (p == NULL)
> + return -ENOENT;
> +
> + *ptr = p;
> + return 0;
> +}
> +
> +static const char *print_vhost_scsi_dev(void *ptr)
> +{
> + VHostSCSI *p = ptr;
> +
> + return (p) ? vhost_scsi_get_id(p) : "<null>";
> +}
> +
> +static void get_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + get_pointer(obj, v, opaque, print_vhost_scsi_dev, name, errp);
> +}
> +
> +static void set_vhost_scsi_dev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + set_pointer(obj, v, opaque, parse_vhost_scsi_dev, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_vhost_scsi = {
> + .name = "vhost-scsi",
> + .get = get_vhost_scsi_dev,
> + .set = set_vhost_scsi_dev,
> +};
> +
> /* --- pointer --- */
>
> /* Not a proper property, just for dirty hacks. TODO Remove it! */
> diff --git a/hw/qdev.h b/hw/qdev.h
> index d699194..d5873bb 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
> extern PropertyInfo qdev_prop_pci_devfn;
> extern PropertyInfo qdev_prop_blocksize;
> extern PropertyInfo qdev_prop_pci_host_devaddr;
> +extern PropertyInfo qdev_prop_vhost_scsi;
>
> #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
> .name = (_name), \
> @@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
> DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
> #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
> +#define DEFINE_PROP_VHOST_SCSI(_n, _s, _f) \
> + DEFINE_PROP(_n, _s, _f, qdev_prop_vhost_scsi, VHostSCSI*)
>
> #define DEFINE_PROP_END_OF_LIST() \
> {}
> diff --git a/hw/vhost-scsi.c b/hw/vhost-scsi.c
> new file mode 100644
> index 0000000..7145b2d
> --- /dev/null
> +++ b/hw/vhost-scsi.c
> @@ -0,0 +1,170 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include <sys/ioctl.h>
> +#include "config.h"
> +#include "qemu-queue.h"
> +#include "vhost-scsi.h"
> +#include "vhost.h"
> +
> +struct VHostSCSI {
> + const char *id;
> + const char *wwpn;
> + uint16_t tpgt;
> + struct vhost_dev dev;
> + struct vhost_virtqueue vqs[3];
> + QLIST_ENTRY(VHostSCSI) list;
> +};
> +
> +static QLIST_HEAD(, VHostSCSI) vhost_scsi_list =
> + QLIST_HEAD_INITIALIZER(vhost_scsi_list);
> +
> +VHostSCSI *find_vhost_scsi(const char *id)
> +{
> + VHostSCSI *vs;
> +
> + QLIST_FOREACH(vs, &vhost_scsi_list, list) {
> + if (strcmp(id, vs->id) == 0) {
> + return vs;
> + }
> + }
> + return NULL;
> +}
> +
> +const char *vhost_scsi_get_id(VHostSCSI *vs)
> +{
> + return vs->id;
> +}
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret, abi_version;
> + struct vhost_scsi_target backend;
> +
> + if (!vhost_dev_query(&vs->dev, vdev)) {
> + return -ENOTSUP;
> + }
> +
> + vs->dev.nvqs = 3;
> + vs->dev.vqs = vs->vqs;
> +
> + ret = vhost_dev_enable_notifiers(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + ret = vhost_dev_start(&vs->dev, vdev);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + memset(&backend, 0, sizeof(backend));
> + ret = ioctl(vs->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + if (abi_version > VHOST_SCSI_ABI_VERSION) {
> + fprintf(stderr, "The running tcm_vhost kernel abi_version: %d is greater"
> + " than vhost_scsi userspace supports: %d\n", abi_version,
> + VHOST_SCSI_ABI_VERSION);
> + ret = -ENOSYS;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> + fprintf(stdout, "TCM_vHost ABI version: %d\n", abi_version);
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
> + if (ret < 0) {
> + ret = -errno;
> + vhost_dev_stop(&vs->dev, vdev);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
> +{
> + int ret;
> + struct vhost_scsi_target backend;
> +
> + pstrcpy((char *)backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->wwpn);
> + backend.vhost_tpgt = vs->tpgt;
> + ret = ioctl(vs->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
> + if (ret < 0) {
> + fprintf(stderr, "Failed to clear endpoint\n");
> + }
> +
> + vhost_dev_stop(&vs->dev, vdev);
> +}
> +
> +static VHostSCSI *vhost_scsi_add(const char *id, const char *wwpn,
> + uint16_t tpgt)
> +{
> + VHostSCSI *vs = g_malloc0(sizeof(*vs));
> + int ret;
> +
> + /* TODO set up vhost-scsi device and bind to tcm_vhost/$wwpm/tpgt_$tpgt */
> + fprintf(stderr, "wwpn = \"%s\" tpgt = \"%u\"\n", id, tpgt);
> +
> + ret = vhost_dev_init(&vs->dev, -1, "/dev/vhost-scsi", false);
> + if (ret < 0) {
> + fprintf(stderr, "vhost-scsi: vhost initialization failed: %s\n",
> + strerror(-ret));
> + return NULL;
> + }
> + vs->dev.backend_features = 0;
> + vs->dev.acked_features = 0;
> +
> + vs->id = g_strdup(id);
> + vs->wwpn = g_strdup(wwpn);
> + vs->tpgt = tpgt;
> + QLIST_INSERT_HEAD(&vhost_scsi_list, vs, list);
> +
> + return vs;
> +}
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts)
> +{
> + const char *id;
> + const char *wwpn;
> + uint64_t tpgt;
> +
> + id = qemu_opts_id(opts);
> + if (!id) {
> + fprintf(stderr, "vhost-scsi: no id specified\n");
> + return NULL;
> + }
> + if (find_vhost_scsi(id)) {
> + fprintf(stderr, "duplicate vhost-scsi: \"%s\"\n", id);
> + return NULL;
> + }
> +
> + wwpn = qemu_opt_get(opts, "wwpn");
> + if (!wwpn) {
> + fprintf(stderr, "vhost-scsi: \"%s\" missing wwpn\n", id);
> + return NULL;
> + }
> +
> + tpgt = qemu_opt_get_number(opts, "tpgt", UINT64_MAX);
> + if (tpgt > UINT16_MAX) {
> + fprintf(stderr, "vhost-scsi: \"%s\" needs a 16-bit tpgt\n", id);
> + return NULL;
> + }
> +
> + return vhost_scsi_add(id, wwpn, tpgt);
> +}
> diff --git a/hw/vhost-scsi.h b/hw/vhost-scsi.h
> new file mode 100644
> index 0000000..f3096dc
> --- /dev/null
> +++ b/hw/vhost-scsi.h
> @@ -0,0 +1,50 @@
> +/*
> + * vhost_scsi host device
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#ifndef VHOST_SCSI_H
> +#define VHOST_SCSI_H
> +
> +#include "qemu-common.h"
> +#include "qemu-option.h"
> +
> +/*
> + * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
> + *
> + * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate +
> + * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage
> + */
> +
> +#define VHOST_SCSI_ABI_VERSION 0
> +
> +/* TODO #include <linux/vhost.h> properly */
> +/* For VHOST_SCSI_SET_ENDPOINT/VHOST_SCSI_CLEAR_ENDPOINT ioctl */
> +struct vhost_scsi_target {
> + int abi_version;
> + unsigned char vhost_wwpn[224];
> + unsigned short vhost_tpgt;
> +};
> +
> +#define VHOST_VIRTIO 0xAF
> +#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
> +#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
> +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct vhost_scsi_target)
> +
> +VHostSCSI *find_vhost_scsi(const char *id);
> +const char *vhost_scsi_get_id(VHostSCSI *vs);
> +
> +VHostSCSI *vhost_scsi_add_opts(QemuOpts *opts);
> +
> +int vhost_scsi_start(VHostSCSI *vs, VirtIODevice *vdev);
> +void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev);
> +
> +#endif
> diff --git a/qemu-common.h b/qemu-common.h
> index f9deca6..ec36002 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -280,6 +280,7 @@ typedef struct EventNotifier EventNotifier;
> typedef struct VirtIODevice VirtIODevice;
> typedef struct QEMUSGList QEMUSGList;
> typedef struct SHPCDevice SHPCDevice;
> +typedef struct VHostSCSI VHostSCSI;
>
> typedef uint64_t pcibus_t;
>
> diff --git a/qemu-config.c b/qemu-config.c
> index 5c3296b..33399ea 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -626,6 +626,21 @@ QemuOptsList qemu_boot_opts = {
> },
> };
>
> +QemuOptsList qemu_vhost_scsi_opts = {
> + .name = "vhost-scsi",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_vhost_scsi_opts.head),
> + .desc = {
> + {
> + .name = "wwpn",
> + .type = QEMU_OPT_STRING,
> + }, {
> + .name = "tpgt",
> + .type = QEMU_OPT_NUMBER,
> + },
> + { /* end of list */ }
> + },
> +};
> +
> static QemuOptsList *vm_config_groups[32] = {
> &qemu_drive_opts,
> &qemu_chardev_opts,
> @@ -641,6 +656,7 @@ static QemuOptsList *vm_config_groups[32] = {
> &qemu_machine_opts,
> &qemu_boot_opts,
> &qemu_iscsi_opts,
> + &qemu_vhost_scsi_opts,
> NULL,
> };
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 47cb5bd..4e7a03c 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -565,6 +565,10 @@ possible drivers and properties, use @code{-device ?} and
> ETEXI
>
> DEFHEADING()
> +DEF("vhost-scsi", HAS_ARG, QEMU_OPTION_vhost_scsi,
> + "-vhost-scsi wwpn=string0,tpgt=number0\n"
> + " add vhost-scsi device\n",
> + QEMU_ARCH_ALL)
>
> DEFHEADING(File system options:)
>
> diff --git a/vl.c b/vl.c
> index 91076f0..61c8284 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -144,6 +144,7 @@ int main(int argc, char **argv)
> #include "qemu-options.h"
> #include "qmp-commands.h"
> #include "main-loop.h"
> +#include "hw/vhost-scsi.h"
> #ifdef CONFIG_VIRTFS
> #include "fsdev/qemu-fsdev.h"
> #endif
> @@ -1858,6 +1859,14 @@ static int fsdev_init_func(QemuOpts *opts, void *opaque)
> }
> #endif
>
> +static int vhost_scsi_init_func(QemuOpts *opts, void *opaque)
> +{
> + if (!vhost_scsi_add_opts(opts)) {
> + return -1;
> + }
> + return 0;
> +}
> +
> static int mon_init_func(QemuOpts *opts, void *opaque)
> {
> CharDriverState *chr;
> @@ -2617,6 +2626,11 @@ int main(int argc, char **argv, char **envp)
> }
> break;
> #endif
> + case QEMU_OPTION_vhost_scsi:
> + if (!qemu_opts_parse(qemu_find_opts("vhost-scsi"), optarg, 0)) {
> + exit(1);
> + }
> + break;
> #ifdef CONFIG_SLIRP
> case QEMU_OPTION_tftp:
> legacy_tftp_prefix = optarg;
> @@ -3337,6 +3351,10 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> }
> #endif
> + if (qemu_opts_foreach(qemu_find_opts("vhost-scsi"),
> + vhost_scsi_init_func, NULL, 1)) {
> + exit(1);
> + }
>
> os_daemonize();
>
>
Anthony, do you think your -object patches are going to go in? Perhaps
we should reuse that option instead of inventing <option-of-the-day>
every time.
Paolo
^ permalink raw reply [flat|nested] 36+ messages in thread