mirror of https://gitee.com/openkylin/libvirt.git
xen_xm: Split the per-disk logic from xenParseXMDisk()
xenParseXMDisk() does a lot of stuff and, in order to make things cleaner, let's split it in two new functions: - xenParseXMDisk(): it's a new function that keeps the old name. It's responsible for the whole per-disk logic from the old xenParseXMDisk(); - xenParseXMDiskList(): it's basically the old xenParseXMDisk(), but now it just iterates over the list of disks, calling xenParseXMDisk() per each disk. This patch is basically preparing the ground for the future when typesafe virConf acessors will be used. Signed-off-by: Fabiano Fidêncio <fabiano@fidencio.org> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
057a78ea31
commit
5d358df82a
|
@ -107,179 +107,187 @@ xenParseXMOS(virConfPtr conf, virDomainDefPtr def)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static virDomainDiskDefPtr
|
||||||
xenParseXMDisk(virConfPtr conf, virDomainDefPtr def)
|
xenParseXMDisk(char *entry, int hvm)
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr disk = NULL;
|
virDomainDiskDefPtr disk = NULL;
|
||||||
int hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM;
|
char *head;
|
||||||
virConfValuePtr list = virConfGetValue(conf, "disk");
|
char *offset;
|
||||||
|
char *tmp;
|
||||||
|
const char *src;
|
||||||
|
|
||||||
if (list && list->type == VIR_CONF_LIST) {
|
if (!(disk = virDomainDiskDefNew(NULL)))
|
||||||
list = list->list;
|
return NULL;
|
||||||
while (list) {
|
|
||||||
char *head;
|
|
||||||
char *offset;
|
|
||||||
char *tmp;
|
|
||||||
const char *src;
|
|
||||||
|
|
||||||
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
|
head = entry;
|
||||||
goto skipdisk;
|
/*
|
||||||
|
* Disks have 3 components, SOURCE,DEST-DEVICE,MODE
|
||||||
|
* eg, phy:/dev/HostVG/XenGuest1,xvda,w
|
||||||
|
* The SOURCE is usually prefixed with a driver type,
|
||||||
|
* and optionally driver sub-type
|
||||||
|
* The DEST-DEVICE is optionally post-fixed with disk type
|
||||||
|
*/
|
||||||
|
|
||||||
head = list->str;
|
/* Extract the source file path*/
|
||||||
if (!(disk = virDomainDiskDefNew(NULL)))
|
if (!(offset = strchr(head, ',')))
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
/*
|
if (offset == head) {
|
||||||
* Disks have 3 components, SOURCE,DEST-DEVICE,MODE
|
/* No source file given, eg CDROM with no media */
|
||||||
* eg, phy:/dev/HostVG/XenGuest1,xvda,w
|
ignore_value(virDomainDiskSetSource(disk, NULL));
|
||||||
* The SOURCE is usually prefixed with a driver type,
|
} else {
|
||||||
* and optionally driver sub-type
|
if (VIR_STRNDUP(tmp, head, offset - head) < 0)
|
||||||
* The DEST-DEVICE is optionally post-fixed with disk type
|
goto error;
|
||||||
*/
|
|
||||||
|
|
||||||
/* Extract the source file path*/
|
if (virDomainDiskSetSource(disk, tmp) < 0) {
|
||||||
if (!(offset = strchr(head, ',')))
|
VIR_FREE(tmp);
|
||||||
goto skipdisk;
|
goto error;
|
||||||
|
}
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
if (offset == head) {
|
head = offset + 1;
|
||||||
/* No source file given, eg CDROM with no media */
|
/* Remove legacy ioemu: junk */
|
||||||
ignore_value(virDomainDiskSetSource(disk, NULL));
|
if (STRPREFIX(head, "ioemu:"))
|
||||||
} else {
|
head = head + 6;
|
||||||
if (VIR_STRNDUP(tmp, head, offset - head) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (virDomainDiskSetSource(disk, tmp) < 0) {
|
/* Extract the dest device name */
|
||||||
VIR_FREE(tmp);
|
if (!(offset = strchr(head, ',')))
|
||||||
goto cleanup;
|
goto error;
|
||||||
}
|
|
||||||
|
if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virStrncpy(disk->dst, head, offset - head,
|
||||||
|
(offset - head) + 1) == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Dest file %s too big for destination"), head);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
head = offset + 1;
|
||||||
|
/* Extract source driver type */
|
||||||
|
src = virDomainDiskGetSource(disk);
|
||||||
|
if (src) {
|
||||||
|
size_t len;
|
||||||
|
/* The main type phy:, file:, tap: ... */
|
||||||
|
if ((tmp = strchr(src, ':')) != NULL) {
|
||||||
|
len = tmp - src;
|
||||||
|
if (VIR_STRNDUP(tmp, src, len) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virDomainDiskSetDriver(disk, tmp) < 0) {
|
||||||
VIR_FREE(tmp);
|
VIR_FREE(tmp);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
|
||||||
head = offset + 1;
|
/* Strip the prefix we found off the source file name */
|
||||||
/* Remove legacy ioemu: junk */
|
if (virDomainDiskSetSource(disk, src + len + 1) < 0)
|
||||||
if (STRPREFIX(head, "ioemu:"))
|
goto error;
|
||||||
head = head + 6;
|
|
||||||
|
|
||||||
/* Extract the dest device name */
|
|
||||||
if (!(offset = strchr(head, ',')))
|
|
||||||
goto skipdisk;
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (virStrncpy(disk->dst, head, offset - head,
|
|
||||||
(offset - head) + 1) == NULL) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Dest file %s too big for destination"), head);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
head = offset + 1;
|
|
||||||
/* Extract source driver type */
|
|
||||||
src = virDomainDiskGetSource(disk);
|
src = virDomainDiskGetSource(disk);
|
||||||
if (src) {
|
}
|
||||||
size_t len;
|
|
||||||
/* The main type phy:, file:, tap: ... */
|
|
||||||
if ((tmp = strchr(src, ':')) != NULL) {
|
|
||||||
len = tmp - src;
|
|
||||||
if (VIR_STRNDUP(tmp, src, len) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (virDomainDiskSetDriver(disk, tmp) < 0) {
|
/* And the sub-type for tap:XXX: type */
|
||||||
VIR_FREE(tmp);
|
if (STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap") ||
|
||||||
goto cleanup;
|
STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap2")) {
|
||||||
}
|
char *driverType;
|
||||||
VIR_FREE(tmp);
|
|
||||||
|
|
||||||
/* Strip the prefix we found off the source file name */
|
if (!(tmp = strchr(src, ':')))
|
||||||
if (virDomainDiskSetSource(disk, src + len + 1) < 0)
|
goto error;
|
||||||
goto cleanup;
|
len = tmp - src;
|
||||||
|
|
||||||
src = virDomainDiskGetSource(disk);
|
if (VIR_STRNDUP(driverType, src, len) < 0)
|
||||||
}
|
goto error;
|
||||||
|
|
||||||
/* And the sub-type for tap:XXX: type */
|
if (STREQ(driverType, "aio"))
|
||||||
if (STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap") ||
|
virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW);
|
||||||
STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap2")) {
|
else
|
||||||
char *driverType;
|
virDomainDiskSetFormat(disk,
|
||||||
|
virStorageFileFormatTypeFromString(driverType));
|
||||||
if (!(tmp = strchr(src, ':')))
|
VIR_FREE(driverType);
|
||||||
goto skipdisk;
|
if (virDomainDiskGetFormat(disk) <= 0) {
|
||||||
len = tmp - src;
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unknown driver type %s"),
|
||||||
if (VIR_STRNDUP(driverType, src, len) < 0)
|
src);
|
||||||
goto cleanup;
|
goto error;
|
||||||
|
|
||||||
if (STREQ(driverType, "aio"))
|
|
||||||
virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW);
|
|
||||||
else
|
|
||||||
virDomainDiskSetFormat(disk,
|
|
||||||
virStorageFileFormatTypeFromString(driverType));
|
|
||||||
VIR_FREE(driverType);
|
|
||||||
if (virDomainDiskGetFormat(disk) <= 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Unknown driver type %s"),
|
|
||||||
src);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strip the prefix we found off the source file name */
|
|
||||||
if (virDomainDiskSetSource(disk, src + len + 1) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
src = virDomainDiskGetSource(disk);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No source, or driver name, so fix to phy: */
|
/* Strip the prefix we found off the source file name */
|
||||||
if (!virDomainDiskGetDriver(disk) &&
|
if (virDomainDiskSetSource(disk, src + len + 1) < 0)
|
||||||
virDomainDiskSetDriver(disk, "phy") < 0)
|
goto error;
|
||||||
goto cleanup;
|
src = virDomainDiskGetSource(disk);
|
||||||
|
|
||||||
/* phy: type indicates a block device */
|
|
||||||
virDomainDiskSetType(disk,
|
|
||||||
STREQ(virDomainDiskGetDriver(disk), "phy") ?
|
|
||||||
VIR_STORAGE_TYPE_BLOCK :
|
|
||||||
VIR_STORAGE_TYPE_FILE);
|
|
||||||
|
|
||||||
/* Check for a :cdrom/:disk postfix */
|
|
||||||
disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
|
|
||||||
if ((tmp = strchr(disk->dst, ':')) != NULL) {
|
|
||||||
if (STREQ(tmp, ":cdrom"))
|
|
||||||
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
|
|
||||||
tmp[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (STRPREFIX(disk->dst, "xvd") || !hvm) {
|
|
||||||
disk->bus = VIR_DOMAIN_DISK_BUS_XEN;
|
|
||||||
} else if (STRPREFIX(disk->dst, "sd")) {
|
|
||||||
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
|
|
||||||
} else {
|
|
||||||
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (STREQ(head, "r") ||
|
|
||||||
STREQ(head, "ro"))
|
|
||||||
disk->src->readonly = true;
|
|
||||||
else if ((STREQ(head, "w!")) ||
|
|
||||||
(STREQ(head, "!")))
|
|
||||||
disk->src->shared = true;
|
|
||||||
|
|
||||||
/* Maintain list in sorted order according to target device name */
|
|
||||||
if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
skipdisk:
|
|
||||||
list = list->next;
|
|
||||||
virDomainDiskDefFree(disk);
|
|
||||||
disk = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
/* No source, or driver name, so fix to phy: */
|
||||||
|
if (!virDomainDiskGetDriver(disk) &&
|
||||||
|
virDomainDiskSetDriver(disk, "phy") < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
cleanup:
|
/* phy: type indicates a block device */
|
||||||
|
virDomainDiskSetType(disk,
|
||||||
|
STREQ(virDomainDiskGetDriver(disk), "phy") ?
|
||||||
|
VIR_STORAGE_TYPE_BLOCK :
|
||||||
|
VIR_STORAGE_TYPE_FILE);
|
||||||
|
|
||||||
|
/* Check for a :cdrom/:disk postfix */
|
||||||
|
disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
|
||||||
|
if ((tmp = strchr(disk->dst, ':')) != NULL) {
|
||||||
|
if (STREQ(tmp, ":cdrom"))
|
||||||
|
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
|
||||||
|
tmp[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STRPREFIX(disk->dst, "xvd") || !hvm)
|
||||||
|
disk->bus = VIR_DOMAIN_DISK_BUS_XEN;
|
||||||
|
else if (STRPREFIX(disk->dst, "sd"))
|
||||||
|
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
|
||||||
|
else
|
||||||
|
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
||||||
|
|
||||||
|
if (STREQ(head, "r") || STREQ(head, "ro"))
|
||||||
|
disk->src->readonly = true;
|
||||||
|
else if (STREQ(head, "w!") || STREQ(head, "!"))
|
||||||
|
disk->src->shared = true;
|
||||||
|
|
||||||
|
return disk;
|
||||||
|
|
||||||
|
error:
|
||||||
virDomainDiskDefFree(disk);
|
virDomainDiskDefFree(disk);
|
||||||
return -1;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
xenParseXMDiskList(virConfPtr conf, virDomainDefPtr def)
|
||||||
|
{
|
||||||
|
int hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM;
|
||||||
|
virConfValuePtr list = virConfGetValue(conf, "disk");
|
||||||
|
|
||||||
|
if (!list || list->type != VIR_CONF_LIST)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (list = list->list; list; list = list->next) {
|
||||||
|
virDomainDiskDefPtr disk;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(disk = xenParseXMDisk(list->str, hvm)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Maintain list in sorted order according to target device name */
|
||||||
|
rc = VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk);
|
||||||
|
virDomainDiskDefFree(disk);
|
||||||
|
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -457,7 +465,7 @@ xenParseXM(virConfPtr conf,
|
||||||
if (xenParseXMOS(conf, def) < 0)
|
if (xenParseXMOS(conf, def) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (xenParseXMDisk(conf, def) < 0)
|
if (xenParseXMDiskList(conf, def) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (xenParseXMInputDevs(conf, def) < 0)
|
if (xenParseXMInputDevs(conf, def) < 0)
|
||||||
|
|
Loading…
Reference in New Issue