}
}
+ for (i = 0; i < def->ndisks; i++) {
+ virDomainDiskDef *disk = def->disks[i];
+
+ /* The 'model' property for USB disks was introduced long after USB
+ * disks to allow switching between 'usb-storage' and 'usb-bot'
+ * device. Despite sharing identical implementation 'usb-bot' allows
+ * proper configuration of USB cdroms. Unfortunately it is not ABI
+ * compatible.
+ *
+ * To preserve migration to older daemons we can strip the model to
+ * the default if:
+ * - it's a normal disk (not cdrom) as both are identical
+ * - for a usb-cdrom strip the model if it's not 'usb-bot' as that
+ * was the old configuration
+ */
+ if (disk->bus == VIR_DOMAIN_DISK_BUS_USB &&
+ (disk->model == VIR_DOMAIN_DISK_MODEL_USB_STORAGE ||
+ disk->device == VIR_DOMAIN_DISK_DEVICE_DISK))
+ disk->model = VIR_DOMAIN_DISK_MODEL_DEFAULT;
+ }
+
/* Replace the CPU definition updated according to QEMU with the one
* used for starting the domain. The updated def will be sent
* separately for backward compatibility.
int
qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk,
- unsigned int parseFlags)
+ unsigned int parseFlags,
+ virQEMUCaps *qemuCaps)
{
virStorageSource *n;
disk->mirror->format == VIR_STORAGE_FILE_NONE)
disk->mirror->format = VIR_STORAGE_FILE_RAW;
+ /* default USB disk model:
+ *
+ * Historically we didn't use model for USB disks. It became necessary once
+ * it turned out that 'usb-storage' doesn't properly expose CDROM devices
+ * with -blockdev. Additionally 'usb-bot' which does properly handle them,
+ * while having identical implementation in qemu and driver in guest, are
+ * not in fact ABI compatible. Thus the logic is as follows:
+ *
+ * If ABI update is not allowed:
+ * - use 'usb-storage' for either (unless only 'usb-bot' is supported)
+ *
+ * If ABI update is possible
+ * - for VIR_DOMAIN_DISK_DEVICE_DISK use 'usb-storage' as it doesn't matter
+ * (it is identical with 'usb-bot' ABI wise)
+ * - for VIR_DOMAIN_DISK_DEVICE_CDROM use 'usb-bot' if available
+ * (as it properly exposes cdrom)
+ *
+ * When formatting migratable XML the code strips 'usb-storage' to preserve
+ * migration to older daemons. If a new definition with 'usb-bot' cdrom is
+ * created via new start or hotplug it will fail migrating. Users must
+ * explicitly set the broken config in XML or unplug the device.
+ */
+ if (qemuCaps &&
+ disk->bus == VIR_DOMAIN_DISK_BUS_USB &&
+ disk->model == VIR_DOMAIN_DISK_MODEL_DEFAULT) {
+
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+ parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE) {
+
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_BOT)) {
+ disk->model = VIR_DOMAIN_DISK_MODEL_USB_BOT;
+ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
+ disk->model = VIR_DOMAIN_DISK_MODEL_USB_STORAGE;
+ }
+
+ } else {
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
+ disk->model = VIR_DOMAIN_DISK_MODEL_USB_STORAGE;
+ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_BOT)) {
+ disk->model = VIR_DOMAIN_DISK_MODEL_USB_BOT;
+ }
+ }
+ }
+
/* default disk encryption engine */
for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
if (n->encryption && n->encryption->engine == VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT)
break;
case VIR_DOMAIN_DEVICE_DISK:
- ret = qemuDomainDeviceDiskDefPostParse(dev->data.disk, parseFlags);
+ ret = qemuDomainDeviceDiskDefPostParse(dev->data.disk, parseFlags, qemuCaps);
break;
case VIR_DOMAIN_DEVICE_VIDEO:
#pragma once
#include "virconftypes.h"
+#include "qemu_capabilities.h"
int
qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk,
- unsigned int parseFlags);
+ unsigned int parseFlags,
+ virQEMUCaps *qemuCaps);
int
qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev,
VIR_DOMAIN_DEF_PARSE_STATUS)))
return -1;
- if (qemuDomainDeviceDiskDefPostParse(disk, 0) < 0)
+ if (qemuDomainDeviceDiskDefPostParse(disk, 0, data->qemuCaps) < 0)
return -1;
if (!(vmdef = virDomainDefNew(data->driver->xmlopt)))
static virStorageSource *
testQemuImageCreateLoadDiskXML(const char *name,
- virDomainXMLOption *xmlopt)
+ virDomainXMLOption *xmlopt,
+ virQEMUCaps *qemuCaps)
{
g_autoptr(virDomainDiskDef) disk = NULL;
VIR_DOMAIN_DEF_PARSE_STATUS)))
return NULL;
- if (qemuDomainDeviceDiskDefPostParse(disk, 0) < 0)
+ if (qemuDomainDeviceDiskDefPostParse(disk, 0, qemuCaps) < 0)
return NULL;
return g_steal_pointer(&disk->src);
g_autofree char *actual = NULL;
g_autofree char *jsonpath = NULL;
- if (!(src = testQemuImageCreateLoadDiskXML(data->name, data->driver->xmlopt)))
+ if (!(src = testQemuImageCreateLoadDiskXML(data->name, data->driver->xmlopt,
+ data->qemuCaps)))
return -1;
if (data->backingname &&
!(src->backingStore = testQemuImageCreateLoadDiskXML(data->backingname,
- data->driver->xmlopt)))
+ data->driver->xmlopt,
+ data->qemuCaps)))
return -1;
if (testQemuDiskXMLToJSONFakeSecrets(src) < 0)
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-bot'>
<driver name='qemu' type='raw' cache='none'/>
<source file='/dev/null' index='1'/>
<backingStore/>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw' cache='none'/>
<source file='/dev/null' index='1'/>
<backingStore/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</disk>
- <disk type='block' device='disk'>
+ <disk type='block' device='disk' model='usb-storage'>
<driver name='qemu' type='qcow2' cache='directsync'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='sdb' bus='usb'/>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img1'/>
<target dev='sda' bus='usb'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img2'/>
<target dev='sdb' bus='usb'/>
<readonly/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img3'/>
<target dev='sdc' bus='usb'/>
<serial>testserial1</serial>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img4'/>
<target dev='sdd' bus='usb'/>
<readonly/>
<serial>testserial2</serial>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img5'/>
<target dev='sde' bus='usb'/>
<alias name='ua-test1'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img6'/>
<target dev='sdf' bus='usb'/>
<readonly/>
<alias name='ua-test2'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img7'/>
<target dev='sdg' bus='usb'/>
<serial>testserial3</serial>
<alias name='ua-test3'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img8'/>
<target dev='sdh' bus='usb'/>
<serial>testserial4</serial>
<alias name='ua-test4'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img9'/>
<target dev='sdi' bus='usb' removable='on'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imga'/>
<target dev='sdj' bus='usb' removable='on'/>
<serial>testserial5</serial>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgb'/>
<target dev='sdk' bus='usb' removable='on'/>
<alias name='ua-test5'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgc'/>
<target dev='sdl' bus='usb' removable='on'/>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img1'/>
<target dev='sda' bus='usb'/>
<address type='usb' bus='0' port='1.1'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img2'/>
<target dev='sdb' bus='usb'/>
<readonly/>
<address type='usb' bus='0' port='1.2'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img3'/>
<target dev='sdc' bus='usb'/>
<serial>testserial1</serial>
<address type='usb' bus='0' port='1.3'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img4'/>
<target dev='sdd' bus='usb'/>
<serial>testserial2</serial>
<address type='usb' bus='0' port='1.4'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img5'/>
<target dev='sde' bus='usb'/>
<alias name='ua-test1'/>
<address type='usb' bus='0' port='1.5'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img6'/>
<target dev='sdf' bus='usb'/>
<alias name='ua-test2'/>
<address type='usb' bus='0' port='1.6'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img7'/>
<target dev='sdg' bus='usb'/>
<alias name='ua-test3'/>
<address type='usb' bus='0' port='1.7'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img8'/>
<target dev='sdh' bus='usb'/>
<alias name='ua-test4'/>
<address type='usb' bus='0' port='1.8'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img9'/>
<target dev='sdi' bus='usb' removable='on'/>
<address type='usb' bus='0' port='2.1'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imga'/>
<target dev='sdj' bus='usb' removable='on'/>
<serial>testserial5</serial>
<address type='usb' bus='0' port='2.2'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgb'/>
<target dev='sdk' bus='usb' removable='on'/>
<alias name='ua-test5'/>
<address type='usb' bus='0' port='2.3'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgc'/>
<target dev='sdl' bus='usb' removable='on'/>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img1'/>
<target dev='sda' bus='usb'/>
<address type='usb' bus='0' port='1.1'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-bot'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img2'/>
<target dev='sdb' bus='usb'/>
<readonly/>
<address type='usb' bus='0' port='1.2'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img3'/>
<target dev='sdc' bus='usb'/>
<serial>testserial1</serial>
<address type='usb' bus='0' port='1.3'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-bot'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img4'/>
<target dev='sdd' bus='usb'/>
<serial>testserial2</serial>
<address type='usb' bus='0' port='1.4'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img5'/>
<target dev='sde' bus='usb'/>
<alias name='ua-test1'/>
<address type='usb' bus='0' port='1.5'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-bot'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img6'/>
<target dev='sdf' bus='usb'/>
<alias name='ua-test2'/>
<address type='usb' bus='0' port='1.6'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img7'/>
<target dev='sdg' bus='usb'/>
<alias name='ua-test3'/>
<address type='usb' bus='0' port='1.7'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-bot'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img8'/>
<target dev='sdh' bus='usb'/>
<alias name='ua-test4'/>
<address type='usb' bus='0' port='1.8'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img9'/>
<target dev='sdi' bus='usb' removable='on'/>
<address type='usb' bus='0' port='2.1'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imga'/>
<target dev='sdj' bus='usb' removable='on'/>
<serial>testserial5</serial>
<address type='usb' bus='0' port='2.2'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgb'/>
<target dev='sdk' bus='usb' removable='on'/>
<alias name='ua-test5'/>
<address type='usb' bus='0' port='2.3'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgc'/>
<target dev='sdl' bus='usb' removable='on'/>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img1'/>
<target dev='sda' bus='usb'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img2'/>
<target dev='sdb' bus='usb'/>
<readonly/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img3'/>
<target dev='sdc' bus='usb'/>
<serial>testserial1</serial>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img4'/>
<target dev='sdd' bus='usb'/>
<readonly/>
<serial>testserial2</serial>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img5'/>
<target dev='sde' bus='usb'/>
<alias name='ua-test1'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img6'/>
<target dev='sdf' bus='usb'/>
<readonly/>
<alias name='ua-test2'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img7'/>
<target dev='sdg' bus='usb'/>
<serial>testserial3</serial>
<alias name='ua-test3'/>
</disk>
- <disk type='file' device='cdrom'>
+ <disk type='file' device='cdrom' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img8'/>
<target dev='sdh' bus='usb'/>
<serial>testserial4</serial>
<alias name='ua-test4'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/img9'/>
<target dev='sdi' bus='usb' removable='on'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imga'/>
<target dev='sdj' bus='usb' removable='on'/>
<serial>testserial5</serial>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgb'/>
<target dev='sdk' bus='usb' removable='on'/>
<alias name='ua-test5'/>
</disk>
- <disk type='file' device='disk'>
+ <disk type='file' device='disk' model='usb-storage'>
<driver name='qemu' type='raw'/>
<source file='/tmp/imgc'/>
<target dev='sdl' bus='usb' removable='on'/>