From 547bd71a4ae36a39edd8f11997ed5d4ff60f4342 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 25 Jul 2008 13:50:08 +0000 Subject: [PATCH] Switch XM config file driver to use new domain APIs for XML generation --- ChangeLog | 8 + src/xend_internal.c | 67 +--- src/xend_internal.h | 11 +- src/xm_internal.c | 879 ++++++++++++++++++++++++++++---------------- 4 files changed, 578 insertions(+), 387 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b82349c89..f2dbe53edf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Fri Jul 25 14:48:27 BST 2008 Daniel P. Berrange + + * src/xend_internal.c, src/xend_internal.h: Remove the + sound_string_to_xml() and make xenDaemonParseSxprChar + non-static + * src/xm_internal.c: Switch config -> XML parser to use + the new domain APIs + Fri Jul 25 14:29:27 BST 2008 Daniel P. Berrange Prepare xm_internal driver for new domain XML apis. diff --git a/src/xend_internal.c b/src/xend_internal.c index d274cf3a86..7371b412f4 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -828,68 +828,6 @@ int is_sound_model_conflict(const char *model, const char *soundstr) { return 0; } -/** - * sound_string_to_xml: - * @soundstr : soundhw string for the form m1,m2,m3 ... - * - * Parses the passed string and returns a heap allocated string containing - * the valid libvirt soundxml. Must be free'd by caller. - * - * Returns NULL on fail, xml string on success (can be the empty string). - */ -char *sound_string_to_xml(const char *sound) { - - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *tmp; - - while (sound) { - int modelsize, valid, collision = 0; - char *model = NULL; - char *model_end = strchr(sound, ','); - modelsize = (model_end ? (model_end - sound) : strlen(sound)); - - if(!(model = strndup(sound, modelsize))) - goto error; - - if (!(valid = is_sound_model_valid(model))) { - // Check for magic 'all' model. If found, throw out current xml - // and build with all available models - if (STREQ(model, "all")) { - int i; - if (virBufferError(&buf)) { - VIR_FREE(model); - goto error; - } - tmp = virBufferContentAndReset(&buf); - VIR_FREE(tmp); - - for (i=0; i < sizeof(sound_models)/sizeof(*sound_models); ++i) - virBufferVSprintf(&buf, " \n", - sound_models[i]); - VIR_FREE(model); - break; - } - } - - if (valid && model_end) - collision = is_sound_model_conflict(model, model_end); - if (valid && !collision) - virBufferVSprintf(&buf, " \n", model); - - sound = (model_end ? ++model_end : NULL); - VIR_FREE(model); - } - - if (virBufferError(&buf)) - goto error; - return virBufferContentAndReset(&buf); - - error: - tmp = virBufferContentAndReset(&buf); - VIR_FREE(tmp); - return NULL; -} - /* PUBLIC FUNCTIONS */ @@ -1544,7 +1482,7 @@ error: return ret; } -static virDomainChrDefPtr +virDomainChrDefPtr xenDaemonParseSxprChar(virConnectPtr conn, const char *value, const char *tty) @@ -1957,7 +1895,8 @@ cleanup: return -1; } -static int + +int xenDaemonParseSxprSound(virConnectPtr conn, virDomainDefPtr def, const char *str) diff --git a/src/xend_internal.h b/src/xend_internal.h index 685f961d3a..7a317ca0fe 100644 --- a/src/xend_internal.h +++ b/src/xend_internal.h @@ -103,6 +103,16 @@ virDomainDefPtr xenDaemonParseSxprString(virConnectPtr conn, const char *sexpr, int xendConfigVersion); + +int +xenDaemonParseSxprSound(virConnectPtr conn, + virDomainDefPtr def, + const char *str); +virDomainChrDefPtr +xenDaemonParseSxprChar(virConnectPtr conn, + const char *value, + const char *tty); + char * xenDaemonFormatSxpr(virConnectPtr conn, virDomainDefPtr def, @@ -110,7 +120,6 @@ xenDaemonFormatSxpr(virConnectPtr conn, int is_sound_model_valid(const char *model); int is_sound_model_conflict(const char *model, const char *soundstr); - char *sound_string_to_xml(const char *sound); /* refactored ones */ diff --git a/src/xm_internal.c b/src/xm_internal.c index 47caec3a44..9ef64ac3d1 100644 --- a/src/xm_internal.c +++ b/src/xm_internal.c @@ -62,6 +62,8 @@ static int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str); +static int xenXMDiskCompare(virDomainDiskDefPtr a, + virDomainDiskDefPtr b); typedef struct xenXMConfCache *xenXMConfCachePtr; typedef struct xenXMConfCache { @@ -134,16 +136,23 @@ struct xenUnifiedDriver xenXMDriver = { }; static void -xenXMError(virConnectPtr conn, virErrorNumber error, const char *info) +xenXMError(virConnectPtr conn, int code, const char *fmt, ...) { - const char *errmsg; + va_list args; + char errorMessage[1024]; + const char *virerr; - if (error == VIR_ERR_OK) - return; + if (fmt) { + va_start(args, fmt); + vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args); + va_end(args); + } else { + errorMessage[0] = '\0'; + } - errmsg = __virErrorMsg(error, info); - __virRaiseError(conn, NULL, NULL, VIR_FROM_XENXM, error, VIR_ERR_ERROR, - errmsg, info, NULL, 0, 0, errmsg, info); + virerr = __virErrorMsg(code, (errorMessage[0] ? errorMessage : NULL)); + __virRaiseError(conn, NULL, NULL, VIR_FROM_XENXM, code, VIR_ERR_ERROR, + virerr, errorMessage, NULL, -1, -1, virerr, errorMessage); } int @@ -170,48 +179,150 @@ xenXMInit (void) /* Convenience method to grab a int from the config file object */ -static int xenXMConfigGetInt(virConfPtr conf, const char *name, long *value) { +static int xenXMConfigGetBool(virConnectPtr conn, + virConfPtr conf, + const char *name, + int *value, + int def) { virConfValuePtr val; - if (!value || !name || !conf) - return (-1); + *value = 0; if (!(val = virConfGetValue(conf, name))) { - return (-1); + *value = def; + return 0; + } + + if (val->type == VIR_CONF_LONG) { + *value = val->l ? 1 : 0; + } else if (val->type == VIR_CONF_STRING) { + if (!val->str) { + *value = def; + } + *value = STREQ(val->str, "1") ? 1 : 0; + } else { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("config value %s was malformed"), name); + return -1; + } + return 0; +} + + +/* Convenience method to grab a int from the config file object */ +static int xenXMConfigGetULong(virConnectPtr conn, + virConfPtr conf, + const char *name, + unsigned long *value, + int def) { + virConfValuePtr val; + + *value = 0; + if (!(val = virConfGetValue(conf, name))) { + *value = def; + return 0; } if (val->type == VIR_CONF_LONG) { *value = val->l; } else if (val->type == VIR_CONF_STRING) { char *ret; - if (!val->str) - return (-1); + if (!val->str) { + *value = def; + } *value = strtol(val->str, &ret, 10); - if (ret == val->str) - return (-1); + if (ret == val->str) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("config value %s was malformed"), name); + return -1; + } } else { - return (-1); + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("config value %s was malformed"), name); + return -1; } - return (0); + return 0; } /* Convenience method to grab a string from the config file object */ -static int xenXMConfigGetString(virConfPtr conf, const char *name, const char **value) { +static int xenXMConfigGetString(virConnectPtr conn, + virConfPtr conf, + const char *name, + const char **value, + const char *def) { virConfValuePtr val; - if (!value || !name || !conf) - return (-1); + *value = NULL; if (!(val = virConfGetValue(conf, name))) { - return (-1); + *value = def; + return 0; + } + + if (val->type != VIR_CONF_STRING) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("config value %s was malformed"), name); + return -1; } - if (val->type != VIR_CONF_STRING) - return (-1); if (!val->str) - return (-1); - *value = val->str; - return (0); + *value = def; + else + *value = val->str; + return 0; } +static int xenXMConfigCopyStringInternal(virConnectPtr conn, + virConfPtr conf, + const char *name, + char **value, + int allowMissing) { + virConfValuePtr val; + + *value = NULL; + if (!(val = virConfGetValue(conf, name))) { + if (allowMissing) + return 0; + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("config value %s was missing"), name); + return -1; + } + + if (val->type != VIR_CONF_STRING) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("config value %s was not a string"), name); + return -1; + } + if (!val->str) { + if (allowMissing) + return 0; + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("config value %s was missing"), name); + return -1; + } + + if (!(*value = strdup(val->str))) { + xenXMError(conn, VIR_ERR_NO_MEMORY, NULL); + return -1; + } + + return 0; +} + + +static int xenXMConfigCopyString(virConnectPtr conn, + virConfPtr conf, + const char *name, + char **value) { + return xenXMConfigCopyStringInternal(conn, conf, name, value, 0); +} + +static int xenXMConfigCopyStringOpt(virConnectPtr conn, + virConfPtr conf, + const char *name, + char **value) { + return xenXMConfigCopyStringInternal(conn, conf, name, value, 1); +} + + /* Convenience method to grab a string UUID from the config file object */ static int xenXMConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid) { virConfValuePtr val; @@ -524,168 +635,202 @@ int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) { */ virDomainDefPtr xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { - virBuffer buf = VIR_BUFFER_INITIALIZER; - const char *name; - unsigned char uuid[VIR_UUID_BUFLEN]; - char uuidstr[VIR_UUID_STRING_BUFLEN]; const char *str; int hvm = 0; - long val; + int val; virConfValuePtr list; - int vnc = 0, sdl = 0; - char vfb[MAX_VFB]; - long vncdisplay; - long vncunused = 1; - const char *vnclisten = NULL; - const char *vncpasswd = NULL; - const char *keymap = NULL; xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData; virDomainDefPtr def = NULL; - char *xml; + virDomainDiskDefPtr disk = NULL; + virDomainNetDefPtr net = NULL; + virDomainGraphicsDefPtr graphics = NULL; + int i; + const char *defaultArch, *defaultMachine; - if (xenXMConfigGetString(conf, "name", &name) < 0) - return (NULL); - if (xenXMConfigGetUUID(conf, "uuid", uuid) < 0) - return (NULL); + if (VIR_ALLOC(def) < 0) + return NULL; - virBufferAddLit(&buf, "\n"); - virBufferEscapeString(&buf, " %s\n", name); - virUUIDFormat(uuid, uuidstr); - virBufferVSprintf(&buf, " %s\n", uuidstr); + def->virtType = VIR_DOMAIN_VIRT_XEN; + def->id = -1; - if ((xenXMConfigGetString(conf, "builder", &str) == 0) && + if (xenXMConfigCopyString(conn, conf, "name", &def->name) < 0) + goto cleanup; + if (xenXMConfigGetUUID(conf, "uuid", def->uuid) < 0) + goto cleanup; + + + if ((xenXMConfigGetString(conn, conf, "builder", &str, "linux") == 0) && STREQ(str, "hvm")) hvm = 1; + if (!(def->os.type = strdup(hvm ? "hvm" : "xen"))) + goto no_memory; + + defaultArch = virCapabilitiesDefaultGuestArch(priv->caps, def->os.type); + if (defaultArch == NULL) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("no supported architecture for os type '%s'"), + def->os.type); + goto cleanup; + } + if (!(def->os.arch = strdup(defaultArch))) + goto no_memory; + + defaultMachine = virCapabilitiesDefaultGuestMachine(priv->caps, + def->os.type, + def->os.arch); + if (defaultMachine != NULL) { + if (!(def->os.machine = strdup(defaultMachine))) + goto no_memory; + } + if (hvm) { const char *boot; - virBufferAddLit(&buf, " \n"); - virBufferAddLit(&buf, " hvm\n"); - if (xenXMConfigGetString(conf, "kernel", &str) == 0) - virBufferEscapeString(&buf, " %s\n", str); + if (xenXMConfigCopyString(conn, conf, "kernel", &def->os.loader) < 0) + goto cleanup; - if (xenXMConfigGetString(conf, "boot", &boot) < 0) - boot = "c"; + if (xenXMConfigGetString(conn, conf, "boot", &boot, "c") < 0) + goto cleanup; - while (*boot) { - const char *dev; + for (i = 0 ; i < VIR_DOMAIN_BOOT_LAST && boot[i] ; i++) { switch (*boot) { case 'a': - dev = "fd"; + def->os.bootDevs[i] = VIR_DOMAIN_BOOT_FLOPPY; break; case 'd': - dev = "cdrom"; + def->os.bootDevs[i] = VIR_DOMAIN_BOOT_CDROM; + break; + case 'n': + def->os.bootDevs[i] = VIR_DOMAIN_BOOT_NET; break; case 'c': default: - dev = "hd"; + def->os.bootDevs[i] = VIR_DOMAIN_BOOT_DISK; break; } - virBufferVSprintf(&buf, " \n", dev); - boot++; + def->os.nBootDevs++; } - - virBufferAddLit(&buf, " \n"); } else { + if (xenXMConfigCopyStringOpt(conn, conf, "bootloader", &def->os.bootloader) < 0) + goto cleanup; + if (xenXMConfigCopyStringOpt(conn, conf, "bootargs", &def->os.bootloaderArgs) < 0) + goto cleanup; - if (xenXMConfigGetString(conf, "bootloader", &str) == 0) - virBufferEscapeString(&buf, " %s\n", str); - if (xenXMConfigGetString(conf, "bootargs", &str) == 0) - virBufferEscapeString(&buf, " %s\n", str); - if (xenXMConfigGetString(conf, "kernel", &str) == 0) { - virBufferAddLit(&buf, " \n"); - virBufferAddLit(&buf, " linux\n"); - virBufferEscapeString(&buf, " %s\n", str); - if (xenXMConfigGetString(conf, "ramdisk", &str) == 0) - virBufferEscapeString(&buf, " %s\n", str); - if (xenXMConfigGetString(conf, "extra", &str) == 0) - virBufferEscapeString(&buf, " %s\n", str); - virBufferAddLit(&buf, " \n"); + if (xenXMConfigCopyStringOpt(conn, conf, "kernel", &def->os.kernel) < 0) + goto cleanup; + if (xenXMConfigCopyStringOpt(conn, conf, "ramdisk", &def->os.initrd) < 0) + goto cleanup; + if (xenXMConfigCopyStringOpt(conn, conf, "extra", &def->os.cmdline) < 0) + goto cleanup; + } + + if (xenXMConfigGetULong(conn, conf, "memory", &def->memory, MIN_XEN_GUEST_SIZE * 2) < 0) + goto cleanup; + + if (xenXMConfigGetULong(conn, conf, "maxmem", &def->maxmem, def->memory) < 0) + goto cleanup; + + def->memory *= 1024; + def->maxmem *= 1024; + + + if (xenXMConfigGetULong(conn, conf, "vcpus", &def->vcpus, 1) < 0) + goto cleanup; + + if (xenXMConfigGetString(conn, conf, "cpus", &str, NULL) < 0) + goto cleanup; + if (str) { + def->cpumasklen = 4096; + if (VIR_ALLOC_N(def->cpumask, def->cpumasklen) < 0) + goto no_memory; + + if (virDomainCpuSetParse(conn, &str, 0, + def->cpumask, def->cpumasklen) < 0) + goto cleanup; + } + + + if (xenXMConfigGetString(conn, conf, "on_poweroff", &str, "destroy") < 0) + goto cleanup; + if ((def->onPoweroff = virDomainLifecycleTypeFromString(str)) < 0) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("unexpected value %s for on_poweroff"), str); + goto cleanup; + } + + if (xenXMConfigGetString(conn, conf, "on_reboot", &str, "restart") < 0) + goto cleanup; + if ((def->onReboot = virDomainLifecycleTypeFromString(str)) < 0) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("unexpected value %s for on_reboot"), str); + goto cleanup; + } + + if (xenXMConfigGetString(conn, conf, "on_crash", &str, "restart") < 0) + goto cleanup; + if ((def->onCrash = virDomainLifecycleTypeFromString(str)) < 0) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("unexpected value %s for on_crash"), str); + goto cleanup; + } + + + + if (hvm) { + if (xenXMConfigGetBool(conn, conf, "pae", &val, 0) < 0) + goto cleanup; + else if (val) + def->features |= (1 << VIR_DOMAIN_FEATURE_PAE); + if (xenXMConfigGetBool(conn, conf, "acpi", &val, 0) < 0) + goto cleanup; + else if (val) + def->features |= (1 << VIR_DOMAIN_FEATURE_ACPI); + if (xenXMConfigGetBool(conn, conf, "apic", &val, 0) < 0) + goto cleanup; + else if (val) + def->features |= (1 << VIR_DOMAIN_FEATURE_APIC); + + if (xenXMConfigGetBool(conn, conf, "localtime", &def->localtime, 0) < 0) + goto cleanup; + } + if (xenXMConfigCopyStringOpt(conn, conf, "device_model", &def->emulator) < 0) + goto cleanup; + + if (def->emulator == NULL) { + const char *type = virDomainVirtTypeToString(def->virtType); + if (!type) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("unknown virt type")); + goto cleanup; } - } - - if (xenXMConfigGetInt(conf, "memory", &val) < 0) - val = MIN_XEN_GUEST_SIZE * 2; - virBufferVSprintf(&buf, " %ld\n", - val * 1024); - - if (xenXMConfigGetInt(conf, "maxmem", &val) < 0) - if (xenXMConfigGetInt(conf, "memory", &val) < 0) - val = MIN_XEN_GUEST_SIZE * 2; - virBufferVSprintf(&buf, " %ld\n", val * 1024); - - virBufferAddLit(&buf, " %ld\n", val); - - if (xenXMConfigGetString(conf, "on_poweroff", &str) < 0) - str = "destroy"; - virBufferVSprintf(&buf, " %s\n", str); - - if (xenXMConfigGetString(conf, "on_reboot", &str) < 0) - str = "restart"; - virBufferVSprintf(&buf, " %s\n", str); - - if (xenXMConfigGetString(conf, "on_crash", &str) < 0) - str = "restart"; - virBufferVSprintf(&buf, " %s\n", str); - - - if (hvm) { - virBufferAddLit(&buf, " \n"); - if (xenXMConfigGetInt(conf, "pae", &val) == 0 && - val) - virBufferAddLit(&buf, " \n"); - if (xenXMConfigGetInt(conf, "acpi", &val) == 0 && - val) - virBufferAddLit(&buf, " \n"); - if (xenXMConfigGetInt(conf, "apic", &val) == 0 && - val) - virBufferAddLit(&buf, " \n"); - virBufferAddLit(&buf, " \n"); - - if (xenXMConfigGetInt(conf, "localtime", &val) < 0) - val = 0; - virBufferVSprintf(&buf, " \n", val ? "localtime" : "utc"); - } - - virBufferAddLit(&buf, " \n"); - - if (hvm) { - if (xenXMConfigGetString(conf, "device_model", &str) == 0) - virBufferEscapeString(&buf, " %s\n", str); + const char *emulator = virCapabilitiesDefaultGuestEmulator(priv->caps, + def->os.type, + def->os.arch, + type); + if (!emulator) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("unsupported guest type")); + goto cleanup; + } + if (!(def->emulator = strdup(emulator))) + goto no_memory; } list = virConfGetValue(conf, "disk"); if (list && list->type == VIR_CONF_LIST) { list = list->list; while (list) { - int block = 0; - int cdrom = 0; - char src[PATH_MAX]; - char dev[NAME_MAX]; - char drvName[NAME_MAX] = ""; - char drvType[NAME_MAX] = ""; char *head; char *offset; char *tmp, *tmp1; - const char *bus; if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) goto skipdisk; head = list->str; + if (VIR_ALLOC(disk) < 0) + goto no_memory; + /* * Disks have 3 components, SOURCE,DEST-DEVICE,MODE * eg, phy:/dev/HostVG/XenGuest1,xvda,w @@ -694,105 +839,143 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { * The DEST-DEVICE is optionally post-fixed with disk type */ - /* Extract the source */ + /* Extract the source file path*/ if (!(offset = strchr(head, ',')) || offset[0] == '\0') goto skipdisk; if ((offset - head) >= (PATH_MAX-1)) goto skipdisk; - strncpy(src, head, (offset - head)); - src[(offset-head)] = '\0'; + if (VIR_ALLOC_N(disk->src, (offset - head) + 1) < 0) + goto no_memory; + strncpy(disk->src, head, (offset - head)); + disk->src[(offset-head)] = '\0'; head = offset + 1; - /* Extract the dest */ + /* Remove legacy ioemu: junk */ + if (STRPREFIX(head, "ioemu:")) + head = head + 6; + + /* Extract the dest device name */ if (!(offset = strchr(head, ',')) || offset[0] == '\0') goto skipdisk; - if ((offset - head) >= (PATH_MAX-1)) - goto skipdisk; - strncpy(dev, head, (offset - head)); - dev[(offset-head)] = '\0'; + if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0) + goto no_memory; + strncpy(disk->dst, head, (offset - head)); + disk->dst[(offset-head)] = '\0'; head = offset + 1; /* Extract source driver type */ - if (!src[0]) { - strcpy(drvName, "phy"); - tmp = &src[0]; - } else if ((tmp = strchr(src, ':')) != NULL) { - strncpy(drvName, src, (tmp-src)); - drvName[tmp-src] = '\0'; + if (disk->src && + (tmp = strchr(disk->src, ':')) != NULL) { + if (VIR_ALLOC_N(disk->driverName, (tmp - disk->src) + 1) < 0) + goto no_memory; + strncpy(disk->driverName, disk->src, (tmp - disk->src)); + disk->driverName[tmp - disk->src] = '\0'; + } else { + if (!(disk->driverName = strdup("phy"))) + goto no_memory; + tmp = disk->src; } /* And the source driver sub-type */ - if (STRPREFIX(drvName, "tap")) { + if (STRPREFIX(disk->driverName, "tap")) { if (!(tmp1 = strchr(tmp+1, ':')) || !tmp1[0]) goto skipdisk; - strncpy(drvType, tmp+1, (tmp1-(tmp+1))); - memmove(src, src+(tmp1-src)+1, strlen(src)-(tmp1-src)); + if (VIR_ALLOC_N(disk->driverType, (tmp1-(tmp+1))) < 0) + goto no_memory; + strncpy(disk->driverType, tmp+1, (tmp1-(tmp+1))); + memmove(disk->src, disk->src+(tmp1-disk->src)+1, strlen(disk->src)-(tmp1-disk->src)); } else { - drvType[0] = '\0'; - if (src[0] && tmp) - memmove(src, src+(tmp-src)+1, strlen(src)-(tmp-src)); + disk->driverType = NULL; + if (disk->src[0] && tmp) + memmove(disk->src, disk->src+(tmp-disk->src)+1, strlen(disk->src)-(tmp-disk->src)); } /* phy: type indicates a block device */ - if (STREQ(drvName, "phy")) { - block = 1; - } - - /* Remove legacy ioemu: junk */ - if (STRPREFIX(dev, "ioemu:")) { - memmove(dev, dev+6, strlen(dev)-5); - } + disk->type = STREQ(disk->driverName, "phy") ? + VIR_DOMAIN_DISK_TYPE_BLOCK : VIR_DOMAIN_DISK_TYPE_FILE; /* Check for a :cdrom/:disk postfix */ - if ((tmp = strchr(dev, ':')) != NULL) { + disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; + if ((tmp = strchr(disk->dst, ':')) != NULL) { if (STREQ(tmp, ":cdrom")) - cdrom = 1; + disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; tmp[0] = '\0'; } - if (STRPREFIX(dev, "xvd") || !hvm) { - bus = "xen"; - } else if (STRPREFIX(dev, "sd")) { - bus = "scsi"; + 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 { - bus = "ide"; + disk->bus = VIR_DOMAIN_DISK_BUS_IDE; } - virBufferVSprintf(&buf, " \n", - block ? "block" : "file", - cdrom ? "cdrom" : "disk"); - if (drvType[0]) - virBufferVSprintf(&buf, " \n", drvName, drvType); - else - virBufferVSprintf(&buf, " \n", drvName); - if (src[0]) { - virBufferVSprintf(&buf, " \n", src); - } - virBufferEscapeString(&buf, " \n", bus); if (STREQ(head, "r") || STREQ(head, "ro")) - virBufferAddLit(&buf, " \n"); + disk->readonly = 1; else if ((STREQ(head, "w!")) || (STREQ(head, "!"))) - virBufferAddLit(&buf, " \n"); - virBufferAddLit(&buf, " \n"); + disk->shared = 1; - skipdisk: + /* Maintain list in sorted order according to target device name */ + if (def->disks == NULL) { + disk->next = def->disks; + def->disks = disk; + } else { + virDomainDiskDefPtr ptr = def->disks; + while (ptr) { + if (!ptr->next || xenXMDiskCompare(disk, ptr->next) < 0) { + disk->next = ptr->next; + ptr->next = disk; + break; + } + ptr = ptr->next; + } + } + disk = NULL; + + skipdisk: list = list->next; + virDomainDiskDefFree(disk); } } if (hvm && priv->xendConfigVersion == 1) { - if (xenXMConfigGetString(conf, "cdrom", &str) == 0) { - virBufferAddLit(&buf, " \n"); - virBufferAddLit(&buf, " \n"); - virBufferEscapeString(&buf, " \n", str); - virBufferAddLit(&buf, " \n"); - virBufferAddLit(&buf, " \n"); - virBufferAddLit(&buf, " \n"); + if (xenXMConfigGetString(conn, conf, "cdrom", &str, NULL) < 0) + goto cleanup; + if (str) { + if (VIR_ALLOC(disk) < 0) + goto no_memory; + + disk->type = VIR_DOMAIN_DISK_TYPE_FILE; + disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; + if (!(disk->driverName = strdup("file"))) + goto no_memory; + if (!(disk->src = strdup(str))) + goto no_memory; + if (!(disk->dst = strdup("hdc"))) + goto no_memory; + disk->bus = VIR_DOMAIN_DISK_BUS_IDE; + disk->readonly = 1; + + + /* Maintain list in sorted order according to target device name */ + if (def->disks == NULL) { + disk->next = def->disks; + def->disks = disk; + } else { + virDomainDiskDefPtr ptr = def->disks; + while (ptr) { + if (!ptr->next || xenXMDiskCompare(disk, ptr->next) < 0) { + disk->next = ptr->next; + ptr->next = disk; + break; + } + ptr = ptr->next; + } + } + disk = NULL; } } @@ -871,63 +1054,144 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { type = 1; } - virBufferAddLit(&buf, " \n"); - if (mac[0]) - virBufferVSprintf(&buf, " \n", mac); - if (type == 1 && bridge[0]) - virBufferVSprintf(&buf, " \n", bridge); - if (script[0]) - virBufferEscapeString(&buf, "