]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Switch XM config file driver to use new domain APIs for XML to config conversion
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 25 Jul 2008 14:10:49 +0000 (14:10 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 25 Jul 2008 14:10:49 +0000 (14:10 +0000)
ChangeLog
src/xend_internal.c
src/xend_internal.h
src/xm_internal.c
src/xm_internal.h
src/xml.c
src/xml.h
tests/xmconfigdata/test-fullvirt-usbmouse.cfg
tests/xmconfigdata/test-fullvirt-usbtablet.cfg

index f2dbe53edfc068969dbf8d890fdc1b0a93e2ebc2..4009582a93e7a84cb5e1275823c0d9868114dcab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Fri Jul 25 15:03:27 BST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/xend_internal.c, src/xend_internal.h: Expose the
+       xenDaemonFormatSxprChr and xenDaemonFormatSxprSound()
+       methods to the XM driver
+       * src/xm_internal.c, src/xm_internal.h: Switch to use
+       new domain APIs for the XML -> config formatter
+       * src/xml.h, src/xml.c: Remove unused Xen specific
+       APIs which now live in xend_internal.c
+       * tests/xmconfigdata/test-fullvirt-usb*.cfg: Add an
+       explicit 'usb=1' config setting
+
 Fri Jul 25 14:48:27 BST 2008 Daniel P. Berrange <berrange@redhat.com>
 
        * src/xend_internal.c, src/xend_internal.h: Remove the
index 7371b412f4022212015f19a30696f562234daea9..880a27962c32c5e94fe586e5b052cf152929fa1d 100644 (file)
@@ -4936,11 +4936,10 @@ xenDaemonFormatSxprGraphicsOld(virConnectPtr conn,
     return 0;
 }
 
-static int
+int
 xenDaemonFormatSxprChr(virConnectPtr conn,
                        virDomainChrDefPtr def,
-                       virBufferPtr buf,
-                       const char *name)
+                       virBufferPtr buf)
 {
     const char *type = virDomainChrTypeToString(def->type);
 
@@ -4955,20 +4954,20 @@ xenDaemonFormatSxprChr(virConnectPtr conn,
     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 : ""),
@@ -4977,7 +4976,7 @@ xenDaemonFormatSxprChr(virConnectPtr conn,
         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 : ""),
@@ -4985,7 +4984,7 @@ xenDaemonFormatSxprChr(virConnectPtr conn,
         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;
@@ -5182,17 +5181,14 @@ xenDaemonFormatSxprNet(virConnectPtr conn,
     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,
@@ -5204,7 +5200,6 @@ xenDaemonFormatSxprSound(virConnectPtr conn,
         sound = sound->next;
     }
 
-    virBufferAddLit(buf, "')");
     return 0;
 }
 
@@ -5396,14 +5391,18 @@ xenDaemonFormatSxpr(virConnectPtr conn,
             }
 
             if (def->parallels) {
-                if (xenDaemonFormatSxprChr(conn, def->parallels, &buf, "parallel") < 0)
+                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)
+                virBufferAddLit(&buf, "(serial ");
+                if (xenDaemonFormatSxprChr(conn, def->serials, &buf) < 0)
                     goto error;
+                virBufferAddLit(&buf, ")");
             } else {
                 virBufferAddLit(&buf, "(serial none)");
             }
@@ -5411,8 +5410,12 @@ xenDaemonFormatSxpr(virConnectPtr conn,
             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 */
index 7a317ca0fea51efa19d1e15ca0f83f65910e9b51..5172cd380b587e3f7e49a5727b8a80ff650bdc0a 100644 (file)
@@ -113,6 +113,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,
                     virDomainDefPtr def,
index 9ef64ac3d1a9cb235d35b8b7b4e56eeab6d4ffbb..822581c8a05a4733a317169972908f84a555cb67 100644 (file)
 #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 "xen_unified.h"
 #include "xm_internal.h"
+#include "xen_unified.h"
 #include "xend_internal.h"
 #include "hash.h"
-#include "internal.h"
-#include "xml.h"
 #include "buf.h"
 #include "uuid.h"
 #include "util.h"
@@ -1711,829 +1701,533 @@ int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str)
 }
 
 
