]> xenbits.xensource.com Git - libvirt.git/commitdiff
disk: Disallow duplicated target 'dev' values
authorJohn Ferlan <jferlan@redhat.com>
Thu, 26 Feb 2015 17:20:01 +0000 (12:20 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 3 Mar 2015 03:38:36 +0000 (22:38 -0500)
https://bugzilla.redhat.com/show_bug.cgi?id=1142631

This patch resolves a situation where the same "<target dev='$name'...>"
can be used for multiple disks in the domain.

While the $name is "mostly" advisory regarding the expected order that
the disk is added to the domain and not guaranteed to map to the device
name in the guest OS, it still should be unique enough such that other
domblk* type operations can be performed.

Without the patch, the domblklist will list the same Target twice:

$ virsh domblklist $dom
Target     Source
------------------------------------------------
sda        /var/lib/libvirt/images/file.qcow2
sda        /var/lib/libvirt/images/file.img

Additionally, getting domblkstat, domblkerror, domblkinfo, and other block*
type calls will not be able to reference the second target.

Fortunately, hotplug disallows adding a "third" sda value:

$ qemu-img create -f raw /var/lib/libvirt/images/file2.img 10M
$ virsh attach-disk $dom /var/lib/libvirt/images/file2.img sda
error: Failed to attach disk
error: operation failed: target sda already exists

$

BUT, it since 'sdb' doesn't exist one would get the following on the same
hotplug attempt, but changing to use 'sdb' instead of 'sda'

$ virsh attach-disk $dom /var/lib/libvirt/images/file2.img sdb
error: Failed to attach disk
error: internal error: unable to execute QEMU command 'device_add': Duplicate ID 'scsi0-0-1' for device

$

Since we cannot fix this issue at parsing time, the best that can be done so
as to not "lose" a domain is to make the check prior to starting the guest
with the results as follows:

$ virsh start $dom
error: Failed to start domain $dom
error: XML error: target 'sda' duplicated for disk sources '/var/lib/libvirt/images/file.qcow2' and '/var/lib/libvirt/images/file.img'

$

Running 'make check' found a few more instances in the tests where this
duplicated target dev value was being used. These also exhibited some
duplicated 'id=' values (negating the uniqueness argument of aliases) in
the corresponding .args file and of course the *xmlout version of a few
input XML files.

15 files changed:
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_command.c
tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-split.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough-sgio.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-lun-passthrough.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool-mode.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml
tests/qemuxml2argvdata/qemuxml2argv-pci-bridge-many-disks.args
tests/qemuxml2argvdata/qemuxml2argv-pci-bridge-many-disks.xml
tests/qemuxml2argvdata/qemuxml2argv-pci-many.args
tests/qemuxml2argvdata/qemuxml2argv-pci-many.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-source-pool.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-pci-bridge-many-disks.xml

index 9b7ae3f2ae7f246a7acb3397dae93f239cb0bffe..c73a221dda84a2b757c54858bb3265836ab973ef 100644 (file)
@@ -11680,6 +11680,33 @@ virDomainDiskControllerMatch(int controller_type, int disk_bus)
     return false;
 }
 
