[libvirt] [PATCH 6/7] qemu: assume -drive argument is always available
John Ferlan
jferlan at redhat.com
Thu Nov 5 23:07:38 UTC 2015
On 11/05/2015 12:33 PM, Daniel P. Berrange wrote:
> As of QEMU 0.9.1 the -drive argument can be used to configure
> all disks, so the QEMU driver can assume it is always available
> and drop support for -hda/-cdrom/etc.
>
> Many of the tests need updating because a great many were
> running without CAPS_DRIVE set, so using the -hda legacy
> syntax.
>
> Fixing the tests uncovered a bug in the argv -> xml
> convertor which failed to handle disk with if=floppy.
>
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
> src/qemu/qemu_capabilities.c | 45 ++-
> src/qemu/qemu_capabilities.h | 2 +-
> src/qemu/qemu_command.c | 365 ++++++++-------------
> src/qemu/qemu_hotplug.c | 3 +-
[...]
format nits and a couple questions about changes.
>
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 79d1692..7676237 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -1104,29 +1104,27 @@ virQEMUCapsComputeCmdFlags(const char *help,
> virQEMUCapsSet(qemuCaps, QEMU_CAPS_XEN_DOMID);
> else if (strstr(help, "-domid"))
> virQEMUCapsSet(qemuCaps, QEMU_CAPS_DOMID);
> - if (strstr(help, "-drive")) {
> - const char *cache = strstr(help, "cache=");
> -
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE);
> - if (cache && (p = strchr(cache, ']'))) {
> - if (memmem(cache, p - cache, "on|off", sizeof("on|off") - 1) == NULL)
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2);
> - if (memmem(cache, p - cache, "directsync", sizeof("directsync") - 1))
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
> + const char *cache = strstr(help, "cache=");
Although it works for this compiler... Should this move up to the start
of the function?
> +
> + if (cache && (p = strchr(cache, ']'))) {
> + if (memmem(cache, p - cache, "on|off", sizeof("on|off") - 1) == NULL)
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2);
> + if (memmem(cache, p - cache, "directsync", sizeof("directsync") - 1))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
> if (memmem(cache, p - cache, "unsafe", sizeof("unsafe") - 1))
> virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE);
> - }
> - if (strstr(help, "format="))
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT);
> - if (strstr(help, "readonly="))
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_READONLY);
> - if (strstr(help, "aio=threads|native"))
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_AIO);
> - if (strstr(help, "copy-on-read=on|off"))
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ);
> - if (strstr(help, "bps="))
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE);
> }
> + if (strstr(help, "format="))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT);
> + if (strstr(help, "readonly="))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_READONLY);
> + if (strstr(help, "aio=threads|native"))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_AIO);
> + if (strstr(help, "copy-on-read=on|off"))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ);
> + if (strstr(help, "bps="))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE);
> +
> if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
> const char *nl = strstr(p, "\n");
>
> @@ -3214,7 +3212,6 @@ static qemuMonitorCallbacks callbacks = {
> static void
> virQEMUCapsInitQMPBasic(virQEMUCapsPtr qemuCaps)
> {
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE);
> virQEMUCapsSet(qemuCaps, QEMU_CAPS_NAME);
> virQEMUCapsSet(qemuCaps, QEMU_CAPS_UUID);
> virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNET_HDR);
> @@ -3938,8 +3935,7 @@ virQEMUCapsFillDomainLoaderCaps(virQEMUCapsPtr qemuCaps,
> VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
> VIR_DOMAIN_LOADER_TYPE_ROM);
>
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) &&
> - virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT))
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT))
> VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
> VIR_DOMAIN_LOADER_TYPE_PFLASH);
>
> @@ -4023,8 +4019,7 @@ virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
> VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
> VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB,
> VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI);
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) &&
> - virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
> virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC))
> VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
> VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI);
> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
> index 2179162..ff66ca9 100644
> --- a/src/qemu/qemu_capabilities.h
> +++ b/src/qemu/qemu_capabilities.h
> @@ -36,7 +36,7 @@ typedef enum {
> X_QEMU_CAPS_KQEMU, /* Whether KQEMU is compiled in */
> X_QEMU_CAPS_VNC_COLON, /* VNC takes or address + display */
> X_QEMU_CAPS_NO_REBOOT, /* Is the -no-reboot flag available */
> - QEMU_CAPS_DRIVE, /* Is the new -drive arg available */
> + X_QEMU_CAPS_DRIVE, /* Is the new -drive arg available */
> QEMU_CAPS_DRIVE_BOOT, /* Does -drive support boot=on */
>
> /* 5 */
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 77913b3..956345f 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -777,20 +777,6 @@ int qemuDomainNetVLAN(virDomainNetDefPtr def)
> }
>
>
> -/* Names used before -drive existed */
> -static int qemuAssignDeviceDiskAliasLegacy(virDomainDiskDefPtr disk)
> -{
> - char *dev_name;
> -
> - if (VIR_STRDUP(dev_name,
> - disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
> - STREQ(disk->dst, "hdc") ? "cdrom" : disk->dst) < 0)
> - return -1;
> - disk->info.alias = dev_name;
> - return 0;
> -}
> -
> -
> char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk,
> virQEMUCapsPtr qemuCaps)
> {
> @@ -845,6 +831,9 @@ static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk)
> case VIR_DOMAIN_DISK_BUS_SD:
> ret = virAsprintf(&dev_name, "sd%d", devid);
> break;
> + case VIR_DOMAIN_DISK_BUS_USB:
> + ret = virAsprintf(&dev_name, "usb%d", devid);
> + break;
[1]
Is this an unrelated bug? Or perhaps was support added after/with
QEMU_CAPS_DEVICE. IOW: Why haven't we hit this before?
Reading further in the patch seems to have another clue, but getting
into this helper means !QEMU_CAPS_DEVICE
> default:
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> _("Unsupported disk name mapping for bus '%s'"),
> @@ -967,14 +956,10 @@ qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef,
> virDomainDiskDefPtr def,
> virQEMUCapsPtr qemuCaps)
> {
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
> - return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps);
> - else
> - return qemuAssignDeviceDiskAliasFixed(def);
> - } else {
> - return qemuAssignDeviceDiskAliasLegacy(def);
> - }
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
> + return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps);
> + else
> + return qemuAssignDeviceDiskAliasFixed(def);
> }
>
>
> @@ -9084,11 +9069,6 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
> break;
>
> case VIR_DOMAIN_LOADER_TYPE_PFLASH:
> - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> - _("this QEMU binary doesn't support -drive"));
> - goto cleanup;
> - }
> if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT)) {
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> _("this QEMU binary doesn't support passing "
> @@ -9267,6 +9247,7 @@ qemuBuildCommandLine(virConnectPtr conn,
> char *boot_order_str = NULL, *boot_opts_str = NULL;
> virBuffer fdc_opts = VIR_BUFFER_INITIALIZER;
> char *fdc_opts_str = NULL;
> + int bootCD = 0, bootFloppy = 0, bootDisk = 0;
>
> VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
> "qemuCaps=%p migrateFrom=%s migrateFD=%d "
> @@ -10081,111 +10062,122 @@ qemuBuildCommandLine(virConnectPtr conn,
> VIR_FREE(optstr);
> }
>
ugh - git diff makes it hard to follow the indents !
> - /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
> - int bootCD = 0, bootFloppy = 0, bootDisk = 0;
> -
> - if ((virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) {
> - /* bootDevs will get translated into either bootindex=N or boot=on
> - * depending on what qemu supports */
> - for (i = 0; i < def->os.nBootDevs; i++) {
> - switch (def->os.bootDevs[i]) {
> - case VIR_DOMAIN_BOOT_CDROM:
> - bootCD = i + 1;
> - break;
> - case VIR_DOMAIN_BOOT_FLOPPY:
> - bootFloppy = i + 1;
> - break;
> - case VIR_DOMAIN_BOOT_DISK:
> - bootDisk = i + 1;
> - break;
> - }
> + if ((virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) {
> + /* bootDevs will get translated into either bootindex=N or boot=on
> + * depending on what qemu supports */
> + for (i = 0; i < def->os.nBootDevs; i++) {
> + switch (def->os.bootDevs[i]) {
> + case VIR_DOMAIN_BOOT_CDROM:
> + bootCD = i + 1;
> + break;
> + case VIR_DOMAIN_BOOT_FLOPPY:
> + bootFloppy = i + 1;
> + break;
> + case VIR_DOMAIN_BOOT_DISK:
> + bootDisk = i + 1;
> + break;
> }
> }
> + }
>
> - for (i = 0; i < def->ndisks; i++) {
> - char *optstr;
> - int bootindex = 0;
> - virDomainDiskDefPtr disk = def->disks[i];
> - bool withDeviceArg = false;
> - bool deviceFlagMasked = false;
> -
> - /* Unless we have -device, then USB disks need special
> - handling */
> - if ((disk->bus == VIR_DOMAIN_DISK_BUS_USB) &&
> - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> - if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
> - virCommandAddArg(cmd, "-usbdevice");
> - virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
> - } else {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - _("unsupported usb disk type for '%s'"),
> - disk->src->path);
> - goto error;
> - }
> - continue;
> - }
> -
> - /* PowerPC pseries based VMs do not support floppy device */
> - if ((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) &&
> - ARCH_IS_PPC64(def->os.arch) && STRPREFIX(def->os.machine, "pseries")) {
> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> - _("PowerPC pseries machines do not support floppy device"));
> + for (i = 0; i < def->ndisks; i++) {
> + char *optstr;
> + int bootindex = 0;
> + virDomainDiskDefPtr disk = def->disks[i];
> + bool withDeviceArg = false;
> + bool deviceFlagMasked = false;
> +
> + /* Unless we have -device, then USB disks need special
> + handling */
[1] From above when adding "usb%d" to qemuAssignDeviceDiskAliasFixed
> + if ((disk->bus == VIR_DOMAIN_DISK_BUS_USB) &&
> + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> + if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
> + virCommandAddArg(cmd, "-usbdevice");
> + virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
> + } else {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("unsupported usb disk type for '%s'"),
> + disk->src->path);
> goto error;
> }
> + continue;
> + }
>
> - switch (disk->device) {
> - case VIR_DOMAIN_DISK_DEVICE_CDROM:
> - bootindex = bootCD;
> - bootCD = 0;
> - break;
> - case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
> - bootindex = bootFloppy;
> - bootFloppy = 0;
> - break;
> - case VIR_DOMAIN_DISK_DEVICE_DISK:
> - case VIR_DOMAIN_DISK_DEVICE_LUN:
> - bootindex = bootDisk;
> - bootDisk = 0;
> - break;
> + /* PowerPC pseries based VMs do not support floppy device */
> + if ((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) &&
> + ARCH_IS_PPC64(def->os.arch) && STRPREFIX(def->os.machine, "pseries")) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("PowerPC pseries machines do not support floppy device"));
> + goto error;
> + }
> +
> + switch (disk->device) {
> + case VIR_DOMAIN_DISK_DEVICE_CDROM:
> + bootindex = bootCD;
> + bootCD = 0;
> + break;
> + case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
> + bootindex = bootFloppy;
> + bootFloppy = 0;
> + break;
> + case VIR_DOMAIN_DISK_DEVICE_DISK:
> + case VIR_DOMAIN_DISK_DEVICE_LUN:
> + bootindex = bootDisk;
> + bootDisk = 0;
> + break;
> + }
> +
> + virCommandAddArg(cmd, "-drive");
> +
> + /* Unfortunately it is not possible to use
> + -device for floppies, xen PV, or SD
> + devices. Fortunately, those don't need
> + static PCI addresses, so we don't really
> + care that we can't use -device */
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> + if (disk->bus != VIR_DOMAIN_DISK_BUS_XEN &&
> + disk->bus != VIR_DOMAIN_DISK_BUS_SD) {
> + withDeviceArg = true;
> + } else {
> + virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE);
> + deviceFlagMasked = true;
> }
> + }
> + optstr = qemuBuildDriveStr(conn, disk,
> + emitBootindex ? false : !!bootindex,
> + qemuCaps);
> + if (deviceFlagMasked)
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE);
> + if (!optstr)
> + goto error;
> + virCommandAddArg(cmd, optstr);
> + VIR_FREE(optstr);
>
> - virCommandAddArg(cmd, "-drive");
> + if (!emitBootindex)
> + bootindex = 0;
> + else if (disk->info.bootIndex)
> + bootindex = disk->info.bootIndex;
>
> - /* Unfortunately it is not possible to use
> - -device for floppies, xen PV, or SD
> - devices. Fortunately, those don't need
> - static PCI addresses, so we don't really
> - care that we can't use -device */
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> - if (disk->bus != VIR_DOMAIN_DISK_BUS_XEN &&
> - disk->bus != VIR_DOMAIN_DISK_BUS_SD) {
> - withDeviceArg = true;
> + if (withDeviceArg) {
> + if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) {
> + if (virAsprintf(&optstr, "drive%c=drive-%s",
> + disk->info.addr.drive.unit ? 'B' : 'A',
> + disk->info.alias) < 0)
> + goto error;
> +
> + if (!qemuDomainMachineNeedsFDC(def)) {
> + virCommandAddArg(cmd, "-global");
> + virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr);
> } else {
> - virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE);
> - deviceFlagMasked = true;
> + virBufferAsprintf(&fdc_opts, "%s,", optstr);
> }
> - }
> - optstr = qemuBuildDriveStr(conn, disk,
> - emitBootindex ? false : !!bootindex,
> - qemuCaps);
> - if (deviceFlagMasked)
> - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE);
> - if (!optstr)
> - goto error;
> - virCommandAddArg(cmd, optstr);
> - VIR_FREE(optstr);
> -
> - if (!emitBootindex)
> - bootindex = 0;
> - else if (disk->info.bootIndex)
> - bootindex = disk->info.bootIndex;
> + VIR_FREE(optstr);
>
> - if (withDeviceArg) {
> - if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) {
> - if (virAsprintf(&optstr, "drive%c=drive-%s",
> - disk->info.addr.drive.unit ? 'B' : 'A',
> - disk->info.alias) < 0)
> + if (bootindex) {
> + if (virAsprintf(&optstr, "bootindex%c=%d",
> + disk->info.addr.drive.unit
> + ? 'B' : 'A',
> + bootindex) < 0)
> goto error;
>
> if (!qemuDomainMachineNeedsFDC(def)) {
> @@ -10195,126 +10187,25 @@ qemuBuildCommandLine(virConnectPtr conn,
> virBufferAsprintf(&fdc_opts, "%s,", optstr);
> }
> VIR_FREE(optstr);
> -
> - if (bootindex) {
> - if (virAsprintf(&optstr, "bootindex%c=%d",
> - disk->info.addr.drive.unit
> - ? 'B' : 'A',
> - bootindex) < 0)
> - goto error;
> -
> - if (!qemuDomainMachineNeedsFDC(def)) {
> - virCommandAddArg(cmd, "-global");
> - virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr);
> - } else {
> - virBufferAsprintf(&fdc_opts, "%s,", optstr);
> - }
> - VIR_FREE(optstr);
> - }
While at first glance it felt like the following hunk was lost - it's
intermixed in the middle of the former "} else {" to the if -drive check...
> - } else {
> - virCommandAddArg(cmd, "-device");
> -
> - if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
> - qemuCaps)))
> - goto error;
> - virCommandAddArg(cmd, optstr);
> - VIR_FREE(optstr);
> - }
> - }
> - }
> - /* Newer Q35 machine types require an explicit FDC controller */
> - virBufferTrim(&fdc_opts, ",", -1);
> - if ((fdc_opts_str = virBufferContentAndReset(&fdc_opts))) {
> - virCommandAddArg(cmd, "-device");
> - virCommandAddArgFormat(cmd, "isa-fdc,%s", fdc_opts_str);
> - VIR_FREE(fdc_opts_str);
> - }
> - } else {
> - for (i = 0; i < def->ndisks; i++) {
> - char dev[NAME_MAX];
> - char *file;
> - const char *fmt;
> - virDomainDiskDefPtr disk = def->disks[i];
> -
> - if ((disk->src->type == VIR_STORAGE_TYPE_BLOCK) &&
> - (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> - _("tray status 'open' is invalid for "
> - "block type disk"));
> - goto error;
> - }
> -
> - if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
> - if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
> - virCommandAddArg(cmd, "-usbdevice");
> - virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
> - } else {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - _("unsupported usb disk type for '%s'"),
> - disk->src->path);
> - goto error;
> - }
> - continue;
> - }
> -
> - if (STREQ(disk->dst, "hdc") &&
> - disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
> - if (disk->src->path) {
> - snprintf(dev, NAME_MAX, "-%s", "cdrom");
> - } else {
> - continue;
> }
> } else {
> - if (STRPREFIX(disk->dst, "hd") ||
> - STRPREFIX(disk->dst, "fd")) {
> - snprintf(dev, NAME_MAX, "-%s", disk->dst);
> - } else {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - _("unsupported disk type '%s'"), disk->dst);
> - goto error;
> - }
> - }
> -
> - if (disk->src->type == VIR_STORAGE_TYPE_DIR) {
> - /* QEMU only supports magic FAT format for now */
> - if (disk->src->format > 0 &&
> - disk->src->format != VIR_STORAGE_FILE_FAT) {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - _("unsupported disk driver type for '%s'"),
> - virStorageFileFormatTypeToString(disk->src->format));
> - goto error;
> - }
> - if (!disk->src->readonly) {
> - virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> - _("cannot create virtual FAT disks in read-write mode"));
> - goto error;
> - }
> - if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
> - fmt = "fat:floppy:%s";
> - else
> - fmt = "fat:%s";
> + virCommandAddArg(cmd, "-device");
>
> - if (virAsprintf(&file, fmt, disk->src) < 0)
> - goto error;
> - } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
> - virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> - _("network disks are only supported with -drive"));
> - goto error;
> - } else {
> - if (VIR_STRDUP(file, disk->src->path) < 0)
> + if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
> + qemuCaps)))
> goto error;
> + virCommandAddArg(cmd, optstr);
> + VIR_FREE(optstr);
> }
> -
> - /* Don't start with source if the tray is open for
> - * CDROM and Floppy device.
> - */
> - if (!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
> - disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
> - disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN))
> - virCommandAddArgList(cmd, dev, file, NULL);
> - VIR_FREE(file);
> }
> }
> + /* Newer Q35 machine types require an explicit FDC controller */
> + virBufferTrim(&fdc_opts, ",", -1);
> + if ((fdc_opts_str = virBufferContentAndReset(&fdc_opts))) {
> + virCommandAddArg(cmd, "-device");
> + virCommandAddArgFormat(cmd, "isa-fdc,%s", fdc_opts_str);
> + VIR_FREE(fdc_opts_str);
> + }
>
> if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) {
> for (i = 0; i < def->nfss; i++) {
> @@ -11167,8 +11058,7 @@ qemuBuildCommandLine(virConnectPtr conn,
> /* SCSI */
> if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
> hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) &&
> - virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
> virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
> char *drvstr;
>
> @@ -12033,6 +11923,9 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
> }
> } else if (STREQ(values[i], "scsi")) {
> def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
> + } else if (STREQ(values[i], "floppy")) {
> + def->bus = VIR_DOMAIN_DISK_BUS_FDC;
> + def->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
Is this another lurking bug? or part of the "if=floppy" bug? Is it
worth separating out just in case in needs to be applied elsewhere?
> } else if (STREQ(values[i], "virtio")) {
> def->bus = VIR_DOMAIN_DISK_BUS_VIRTIO;
> } else if (STREQ(values[i], "xen")) {
> @@ -12202,6 +12095,8 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
> ignore_value(VIR_STRDUP(def->dst, "vda"));
> } else if (def->bus == VIR_DOMAIN_DISK_BUS_XEN) {
> ignore_value(VIR_STRDUP(def->dst, "xvda"));
> + } else if (def->bus == VIR_DOMAIN_DISK_BUS_FDC) {
> + ignore_value(VIR_STRDUP(def->dst, "fda"));
Similar comment
> } else {
> ignore_value(VIR_STRDUP(def->dst, "hda"));
> }
More information about the libvir-list
mailing list