-/*
- * 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;
-
-    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;
-    }
-
-    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;
+static int xenXMDomainConfigFormatDisk(virConnectPtr conn,
+                                       virConfValuePtr list,
+                                       virDomainDiskDefPtr disk,
+                                       int hvm,
+                                       int xendConfigVersion)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    virConfValuePtr val, tmp;
+    char *str;
+
+    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:");
 
-    if (xenXMConfigSetString(conf, setting, (const char *)obj->stringval) < 0)
-        goto error;
-
-    ret = 0;
-
- error:
-    xmlXPathFreeObject(obj);
-
-    return ret;
-}
+    virBufferVSprintf(&buf, "%s", disk->dst);
+    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
+        virBufferAddLit(&buf, ":cdrom");
 
-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 (disk->readonly)
+        virBufferAddLit(&buf, ",r");
+    else if (disk->shared)
+        virBufferAddLit(&buf, ",!");
+    else
+        virBufferAddLit(&buf, ",w");
 
-    if (target == NULL) {
-        xmlFree(source);
-        xmlFree(device);
-        return (-1);
+    if (virBufferError(&buf)) {
+        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+        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;
-        } else {
-            cdrom = 1;
-        }
-    }
+    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;
 
-    if (source == NULL && !cdrom) {
-        xmlFree(target);
-        xmlFree(device);
-        return (-1);
-    }
+    return 0;
 
-    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;
-    }
+cleanup:
+    str = virBufferContentAndReset(&buf);
+    VIR_FREE(str);
+    return -1;
+}
 
-    if(source)
-        buflen += strlen((const char*)source) + 1;
-    else
-        buflen += 1;
-    buflen += strlen((const char*)target) + 1;
-    if (hvm && xendConfigVersion == 1) /* ioemu: */
-        buflen += 6;
+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;
 
-    if (cdrom) /* :cdrom */
-        buflen += 6;
+    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;
 
-    buflen += 2; /* mode */
+    case VIR_DOMAIN_NET_TYPE_NETWORK:
+        break;
 
-    if (VIR_ALLOC_N(buf, buflen) < 0)
+    default:
+        xenXMError(conn, VIR_ERR_INTERNAL_ERROR,
+                   _("unsupported network type %d"),
+                   net->type);
         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");
-            }
-        } else {
-            if (typ == 0)
-                strcpy(buf, "file");
-            else
-                strcpy(buf, "phy");
-        }
-        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 (hvm)
+        virBufferAddLit(&buf, ",type=ioemu");
 
-    if (!mac) {
+    if (net->model)
+        virBufferVSprintf(&buf, ",model=%s",
+                          net->model);
+
+    if (VIR_ALLOC(val) < 0) {
+        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
         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);
-    }
+    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;
 
- cleanup:
-    VIR_FREE(bridge);
-    xmlFree(mac);
-    xmlFree(source);
-    xmlFree(script);
-    xmlFree(ip);
-    xmlFree(model);
+    return 0;
 
-    return buf;
+cleanup:
+    str = virBufferContentAndReset(&buf);
+    VIR_FREE(str);
+    return -1;
 }
 
 
+
 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;
+    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 (!(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;
+        goto cleanup;
 
 
-    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 (xenXMConfigSetString(conf, "name", def->name) < 0)
+        goto no_memory;
 
-    if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "memory", "string(/domain/memory)", -1024, 0,
-                                   "domain memory element missing") < 0)
-        goto error;
+    virUUIDFormat(def->uuid, uuid);
+    if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
+        goto no_memory;
 