+/* Return true if there's a duplicate disk[]->dst name for the same bus */
+bool
+virDomainDiskDefDstDuplicates(virDomainDefPtr def)
+{
+    size_t i, j;
+
+    /* optimization */
+    if (def->ndisks <= 1)
+        return false;
+
+    for (i = 1; i < def->ndisks; i++) {
+        for (j = 0; j < i; j++) {
+            if (def->disks[i]->bus == def->disks[j]->bus &&
+                STREQ(def->disks[i]->dst, def->disks[j]->dst)) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("target '%s' duplicated for disk sources "
+                                 "'%s' and '%s'"),
+                               def->disks[i]->dst,
+                               NULLSTR(virDomainDiskGetSource(def->disks[i])),
+                               NULLSTR(virDomainDiskGetSource(def->disks[j])));
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
 int
 virDomainDiskIndexByAddress(virDomainDefPtr def,
                             virDevicePCIAddressPtr pci_address,
index 02ddd93a4d2234b826f65cbd2c605cfff3fdee98..ee95f19d2bbf67c1d962b11945db284aadce950e 100644 (file)
@@ -2574,6 +2574,7 @@ int virDomainEmulatorPinDel(virDomainDefPtr def);
 
 void virDomainRNGDefFree(virDomainRNGDefPtr def);
 
+bool virDomainDiskDefDstDuplicates(virDomainDefPtr def);
 int virDomainDiskIndexByAddress(virDomainDefPtr def,
                                 virDevicePCIAddressPtr pci_controller,
                                 unsigned int bus, unsigned int target,
index 496b0522bbfef3d5a5c67e33dc3cfbdaae8abfc7..7b6a3865486db587146ec781a84dcab624c1a7e8 100644 (file)
@@ -224,6 +224,7 @@ virDomainDiskBusTypeToString;
 virDomainDiskCacheTypeFromString;
 virDomainDiskCacheTypeToString;
 virDomainDiskDefAssignAddress;
+virDomainDiskDefDstDuplicates;
 virDomainDiskDefForeachPath;
 virDomainDiskDefFree;
 virDomainDiskDefNew;
index 549853c9042f718ff8c0e61b0e5a0a66bb45b807..c112619669cfbb2ebe8fa1978eb466d3b942d8a6 100644 (file)
@@ -3882,6 +3882,9 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
     const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
     int controllerModel;
 
+    if (virDomainDiskDefDstDuplicates(def))
+        goto error;
+
     if (qemuCheckDiskConfig(disk) < 0)
         goto error;
 
index 4402f3eda316ca88f51ba7ee95646bcf32c7f53a..20b6f287f99708079fbe0351dfe27a0310d07f5d 100644 (file)
@@ -21,7 +21,7 @@
     </disk>
     <disk type='block' device='cdrom'>
       <source dev='/dev/HostVG/QEMUGuest2'/>
-      <target dev='sda' bus='scsi'/>
+      <target dev='sdb' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
     <disk type='file' device='disk'>
index 7cf57ec985ed2df51dfd299cd1348b9a3ff1e31a..4dbbd2995a65bfb5c6567c81213f883d69bc4579 100644 (file)
@@ -21,7 +21,7 @@
     </disk>
     <disk type='block' device='lun' sgio='filtered'>
       <source dev='/dev/HostVG/QEMUGuest2'/>
-      <target dev='hda' bus='scsi'/>
+      <target dev='hdb' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='1' unit='1'/>
     </disk>
     <controller type='scsi' index='0' model='virtio-scsi'/>
index 8111ea3d234a8d7501e6b334b25a5e2b70f341a2..3858ede77d8e4d3248913347c18e3432b7730031 100644 (file)
@@ -21,7 +21,7 @@
     </disk>
     <disk type='block' device='lun'>
       <source dev='/dev/HostVG/QEMUGuest2'/>
-      <target dev='hda' bus='scsi'/>
+      <target dev='hdb' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='1' unit='1'/>
     </disk>
     <controller type='scsi' index='0' model='virtio-scsi'/>
index 9f902936bb115f268d2933f56898e5ccccca5206..c791717232b398f6b64ea4a08b59dd60bfcbe814 100644 (file)
@@ -30,7 +30,7 @@
           <label>system_u:system_r:public_content_t:s0</label>
         </seclabel>
       </source>
-      <target dev='hda' bus='ide'/>
+      <target dev='hdb' bus='ide'/>
       <readonly/>
       <address type='drive' controller='0' bus='0' target='0' unit='2'/>
     </disk>
index 95d5be29045611d3db7e57dbc03645f63928685c..ef095a0920766f5d19e70a52ae939784ed8df77f 100644 (file)
@@ -34,7 +34,7 @@
     </disk>
     <disk type='file' device='disk'>
       <source file='/tmp/idedisk.img'/>
-      <target dev='hdc' bus='ide'/>
+      <target dev='hdd' bus='ide'/>
       <address type='drive' controller='0' bus='0' target='0' unit='2'/>
     </disk>
     <controller type='usb' index='0'/>
index 893eaa15a856bda4aa40eb7aaf33bb60bff4c5ab..fcd9692407d21b1702f327e9bae78cff862ae3d6 100644 (file)
@@ -8,8 +8,8 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
 -device pci-bridge,chassis_nr=3,id=pci.3,bus=pci.0,addr=0x5 \
 -usb -drive file=/var/lib/libvirt/images/test.img,if=none,id=drive-virtio-disk0 \
 -device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk0,id=virtio-disk0 \
--drive file=/var/lib/libvirt/images/disk-a-a.img,if=none,id=drive-virtio-disk0 \
--device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-virtio-disk0,id=virtio-disk0 \
+-drive file=/var/lib/libvirt/images/disk-a-a.img,if=none,id=drive-virtio-disk26 \
+-device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-virtio-disk26,id=virtio-disk26 \
 -drive file=/var/lib/libvirt/images/disk-a-b.img,if=none,id=drive-virtio-disk27 \
 -device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk27,id=virtio-disk27 \
 -drive file=/var/lib/libvirt/images/disk-a-c.img,if=none,id=drive-virtio-disk28 \
index 1f3ad6ecbcab59d196a30632db5f34552155ba17..bc429216e18670c8152ca951933724c841519b9d 100644 (file)
@@ -29,7 +29,7 @@
     <disk type='file' device='disk'>
       <driver name='qemu' type='raw'/>
       <source file='/var/lib/libvirt/images/disk-a-a.img'/>
-      <target dev='vda' bus='virtio'/>
+      <target dev='vdaa' bus='virtio'/>
     </disk>
     <disk type='file' device='disk'>
       <driver name='qemu' type='raw'/>
index 9551c91de3f7b03075a13fbcd725708a4a72d560..0f3306542589631651bddec4b90ac8f789d2d484 100644 (file)
@@ -6,10 +6,10 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
 -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
 -drive file=/var/lib/libvirt/images/test.img,if=none,id=drive-virtio-disk0 \
 -device virtio-blk-pci,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0 \
--drive file=/var/lib/libvirt/images/test1.img,if=none,id=drive-virtio-disk0 \
--device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0 \
--drive file=/var/lib/libvirt/images/disk-a-a.img,if=none,id=drive-virtio-disk0 \
--device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0 \
+-drive file=/var/lib/libvirt/images/test1.img,if=none,id=drive-virtio-disk1 \
+-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk1,id=virtio-disk1 \
+-drive file=/var/lib/libvirt/images/disk-a-a.img,if=none,id=drive-virtio-disk26 \
+-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk26,id=virtio-disk26 \
 -drive file=/var/lib/libvirt/images/disk-a-b.img,if=none,id=drive-virtio-disk27 \
 -device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-virtio-disk27,id=virtio-disk27 \
 -drive file=/var/lib/libvirt/images/disk-a-c.img,if=none,id=drive-virtio-disk28 \
index 400470e578113e199c99a82013586fd384c70848..b3c9ab1378f1da7d2b103d3066b01ea916b5e39c 100644 (file)
     <disk type='file' device='disk'>
       <driver name='qemu' type='raw'/>
       <source file='/var/lib/libvirt/images/test1.img'/>
-      <target dev='vda' bus='virtio'/>
+      <target dev='vdb' bus='virtio'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
     </disk>
     <disk type='file' device='disk'>
       <driver name='qemu' type='raw'/>
       <source file='/var/lib/libvirt/images/disk-a-a.img'/>
-      <target dev='vda' bus='virtio'/>
+      <target dev='vdaa' bus='virtio'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
     </disk>
     <disk type='file' device='disk'>
index e96f76eae847da92cb70213c16e05fec3e4ff0ab..31e4928caf686b481735f6c41111b0eea4cfc39c 100644 (file)
@@ -32,7 +32,7 @@
     </disk>
     <disk type='file' device='disk'>
       <source file='/tmp/idedisk.img'/>
-      <target dev='hdc' bus='ide'/>
+      <target dev='hdd' bus='ide'/>
       <address type='drive' controller='0' bus='0' target='0' unit='2'/>
     </disk>
     <controller type='usb' index='0'/>
index d49f5f4d0755240e0e1ba3f458ba4d1dbeb0d5dd..060fe870e6a6a43c55932c40b19e4b233d75e8ac 100644 (file)
@@ -30,7 +30,7 @@
     <disk type='file' device='disk'>
       <driver name='qemu' type='raw'/>
       <source file='/var/lib/libvirt/images/disk-a-a.img'/>
-      <target dev='vda' bus='virtio'/>
+      <target dev='vdaa' bus='virtio'/>
     </disk>
     <disk type='file' device='disk'>
       <driver name='qemu' type='raw'/>