[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/16] vhost-scsi: add -vhost-scsi host device
From: |
zwu . kernel |
Subject: |
[Qemu-devel] [PATCH 11/16] vhost-scsi: add -vhost-scsi host device |
Date: |
Thu, 19 Apr 2012 10:39:04 +0800 |
From: Stefan Hajnoczi <address@hidden>
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.
Signed-off-by: Stefan Hajnoczi <address@hidden>
Signed-off-by: Zhi Yong Wu <address@hidden>
---
Makefile.target | 2 +-
hw/qdev-properties.c | 32 ++++++++++++
hw/qdev.h | 3 +
hw/vhost-scsi.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++
hw/vhost-scsi.h | 28 +++++++++++
qemu-common.h | 1 +
qemu-config.c | 16 ++++++
qemu-options.hx | 4 ++
vl.c | 18 +++++++
9 files changed, 234 insertions(+), 1 deletions(-)
create mode 100644 hw/vhost-scsi.c
create mode 100644 hw/vhost-scsi.h
diff --git a/Makefile.target b/Makefile.target
index 84951a0..d748f94 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -219,7 +219,7 @@ obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o
balloon.o ioport.o
obj-$(CONFIG_NO_PCI) += pci-stub.o
obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
virtio-serial-bus.o
obj-$(CONFIG_VIRTIO) += virtio-scsi.o
-obj-y += vhost_net.o
+obj-y += vhost_net.o vhost-scsi.o
obj-$(CONFIG_VHOST_NET) += vhost.o
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
obj-$(CONFIG_KVM) += kvm.o kvm-all.o
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 98dd06a..2a108a0 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -2,6 +2,7 @@
#include "qdev.h"
#include "qerror.h"
#include "blockdev.h"
+#include "vhost-scsi.h"
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
{
@@ -688,6 +689,37 @@ PropertyInfo qdev_prop_vlan = {
.set = set_vlan,
};
+/* --- vhost-scsi --- */
+
+static int parse_vhost_scsi(DeviceState *dev, Property *prop, const char *str)
+{
+ VHostSCSI **ptr = qdev_get_prop_ptr(dev, prop);
+
+ *ptr = find_vhost_scsi(str);
+ if (*ptr == NULL) {
+ return -ENOENT;
+ }
+ return 0;
+}
+
+static int print_vhost_scsi(DeviceState *dev, Property *prop,
+ char *dest, size_t len)
+{
+ VHostSCSI **ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (*ptr) {
+ return snprintf(dest, len, "%s", vhost_scsi_get_id(*ptr));
+ } else {
+ return snprintf(dest, len, "<null>");
+ }
+}
+
+PropertyInfo qdev_prop_vhost_scsi = {
+ .name = "vhost-scsi",
+ .parse = parse_vhost_scsi,
+ .print = print_vhost_scsi,
+};
+
/* --- pointer --- */
/* Not a proper property, just for dirty hacks. TODO Remove it! */
diff --git a/hw/qdev.h b/hw/qdev.h
index 4e90119..dc51678 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -225,6 +225,7 @@ extern PropertyInfo qdev_prop_netdev;
extern PropertyInfo qdev_prop_vlan;
extern PropertyInfo qdev_prop_pci_devfn;
extern PropertyInfo qdev_prop_blocksize;
+extern PropertyInfo qdev_prop_vhost_scsi;
#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
.name = (_name), \
@@ -288,6 +289,8 @@ extern PropertyInfo qdev_prop_blocksize;
LostTickPolicy)
#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
+#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..6e3645f
--- /dev/null
+++ b/hw/vhost-scsi.c
@@ -0,0 +1,131 @@
+/*
+ * vhost_scsi host device
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Stefan Hajnoczi <address@hidden>
+ *
+ * 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 "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;
+
+ if (!vhost_dev_query(&vs->dev, vdev)) {
+ return -ENOTSUP;
+ }
+
+ vs->dev.nvqs = 3;
+ vs->dev.vqs = vs->vqs;
+ ret = vhost_dev_start(&vs->dev, vdev);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* TODO set wwpn and tpgt */
+ fprintf(stderr, "vhost_scsi_start\n");
+ return 0;
+}
+
+void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
+{
+ fprintf(stderr, "vhost_scsi_stop\n");
+ /* TODO clear wwpn and tpgt */
+
+ 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..e5e67e3
--- /dev/null
+++ b/hw/vhost-scsi.h
@@ -0,0 +1,28 @@
+/*
+ * vhost_scsi host device
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Stefan Hajnoczi <address@hidden>
+ *
+ * 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"
+
+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 50f659a..3bf4895 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -259,6 +259,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 be84a03..fffcbcc 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -613,6 +613,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,
@@ -628,6 +643,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 a169792..1a580d8 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -561,6 +561,10 @@ possible drivers and properties, use @code{-device ?} and
ETEXI
DEFHEADING()
+DEF("vhost-scsi", HAS_ARG, QEMU_OPTION_vhost_scsi,
+ "-virtio-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 ae91a8a..221a294 100644
--- a/vl.c
+++ b/vl.c
@@ -149,6 +149,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
@@ -1850,6 +1851,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;
@@ -2611,6 +2620,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;
@@ -3322,6 +3336,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.6
- [Qemu-devel] [PATCH 05/16] virtio-scsi: Build virtio-scsi.o against vhost.o, (continued)
- [Qemu-devel] [PATCH 05/16] virtio-scsi: Build virtio-scsi.o against vhost.o, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 04/16] virtio-scsi: Fix tgpt typo to tpgt and use uint16_t, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 07/16] virtio-scsi: Start/stop vhost, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 03/16] virtio-scsi: Add vhost_vring_target ioctl struct, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 06/16] virtio-scsi: Open and initialize /dev/vhost-scsi, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 01/16] virtio-scsi: Add wwpn and tgpt properties, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 13/16] virtio-scsi: WIP VHOST_SCSI_SET_ENDPOINT call, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 12/16] virtio-scsi: use the vhost-scsi host device, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 14/16] vhost-scsi: enable vhost notifiers for multiple queues, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 09/16] virtio-pci: support host notifiers in TCG mode, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 11/16] vhost-scsi: add -vhost-scsi host device,
zwu . kernel <=
- [Qemu-devel] [PATCH 08/16] notifier: add validity check and notify function, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 15/16] vhost-scsi: move some definitions to its header file, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 10/16] virtio-pci: check that event notification worked, zwu . kernel, 2012/04/18
- [Qemu-devel] [PATCH 16/16] vhost-scsi: clear endpoint on stopped, zwu . kernel, 2012/04/18
- Re: [Qemu-devel] [PATCH 00/16] QEMU vhost-scsi support, Paolo Bonzini, 2012/04/19