-    if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "memory", "string(/domain/currentMemory)", -1024, 1,
-                                   "domain currentMemory element missing") < 0)
-        goto error;
+    if (xenXMConfigSetInt(conf, "maxmem", def->maxmem / 1024) < 0)
+        goto no_memory;
 
-    if (xenXMConfigSetInt(conf, "vcpus", 1) < 0)
-        goto error;
+    if (xenXMConfigSetInt(conf, "memory", def->memory / 1024) < 0)
+        goto no_memory;
 
-    if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "vcpus", "string(/domain/vcpu)", 0, 1,
-                                   "cannot set vcpus config parameter") < 0)
-        goto error;
+    if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)
+        goto no_memory;
 
-    cpus = virXPathString("string(/domain/vcpu/@cpuset)", ctxt);
-    if (cpus != NULL) {
-        char *ranges;
+    if (def->cpumask &&
+        !(cpus = virDomainCpuSetFormat(conn, def->cpumask, def->cpumasklen)) < 0)
+        goto cleanup;
 
-        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);
-    }
+    if (cpus &&
+        xenXMConfigSetString(conf, "cpus", cpus) < 0)
+        goto no_memory;
+    VIR_FREE(cpus);
 
-    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;
+    hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
 
     if (hvm) {
-        const char *boot = "c";
-        int clockLocal = 0;
+        char boot[VIR_DOMAIN_BOOT_LAST+1];
         if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
-            goto error;
+            goto no_memory;
 
-        if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "kernel", "string(/domain/os/loader)", 1,
-                                          "cannot set the os loader parameter") < 0)
-            goto error;
+        if (def->os.loader &&
+            xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
+            goto no_memory;
 
-        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";
+        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;
+            }
         }
-        xmlXPathFreeObject(obj);
-        obj = NULL;
+        if (!def->os.nBootDevs) {
+            boot[0] = 'c';
+            boot[1] = '\0';
+        } else {
+            boot[def->os.nBootDevs] = '\0';
+        }
+
         if (xenXMConfigSetString(conf, "boot", boot) < 0)
-            goto error;
+            goto no_memory;
 
