mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Split code for building QEMU -drive arg in separate method
To enable it to be called from multiple locations, split out the code for building the -drive arg string. This will be needed by later patches which do drive hotplug, the conversion to use -device, and the conversion to controller/bus/unit addressing * src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Add qemuBuildDriveStr for building -drive arg string
This commit is contained in:
parent
ab0da52b43
commit
2982d73a11
@ -1523,6 +1523,104 @@ qemuAssignNetNames(virDomainDefPtr def,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
|
||||||
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuSafeSerialParamValue(virConnectPtr conn,
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen (value)) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("driver serial '%s' contains unsafe characters"),
|
||||||
|
value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
qemuBuildDriveStr(virDomainDiskDefPtr disk,
|
||||||
|
int bootable,
|
||||||
|
int qemuCmdFlags)
|
||||||
|
{
|
||||||
|
virBuffer opt = VIR_BUFFER_INITIALIZER;
|
||||||
|
const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
|
||||||
|
int idx = virDiskNameToIndex(disk->dst);
|
||||||
|
|
||||||
|
if (idx < 0) {
|
||||||
|
qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported disk type '%s'"), disk->dst);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disk->src) {
|
||||||
|
if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
|
||||||
|
/* QEMU only supports magic FAT format for now */
|
||||||
|
if (disk->driverType &&
|
||||||
|
STRNEQ(disk->driverType, "fat")) {
|
||||||
|
qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported disk driver type for '%s'"),
|
||||||
|
disk->driverType);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!disk->readonly) {
|
||||||
|
qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("cannot create virtual FAT disks in read-write mode"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
|
||||||
|
virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src);
|
||||||
|
else
|
||||||
|
virBufferVSprintf(&opt, "file=fat:%s,", disk->src);
|
||||||
|
} else {
|
||||||
|
virBufferVSprintf(&opt, "file=%s,", disk->src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virBufferVSprintf(&opt, "if=%s", bus);
|
||||||
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
|
||||||
|
virBufferAddLit(&opt, ",media=cdrom");
|
||||||
|
virBufferVSprintf(&opt, ",index=%d", idx);
|
||||||
|
if (bootable &&
|
||||||
|
disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
|
||||||
|
virBufferAddLit(&opt, ",boot=on");
|
||||||
|
if (disk->driverType &&
|
||||||
|
disk->type != VIR_DOMAIN_DISK_TYPE_DIR &&
|
||||||
|
qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT)
|
||||||
|
virBufferVSprintf(&opt, ",format=%s", disk->driverType);
|
||||||
|
if (disk->serial &&
|
||||||
|
(qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_SERIAL)) {
|
||||||
|
if (qemuSafeSerialParamValue(NULL, disk->serial) < 0)
|
||||||
|
goto error;
|
||||||
|
virBufferVSprintf(&opt, ",serial=%s", disk->serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disk->cachemode) {
|
||||||
|
const char *mode =
|
||||||
|
(qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_CACHE_V2) ?
|
||||||
|
qemuDiskCacheV2TypeToString(disk->cachemode) :
|
||||||
|
qemuDiskCacheV1TypeToString(disk->cachemode);
|
||||||
|
|
||||||
|
virBufferVSprintf(&opt, ",cache=%s", mode);
|
||||||
|
} else if (disk->shared && !disk->readonly) {
|
||||||
|
virBufferAddLit(&opt, ",cache=off");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBufferError(&opt)) {
|
||||||
|
virReportOOMError(NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return virBufferContentAndReset(&opt);
|
||||||
|
|
||||||
|
error:
|
||||||
|
virBufferFreeAndReset(&opt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuBuildNicStr(virConnectPtr conn,
|
qemuBuildNicStr(virConnectPtr conn,
|
||||||
virDomainNetDefPtr net,
|
virDomainNetDefPtr net,
|
||||||
@ -1866,23 +1964,6 @@ no_memory:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
|
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuSafeSerialParamValue(virConnectPtr conn,
|
|
||||||
const char *value)
|
|
||||||
{
|
|
||||||
if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen (value)) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("driver serial '%s' contains unsafe characters"),
|
|
||||||
value);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructs a argv suitable for launching qemu with config defined
|
* Constructs a argv suitable for launching qemu with config defined
|
||||||
* for a given virtual machine.
|
* for a given virtual machine.
|
||||||
@ -2274,12 +2355,9 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < def->ndisks ; i++) {
|
for (i = 0 ; i < def->ndisks ; i++) {
|
||||||
virBuffer opt = VIR_BUFFER_INITIALIZER;
|
|
||||||
char *optstr;
|
char *optstr;
|
||||||
int bootable = 0;
|
int bootable = 0;
|
||||||
virDomainDiskDefPtr disk = def->disks[i];
|
virDomainDiskDefPtr disk = def->disks[i];
|
||||||
int idx = virDiskNameToIndex(disk->dst);
|
|
||||||
const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
|
|
||||||
|
|
||||||
if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
|
if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
|
||||||
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
||||||
@ -2292,14 +2370,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_ARG_SPACE;
|
|
||||||
|
|
||||||
if (idx < 0) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("unsupported disk type '%s'"), disk->dst);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (disk->device) {
|
switch (disk->device) {
|
||||||
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
||||||
bootable = bootCD;
|
bootable = bootCD;
|
||||||
@ -2315,69 +2385,10 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disk->src) {
|
ADD_ARG_LIT("-drive");
|
||||||
if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
|
|
||||||
/* QEMU only supports magic FAT format for now */
|
if (!(optstr = qemuBuildDriveStr(disk, bootable, qemuCmdFlags)))
|
||||||
if (disk->driverType &&
|
|
||||||
STRNEQ(disk->driverType, "fat")) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("unsupported disk driver type for '%s'"),
|
|
||||||
disk->driverType);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
if (!disk->readonly) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("cannot create virtual FAT disks in read-write mode"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
|
|
||||||
virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src);
|
|
||||||
else
|
|
||||||
virBufferVSprintf(&opt, "file=fat:%s,", disk->src);
|
|
||||||
} else {
|
|
||||||
virBufferVSprintf(&opt, "file=%s,", disk->src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virBufferVSprintf(&opt, "if=%s", bus);
|
|
||||||
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
|
|
||||||
virBufferAddLit(&opt, ",media=cdrom");
|
|
||||||
virBufferVSprintf(&opt, ",index=%d", idx);
|
|
||||||
if (bootable &&
|
|
||||||
disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
|
|
||||||
virBufferAddLit(&opt, ",boot=on");
|
|
||||||
if (disk->driverType &&
|
|
||||||
disk->type != VIR_DOMAIN_DISK_TYPE_DIR &&
|
|
||||||
qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT)
|
|
||||||
virBufferVSprintf(&opt, ",format=%s", disk->driverType);
|
|
||||||
if (disk->serial &&
|
|
||||||
(qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_SERIAL)) {
|
|
||||||
if (qemuSafeSerialParamValue(conn, disk->serial) < 0)
|
|
||||||
goto error;
|
|
||||||
virBufferVSprintf(&opt, ",serial=%s", disk->serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disk->cachemode) {
|
|
||||||
const char *mode =
|
|
||||||
(qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_CACHE_V2) ?
|
|
||||||
qemuDiskCacheV2TypeToString(disk->cachemode) :
|
|
||||||
qemuDiskCacheV1TypeToString(disk->cachemode);
|
|
||||||
|
|
||||||
virBufferVSprintf(&opt, ",cache=%s", mode);
|
|
||||||
} else if (disk->shared && !disk->readonly) {
|
|
||||||
virBufferAddLit(&opt, ",cache=off");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virBufferError(&opt)) {
|
|
||||||
virBufferFreeAndReset(&opt);
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
optstr = virBufferContentAndReset(&opt);
|
|
||||||
|
|
||||||
if ((qargv[qargc++] = strdup("-drive")) == NULL) {
|
|
||||||
VIR_FREE(optstr);
|
|
||||||
goto no_memory;
|
|
||||||
}
|
|
||||||
ADD_ARG(optstr);
|
ADD_ARG(optstr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -193,6 +193,11 @@ int qemuBuildNicStr (virConnectPtr conn,
|
|||||||
int vlan,
|
int vlan,
|
||||||
char **str);
|
char **str);
|
||||||
|
|
||||||
|
|
||||||
|
char * qemuBuildDriveStr (virDomainDiskDefPtr disk,
|
||||||
|
int bootable,
|
||||||
|
int qemuCmdFlags);
|
||||||
|
|
||||||
int qemudNetworkIfaceConnect (virConnectPtr conn,
|
int qemudNetworkIfaceConnect (virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainNetDefPtr net,
|
virDomainNetDefPtr net,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user