Summary
-------
It seems like libvirt is generating the same QEMU drive host
alias ('drive-virtio-disk%d') for different two disk labels (vdb, vdb1).
[Refer the contextual root cause analysis discussion at the end with
Laine & Peter.]
Let's take a quick example to demonstrate the issue.
On a guest that is shut down, attach a couplee of disks with labels
'vdb', and 'vdb1'
$ sudo virsh attach-disk cvm1 \
/export/vmimages/1.raw vdb --config
$ sudo virsh attach-disk cvm1 \
/export/vmimages/1.raw vdb1 --config
$ virsh domblklist cvm1
Target Source
------------------------------------------------
vda /var/lib/libvirt/images/cirros-0.3.3-x86_64-disk.img
vdb /export/vmimages/1.raw
vdb1 /export/vmimages/1.raw
Which results in guest XML:
[...]
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/export/vmimages/1.raw'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x07' function='0x0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/export/vmimages/1.raw'/>
<target dev='vdb1' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x08' function='0x0'/>
</disk>
[...]
Sarting the guest (error message manually wrapped) fails, as
$ virsh start cvm1
error: Failed to start domain cvm1
error: internal error: process exited while connecting to monitor:
qemu-system-x86_64: -drive
file=/export/vmimages/1.raw,format=raw,if=none,id=drive-virtio-disk1: Duplicate
ID 'drive-virtio-disk1' for drive
It results in QEMU CLI:
-drive file=/export/vmimages/1.raw,format=raw,if=none,id=drive-virtio-disk1 \
-device
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x7,drive=drive-virtio-disk1,id=virtio-disk1 \
-drive file=/export/vmimages/1.raw,format=raw,if=none,id=drive-virtio-disk1 \
-device
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x8,drive=drive-virtio-disk1,id=virtio-disk1 \
Root cause analysis discussion from IRC from Friday
---------------------------------------------------
[laine]
The problem is that the "alias" libvirt generates based on the target
device name should be unique, but it isn't.
I can see why it's doing that. When putting the index of the disk it's
processing within the entries into drive-virtio-disk%d, it learns the
index by calling virDiskNameToIndex().
It's going through a list of disks, 0, 1, 2, 3, etc creating the
alias. But at each index, it calls this other function to learn the
index, and that function just searches for the first entry that matches
the name.
If they *really* don't know the index (because they only have a
pointer to the entry) they should just search for the entry with the
matching *address in memory*
Haven't stepped through it carefully, but it looks like "vdb" and
"vdb1" lead to the same id, and also "vdb" and "sdb"
[pkrempa]
The alias generator calls virDiskNameToIndex() which calls
virDiskNameParse(). virDiskNameParse() parses the name including
the partition number and returns it. virDiskNameToIndex() discards
the partition number and returns the disk index.
If we accept both 'sdb' and 'sdb1' but generate the same alias then
that's a bug.
--
/kashyap