-        if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "pae", "string(count(/domain/features/pae))", 0, 0,
-                                       "cannot set the pae parameter") < 0)
-            goto error;
+        if (xenXMConfigSetInt(conf, "pae",
+                              (def->features &
+                               (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
+            goto no_memory;
 
-        if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "acpi", "string(count(/domain/features/acpi))", 0, 0,
-                                       "cannot set the acpi parameter") < 0)
-            goto error;
+        if (xenXMConfigSetInt(conf, "acpi",
+                              (def->features &
+                               (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
+            goto no_memory;
 
-        if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "apic", "string(count(/domain/features/apic))", 0, 0,
-                                       "cannot set the apic parameter") < 0)
-            goto error;
+        if (xenXMConfigSetInt(conf, "apic",
+                              (def->features &
+                               (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
+            goto no_memory;
 
-        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 (xenXMConfigSetInt(conf, "localtime", def->localtime ? 1 : 0) < 0)
+            goto no_memory;
 
         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;
+            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 (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 (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 (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 (!(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 (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "on_crash", "string(/domain/on_crash)", 1,
-                                      "cannot set the on_crash parameter") < 0)
-        goto error;
 
+    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 (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 (!(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 || 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;
+
+    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;
         }
-        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 (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 {
+            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) {
-                xenXMError(conn, VIR_ERR_NO_MEMORY, _("config"));
-                goto error;
+                VIR_FREE(vfbstr);
+                goto no_memory;
             }
-            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 (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 error;
+                goto no_memory;
         }
-        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;
-        }
-        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;
-    }
-    xmlXPathFreeObject(obj);
+    disk = def->disks;
+    if (VIR_ALLOC(diskVal) < 0)
+        goto no_memory;
+    diskVal->type = VIR_CONF_LIST;
+    diskVal->list = 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;
+    while (disk) {
+        if (priv->xendConfigVersion == 1 &&
+            disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+            disk->dst && STREQ(disk->dst, "hdc")) {
+            disk = disk->next;
+            continue;
         }
-        if (virConfSetValue(conf, "vif", vifs) < 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);
-    obj = NULL;
+    if (diskVal->list == NULL)
+        VIR_FREE(diskVal);
+    else if (virConfSetValue(conf, "disk", diskVal) < 0) {
+        diskVal = NULL;
+        goto no_memory;
+    }
+    diskVal = NULL;
 
-    if (hvm) {
-        xmlNodePtr cur;
-        cur = virXPathNode("/domain/devices/parallel[1]", ctxt);
-        if (cur != NULL) {
-            char scratch[PATH_MAX];
 
-            if (virDomainParseXMLOSDescHVMChar(conn, scratch, sizeof(scratch), cur) < 0) {
-                goto error;
-            }
+    net = def->nets;
+    if (VIR_ALLOC(netVal) < 0)
+        goto no_memory;
+    netVal->type = VIR_CONF_LIST;
+    netVal->list = NULL;
 
-            if (xenXMConfigSetString(conf, "parallel", scratch) < 0)
-                goto error;
+    while (net) {
+        if (xenXMDomainConfigFormatNet(conn, netVal, net,
+                                       hvm) < 0)
+            goto cleanup;
+
+        net = net->next;
+    }
+    if (netVal->list == NULL)
+        VIR_FREE(netVal);
+    else if (virConfSetValue(conf, "vif", netVal) < 0) {
+        netVal = NULL;
+        goto no_memory;
+    }
+    netVal = NULL;
+
+    if (hvm) {
+        if (def->parallels) {
+            virBuffer buf = VIR_BUFFER_INITIALIZER;
+            char *str;
+            int ret;
+
+            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);
 }
 
index 2aa818a8c1d1f92fb0cb34c531532d7de89d114f..012a8fced600d735bec2651fbb0db60f60423c75 100644 (file)
@@ -25,9 +25,8 @@
 #ifndef _LIBVIRT_XM_INTERNAL_H_
 #define _LIBVIRT_XM_INTERNAL_H_
 
-#include "libvirt/libvirt.h"
-#include "conf.h"
 #include "internal.h"
+#include "conf.h"
 #include "domain_conf.h"
 
 extern struct xenUnifiedDriver xenXMDriver;
index dc1839624a0bec02b98e35a8f2e633a1333d745f..0bcd07c3b79f56ad5bfd5b986a09f22ef78537cb 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -368,291 +368,3 @@ virXPathNodeSet(const char *xpath, xmlXPathContextPtr ctxt,
     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 */
index eb66cef0982db429061023b64d6ea18309a13135..cb6a9ec98ea81d448b17cbb5e3286908bcc4fcbd 100644 (file)
--- a/src/xml.h
+++ b/src/xml.h
@@ -39,16 +39,4 @@ int          virXPathNodeSet (const char *xpath,
 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__ */
index 9079734879360a4e596c88dceb34f8b97de52244..e4e10fff4b9725f2418286eee866932e536b4d65 100755 (executable)
@@ -14,6 +14,7 @@ on_poweroff = "destroy"
 on_reboot = "restart"
 on_crash = "restart"
 device_model = "/usr/lib/xen/bin/qemu-dm"
+usb = 1
 usbdevice = "mouse"
 sdl = 0
 vnc = 1
index f90f0876edb0b713efcfb87d64a417d92a308150..1c43aedaf26e449bf0661943614582f08d0dd521 100755 (executable)
@@ -14,6 +14,7 @@ on_poweroff = "destroy"
 on_reboot = "restart"
 on_crash = "restart"
 device_model = "/usr/lib/xen/bin/qemu-dm"
+usb = 1
 usbdevice = "tablet"
 sdl = 0
 vnc = 1