This completes the Xen driver work, replacing the code which converts from XML into virConfPtr objects, with code which converts from virDomainDefPtr into virConfPtr objects. The XML parsing is now fully handled by the generic routines. At this point, the xml.c file no longer contains any Xen specific code and is solely generic XML routines. src/xend_internal.c | 45 src/xend_internal.h | 9 src/xm_internal.c | 1288 +++++++++---------------- src/xm_internal.h | 3 src/xml.c | 288 ----- src/xml.h | 12 tests/xmconfigdata/test-fullvirt-usbmouse.cfg | 1 tests/xmconfigdata/test-fullvirt-usbtablet.cfg | 1 8 files changed, 527 insertions(+), 1120 deletions(-) Daniel diff -r 6f2488f348b8 src/xend_internal.c --- a/src/xend_internal.c Thu Jul 03 16:50:10 2008 +0100 +++ b/src/xend_internal.c Thu Jul 03 16:50:15 2008 +0100 @@ -4897,11 +4897,10 @@ return 0; } -static int +int xenDaemonFormatSxprChr(virConnectPtr conn, virDomainChrDefPtr def, - virBufferPtr buf, - const char *name) + virBufferPtr buf) { const char *type = virDomainChrTypeToString(def->type); @@ -4916,20 +4915,20 @@ case VIR_DOMAIN_CHR_TYPE_STDIO: case VIR_DOMAIN_CHR_TYPE_VC: case VIR_DOMAIN_CHR_TYPE_PTY: - virBufferVSprintf(buf, "(%s %s)", name, type); + virBufferVSprintf(buf, "%s", type); break; case VIR_DOMAIN_CHR_TYPE_FILE: case VIR_DOMAIN_CHR_TYPE_PIPE: - virBufferVSprintf(buf, "(%s %s:%s)", name, type, def->data.file.path); + virBufferVSprintf(buf, "%s:%s", type, def->data.file.path); break; case VIR_DOMAIN_CHR_TYPE_DEV: - virBufferVSprintf(buf, "(%s %s)", name, def->data.file.path); + virBufferVSprintf(buf, "%s", def->data.file.path); break; case VIR_DOMAIN_CHR_TYPE_TCP: - virBufferVSprintf(buf, "(%s %s:%s:%s%s)", name, + virBufferVSprintf(buf, "%s:%s:%s%s", (def->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_RAW ? "tcp" : "telnet"), (def->data.tcp.host ? def->data.tcp.host : ""), @@ -4938,7 +4937,7 @@ break; case VIR_DOMAIN_CHR_TYPE_UDP: - virBufferVSprintf(buf, "(%s %s:%s:%s@%s:%s)", name, type, + virBufferVSprintf(buf, "%s:%s:%s@%s:%s", type, (def->data.udp.connectHost ? def->data.udp.connectHost : ""), (def->data.udp.connectService ? def->data.udp.connectService : ""), (def->data.udp.bindHost ? def->data.udp.bindHost : ""), @@ -4946,7 +4945,7 @@ break; case VIR_DOMAIN_CHR_TYPE_UNIX: - virBufferVSprintf(buf, "(%s %s:%s%s)", name, type, + virBufferVSprintf(buf, "%s:%s%s", type, def->data.nix.path, def->data.nix.listen ? ",listen" : ""); break; @@ -5143,17 +5142,14 @@ return 0; } -static int +int xenDaemonFormatSxprSound(virConnectPtr conn, virDomainSoundDefPtr sound, virBufferPtr buf) { const char *str; virDomainSoundDefPtr prev = NULL; - if (!sound) - return 0; - - virBufferAddLit(buf, "(soundhw '"); + while (sound) { if (!(str = virDomainSoundModelTypeToString(sound->model))) { virXendError(conn, VIR_ERR_INTERNAL_ERROR, @@ -5165,7 +5161,6 @@ sound = sound->next; } - virBufferAddLit(buf, "')"); return 0; } @@ -5357,14 +5352,18 @@ } if (def->parallels) { - if (xenDaemonFormatSxprChr(conn, def->parallels, &buf, "parallel") < 0) - goto error; + virBufferAddLit(&buf, "(parallel "); + if (xenDaemonFormatSxprChr(conn, def->parallels, &buf) < 0) + goto error; + virBufferAddLit(&buf, ")"); } else { virBufferAddLit(&buf, "(parallel none)"); } if (def->serials) { - if (xenDaemonFormatSxprChr(conn, def->serials, &buf, "serial") < 0) - goto error; + virBufferAddLit(&buf, "(serial "); + if (xenDaemonFormatSxprChr(conn, def->serials, &buf) < 0) + goto error; + virBufferAddLit(&buf, ")"); } else { virBufferAddLit(&buf, "(serial none)"); } @@ -5372,8 +5371,12 @@ if (def->localtime) virBufferAddLit(&buf, "(localtime 1)"); - if (xenDaemonFormatSxprSound(conn, def->sounds, &buf) < 0) - goto error; + if (def->sounds) { + virBufferAddLit(&buf, "(soundhw '"); + if (xenDaemonFormatSxprSound(conn, def->sounds, &buf) < 0) + goto error; + virBufferAddLit(&buf, "')"); + } } /* get the device emulation model */ diff -r 6f2488f348b8 src/xend_internal.h --- a/src/xend_internal.h Thu Jul 03 16:50:10 2008 +0100 +++ b/src/xend_internal.h Thu Jul 03 16:50:15 2008 +0100 @@ -112,6 +112,15 @@ xenDaemonParseSxprChar(virConnectPtr conn, const char *value, const char *tty); + +int +xenDaemonFormatSxprChr(virConnectPtr conn, + virDomainChrDefPtr def, + virBufferPtr buf); +int +xenDaemonFormatSxprSound(virConnectPtr conn, + virDomainSoundDefPtr sound, + virBufferPtr buf); char * xenDaemonFormatSxpr(virConnectPtr conn, diff -r 6f2488f348b8 src/xm_internal.c --- a/src/xm_internal.c Thu Jul 03 16:50:10 2008 +0100 +++ b/src/xm_internal.c Thu Jul 03 16:50:15 2008 +0100 @@ -36,20 +36,10 @@ #include <stdint.h> #include <xen/dom0_ops.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> - -#ifndef NAME_MAX -#define NAME_MAX 255 -#endif - +#include "xm_internal.h" #include "xen_unified.h" -#include "xm_internal.h" #include "xend_internal.h" #include "hash.h" -#include "internal.h" -#include "xml.h" #include "buf.h" #include "uuid.h" #include "util.h" @@ -1653,829 +1643,533 @@ } -/* - * Convenience method to set an int config param - * based on an XPath expression - */ -static -int xenXMConfigSetIntFromXPath(virConnectPtr conn, - virConfPtr conf, xmlXPathContextPtr ctxt, - const char *setting, const char *xpath, - long scale, int allowMissing, const char *error) { - xmlXPathObjectPtr obj; - long intval; - char *strend; - int ret = -1; +static int xenXMDomainConfigFormatDisk(virConnectPtr conn, + virConfValuePtr list, + virDomainDiskDefPtr disk, + int hvm, + int xendConfigVersion) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + virConfValuePtr val, tmp; + char *str; - obj = xmlXPathEval(BAD_CAST xpath, ctxt); - if ((obj == NULL) || (obj->type != XPATH_STRING) || - (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - if (allowMissing) - ret = 0; - else - xenXMError(conn, VIR_ERR_XML_ERROR, error); - goto error; + if(disk->src) { + if (disk->driverName) { + virBufferVSprintf(&buf, "%s:", disk->driverName); + if (STREQ(disk->driverName, "tap")) + virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio"); + } else { + virBufferVSprintf(&buf, "%s:", + disk->type == VIR_DOMAIN_DISK_TYPE_FILE ? + "file" : "phy"); + } + virBufferVSprintf(&buf, "%s", disk->src); + } + virBufferAddLit(&buf, ","); + if (hvm && xendConfigVersion == 1) + virBufferAddLit(&buf, "ioemu:"); + + virBufferVSprintf(&buf, "%s", disk->dst); + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) + virBufferAddLit(&buf, ":cdrom"); + + if (disk->readonly) + virBufferAddLit(&buf, ",r"); + else if (disk->shared) + virBufferAddLit(&buf, ",!"); + else + virBufferAddLit(&buf, ",w"); + + if (virBufferError(&buf)) { + xenXMError(conn, VIR_ERR_NO_MEMORY, NULL); + return -1; } - intval = strtol((char *)obj->stringval, &strend, 10); - if (strend == (char *)obj->stringval) { - xenXMError(conn, VIR_ERR_XML_ERROR, error); - goto error; - } - - if (scale > 0) - intval = intval * scale; - else if (scale < 0) - intval = intval / (-1*scale); - - if (xenXMConfigSetInt(conf, setting, intval) < 0) - goto error; - - ret = 0; - - error: - xmlXPathFreeObject(obj); - - return ret; -} - -/* - * Convenience method to set a string param - * based on an XPath expression - */ -static -int xenXMConfigSetStringFromXPath(virConnectPtr conn, - virConfPtr conf, xmlXPathContextPtr ctxt, - const char *setting, const char *xpath, - int allowMissing, const char *error) { - xmlXPathObjectPtr obj; - int ret = -1; - - obj = xmlXPathEval(BAD_CAST xpath, ctxt); - - if ((obj == NULL) || (obj->type != XPATH_STRING) || - (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - if (allowMissing) - ret = 0; - else - xenXMError(conn, VIR_ERR_XML_ERROR, error); - goto error; - } - - if (xenXMConfigSetString(conf, setting, (const char *)obj->stringval) < 0) - goto error; - - ret = 0; - - error: - xmlXPathFreeObject(obj); - - return ret; -} - -static int xenXMParseXMLDisk(xmlNodePtr node, int hvm, int xendConfigVersion, char **disk) { - xmlNodePtr cur; - xmlChar *type = NULL; - xmlChar *device = NULL; - xmlChar *source = NULL; - xmlChar *target = NULL; - xmlChar *drvName = NULL; - xmlChar *drvType = NULL; - int readonly = 0; - int shareable = 0; - int typ = 0; - int cdrom = 0; - int ret = -1; - int buflen = 0; - char *buf = NULL; - - type = xmlGetProp(node, BAD_CAST "type"); - if (type != NULL) { - if (xmlStrEqual(type, BAD_CAST "file")) - typ = 0; - else if (xmlStrEqual(type, BAD_CAST "block")) - typ = 1; - xmlFree(type); - } - device = xmlGetProp(node, BAD_CAST "device"); - - cur = node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE) { - if ((source == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "source"))) { - - if (typ == 0) - source = xmlGetProp(cur, BAD_CAST "file"); - else - source = xmlGetProp(cur, BAD_CAST "dev"); - } else if ((target == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "target"))) { - target = xmlGetProp(cur, BAD_CAST "dev"); - } else if ((drvName == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "driver"))) { - drvName = xmlGetProp(cur, BAD_CAST "name"); - if (drvName && STREQ((const char *)drvName, "tap")) - drvType = xmlGetProp(cur, BAD_CAST "type"); - } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) { - readonly = 1; - } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) { - shareable = 1; - } - } - cur = cur->next; - } - - if (target == NULL) { - xmlFree(source); - xmlFree(device); - return (-1); - } - - /* Xend (all versions) put the floppy device config - * under the hvm (image (os)) block - */ - if (hvm && - device && - STREQ((const char *)device, "floppy")) { - ret = 0; + if (VIR_ALLOC(val) < 0) { + xenXMError(conn, VIR_ERR_NO_MEMORY, NULL); goto cleanup; } - /* Xend <= 3.0.2 doesn't include cdrom config here */ - if (hvm && - device && - STREQ((const char *)device, "cdrom")) { - if (xendConfigVersion == 1) { - ret = 0; - goto cleanup; + val->type = VIR_CONF_STRING; + val->str = virBufferContentAndReset(&buf); + tmp = list->list; + while (tmp && tmp->next) + tmp = tmp->next; + if (tmp) + tmp->next = val; + else + list->list = val; + + return 0; + +cleanup: + str = virBufferContentAndReset(&buf); + VIR_FREE(str); + return -1; +} + +static int xenXMDomainConfigFormatNet(virConnectPtr conn, + virConfValuePtr list, + virDomainNetDefPtr net, + int hvm) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + virConfValuePtr val, tmp; + char *str; + + virBufferVSprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x", + net->mac[0], net->mac[1], + net->mac[2], net->mac[3], + net->mac[4], net->mac[5]); + + switch (net->type) { + case VIR_DOMAIN_NET_TYPE_BRIDGE: + virBufferVSprintf(&buf, ",bridge=%s", net->data.bridge.brname); + break; + + case VIR_DOMAIN_NET_TYPE_ETHERNET: + if (net->data.ethernet.script) + virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script); + if (net->data.ethernet.ipaddr) + virBufferVSprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr); + break; + + case VIR_DOMAIN_NET_TYPE_NETWORK: + break; + + default: + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("unsupported network type %d"), + net->type); + goto cleanup; + } + + if (hvm) + virBufferAddLit(&buf, ",type=ioemu"); + + if (net->model) + virBufferVSprintf(&buf, ",model=%s", + net->model); + + if (VIR_ALLOC(val) < 0) { + xenXMError(conn, VIR_ERR_NO_MEMORY, NULL); + goto cleanup; + } + + val->type = VIR_CONF_STRING; + val->str = virBufferContentAndReset(&buf); + tmp = list->list; + while (tmp && tmp->next) + tmp = tmp->next; + if (tmp) + tmp->next = val; + else + list->list = val; + + return 0; + +cleanup: + str = virBufferContentAndReset(&buf); + VIR_FREE(str); + return -1; +} + + + +virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, + virDomainDefPtr def) { + virConfPtr conf = NULL; + int hvm = 0, i; + xenUnifiedPrivatePtr priv; + char *cpus = NULL; + const char *lifecycle; + char uuid[VIR_UUID_STRING_BUFLEN]; + virDomainDiskDefPtr disk; + virDomainNetDefPtr net; + virConfValuePtr diskVal = NULL; + virConfValuePtr netVal = NULL; + + priv = (xenUnifiedPrivatePtr) conn->privateData; + + if (!(conf = virConfNew())) + goto cleanup; + + + if (xenXMConfigSetString(conf, "name", def->name) < 0) + goto no_memory; + + virUUIDFormat(def->uuid, uuid); + if (xenXMConfigSetString(conf, "uuid", uuid) < 0) + goto no_memory; + + if (xenXMConfigSetInt(conf, "maxmem", def->maxmem / 1024) < 0) + goto no_memory; + + if (xenXMConfigSetInt(conf, "memory", def->memory / 1024) < 0) + goto no_memory; + + if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0) + goto no_memory; + + if (def->cpumask && + !(cpus = virDomainCpuSetFormat(conn, def->cpumask, def->cpumasklen)) < 0) + goto cleanup; + + if (cpus && + xenXMConfigSetString(conf, "cpus", cpus) < 0) + goto no_memory; + VIR_FREE(cpus); + + hvm = STREQ(def->os.type, "hvm") ? 1 : 0; + + if (hvm) { + char boot[VIR_DOMAIN_BOOT_LAST+1]; + if (xenXMConfigSetString(conf, "builder", "hvm") < 0) + goto no_memory; + + if (def->os.loader && + xenXMConfigSetString(conf, "kernel", def->os.loader) < 0) + goto no_memory; + + for (i = 0 ; i < def->os.nBootDevs ; i++) { + switch (def->os.bootDevs[i]) { + case VIR_DOMAIN_BOOT_FLOPPY: + boot[i] = 'a'; + break; + case VIR_DOMAIN_BOOT_CDROM: + boot[i] = 'd'; + break; + case VIR_DOMAIN_BOOT_NET: + boot[i] = 'n'; + break; + case VIR_DOMAIN_BOOT_DISK: + default: + boot[i] = 'c'; + break; + } + } + if (!def->os.nBootDevs) { + boot[0] = 'c'; + boot[1] = '\0'; } else { - cdrom = 1; + boot[def->os.nBootDevs] = '\0'; + } + + if (xenXMConfigSetString(conf, "boot", boot) < 0) + goto no_memory; + + if (xenXMConfigSetInt(conf, "pae", + (def->features & + (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0) + goto no_memory; + + if (xenXMConfigSetInt(conf, "acpi", + (def->features & + (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0) + goto no_memory; + + if (xenXMConfigSetInt(conf, "apic", + (def->features & + (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0) + goto no_memory; + + + if (xenXMConfigSetInt(conf, "localtime", def->localtime ? 1 : 0) < 0) + goto no_memory; + + if (priv->xendConfigVersion == 1) { + disk = def->disks; + while (disk) { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && + disk->dst && STREQ(disk->dst, "hdc") && disk->src) { + if (xenXMConfigSetString(conf, "cdrom", disk->src) < 0) + goto no_memory; + break; + } + disk = disk->next; + } + } + + /* XXX floppy disks */ + } else { + if (def->os.bootloader && + xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0) + goto no_memory; + if (def->os.bootloaderArgs && + xenXMConfigSetString(conf, "bootloader_args", def->os.bootloaderArgs) < 0) + goto no_memory; + if (def->os.kernel && + xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0) + goto no_memory; + if (def->os.initrd && + xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0) + goto no_memory; + if (def->os.cmdline && + xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0) + goto no_memory; + + } + + if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("unexpected lifecycle action %d"), def->onPoweroff); + goto cleanup; + } + if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0) + goto no_memory; + + + if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("unexpected lifecycle action %d"), def->onReboot); + goto cleanup; + } + if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0) + goto no_memory; + + + if (!(lifecycle = virDomainLifecycleTypeToString(def->onCrash))) { + xenXMError(conn, VIR_ERR_INTERNAL_ERROR, + _("unexpected lifecycle action %d"), def->onCrash); + goto cleanup; + } + if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0) + goto no_memory; + + + + if (hvm) { + virDomainInputDefPtr input; + if (def->emulator && + xenXMConfigSetString(conf, "device_model", def->emulator) < 0) + goto no_memory; + + input = def->inputs; + while (input) { + if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) { + if (xenXMConfigSetInt(conf, "usb", 1) < 0) + goto no_memory; + if (xenXMConfigSetString(conf, "usbdevice", + input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? + "mouse" : "tablet") < 0) + goto no_memory; + break; + } + input = input->next; } } - if (source == NULL && !cdrom) { - xmlFree(target); - xmlFree(device); - return (-1); - } - - if (drvName) { - buflen += strlen((const char*)drvName) + 1; - if (STREQ((const char*)drvName, "tap")) { - if (drvType) - buflen += strlen((const char*)drvType) + 1; - else - buflen += 4; - } - } else { - if (typ == 0) - buflen += 5; - else - buflen += 4; - } - - if(source) - buflen += strlen((const char*)source) + 1; - else - buflen += 1; - buflen += strlen((const char*)target) + 1; - if (hvm && xendConfigVersion == 1) /* ioemu: */ - buflen += 6; - - if (cdrom) /* :cdrom */ - buflen += 6; - - buflen += 2; /* mode */ - - if (VIR_ALLOC_N(buf, buflen) < 0) - goto cleanup; - - if(source) { - if (drvName) { - strcpy(buf, (const char*)drvName); - if (STREQ((const char*)drvName, "tap")) { - strcat(buf, ":"); - if (drvType) - strcat(buf, (const char*)drvType); - else - strcat(buf, "aio"); + if (def->graphics) { + if (hvm || priv->xendConfigVersion < 3) { + if (def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { + if (xenXMConfigSetInt(conf, "sdl", 1) < 0) + goto no_memory; + if (xenXMConfigSetInt(conf, "vnc", 0) < 0) + goto no_memory; + if (def->graphics->data.sdl.display && + xenXMConfigSetString(conf, "display", + def->graphics->data.sdl.display) < 0) + goto no_memory; + if (def->graphics->data.sdl.xauth && + xenXMConfigSetString(conf, "xauthority", + def->graphics->data.sdl.xauth) < 0) + goto no_memory; + } else { + if (xenXMConfigSetInt(conf, "sdl", 0) < 0) + goto no_memory; + if (xenXMConfigSetInt(conf, "vnc", 1) < 0) + goto no_memory; + if (xenXMConfigSetInt(conf, "vncunused", + def->graphics->data.vnc.autoport ? 1 : 0) < 0) + goto no_memory; + if (!def->graphics->data.vnc.autoport && + xenXMConfigSetInt(conf, "vncdisplay", + def->graphics->data.vnc.port - 5900) < 0) + goto no_memory; + if (def->graphics->data.vnc.listenAddr && + xenXMConfigSetString(conf, "vnclisten", + def->graphics->data.vnc.listenAddr) < 0) + goto no_memory; + if (def->graphics->data.vnc.passwd && + xenXMConfigSetString(conf, "vncpasswd", + def->graphics->data.vnc.passwd) < 0) + goto no_memory; + if (def->graphics->data.vnc.keymap && + xenXMConfigSetString(conf, "keymap", + def->graphics->data.vnc.keymap) < 0) + goto no_memory; } } else { - if (typ == 0) - strcpy(buf, "file"); - else - strcpy(buf, "phy"); + virConfValuePtr vfb, disp; + char *vfbstr = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + if (def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { + virBufferAddLit(&buf, "type=sdl"); + if (def->graphics->data.sdl.display) + virBufferVSprintf(&buf, ",display=%s", + def->graphics->data.sdl.display); + if (def->graphics->data.sdl.xauth) + virBufferVSprintf(&buf, ",xauthority=%s", + def->graphics->data.sdl.xauth); + } else { + virBufferAddLit(&buf, "type=vnc"); + virBufferVSprintf(&buf, ",vncunused=%d", + def->graphics->data.vnc.autoport ? 1 : 0); + if (!def->graphics->data.vnc.autoport) + virBufferVSprintf(&buf, ",vncdisplay=%d", + def->graphics->data.vnc.port - 5900); + if (def->graphics->data.vnc.listenAddr) + virBufferVSprintf(&buf, ",vnclisten=%s", + def->graphics->data.vnc.listenAddr); + if (def->graphics->data.vnc.passwd) + virBufferVSprintf(&buf, ",vncpasswd=%s", + def->graphics->data.vnc.passwd); + if (def->graphics->data.vnc.keymap) + virBufferVSprintf(&buf, ",keymap=%s", + def->graphics->data.vnc.keymap); + } + if (virBufferError(&buf)) + goto no_memory; + + vfbstr = virBufferContentAndReset(&buf); + + if (VIR_ALLOC(vfb) < 0) { + VIR_FREE(vfbstr); + goto no_memory; + } + + if (VIR_ALLOC(disp) < 0) { + VIR_FREE(vfb); + VIR_FREE(vfbstr); + goto no_memory; + } + + vfb->type = VIR_CONF_LIST; + vfb->list = disp; + disp->type = VIR_CONF_STRING; + disp->str = vfbstr; + + if (virConfSetValue(conf, "vfb", vfb) < 0) + goto no_memory; } - strcat(buf, ":"); - strcat(buf, (const char*)source); - } else { - strcpy(buf, ""); - } - strcat(buf, ","); - if (hvm && xendConfigVersion == 1) - strcat(buf, "ioemu:"); - strcat(buf, (const char*)target); - if (cdrom) - strcat(buf, ":cdrom"); - - if (readonly) - strcat(buf, ",r"); - else if (shareable) - strcat(buf, ",!"); - else - strcat(buf, ",w"); - ret = 0; - cleanup: - xmlFree(drvType); - xmlFree(drvName); - xmlFree(device); - xmlFree(target); - xmlFree(source); - *disk = buf; - - return (ret); -} -static char *xenXMParseXMLVif(virConnectPtr conn, xmlNodePtr node, int hvm) { - xmlNodePtr cur; - xmlChar *type = NULL; - xmlChar *source = NULL; - xmlChar *mac = NULL; - xmlChar *script = NULL; - xmlChar *model = NULL; - xmlChar *ip = NULL; - int typ = 0; - char *buf = NULL; - int buflen = 0; - char *bridge = NULL; - - type = xmlGetProp(node, BAD_CAST "type"); - if (type != NULL) { - if (xmlStrEqual(type, BAD_CAST "bridge")) - typ = 0; - else if (xmlStrEqual(type, BAD_CAST "ethernet")) - typ = 1; - else if (xmlStrEqual(type, BAD_CAST "network")) - typ = 2; - xmlFree(type); - } - cur = node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE) { - if ((source == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "source"))) { - - if (typ == 0) - source = xmlGetProp(cur, BAD_CAST "bridge"); - else if (typ == 1) - source = xmlGetProp(cur, BAD_CAST "dev"); - else - source = xmlGetProp(cur, BAD_CAST "network"); - } else if ((mac == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "mac"))) { - mac = xmlGetProp(cur, BAD_CAST "address"); - } else if ((model == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "model"))) { - model = xmlGetProp(cur, BAD_CAST "type"); - } else if ((ip == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "ip"))) { - ip = xmlGetProp(cur, BAD_CAST "address"); - } else if ((script == NULL) && - (xmlStrEqual(cur->name, BAD_CAST "script"))) { - script = xmlGetProp(cur, BAD_CAST "path"); - } - } - cur = cur->next; - } - - if (!mac) { - goto cleanup; - } - buflen += 5 + strlen((const char *)mac); - if (source) { - if (typ == 0) { - buflen += 8 + strlen((const char *)source); - } else if (typ == 1) { - buflen += 5 + strlen((const char *)source); - } else { - virNetworkPtr network = virNetworkLookupByName(conn, (const char *) source); - if (!network || !(bridge = virNetworkGetBridgeName(network))) { - if (network) - virNetworkFree(network); - goto cleanup; - } - virNetworkFree(network); - buflen += 8 + strlen(bridge); - } - } - if (hvm) - buflen += 11; - if (script) - buflen += 8 + strlen((const char*)script); - if (model) - buflen += 7 + strlen((const char*)model); - if (ip) - buflen += 4 + strlen((const char*)ip); - - if (VIR_ALLOC_N(buf, buflen) < 0) - goto cleanup; - - strcpy(buf, "mac="); - strcat(buf, (const char*)mac); - if (source) { - if (typ == 0) { - strcat(buf, ",bridge="); - strcat(buf, (const char*)source); - } else if (typ == 1) { - strcat(buf, ",dev="); - strcat(buf, (const char*)source); - } else { - strcat(buf, ",bridge="); - strcat(buf, bridge); - } - } - if (hvm) { - strcat(buf, ",type=ioemu"); - } - if (script) { - strcat(buf, ",script="); - strcat(buf, (const char*)script); - } - if (model) { - strcat(buf, ",model="); - strcat(buf, (const char*)model); - } - if (ip) { - strcat(buf, ",ip="); - strcat(buf, (const char*)ip); - } - - cleanup: - VIR_FREE(bridge); - xmlFree(mac); - xmlFree(source); - xmlFree(script); - xmlFree(ip); - xmlFree(model); - - return buf; -} - - -virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, - virDomainDefPtr def) { - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlXPathObjectPtr obj = NULL; - xmlXPathContextPtr ctxt = NULL; - xmlChar *prop = NULL; - virConfPtr conf = NULL; - int hvm = 0, i; - xenUnifiedPrivatePtr priv; - char *cpus; - char *xml; - - priv = (xenUnifiedPrivatePtr) conn->privateData; - - if (!(xml = virDomainDefFormat(conn, def, VIR_DOMAIN_XML_SECURE))) - return NULL; - - doc = xmlReadDoc((const xmlChar *) xml, "domain.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING); - VIR_FREE(xml); - if (doc == NULL) { - xenXMError(conn, VIR_ERR_XML_ERROR, - _("cannot read XML domain definition")); - return (NULL); - } - node = xmlDocGetRootElement(doc); - if ((node == NULL) || (!xmlStrEqual(node->name, BAD_CAST "domain"))) { - xenXMError(conn, VIR_ERR_XML_ERROR, - _("missing top level domain element")); - goto error; - } - - prop = xmlGetProp(node, BAD_CAST "type"); - if (prop != NULL) { - if (!xmlStrEqual(prop, BAD_CAST "xen")) { - xenXMError(conn, VIR_ERR_XML_ERROR, - _("domain type is invalid")); - goto error; - } - xmlFree(prop); - prop = NULL; - } - if (!(ctxt = xmlXPathNewContext(doc))) { - xenXMError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot create XPath context")); - goto error; - } - if (!(conf = virConfNew())) - goto error; - - - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "name", "string(/domain/name)", 0, - "domain name element missing") < 0) - goto error; - - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "uuid", "string(/domain/uuid)", 0, - "domain uuid element missing") < 0) - goto error; - - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "maxmem", "string(/domain/memory)", -1024, 0, - "domain memory element missing") < 0) - goto error; - - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "memory", "string(/domain/memory)", -1024, 0, - "domain memory element missing") < 0) - goto error; - - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "memory", "string(/domain/currentMemory)", -1024, 1, - "domain currentMemory element missing") < 0) - goto error; - - if (xenXMConfigSetInt(conf, "vcpus", 1) < 0) - goto error; - - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "vcpus", "string(/domain/vcpu)", 0, 1, - "cannot set vcpus config parameter") < 0) - goto error; - - cpus = virXPathString("string(/domain/vcpu/@cpuset)", ctxt); - if (cpus != NULL) { - char *ranges; - - ranges = virConvertCpuSet(conn, cpus, 0); - VIR_FREE(cpus); - if (ranges == NULL) { - goto error; - } - if (xenXMConfigSetString(conf, "cpus", ranges) < 0) { - VIR_FREE(ranges); - goto error; - } - VIR_FREE(ranges); - } - - obj = xmlXPathEval(BAD_CAST "string(/domain/os/type)", ctxt); - if ((obj != NULL) && (obj->type == XPATH_STRING) && - (obj->stringval != NULL) && STREQ((char*)obj->stringval, "hvm")) - hvm = 1; - xmlXPathFreeObject(obj); - obj = NULL; - - if (hvm) { - const char *boot = "c"; - int clockLocal = 0; - if (xenXMConfigSetString(conf, "builder", "hvm") < 0) - goto error; - - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "kernel", "string(/domain/os/loader)", 1, - "cannot set the os loader parameter") < 0) - goto error; - - obj = xmlXPathEval(BAD_CAST "string(/domain/os/boot/@dev)", ctxt); - if ((obj != NULL) && (obj->type == XPATH_STRING) && - (obj->stringval != NULL)) { - if (STREQ((const char*)obj->stringval, "fd")) - boot = "a"; - else if (STREQ((const char*)obj->stringval, "hd")) - boot = "c"; - else if (STREQ((const char*)obj->stringval, "cdrom")) - boot = "d"; - } - xmlXPathFreeObject(obj); - obj = NULL; - if (xenXMConfigSetString(conf, "boot", boot) < 0) - goto error; - - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "pae", "string(count(/domain/features/pae))", 0, 0, - "cannot set the pae parameter") < 0) - goto error; - - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "acpi", "string(count(/domain/features/acpi))", 0, 0, - "cannot set the acpi parameter") < 0) - goto error; - - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "apic", "string(count(/domain/features/apic))", 0, 0, - "cannot set the apic parameter") < 0) - goto error; - - obj = xmlXPathEval(BAD_CAST "string(/domain/clock/@offset)", ctxt); - if ((obj != NULL) && (obj->type == XPATH_STRING) && - (obj->stringval != NULL)) { - if (STREQ((const char*)obj->stringval, "localtime")) - clockLocal = 1; - } - xmlXPathFreeObject(obj); - obj = NULL; - if (xenXMConfigSetInt(conf, "localtime", clockLocal) < 0) - goto error; - - if (priv->xendConfigVersion == 1) { - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "cdrom", "string(/domain/devices/disk[@device='cdrom']/source/@file)", 1, - "cannot set the cdrom parameter") < 0) - goto error; - } - } else { - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "bootloader", "string(/domain/bootloader)", 1, - "cannot set the bootloader parameter") < 0) - goto error; - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "bootargs", "string(/domain/bootloader_args)", 1, - "cannot set the bootloader_args parameter") < 0) - goto error; - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "kernel", "string(/domain/os/kernel)", 1, - "cannot set the kernel parameter") < 0) - goto error; - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "ramdisk", "string(/domain/os/initrd)", 1, - "cannot set the ramdisk parameter") < 0) - goto error; - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "extra", "string(/domain/os/cmdline)", 1, - "cannot set the cmdline parameter") < 0) - goto error; - - } - - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "on_poweroff", "string(/domain/on_poweroff)", 1, - "cannot set the on_poweroff parameter") < 0) - goto error; - - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "on_reboot", "string(/domain/on_reboot)", 1, - "cannot set the on_reboot parameter") < 0) - goto error; - - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "on_crash", "string(/domain/on_crash)", 1, - "cannot set the on_crash parameter") < 0) - goto error; - - - if (hvm) { - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "device_model", "string(/domain/devices/emulator)", 1, - "cannot set the device_model parameter") < 0) - goto error; - - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "usbdevice", "string(/domain/devices/input[@bus='usb' or (not(@bus) and @type='tablet')]/@type)", 1, - "cannot set the usbdevice parameter") < 0) - goto error; - } - - if (hvm || priv->xendConfigVersion < 3) { - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "sdl", "string(count(/domain/devices/graphics[@type='sdl']))", 0, 0, - "cannot set the sdl parameter") < 0) - goto error; - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "vnc", "string(count(/domain/devices/graphics[@type='vnc']))", 0, 0, - "cannot set the vnc parameter") < 0) - goto error; - if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "vncunused", "string(count(/domain/devices/graphics[@type='vnc' and @port='-1']))", 0, 0, - "cannot set the vncunused parameter") < 0) - goto error; - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "vnclisten", "string(/domain/devices/graphics[@type='vnc']/@listen)", 1, - "cannot set the vnclisten parameter") < 0) - goto error; - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "vncpasswd", "string(/domain/devices/graphics[@type='vnc']/@passwd)", 1, - "cannot set the vncpasswd parameter") < 0) - goto error; - if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "keymap", "string(/domain/devices/graphics[@type='vnc']/@keymap)", 1, - "cannot set the keymap parameter") < 0) - goto error; - - obj = xmlXPathEval(BAD_CAST "string(/domain/devices/graphics[@type='vnc']/@port)", ctxt); - if ((obj != NULL) && (obj->type == XPATH_STRING) && - (obj->stringval != NULL)) { - int port = strtol((const char *)obj->stringval, NULL, 10); - if (port != -1) { - char portstr[50]; - snprintf(portstr, sizeof(portstr), "%d", port-5900); - if (xenXMConfigSetString(conf, "vncdisplay", portstr) < 0) - goto error; - } - } - xmlXPathFreeObject(obj); - } else { - virConfValuePtr vfb; - obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) { - if (VIR_ALLOC(vfb) < 0) { - xenXMError(conn, VIR_ERR_NO_MEMORY, _("config")); - goto error; - } - vfb->type = VIR_CONF_LIST; - vfb->list = NULL; - for (i = obj->nodesetval->nodeNr -1 ; i >= 0 ; i--) { - xmlChar *type; - char *val = NULL; - - if (!(type = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "type"))) { - continue; - } - if (STREQ((const char*)type, "sdl")) { - val = strdup("type=sdl"); - } else if (STREQ((const char*)type, "vnc")) { - int len = 8 + 1; /* type=vnc & NULL */ - xmlChar *vncport = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "port"); - xmlChar *vnclisten = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "listen"); - xmlChar *vncpasswd = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "passwd"); - xmlChar *keymap = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "keymap"); - int vncunused = vncport ? (STREQ((const char*)vncport, "-1") ? 1 : 0) : 1; - if (vncunused) - len += 12; - else - len += 12 + strlen((const char*)vncport);/* vncdisplay= */ - if (vnclisten) - len += 11 + strlen((const char*)vnclisten); - if (vncpasswd) - len += 11 + strlen((const char*)vncpasswd); - if (keymap) - len += 8 + strlen((const char*)keymap); - if (VIR_ALLOC_N(val, len) < 0) { - xmlFree(type); - xmlFree(vncport); - xmlFree(vnclisten); - xmlFree(vncpasswd); - xmlFree(keymap); - VIR_FREE(vfb); - xenXMError (conn, VIR_ERR_NO_MEMORY, strerror (errno)); - goto error; - } - strcpy(val, "type=vnc"); - if (vncunused) { - strcat(val, ",vncunused=1"); - } else { - char portstr[50]; - int port = atoi((const char*)vncport); - snprintf(portstr, sizeof(portstr), "%d", port-5900); - strcat(val, ",vncdisplay="); - strcat(val, portstr); - } - xmlFree(vncport); - if (vnclisten) { - strcat(val, ",vnclisten="); - strcat(val, (const char*)vnclisten); - xmlFree(vnclisten); - } - if (vncpasswd) { - strcat(val, ",vncpasswd="); - strcat(val, (const char*)vncpasswd); - xmlFree(vncpasswd); - } - if (keymap) { - strcat(val, ",keymap="); - strcat(val, (const char*)keymap); - xmlFree(keymap); - } - } - xmlFree(type); - if (val) { - virConfValuePtr disp; - if (VIR_ALLOC(disp) < 0) { - VIR_FREE(val); - VIR_FREE(vfb); - xenXMError(conn, VIR_ERR_NO_MEMORY, _("config")); - goto error; - } - disp->type = VIR_CONF_STRING; - disp->str = val; - disp->next = vfb->list; - vfb->list = disp; - } - } - if (virConfSetValue(conf, "vfb", vfb) < 0) - goto error; - } - xmlXPathFreeObject(obj); } /* analyze of the devices */ - obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) { - virConfValuePtr disks; - if (VIR_ALLOC(disks) < 0) { - xenXMError(conn, VIR_ERR_NO_MEMORY, _("config")); - goto error; + disk = def->disks; + if (VIR_ALLOC(diskVal) < 0) + goto no_memory; + diskVal->type = VIR_CONF_LIST; + diskVal->list = NULL; + + while (disk) { + if (priv->xendConfigVersion == 1 && + disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && + disk->dst && STREQ(disk->dst, "hdc")) { + disk = disk->next; + continue; } - disks->type = VIR_CONF_LIST; - disks->list = NULL; - for (i = obj->nodesetval->nodeNr -1 ; i >= 0 ; i--) { - virConfValuePtr thisDisk; - char *disk = NULL; - if (xenXMParseXMLDisk(obj->nodesetval->nodeTab[i], hvm, priv->xendConfigVersion, &disk) < 0) { - virConfFreeValue(disks); - goto error; - } - if (disk) { - if (VIR_ALLOC(thisDisk) < 0) { - VIR_FREE(disk); - virConfFreeValue(disks); - xenXMError(conn, VIR_ERR_NO_MEMORY, _("config")); - goto error; - } - thisDisk->type = VIR_CONF_STRING; - thisDisk->str = disk; - thisDisk->next = disks->list; - disks->list = thisDisk; - } - } - if (virConfSetValue(conf, "disk", disks) < 0) - goto error; + if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) + continue; + + if (xenXMDomainConfigFormatDisk(conn, diskVal, disk, + hvm, priv->xendConfigVersion) < 0) + goto cleanup; + + disk = disk->next; } - xmlXPathFreeObject(obj); + if (diskVal->list == NULL) + VIR_FREE(diskVal); + else if (virConfSetValue(conf, "disk", diskVal) < 0) { + diskVal = NULL; + goto no_memory; + } + diskVal = NULL; - obj = xmlXPathEval(BAD_CAST "/domain/devices/interface", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) { - virConfValuePtr vifs; - if (VIR_ALLOC(vifs) < 0) { - xenXMError(conn, VIR_ERR_NO_MEMORY, _("config")); - goto error; - } - vifs->type = VIR_CONF_LIST; - vifs->list = NULL; - for (i = obj->nodesetval->nodeNr - 1; i >= 0; i--) { - virConfValuePtr thisVif; - char *vif = xenXMParseXMLVif(conn, obj->nodesetval->nodeTab[i], hvm); - if (!vif) { - virConfFreeValue(vifs); - goto error; - } - if (VIR_ALLOC(thisVif) < 0) { - VIR_FREE(vif); - virConfFreeValue(vifs); - xenXMError(conn, VIR_ERR_NO_MEMORY, _("config")); - goto error; - } - thisVif->type = VIR_CONF_STRING; - thisVif->str = vif; - thisVif->next = vifs->list; - vifs->list = thisVif; - } - if (virConfSetValue(conf, "vif", vifs) < 0) - goto error; + + net = def->nets; + if (VIR_ALLOC(netVal) < 0) + goto no_memory; + netVal->type = VIR_CONF_LIST; + netVal->list = NULL; + + while (net) { + if (xenXMDomainConfigFormatNet(conn, netVal, net, + hvm) < 0) + goto cleanup; + + net = net->next; } - xmlXPathFreeObject(obj); - obj = NULL; + if (netVal->list == NULL) + VIR_FREE(netVal); + else if (virConfSetValue(conf, "vif", netVal) < 0) { + netVal = NULL; + goto no_memory; + } + netVal = NULL; if (hvm) { - xmlNodePtr cur; - cur = virXPathNode("/domain/devices/parallel[1]", ctxt); - if (cur != NULL) { - char scratch[PATH_MAX]; + if (def->parallels) { + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *str; + int ret; - if (virDomainParseXMLOSDescHVMChar(conn, scratch, sizeof(scratch), cur) < 0) { - goto error; - } - - if (xenXMConfigSetString(conf, "parallel", scratch) < 0) - goto error; + ret = xenDaemonFormatSxprChr(conn, def->parallels, &buf); + str = virBufferContentAndReset(&buf); + if (ret == 0) + ret = xenXMConfigSetString(conf, "parallel", str); + VIR_FREE(str); + if (ret < 0) + goto no_memory; } else { if (xenXMConfigSetString(conf, "parallel", "none") < 0) - goto error; + goto no_memory; } - cur = virXPathNode("/domain/devices/serial[1]", ctxt); - if (cur != NULL) { - char scratch[PATH_MAX]; - if (virDomainParseXMLOSDescHVMChar(conn, scratch, sizeof(scratch), cur) < 0) - goto error; - if (xenXMConfigSetString(conf, "serial", scratch) < 0) - goto error; + if (def->serials) { + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *str; + int ret; + + ret = xenDaemonFormatSxprChr(conn, def->serials, &buf); + str = virBufferContentAndReset(&buf); + if (ret == 0) + ret = xenXMConfigSetString(conf, "serial", str); + VIR_FREE(str); + if (ret < 0) + goto no_memory; } else { - if (virXPathBoolean("count(/domain/devices/console) > 0", ctxt)) { - if (xenXMConfigSetString(conf, "serial", "pty") < 0) - goto error; - } else { - if (xenXMConfigSetString(conf, "serial", "none") < 0) - goto error; - } + if (xenXMConfigSetString(conf, "serial", "none") < 0) + goto no_memory; } - if (virXPathNode("/domain/devices/sound", ctxt)) { - char *soundstr; - if (!(soundstr = virBuildSoundStringFromXML(conn, ctxt))) - goto error; - if (xenXMConfigSetString(conf, "soundhw", soundstr) < 0) { - VIR_FREE(soundstr); - goto error; - } - VIR_FREE(soundstr); + + if (def->sounds) { + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *str = NULL; + int ret = xenDaemonFormatSxprSound(conn, + def->sounds, + &buf); + str = virBufferContentAndReset(&buf); + if (ret == 0) + ret = xenXMConfigSetString(conf, "soundhw", str); + + VIR_FREE(str); + if (ret < 0) + goto no_memory; } } - xmlFreeDoc(doc); - xmlXPathFreeContext(ctxt); - return conf; - error: +no_memory: + xenXMError(conn, VIR_ERR_NO_MEMORY, NULL); + +cleanup: + virConfFreeValue(diskVal); + virConfFreeValue(netVal); + VIR_FREE(cpus); if (conf) virConfFree(conf); - xmlFree(prop); - xmlXPathFreeObject(obj); - xmlXPathFreeContext(ctxt); - if (doc != NULL) - xmlFreeDoc(doc); return (NULL); } diff -r 6f2488f348b8 src/xm_internal.h --- a/src/xm_internal.h Thu Jul 03 16:50:10 2008 +0100 +++ b/src/xm_internal.h Thu Jul 03 16:50:15 2008 +0100 @@ -25,9 +25,8 @@ #ifndef _LIBVIRT_XM_INTERNAL_H_ #define _LIBVIRT_XM_INTERNAL_H_ -#include "libvirt/libvirt.h" +#include "internal.h" #include "conf.h" -#include "internal.h" #include "domain_conf.h" extern struct xenUnifiedDriver xenXMDriver; diff -r 6f2488f348b8 src/xml.c --- a/src/xml.c Thu Jul 03 16:50:10 2008 +0100 +++ b/src/xml.c Thu Jul 03 16:50:15 2008 +0100 @@ -368,291 +368,3 @@ return (ret); } -#if WITH_XEN -#ifndef PROXY -/** - * virConvertCpuSet: - * @conn: connection - * @str: pointer to a Xen or user provided CPU set string pointer - * @maxcpu: number of CPUs on the node, if 0 4096 will be used - * - * Parse the given CPU set string and convert it to a range based - * string. - * - * Returns a new string which must be freed by the caller or NULL in - * case of error. - */ -char * -virConvertCpuSet(virConnectPtr conn, const char *str, int maxcpu) { - int ret; - char *res, *cpuset; - const char *cur = str; - - if (str == NULL) - return(NULL); - - if (maxcpu <= 0) - maxcpu = 4096; - - if (VIR_ALLOC_N(cpuset, maxcpu) < 0) { - virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0); - return(NULL); - } - - ret = virDomainCpuSetParse(conn, &cur, 0, cpuset, maxcpu); - if (ret < 0) { - VIR_FREE(cpuset); - return(NULL); - } - res = virDomainCpuSetFormat(conn, cpuset, maxcpu); - VIR_FREE(cpuset); - return (res); -} - - -/** - * virBuildSoundStringFromXML - * @sound buffer to populate - * @len size of preallocated buffer 'sound' - * @ctxt xml context to pull sound info from - * - * Builds a string of the form m1,m2,m3 from the different sound models - * in the xml. String must be free'd by caller. - * - * Returns string on success, NULL on error - */ -char * virBuildSoundStringFromXML(virConnectPtr conn, - xmlXPathContextPtr ctxt) { - - int nb_nodes, size = 256; - char *sound; - xmlNodePtr *nodes = NULL; - - if (VIR_ALLOC_N(sound, size + 1) < 0) { - virXMLError(conn, VIR_ERR_NO_MEMORY, - _("failed to allocate sound string"), 0); - return NULL; - } - - nb_nodes = virXPathNodeSet("/domain/devices/sound", ctxt, &nodes); - if (nb_nodes > 0) { - int i; - for (i = 0; i < nb_nodes && size > 0; i++) { - char *model = NULL; - int collision = 0; - - model = (char *) xmlGetProp(nodes[i], (xmlChar *) "model"); - if (!model) { - virXMLError(conn, VIR_ERR_XML_ERROR, - _("no model for sound device"), 0); - goto error; - } - - if (!is_sound_model_valid(model)) { - virXMLError(conn, VIR_ERR_XML_ERROR, - _("unknown sound model type"), 0); - VIR_FREE(model); - goto error; - } - - // Check for duplicates in currently built string - if (*sound) - collision = is_sound_model_conflict(model, sound); - - // If no collision, add to string - if (!collision) { - if (*sound && (size >= (strlen(model) + 1))) { - strncat(sound, ",", size--); - } else if (*sound || size < strlen(model)) { - VIR_FREE(model); - continue; - } - strncat(sound, model, size); - size -= strlen(model); - } - - VIR_FREE(model); - } - } - VIR_FREE(nodes); - return sound; - error: - VIR_FREE(nodes); - return NULL; -} - -int -virDomainParseXMLOSDescHVMChar(virConnectPtr conn, - char *buf, - size_t buflen, - xmlNodePtr node) -{ - xmlChar *type = NULL; - xmlChar *path = NULL; - xmlChar *bindHost = NULL; - xmlChar *bindService = NULL; - xmlChar *connectHost = NULL; - xmlChar *connectService = NULL; - xmlChar *mode = NULL; - xmlChar *protocol = NULL; - xmlNodePtr cur; - - type = xmlGetProp(node, BAD_CAST "type"); - - if (type != NULL) { - cur = node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(cur->name, BAD_CAST "source")) { - if (mode == NULL) - mode = xmlGetProp(cur, BAD_CAST "mode"); - - if (STREQ((const char *)type, "dev") || - STREQ((const char *)type, "file") || - STREQ((const char *)type, "pipe") || - STREQ((const char *)type, "unix")) { - if (path == NULL) - path = xmlGetProp(cur, BAD_CAST "path"); - - } else if (STREQ((const char *)type, "udp") || - STREQ((const char *)type, "tcp")) { - if (mode == NULL || - STREQ((const char *)mode, "connect")) { - - if (connectHost == NULL) - connectHost = xmlGetProp(cur, BAD_CAST "host"); - if (connectService == NULL) - connectService = xmlGetProp(cur, BAD_CAST "service"); - } else { - if (bindHost == NULL) - bindHost = xmlGetProp(cur, BAD_CAST "host"); - if (bindService == NULL) - bindService = xmlGetProp(cur, BAD_CAST "service"); - } - - if (STREQ((const char*)type, "udp")) { - xmlFree(mode); - mode = NULL; - } - } - } else if (xmlStrEqual(cur->name, BAD_CAST "protocol")) { - if (protocol == NULL) - protocol = xmlGetProp(cur, BAD_CAST "type"); - } - } - cur = cur->next; - } - } - - if (type == NULL || - STREQ((const char *)type, "pty")) { - strncpy(buf, "pty", buflen); - } else if (STREQ((const char *)type, "null") || - STREQ((const char *)type, "stdio") || - STREQ((const char *)type, "vc")) { - snprintf(buf, buflen, "%s", type); - } else if (STREQ((const char *)type, "file") || - STREQ((const char *)type, "dev") || - STREQ((const char *)type, "pipe")) { - if (path == NULL) { - virXMLError(conn, VIR_ERR_XML_ERROR, - _("Missing source path attribute for char device"), 0); - goto cleanup; - } - - if (STREQ((const char *)type, "dev")) - strncpy(buf, (const char *)path, buflen); - else - snprintf(buf, buflen, "%s:%s", type, path); - } else if (STREQ((const char *)type, "tcp")) { - int telnet = 0; - if (protocol != NULL && - STREQ((const char *)protocol, "telnet")) - telnet = 1; - - if (mode == NULL || - STREQ((const char *)mode, "connect")) { - if (connectHost == NULL) { - virXMLError(conn, VIR_ERR_INTERNAL_ERROR, - _("Missing source host attribute for char device"), 0); - goto cleanup; - } - if (connectService == NULL) { - virXMLError(conn, VIR_ERR_INTERNAL_ERROR, - _("Missing source service attribute for char device"), 0); - goto cleanup; - } - - snprintf(buf, buflen, "%s:%s:%s", - (telnet ? "telnet" : "tcp"), - connectHost, connectService); - } else { - if (bindHost == NULL) { - virXMLError(conn, VIR_ERR_INTERNAL_ERROR, - _("Missing source host attribute for char device"), 0); - goto cleanup; - } - if (bindService == NULL) { - virXMLError(conn, VIR_ERR_INTERNAL_ERROR, - _("Missing source service attribute for char device"), 0); - goto cleanup; - } - - snprintf(buf, buflen, "%s:%s:%s,listen", - (telnet ? "telnet" : "tcp"), - bindHost, bindService); - } - } else if (STREQ((const char *)type, "udp")) { - if (connectService == NULL) { - virXMLError(conn, VIR_ERR_XML_ERROR, - _("Missing source service attribute for char device"), 0); - goto cleanup; - } - - snprintf(buf, buflen, "udp:%s:%s@%s:%s", - connectHost ? (const char *)connectHost : "", - connectService, - bindHost ? (const char *)bindHost : "", - bindService ? (const char *)bindService : ""); - } else if (STREQ((const char *)type, "unix")) { - if (path == NULL) { - virXMLError(conn, VIR_ERR_XML_ERROR, - _("Missing source path attribute for char device"), 0); - goto cleanup; - } - - if (mode == NULL || - STREQ((const char *)mode, "connect")) { - snprintf(buf, buflen, "%s:%s", type, path); - } else { - snprintf(buf, buflen, "%s:%s,listen", type, path); - } - } - buf[buflen-1] = '\0'; - - xmlFree(mode); - xmlFree(protocol); - xmlFree(type); - xmlFree(bindHost); - xmlFree(bindService); - xmlFree(connectHost); - xmlFree(connectService); - xmlFree(path); - - return 0; - -cleanup: - xmlFree(mode); - xmlFree(protocol); - xmlFree(type); - xmlFree(bindHost); - xmlFree(bindService); - xmlFree(connectHost); - xmlFree(connectService); - xmlFree(path); - return -1; -} - -#endif /* !PROXY */ - -#endif /* WITH_XEN */ diff -r 6f2488f348b8 src/xml.h --- a/src/xml.h Thu Jul 03 16:50:10 2008 +0100 +++ b/src/xml.h Thu Jul 03 16:50:15 2008 +0100 @@ -39,16 +39,4 @@ char * virXMLPropString(xmlNodePtr node, const char *name); -char * -virConvertCpuSet(virConnectPtr conn, const char *str, int maxcpu); - -char * virBuildSoundStringFromXML(virConnectPtr conn, - xmlXPathContextPtr ctxt); - -int -virDomainParseXMLOSDescHVMChar(virConnectPtr conn, - char *buf, - size_t buflen, - xmlNodePtr node); - #endif /* __VIR_XML_H__ */ diff -r 6f2488f348b8 tests/xmconfigdata/test-fullvirt-usbmouse.cfg --- a/tests/xmconfigdata/test-fullvirt-usbmouse.cfg Thu Jul 03 16:50:10 2008 +0100 +++ b/tests/xmconfigdata/test-fullvirt-usbmouse.cfg Thu Jul 03 16:50:15 2008 +0100 @@ -14,6 +14,7 @@ on_reboot = "restart" on_crash = "restart" device_model = "/usr/lib/xen/bin/qemu-dm" +usb = 1 usbdevice = "mouse" sdl = 0 vnc = 1 diff -r 6f2488f348b8 tests/xmconfigdata/test-fullvirt-usbtablet.cfg --- a/tests/xmconfigdata/test-fullvirt-usbtablet.cfg Thu Jul 03 16:50:10 2008 +0100 +++ b/tests/xmconfigdata/test-fullvirt-usbtablet.cfg Thu Jul 03 16:50:15 2008 +0100 @@ -14,6 +14,7 @@ on_reboot = "restart" on_crash = "restart" device_model = "/usr/lib/xen/bin/qemu-dm" +usb = 1 usbdevice = "tablet" sdl = 0 vnc = 1 -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list