提交 5d358df8 编写于 作者: F Fabiano Fidêncio 提交者: Ján Tomko

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: NFabiano Fidêncio <fabiano@fidencio.org>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
Signed-off-by: NJán Tomko <jtomko@redhat.com>
上级 057a78ea
...@@ -107,179 +107,187 @@ xenParseXMOS(virConfPtr conf, virDomainDefPtr def) ...@@ -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
*/
/* Extract the source file path*/
if (!(offset = strchr(head, ',')))
goto error;
if (offset == head) {
/* No source file given, eg CDROM with no media */
ignore_value(virDomainDiskSetSource(disk, NULL));
} else {
if (VIR_STRNDUP(tmp, head, offset - head) < 0)
goto error;
head = list->str; if (virDomainDiskSetSource(disk, tmp) < 0) {
if (!(disk = virDomainDiskDefNew(NULL))) VIR_FREE(tmp);
return -1; goto error;
}
VIR_FREE(tmp);
}
/* head = offset + 1;
* Disks have 3 components, SOURCE,DEST-DEVICE,MODE /* Remove legacy ioemu: junk */
* eg, phy:/dev/HostVG/XenGuest1,xvda,w if (STRPREFIX(head, "ioemu:"))
* The SOURCE is usually prefixed with a driver type, head = head + 6;
* and optionally driver sub-type
* The DEST-DEVICE is optionally post-fixed with disk type /* Extract the dest device name */
*/ if (!(offset = strchr(head, ',')))
goto error;
/* Extract the source file path*/
if (!(offset = strchr(head, ','))) if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0)
goto skipdisk; goto error;
if (offset == head) { if (virStrncpy(disk->dst, head, offset - head,
/* No source file given, eg CDROM with no media */ (offset - head) + 1) == NULL) {
ignore_value(virDomainDiskSetSource(disk, NULL)); virReportError(VIR_ERR_INTERNAL_ERROR,
} else { _("Dest file %s too big for destination"), head);
if (VIR_STRNDUP(tmp, head, offset - head) < 0) goto error;
goto cleanup; }
if (virDomainDiskSetSource(disk, tmp) < 0) { head = offset + 1;
VIR_FREE(tmp); /* Extract source driver type */
goto cleanup; 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 */ src = virDomainDiskGetSource(disk);
if (!(offset = strchr(head, ','))) }
goto skipdisk;
if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0) /* And the sub-type for tap:XXX: type */
goto cleanup; if (STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap") ||
STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap2")) {
char *driverType;
if (virStrncpy(disk->dst, head, offset - head, if (!(tmp = strchr(src, ':')))
(offset - head) + 1) == NULL) { goto error;
len = tmp - src;
if (VIR_STRNDUP(driverType, src, len) < 0)
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, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Dest file %s too big for destination"), head); _("Unknown driver type %s"),
goto cleanup; src);
goto error;
} }
head = offset + 1; /* Strip the prefix we found off the source file name */
/* Extract source driver type */ if (virDomainDiskSetSource(disk, src + len + 1) < 0)
goto error;
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) {
VIR_FREE(tmp);
goto cleanup;
}
VIR_FREE(tmp);
/* Strip the prefix we found off the source file name */
if (virDomainDiskSetSource(disk, src + len + 1) < 0)
goto cleanup;
src = virDomainDiskGetSource(disk);
}
/* And the sub-type for tap:XXX: type */ /* No source, or driver name, so fix to phy: */
if (STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap") || if (!virDomainDiskGetDriver(disk) &&
STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap2")) { virDomainDiskSetDriver(disk, "phy") < 0)
char *driverType; goto error;
if (!(tmp = strchr(src, ':'))) /* phy: type indicates a block device */
goto skipdisk; virDomainDiskSetType(disk,
len = tmp - src; STREQ(virDomainDiskGetDriver(disk), "phy") ?
VIR_STORAGE_TYPE_BLOCK :
if (VIR_STRNDUP(driverType, src, len) < 0) VIR_STORAGE_TYPE_FILE);
goto cleanup;
/* Check for a :cdrom/:disk postfix */
if (STREQ(driverType, "aio")) disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW); if ((tmp = strchr(disk->dst, ':')) != NULL) {
else if (STREQ(tmp, ":cdrom"))
virDomainDiskSetFormat(disk, disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
virStorageFileFormatTypeFromString(driverType)); tmp[0] = '\0';
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: */ if (STRPREFIX(disk->dst, "xvd") || !hvm)
if (!virDomainDiskGetDriver(disk) && disk->bus = VIR_DOMAIN_DISK_BUS_XEN;
virDomainDiskSetDriver(disk, "phy") < 0) else if (STRPREFIX(disk->dst, "sd"))
goto cleanup; disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
else
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
/* phy: type indicates a block device */ if (STREQ(head, "r") || STREQ(head, "ro"))
virDomainDiskSetType(disk, disk->src->readonly = true;
STREQ(virDomainDiskGetDriver(disk), "phy") ? else if (STREQ(head, "w!") || STREQ(head, "!"))
VIR_STORAGE_TYPE_BLOCK : disk->src->shared = true;
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) { return disk;
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") || error:
STREQ(head, "ro")) virDomainDiskDefFree(disk);
disk->src->readonly = true; return NULL;
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: static int
list = list->next; xenParseXMDiskList(virConfPtr conf, virDomainDefPtr def)
virDomainDiskDefFree(disk); {
disk = NULL; 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; return 0;
cleanup:
virDomainDiskDefFree(disk);
return -1;
} }
...@@ -457,7 +465,7 @@ xenParseXM(virConfPtr conf, ...@@ -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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册