[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCHv2 2/2] qemu: add new disk device='lun' for bus='virtio' & type='block'

On 01/05/2012 03:44 AM, Paolo Bonzini wrote:
Summary: two nits, one in the docs and one at the end of this email.

[Osier, I'm CCing you because there is some food for thought for SCSI].

On 01/05/2012 05:17 AM, Laine Stump wrote:
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 18b7e22..dcdf91f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1001,8 +1001,16 @@
           "block", "dir", or "network"
           and refers to the underlying source for the disk. The optional
           <code>device</code>   attribute indicates how the disk is to be exposed
-        to the guest OS. Possible values for this attribute are "floppy", "disk"
-        and "cdrom", defaulting to "disk".  The
+        to the guest OS. Possible values for this attribute are
+        "floppy", "disk", "cdrom", and "lun", defaulting to
+        "disk". "lun" (<span class="since">since 0.9.10</span>) is only
+        valid when type is "block" and the target element's "bus"
+        attribute is "virtio", and behaves identically to "disk",
+        except that generic SCSI commands from the guest are accepted
What about "are forwarded to the disk"?

Okay, I'm adding that to the end of the sentence.

This is also true in the SCSI
case (for SCSI, "block" will emulate commands rather than fail them; but
for "lun" the behavior is identical).

We can add that to the docs when virtio-blk-scsi support is added.

+        - also note that device='lun' will only be recognized for
+        actual raw devices, never for individual partitions or LVM
+        partitions (in those cases, the kernel will reject the generic
+        SCSI commands, making it identical to device='disk').  The
Perhaps add a note that QEMU may fail to start? Again, this is not the
case for virtio but it will be for "scsi".

I'd rather add that information when it actually is true (i.e. when virtio-blk-scsi support is put in).

           optional<code>snapshot</code>   attribute indicates the default
           behavior of the disk during disk snapshots: "internal"
           requires a file format such as qcow2 that can store both the
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 7a8f7f4..2f8bec5 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -794,6 +794,7 @@
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 21113c6..a06942b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -157,7 +157,8 @@ VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
-              "floppy")
+              "floppy",
+              "lun")

@@ -3093,7 +3094,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
       if (def->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
           def->readonly = 1;

-    if (def->device == VIR_DOMAIN_DISK_DEVICE_DISK&&
+    if ((def->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
+         def->device == VIR_DOMAIN_DISK_DEVICE_LUN)&&
           !STRPREFIX((const char *)target, "hd")&&
           !STRPREFIX((const char *)target, "sd")&&
           !STRPREFIX((const char *)target, "vd")&&
I wonder if you should extend this check to VIR_DOMAIN_DISK_DEVICE_CDROM
as well.

Won't the list of names be different? ("sr")? At any rate, that's an orthogonal issue, and should be addressed with a separate patch.

+    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+        /* make sure that both the bus and the qemu binary support
+         *  type='lun' (SG_IO).
+         */
+        if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("disk device='lun' is not supported for bus='%s'"),
+                            bus);
+            goto error;
+        }
+        if (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("disk device='lun' is not supported for type='%s'"),
+                            virDomainDiskTypeToString(disk->type));
+            goto error;
+        }
+        if (!qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SG_IO)) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                            _("disk device='lun' is not supported by this QEMU"));
+            goto error;
+        }
+    }
       switch (disk->bus) {
           virBufferAddLit(&opt, "ide-drive");
@@ -2050,6 +2074,14 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk,
               virBufferAsprintf(&opt, ",event_idx=%s",
+        if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) {
+            /* if sg_io is true but the scsi option isn't supported,
+             * that means it's just always on in this version of qemu.
+             */
+            virBufferAsprintf(&opt, ",scsi=%s",
+                              (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
+                              ? "on" : "off");
+        }
           if (qemuBuildDeviceAddressStr(&opt,&disk->info, qemuCaps)<   0)
               goto error;
@@ -4241,6 +4273,7 @@ qemuBuildCommandLine(virConnectPtr conn,
                   bootFloppy = 0;
               case VIR_DOMAIN_DISK_DEVICE_DISK:
+            case VIR_DOMAIN_DISK_DEVICE_LUN:
                   bootindex = bootDisk;
                   bootDisk = 0;
Suboptimal, because a type='lun' disk could well be a CD. :/ But
short of supporting bootindex directly in the<disk>  and<network>
items, we cannot do much about it though.

So this is a problem, but not fixable now, correct?

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 82bab67..3c55216 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4987,6 +4987,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
           ret = qemuDomainChangeEjectableMedia(driver, vm, disk, false);
Side note: this fails if you're trying to hot-plug a SCSI CD drive.
Probably this error condition in qemuDomainChangeEjectableMedia:

     for (i = 0 ; i<  vm->def->ndisks ; i++) {
         if (vm->def->disks[i]->bus == disk->bus&&
             STREQ(vm->def->disks[i]->dst, disk->dst)) {
             origdisk = vm->def->disks[i];

     if (!origdisk) {
                         _("No device with bus '%s' and target '%s'"),
         return -1;

should instead fall back to device hot-plug for VIR_DOMAIN_DISK_BUS_SCSI.

Just to verify - this is another thing that you've noticed in the code, but is orthogonal to this patch, correct?

           if (disk->bus == VIR_DOMAIN_DISK_BUS_USB)
               ret = qemuDomainAttachUsbMassstorageDevice(conn, driver, vm,
@@ -5109,6 +5110,7 @@ qemuDomainDetachDeviceDiskLive(struct qemud_driver *driver,

       switch (disk->device) {
           if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
               ret = qemuDomainDetachPciDiskDevice(driver, vm, dev);
           else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI)
@@ -9607,7 +9609,8 @@ static int qemuDomainSnapshotIsAllowed(virDomainObjPtr vm)
        * that succeed as well
       for (i = 0; i<   vm->def->ndisks; i++) {
-        if (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK&&
+        if ((vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
+             vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_LUN)&&
               (!vm->def->disks[i]->driverType ||
                STRNEQ(vm->def->disks[i]->driverType, "qcow2"))) {
I think that we should fail for device='lun' and format != 'raw'.

Truthfully, I didn't totally understand what that code was doing, but it seemed appropriate to at least duplicate the behavior of DEVICE_DISK :-) Looking at it some more, I *think* what is necessary, is to always return false if there is a disk that is DEVICE_LUN, since really the only thing that can be snapshotted is a qcow2 disk, and DEVICE_LUN disks by definition are never qcow2. So does it seem reasonable to change this to:

-        if (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK&&
-              (!vm->def->disks[i]->driverType ||
-              STRNEQ(vm->def->disks[i]->driverType, "qcow2"))) {
+        if ((vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_LUN) ||
+             (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK&&
+              STRNEQ_NULLABLE(vm->def->disks[i]->driverType, "qcow2"))) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]