1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

qemu: Introduce qemuBuildDiskDriveCommandLine

Add new function to manage adding the disk -drive options to the
command line removing that task from the mainline qemuBuildCommandLine.

Also since using const virDomainDef in new function, that means other
functions called needed to change their usage.

Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
John Ferlan 2016-02-18 09:56:10 -05:00
parent f87be33a6f
commit 0ea0f6c496
4 changed files with 173 additions and 154 deletions

View File

@ -5892,7 +5892,7 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
} }
int int
virDomainDeviceFindControllerModel(virDomainDefPtr def, virDomainDeviceFindControllerModel(const virDomainDef *def,
virDomainDeviceInfoPtr info, virDomainDeviceInfoPtr info,
int controllerType) int controllerType)
{ {
@ -18488,7 +18488,7 @@ virDomainDefAddImplicitControllers(virDomainDefPtr def)
} }
virDomainIOThreadIDDefPtr virDomainIOThreadIDDefPtr
virDomainIOThreadIDFind(virDomainDefPtr def, virDomainIOThreadIDFind(const virDomainDef *def,
unsigned int iothread_id) unsigned int iothread_id)
{ {
size_t i; size_t i;

View File

@ -2522,7 +2522,7 @@ int virDomainDiskSetDriver(virDomainDiskDefPtr def, const char *name)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
int virDomainDiskGetFormat(virDomainDiskDefPtr def); int virDomainDiskGetFormat(virDomainDiskDefPtr def);
void virDomainDiskSetFormat(virDomainDiskDefPtr def, int format); void virDomainDiskSetFormat(virDomainDiskDefPtr def, int format);
int virDomainDeviceFindControllerModel(virDomainDefPtr def, int virDomainDeviceFindControllerModel(const virDomainDef *def,
virDomainDeviceInfoPtr info, virDomainDeviceInfoPtr info,
int controllerType); int controllerType);
virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def, virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def,
@ -2705,7 +2705,7 @@ bool virDomainDefCheckABIStability(virDomainDefPtr src,
int virDomainDefAddImplicitControllers(virDomainDefPtr def); int virDomainDefAddImplicitControllers(virDomainDefPtr def);
virDomainIOThreadIDDefPtr virDomainIOThreadIDFind(virDomainDefPtr def, virDomainIOThreadIDDefPtr virDomainIOThreadIDFind(const virDomainDef *def,
unsigned int iothread_id); unsigned int iothread_id);
virDomainIOThreadIDDefPtr virDomainIOThreadIDAdd(virDomainDefPtr def, virDomainIOThreadIDDefPtr virDomainIOThreadIDAdd(virDomainDefPtr def,
unsigned int iothread_id); unsigned int iothread_id);

View File

@ -1497,7 +1497,7 @@ qemuBuildDriveStr(virConnectPtr conn,
static bool static bool
qemuCheckIOThreads(virDomainDefPtr def, qemuCheckIOThreads(const virDomainDef *def,
virDomainDiskDefPtr disk) virDomainDiskDefPtr disk)
{ {
/* Right "type" of disk" */ /* Right "type" of disk" */
@ -1523,7 +1523,7 @@ qemuCheckIOThreads(virDomainDefPtr def,
char * char *
qemuBuildDriveDevStr(virDomainDefPtr def, qemuBuildDriveDevStr(const virDomainDef *def,
virDomainDiskDefPtr disk, virDomainDiskDefPtr disk,
int bootindex, int bootindex,
virQEMUCapsPtr qemuCaps) virQEMUCapsPtr qemuCaps)
@ -1820,6 +1820,168 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
} }
static int
qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
virConnectPtr conn,
const virDomainDef *def,
virQEMUCapsPtr qemuCaps,
bool emitBootindex)
{
size_t i;
int bootCD = 0, bootFloppy = 0, bootDisk = 0;
virBuffer fdc_opts = VIR_BUFFER_INITIALIZER;
char *fdc_opts_str = NULL;
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);
return -1;
}
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"));
return -1;
}
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)
return -1;
virCommandAddArg(cmd, optstr);
VIR_FREE(optstr);
if (!emitBootindex)
bootindex = 0;
else if (disk->info.bootIndex)
bootindex = disk->info.bootIndex;
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)
return -1;
if (!qemuDomainMachineNeedsFDC(def)) {
virCommandAddArg(cmd, "-global");
virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr);
} else {
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)
return -1;
if (!qemuDomainMachineNeedsFDC(def)) {
virCommandAddArg(cmd, "-global");
virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr);
} else {
virBufferAsprintf(&fdc_opts, "%s,", optstr);
}
VIR_FREE(optstr);
}
} else {
virCommandAddArg(cmd, "-device");
if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
qemuCaps)))
return -1;
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);
}
return 0;
}
char *qemuBuildFSStr(virDomainFSDefPtr fs, char *qemuBuildFSStr(virDomainFSDefPtr fs,
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED) virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED)
{ {
@ -7734,9 +7896,7 @@ qemuBuildCommandLine(virConnectPtr conn,
bool emitBootindex = false; bool emitBootindex = false;
int actualSerials = 0; int actualSerials = 0;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virBuffer fdc_opts = VIR_BUFFER_INITIALIZER; int bootHostdevNet = 0;
char *fdc_opts_str = NULL;
int bootCD = 0, bootFloppy = 0, bootDisk = 0, bootHostdevNet = 0;
VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d " VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
@ -7849,150 +8009,9 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuBuildHubCommandLine(cmd, def, qemuCaps) < 0) if (qemuBuildHubCommandLine(cmd, def, qemuCaps) < 0)
goto error; goto error;
if ((virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) { if (qemuBuildDiskDriveCommandLine(cmd, conn, def, qemuCaps,
/* bootDevs will get translated into either bootindex=N or boot=on emitBootindex) < 0)
* 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; 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"));
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);
if (!emitBootindex)
bootindex = 0;
else if (disk->info.bootIndex)
bootindex = disk->info.bootIndex;
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 {
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);
}
} 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);
}
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) {
for (i = 0; i < def->nfss; i++) { for (i = 0; i < def->nfss; i++) {

View File

@ -121,7 +121,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
virQEMUCapsPtr qemuCaps); virQEMUCapsPtr qemuCaps);
/* Current, best practice */ /* Current, best practice */
char *qemuBuildDriveDevStr(virDomainDefPtr def, char *qemuBuildDriveDevStr(const virDomainDef *def,
virDomainDiskDefPtr disk, virDomainDiskDefPtr disk,
int bootindex, int bootindex,
virQEMUCapsPtr qemuCaps); virQEMUCapsPtr qemuCaps);