qemu: Refactor disk source string formatting

This patch adds function qemuGetDriveSourceString to produce
qemu-compatible disk source strings that will enable to reuse the code
and refactors building of the qemu commandline of disks to use this new
helper.
This commit is contained in:
Peter Krempa 2013-11-21 18:43:59 +01:00
parent b384e2b4d7
commit 0df53f0432

View File

@ -3827,19 +3827,62 @@ cleanup:
static int static int
qemuBuildDriveURIString(virConnectPtr conn, qemuGetDriveSourceString(int type,
virDomainDiskDefPtr disk, const char *src,
virBufferPtr opt) int protocol,
size_t nhosts,
virDomainDiskHostDefPtr hosts,
const char *username,
const char *secret,
char **path)
{ {
*path = NULL;
switch ((enum virDomainDiskType) type) {
case VIR_DOMAIN_DISK_TYPE_BLOCK:
case VIR_DOMAIN_DISK_TYPE_FILE:
case VIR_DOMAIN_DISK_TYPE_DIR:
if (!src)
return 1;
if (VIR_STRDUP(*path, src) < 0)
return -1;
break;
case VIR_DOMAIN_DISK_TYPE_NETWORK:
if (!(*path = qemuBuildNetworkDriveURI(protocol,
src,
nhosts,
hosts,
username,
secret)))
return -1;
break;
case VIR_DOMAIN_DISK_TYPE_VOLUME:
case VIR_DOMAIN_DISK_TYPE_LAST:
break;
}
return 0;
}
static int
qemuDomainDiskGetSourceString(virConnectPtr conn,
virDomainDiskDefPtr disk,
char **source)
{
int actualType = qemuDiskGetActualType(disk);
char *secret = NULL; char *secret = NULL;
char *builturi = NULL;
int ret = -1; int ret = -1;
virBufferAddLit(opt, "file="); *source = NULL;
if ((disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI || if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK &&
disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) && disk->auth.username &&
disk->auth.username) { (disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI ||
disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD)) {
bool encode = false; bool encode = false;
int secretType = VIR_SECRET_USAGE_TYPE_ISCSI; int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
@ -3860,32 +3903,23 @@ qemuBuildDriveURIString(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
ret = qemuGetDriveSourceString(qemuDiskGetActualType(disk),
if (!(builturi = qemuBuildNetworkDriveURI(disk->protocol, disk->src,
disk->src, disk->protocol,
disk->nhosts, disk->nhosts,
disk->hosts, disk->hosts,
disk->auth.username, disk->auth.username,
secret))) secret,
goto cleanup; source);
virBufferEscape(opt, ',', ",", "%s", builturi);
virBufferAddChar(opt, ',');
ret = 0;
cleanup: cleanup:
VIR_FREE(secret); VIR_FREE(secret);
VIR_FREE(builturi);
return ret; return ret;
} }
char * char *
qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, qemuBuildDriveStr(virConnectPtr conn,
virDomainDiskDefPtr disk, virDomainDiskDefPtr disk,
bool bootable, bool bootable,
virQEMUCapsPtr qemuCaps) virQEMUCapsPtr qemuCaps)
@ -3896,6 +3930,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainDiskGeometryTransTypeToString(disk->geometry.trans); virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
int idx = virDiskNameToIndex(disk->dst); int idx = virDiskNameToIndex(disk->dst);
int busid = -1, unitid = -1; int busid = -1, unitid = -1;
char *source = NULL;
int actualType = qemuDiskGetActualType(disk); int actualType = qemuDiskGetActualType(disk);
if (idx < 0) { if (idx < 0) {
@ -3978,15 +4013,18 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
break; break;
} }
/* disk->src is NULL when we use nbd disks */ if (qemuDomainDiskGetSourceString(conn, disk, &source) < 0)
if ((disk->src || goto error;
(actualType == VIR_DOMAIN_DISK_TYPE_NETWORK &&
disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) && if (source &&
!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) && disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
if (actualType == VIR_DOMAIN_DISK_TYPE_DIR) { virBufferAddLit(&opt, "file=");
switch (actualType) {
case VIR_DOMAIN_DISK_TYPE_DIR:
/* QEMU only supports magic FAT format for now */ /* QEMU only supports magic FAT format for now */
if (disk->format > 0 && disk->format != VIR_STORAGE_FILE_FAT) { if (disk->format > 0 && disk->format != VIR_STORAGE_FILE_FAT) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
@ -3994,32 +4032,38 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
virStorageFileFormatTypeToString(disk->format)); virStorageFileFormatTypeToString(disk->format));
goto error; goto error;
} }
if (!disk->readonly) { if (!disk->readonly) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot create virtual FAT disks in read-write mode")); _("cannot create virtual FAT disks in read-write mode"));
goto error; goto error;
} }
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
virBufferEscape(&opt, ',', ",", "file=fat:floppy:%s,",
disk->src);
else
virBufferEscape(&opt, ',', ",", "file=fat:%s,", disk->src);
} else if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK) { virBufferAddLit(&opt, "fat:");
if (qemuBuildDriveURIString(conn, disk, &opt) < 0)
goto error; if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
} else { virBufferAddLit(&opt, "floppy:");
if ((actualType == VIR_DOMAIN_DISK_TYPE_BLOCK) &&
(disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { break;
case VIR_DOMAIN_DISK_TYPE_BLOCK:
if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME ? disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME ?
_("tray status 'open' is invalid for block type volume") : _("tray status 'open' is invalid for block type volume") :
_("tray status 'open' is invalid for block type disk")); _("tray status 'open' is invalid for block type disk"));
goto error; goto error;
} }
virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
break;
default:
break;
} }
virBufferEscape(&opt, ',', ",", "%s,", source);
} }
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
virBufferAddLit(&opt, "if=none"); virBufferAddLit(&opt, "if=none");
else else