[libvirt] [PATCH] qemu: Use scsi-block for lun passthrough instead of scsi-disk

Osier Yang jyang at redhat.com
Mon Mar 12 13:55:32 UTC 2012


And don't allow to hotplug a usb disk with "device == lun". This
is the missed pieces in previous virtio-scsi patchset:

http://www.redhat.com/archives/libvir-list/2012-February/msg01052.html
---
 src/qemu/qemu_capabilities.c                       |    3 +
 src/qemu/qemu_capabilities.h                       |    1 +
 src/qemu/qemu_command.c                            |   46 +++++++++++++------
 src/qemu/qemu_driver.c                             |   14 ++++--
 tests/qemuhelptest.c                               |    3 +-
 .../qemuxml2argv-disk-scsi-lun-passthrough.args    |   10 ++++
 .../qemuxml2argv-disk-scsi-lun-passthrough.xml     |   32 ++++++++++++++
 tests/qemuxml2argvtest.c                           |    4 ++
 8 files changed, 93 insertions(+), 20 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.xml

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 64a4546..ace5011 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -154,6 +154,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
               "drive-iotune", /* 85 */
               "system_wakeup",
               "scsi-disk.channel",
+              "scsi-block",
     );
 
 struct qemu_feature_flags {
@@ -1444,6 +1445,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
         qemuCapsSet(flags, QEMU_CAPS_VIRTIO_BLK_SCSI);
     if (strstr(str, "scsi-disk.channel"))
         qemuCapsSet(flags, QEMU_CAPS_SCSI_DISK_CHANNEL);
+    if (strstr(str, "scsi-block"))
+        qemuCapsSet(flags, QEMU_CAPS_SCSI_BLOCK);
 
     return 0;
 }
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index db584ce..62b4270 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -122,6 +122,7 @@ enum qemuCapsFlags {
     QEMU_CAPS_DRIVE_IOTUNE       = 85, /* -drive bps= and friends */
     QEMU_CAPS_WAKEUP             = 86, /* system_wakeup monitor command */
     QEMU_CAPS_SCSI_DISK_CHANNEL  = 87, /* Is scsi-disk.channel available? */
+    QEMU_CAPS_SCSI_BLOCK         = 88, /* -device scsi-block */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6ec1eb9..048bad8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2190,6 +2190,15 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
                           disk->info.addr.drive.unit);
         break;
     case VIR_DOMAIN_DISK_BUS_SCSI:
+        if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+            if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_BLOCK)) {
+                qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                _("This QEMU doesn't support scsi-block for "
+                                  "lun passthrough"));
+                goto error;
+            }
+        }
+
         controllerModel =
             virDomainDiskFindControllerModel(def, disk,
                                              VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
@@ -2205,30 +2214,37 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
                 goto error;
             }
 
-            virBufferAddLit(&opt, "scsi-disk");
+            if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
+                virBufferAddLit(&opt, "scsi-block");
+            else
+                virBufferAddLit(&opt, "scsi-disk");
             virBufferAsprintf(&opt, ",bus=scsi%d.%d,scsi-id=%d",
                               disk->info.addr.drive.controller,
                               disk->info.addr.drive.bus,
                               disk->info.addr.drive.unit);
         } else {
-            if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) {
-                if (disk->info.addr.drive.target > 7) {
-                    qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                                    _("This QEMU doesn't support target "
-                                      "greater than 7"));
-                    goto error;
-                }
+            if ((disk->device != VIR_DOMAIN_DISK_DEVICE_LUN)) {
+                if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) {
+                    if (disk->info.addr.drive.target > 7) {
+                        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                        _("This QEMU doesn't support target "
+                                          "greater than 7"));
+                        goto error;
+                    }
 
-                if ((disk->info.addr.drive.bus != disk->info.addr.drive.unit) &&
-                    (disk->info.addr.drive.bus != 0)) {
-                    qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                                    _("This QEMU only supports both bus and "
-                                      "unit equal to 0"));
-                    goto error;
+                    if ((disk->info.addr.drive.bus != disk->info.addr.drive.unit) &&
+                        (disk->info.addr.drive.bus != 0)) {
+                        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                        _("This QEMU only supports both bus and "
+                                          "unit equal to 0"));
+                        goto error;
+                    }
                 }
+                virBufferAddLit(&opt, "scsi-disk");
+            } else {
+                virBufferAddLit(&opt, "scsi-block");
             }
 
-            virBufferAddLit(&opt, "scsi-disk");
             virBufferAsprintf(&opt, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d",
                               disk->info.addr.drive.controller,
                               disk->info.addr.drive.bus,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index be678f3..b4878c3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5090,17 +5090,23 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
         break;
     case VIR_DOMAIN_DISK_DEVICE_DISK:
     case VIR_DOMAIN_DISK_DEVICE_LUN:
-        if (disk->bus == VIR_DOMAIN_DISK_BUS_USB)
+        if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
+            if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+                qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                _("disk device='lun' is not supported for usb bus"));
+                break;
+            }
             ret = qemuDomainAttachUsbMassstorageDevice(conn, driver, vm,
                                                        disk);
-        else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
+        } else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
             ret = qemuDomainAttachPciDiskDevice(conn, driver, vm, disk);
-        else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI)
+        } else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
             ret = qemuDomainAttachSCSIDisk(conn, driver, vm, disk);
-        else
+        } else {
             qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                             _("disk bus '%s' cannot be hotplugged."),
                             virDomainDiskBusTypeToString(disk->bus));
+        }
         break;
     default:
         qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 370cd0d..05fdc4d 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -673,7 +673,8 @@ mymain(void)
             QEMU_CAPS_VIRTIO_BLK_SCSI,
             QEMU_CAPS_VIRTIO_BLK_SG_IO,
             QEMU_CAPS_CPU_HOST,
-            QEMU_CAPS_FSDEV_WRITEOUT);
+            QEMU_CAPS_FSDEV_WRITEOUT,
+            QEMU_CAPS_SCSI_BLOCK);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.args
new file mode 100644
index 0000000..1d2b476
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.args
@@ -0,0 +1,10 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 \
+-device lsi,id=scsi1,bus=pci.0,addr=0x4 \
+-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-scsi0-0-0-0 \
+-device scsi-block,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \
+-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-scsi0-0-1-1 \
+-device scsi-block,bus=scsi0.0,channel=0,scsi-id=1,lun=1,drive=drive-scsi0-0-1-1,id=scsi0-0-1-1 \
+-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.xml
new file mode 100644
index 0000000..7f0cc81
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='lun'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <disk type='block' device='lun'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' target='1' unit='1'/>
+    </disk>
+    <controller type='scsi' index='0' model='virtio-scsi'/>
+    <controller type='scsi' index='1' model='lsilogic'/>
+    <controller type='usb' index='0'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 9001834..d0affc7 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -487,6 +487,10 @@ mymain(void)
             QEMU_CAPS_DRIVE,
             QEMU_CAPS_DEVICE,
             QEMU_CAPS_VIRTIO_BLK_SCSI, QEMU_CAPS_VIRTIO_BLK_SG_IO);
+    DO_TEST("disk-scsi-lun-passthrough", false,
+            QEMU_CAPS_DRIVE,
+            QEMU_CAPS_DEVICE,
+            QEMU_CAPS_SCSI_BLOCK, QEMU_CAPS_VIRTIO_BLK_SG_IO);
 
     DO_TEST("graphics-vnc", false, NONE);
     DO_TEST("graphics-vnc-socket", false, NONE);
-- 
1.7.1




More information about the libvir-list mailing list