[libvirt] PATCH: 2/2: port QEMU driver to new domain APIs

Daniel P. Berrange berrange at redhat.com
Tue Jun 24 16:28:39 UTC 2008


This patch ports the QEMU driver to the domain XML apis.
Obviously we delete alot of the struct defintions and all the code
used for parsing and formatting XML. Then there follows alot of fixup to
deal with API name changes. The other notable point is that the char *
arrays are no longer pre-declared as PATH_MAX in size, instead being
allocated on the heap. So we change alot of conditionals from looking 
like

  foo[0] == '\0'

over to

  foo == NULL

The qemudBuildCommandLine() functions gains a whole lot of extra args
since we no longer pass our QEMU specific state in via the domain's
config object (as that's shared between all drivers). 


 src/qemu_conf.c                                      | 2552 +------------------
 src/qemu_conf.h                                      |  366 --
 src/qemu_driver.c                                    |  443 +--
 tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml   |    2 
 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml |    2 
 tests/qemuxml2argvdata/qemuxml2argv-input-xen.args   |    2 
 tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml    |    4 
 tests/qemuxml2argvdata/qemuxml2argv-sound.xml        |    7 
 tests/qemuxml2argvtest.c                             |   26 
 tests/qemuxml2xmltest.c                              |   20 
 10 files changed, 486 insertions(+), 2938 deletions(-)


Regards,
Daniel

diff -r 286320a1cbc8 src/qemu_conf.c
--- a/src/qemu_conf.c	Sun Jun 22 18:04:01 2008 -0400
+++ b/src/qemu_conf.c	Sun Jun 22 18:08:24 2008 -0400
@@ -57,6 +57,15 @@
 #include "c-ctype.h"
 #include "xml.h"
 
+VIR_ENUM_DECL(virDomainDiskQEMUBus)
+VIR_ENUM_IMPL(virDomainDiskQEMUBus, VIR_DOMAIN_DISK_BUS_LAST,
+              "ide",
+              "floppy",
+              "scsi",
+              "virtio",
+              "xen")
+
+
 #define qemudLog(level, msg...) fprintf(stderr, msg)
 
 void qemudReportError(virConnectPtr conn,
@@ -64,12 +73,12 @@
                       virNetworkPtr net,
                       int code, const char *fmt, ...) {
     va_list args;
-    char errorMessage[QEMUD_MAX_ERROR_LEN];
+    char errorMessage[1024];
     const char *virerr;
 
     if (fmt) {
         va_start(args, fmt);
-        vsnprintf(errorMessage, QEMUD_MAX_ERROR_LEN-1, fmt, args);
+        vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args);
         va_end(args);
     } else {
         errorMessage[0] = '\0';
@@ -86,7 +95,11 @@
     virConfValuePtr p;
 
     /* Setup 2 critical defaults */
-    strcpy(driver->vncListen, "127.0.0.1");
+    if (!(driver->vncListen = strdup("127.0.0.1"))) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY,
+                         "%s", _("failed to allocate vncListen"));
+        return -1;
+    }
     if (!(driver->vncTLSx509certdir = strdup(SYSCONF_DIR "/pki/libvirt-vnc"))) {
         qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY,
                          "%s", _("failed to allocate vncTLSx509certdir"));
@@ -133,104 +146,17 @@
     p = virConfGetValue (conf, "vnc_listen");
     CHECK_TYPE ("vnc_listen", VIR_CONF_STRING);
     if (p && p->str) {
-        strncpy(driver->vncListen, p->str, sizeof(driver->vncListen));
-        driver->vncListen[sizeof(driver->vncListen)-1] = '\0';
+        if (!(driver->vncListen = strdup(p->str))) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY,
+                             "%s", _("failed to allocate vncTLSx509certdir"));
+            virConfFree(conf);
+            return -1;
+        }
     }
 
     virConfFree (conf);
     return 0;
 }
-
-
-struct qemud_vm *qemudFindVMByID(const struct qemud_driver *driver, int id) {
-    struct qemud_vm *vm = driver->vms;
-
-    while (vm) {
-        if (qemudIsActiveVM(vm) && vm->id == id)
-            return vm;
-        vm = vm->next;
-    }
-
-    return NULL;
-}
-
-struct qemud_vm *qemudFindVMByUUID(const struct qemud_driver *driver,
-                                   const unsigned char *uuid) {
-    struct qemud_vm *vm = driver->vms;
-
-    while (vm) {
-        if (!memcmp(vm->def->uuid, uuid, VIR_UUID_BUFLEN))
-            return vm;
-        vm = vm->next;
-    }
-
-    return NULL;
-}
-
-struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver,
-                                   const char *name) {
-    struct qemud_vm *vm = driver->vms;
-
-    while (vm) {
-        if (STREQ(vm->def->name, name))
-            return vm;
-        vm = vm->next;
-    }
-
-    return NULL;
-}
-
-
-/* Free all memory associated with a struct qemud_vm object */
-void qemudFreeVMDef(struct qemud_vm_def *def) {
-    struct qemud_vm_disk_def *disk = def->disks;
-    struct qemud_vm_net_def *net = def->nets;
-    struct qemud_vm_input_def *input = def->inputs;
-    struct qemud_vm_chr_def *serial = def->serials;
-    struct qemud_vm_chr_def *parallel = def->parallels;
-    struct qemud_vm_sound_def *sound = def->sounds;
-
-    while (disk) {
-        struct qemud_vm_disk_def *prev = disk;
-        disk = disk->next;
-        VIR_FREE(prev);
-    }
-    while (net) {
-        struct qemud_vm_net_def *prev = net;
-        net = net->next;
-        VIR_FREE(prev);
-    }
-    while (input) {
-        struct qemud_vm_input_def *prev = input;
-        input = input->next;
-        VIR_FREE(prev);
-    }
-    while (serial) {
-        struct qemud_vm_chr_def *prev = serial;
-        serial = serial->next;
-        VIR_FREE(prev);
-    }
-    while (parallel) {
-        struct qemud_vm_chr_def *prev = parallel;
-        parallel = parallel->next;
-        VIR_FREE(prev);
-    }
-    while (sound) {
-        struct qemud_vm_sound_def *prev = sound;
-        sound = sound->next;
-        VIR_FREE(prev);
-    }
-    xmlFree(def->keymap);
-    VIR_FREE(def);
-}
-
-void qemudFreeVM(struct qemud_vm *vm) {
-    qemudFreeVMDef(vm->def);
-    if (vm->newDef)
-        qemudFreeVMDef(vm->newDef);
-    VIR_FREE(vm);
-}
-
 
 /* The list of possible machine types for various architectures,
    as supported by QEMU - taken from 'qemu -M ?' for each arch */
@@ -477,12 +403,14 @@
 }
 
 
-static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
+int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
     pid_t child;
     int newstdout[2];
 
-    *flags = 0;
-    *version = 0;
+    if (flags)
+        *flags = 0;
+    if (version)
+        *version = 0;
 
     if (pipe(newstdout) < 0) {
         return -1;
@@ -538,19 +466,22 @@
             goto cleanup2;
         }
 
-        *version = (major * 1000 * 1000) + (minor * 1000) + micro;
-        if (strstr(help, "-no-kqemu"))
-            *flags |= QEMUD_CMD_FLAG_KQEMU;
-        if (strstr(help, "-no-reboot"))
-            *flags |= QEMUD_CMD_FLAG_NO_REBOOT;
-        if (strstr(help, "-name"))
-            *flags |= QEMUD_CMD_FLAG_NAME;
-        if (strstr(help, "-drive"))
-            *flags |= QEMUD_CMD_FLAG_DRIVE;
-        if (strstr(help, "boot=on"))
-            *flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
-        if (*version >= 9000)
-            *flags |= QEMUD_CMD_FLAG_VNC_COLON;
+        if (version)
+            *version = (major * 1000 * 1000) + (minor * 1000) + micro;
+        if (flags) {
+            if (strstr(help, "-no-kqemu"))
+                *flags |= QEMUD_CMD_FLAG_KQEMU;
+            if (strstr(help, "-no-reboot"))
+                *flags |= QEMUD_CMD_FLAG_NO_REBOOT;
+            if (strstr(help, "-name"))
+                *flags |= QEMUD_CMD_FLAG_NAME;
+            if (strstr(help, "-drive"))
+                *flags |= QEMUD_CMD_FLAG_DRIVE;
+            if (strstr(help, "boot=on"))
+                *flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
+            if (*version >= 9000)
+                *flags |= QEMUD_CMD_FLAG_VNC_COLON;
+        }
         ret = 0;
 
         qemudDebug("Version %d %d %d  Cooked version: %d, with flags ? %d",
@@ -612,1620 +543,13 @@
     return 0;
 }
 
-/* Converts def->virtType to applicable string type
- * @param type integer virt type
- * @return string type on success, NULL on fail
- */
-const char * qemudVirtTypeToString(int type) {
-    switch (type) {
-        case QEMUD_VIRT_QEMU:
-            return "qemu";
-        case QEMUD_VIRT_KQEMU:
-            return "kqemu";
-        case QEMUD_VIRT_KVM:
-            return "kvm";
-    }
-    return NULL;
-}
-
-/* Parse the XML definition for a disk
- * @param disk pre-allocated & zero'd disk record
- * @param node XML nodeset to parse for disk definition
- * @return 0 on success, -1 on failure
- */
-static int qemudParseDiskXML(virConnectPtr conn,
-                             struct qemud_vm_disk_def *disk,
-                             xmlNodePtr node) {
-    xmlNodePtr cur;
-    xmlChar *device = NULL;
-    xmlChar *source = NULL;
-    xmlChar *target = NULL;
-    xmlChar *type = NULL;
-    xmlChar *bus = NULL;
-    int typ = 0;
-
-    type = xmlGetProp(node, BAD_CAST "type");
-    if (type != NULL) {
-        if (xmlStrEqual(type, BAD_CAST "file"))
-            typ = QEMUD_DISK_FILE;
-        else if (xmlStrEqual(type, BAD_CAST "block"))
-            typ = QEMUD_DISK_BLOCK;
-        else {
-            typ = QEMUD_DISK_FILE;
-        }
-        xmlFree(type);
-        type = NULL;
-    }
-
-    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 == QEMUD_DISK_FILE)
-                    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");
-                bus = xmlGetProp(cur, BAD_CAST "bus");
-            } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
-                disk->readonly = 1;
-            }
-        }
-        cur = cur->next;
-    }
-
-    if (source == NULL) {
-        /* There is a case without the source
-         * to the CD-ROM device
-         */
-        if (!device || STRNEQ((const char *) device, "cdrom")) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SOURCE,
-                             target ? "%s" : NULL, target);
-            goto error;
-        }
-    }
-
-    if (target == NULL) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_TARGET, source ? "%s" : NULL, source);
-        goto error;
-    }
-
-    if (device &&
-        STREQ((const char *)device, "floppy") &&
-        STRNEQ((const char *)target, "fda") &&
-        STRNEQ((const char *)target, "fdb")) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Invalid floppy device name: %s"), target);
-        goto error;
-    }
-
-    if (device &&
-        STREQ((const char *)device, "cdrom") &&
-        STRNEQ((const char *)target, "hdc")) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Invalid cdrom device name: %s"), target);
-        goto error;
-    }
-
-    if (device &&
-        STREQ((const char *)device, "cdrom"))
-        disk->readonly = 1;
-
-    if ((!device || STREQ((const char *)device, "disk")) &&
-        !STRPREFIX((const char *)target, "hd") &&
-        !STRPREFIX((const char *)target, "sd") &&
-        !STRPREFIX((const char *)target, "vd") &&
-        !STRPREFIX((const char *)target, "xvd")) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Invalid harddisk device name: %s"), target);
-        goto error;
-    }
-
-    strncpy(disk->src, (source ? (const char *) source : "\0"), NAME_MAX-1);
-    disk->src[NAME_MAX-1] = '\0';
-
-    strncpy(disk->dst, (const char *)target, NAME_MAX-1);
-    disk->dst[NAME_MAX-1] = '\0';
-    disk->type = typ;
-
-    if (!device)
-        disk->device = QEMUD_DISK_DISK;
-    else if (STREQ((const char *)device, "disk"))
-        disk->device = QEMUD_DISK_DISK;
-    else if (STREQ((const char *)device, "cdrom"))
-        disk->device = QEMUD_DISK_CDROM;
-    else if (STREQ((const char *)device, "floppy"))
-        disk->device = QEMUD_DISK_FLOPPY;
-    else {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Invalid device type: %s"), device);
-        goto error;
-    }
-
-    if (!bus) {
-        if (disk->device == QEMUD_DISK_FLOPPY) {
-            disk->bus = QEMUD_DISK_BUS_FDC;
-        } else {
-            if (STRPREFIX((const char *)target, "hd"))
-                disk->bus = QEMUD_DISK_BUS_IDE;
-            else if (STRPREFIX((const char *)target, "sd"))
-                disk->bus = QEMUD_DISK_BUS_SCSI;
-            else if (STRPREFIX((const char *)target, "vd"))
-                disk->bus = QEMUD_DISK_BUS_VIRTIO;
-            else if (STRPREFIX((const char *)target, "xvd"))
-                disk->bus = QEMUD_DISK_BUS_XEN;
-            else
-                disk->bus = QEMUD_DISK_BUS_IDE;
-        }
-    } else if (STREQ((const char *)bus, "ide"))
-        disk->bus = QEMUD_DISK_BUS_IDE;
-    else if (STREQ((const char *)bus, "fdc"))
-        disk->bus = QEMUD_DISK_BUS_FDC;
-    else if (STREQ((const char *)bus, "scsi"))
-        disk->bus = QEMUD_DISK_BUS_SCSI;
-    else if (STREQ((const char *)bus, "virtio"))
-        disk->bus = QEMUD_DISK_BUS_VIRTIO;
-    else if (STREQ((const char *)bus, "xen"))
-        disk->bus = QEMUD_DISK_BUS_XEN;
-    else {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Invalid bus type: %s"), bus);
-        goto error;
-    }
-
-    if (disk->device == QEMUD_DISK_FLOPPY &&
-        disk->bus != QEMUD_DISK_BUS_FDC) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Invalid bus type '%s' for floppy disk"), bus);
-        goto error;
-    }
-
-    xmlFree(device);
-    xmlFree(target);
-    xmlFree(source);
-    xmlFree(bus);
-
-    return 0;
-
- error:
-    xmlFree(bus);
-    xmlFree(type);
-    xmlFree(target);
-    xmlFree(source);
-    xmlFree(device);
-    return -1;
-}
-
-static void qemudRandomMAC(struct qemud_vm_net_def *net) {
-    net->mac[0] = 0x52;
-    net->mac[1] = 0x54;
-    net->mac[2] = 0x00;
-    net->mac[3] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
-    net->mac[4] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
-    net->mac[5] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
-}
-
-
-/* Parse the XML definition for a network interface
- * @param net pre-allocated & zero'd net record
- * @param node XML nodeset to parse for net definition
- * @return 0 on success, -1 on failure
- */
-static int qemudParseInterfaceXML(virConnectPtr conn,
-                                  struct qemud_vm_net_def *net,
-                                  xmlNodePtr node) {
-    xmlNodePtr cur;
-    xmlChar *macaddr = NULL;
-    xmlChar *type = NULL;
-    xmlChar *network = NULL;
-    xmlChar *bridge = NULL;
-    xmlChar *ifname = NULL;
-    xmlChar *script = NULL;
-    xmlChar *address = NULL;
-    xmlChar *port = NULL;
-    xmlChar *model = NULL;
-
-    net->type = QEMUD_NET_USER;
-
-    type = xmlGetProp(node, BAD_CAST "type");
-    if (type != NULL) {
-        if (xmlStrEqual(type, BAD_CAST "user"))
-            net->type = QEMUD_NET_USER;
-        else if (xmlStrEqual(type, BAD_CAST "ethernet"))
-            net->type = QEMUD_NET_ETHERNET;
-        else if (xmlStrEqual(type, BAD_CAST "server"))
-            net->type = QEMUD_NET_SERVER;
-        else if (xmlStrEqual(type, BAD_CAST "client"))
-            net->type = QEMUD_NET_CLIENT;
-        else if (xmlStrEqual(type, BAD_CAST "mcast"))
-            net->type = QEMUD_NET_MCAST;
-        else if (xmlStrEqual(type, BAD_CAST "network"))
-            net->type = QEMUD_NET_NETWORK;
-        else if (xmlStrEqual(type, BAD_CAST "bridge"))
-            net->type = QEMUD_NET_BRIDGE;
-        else
-            net->type = QEMUD_NET_USER;
-        xmlFree(type);
-        type = NULL;
-    }
-
-    cur = node->children;
-    while (cur != NULL) {
-        if (cur->type == XML_ELEMENT_NODE) {
-            if ((macaddr == NULL) &&
-                (xmlStrEqual(cur->name, BAD_CAST "mac"))) {
-                macaddr = xmlGetProp(cur, BAD_CAST "address");
-            } else if ((network == NULL) &&
-                       (net->type == QEMUD_NET_NETWORK) &&
-                       (xmlStrEqual(cur->name, BAD_CAST "source"))) {
-                network = xmlGetProp(cur, BAD_CAST "network");
-            } else if ((network == NULL) &&
-                       (net->type == QEMUD_NET_BRIDGE) &&
-                       (xmlStrEqual(cur->name, BAD_CAST "source"))) {
-                bridge = xmlGetProp(cur, BAD_CAST "bridge");
-            } else if ((network == NULL) &&
-                       ((net->type == QEMUD_NET_SERVER) ||
-                        (net->type == QEMUD_NET_CLIENT) ||
-                        (net->type == QEMUD_NET_MCAST)) &&
-                       (xmlStrEqual(cur->name, BAD_CAST "source"))) {
-                address = xmlGetProp(cur, BAD_CAST "address");
-                port = xmlGetProp(cur, BAD_CAST "port");
-            } else if ((ifname == NULL) &&
-                       ((net->type == QEMUD_NET_NETWORK) ||
-                        (net->type == QEMUD_NET_ETHERNET) ||
-                        (net->type == QEMUD_NET_BRIDGE)) &&
-                       xmlStrEqual(cur->name, BAD_CAST "target")) {
-                ifname = xmlGetProp(cur, BAD_CAST "dev");
-                if (STRPREFIX((const char*)ifname, "vnet")) {
-                    /* An auto-generated target name, blank it out */
-                    xmlFree(ifname);
-                    ifname = NULL;
-                }
-            } else if ((script == NULL) &&
-                       (net->type == QEMUD_NET_ETHERNET) &&
-                       xmlStrEqual(cur->name, BAD_CAST "script")) {
-                script = xmlGetProp(cur, BAD_CAST "path");
-            } else if (xmlStrEqual (cur->name, BAD_CAST "model")) {
-                model = xmlGetProp (cur, BAD_CAST "type");
-            }
-        }
-        cur = cur->next;
-    }
-
-    if (macaddr) {
-        unsigned int mac[6];
-        sscanf((const char *)macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
-               (unsigned int*)&mac[0],
-               (unsigned int*)&mac[1],
-               (unsigned int*)&mac[2],
-               (unsigned int*)&mac[3],
-               (unsigned int*)&mac[4],
-               (unsigned int*)&mac[5]);
-        net->mac[0] = mac[0];
-        net->mac[1] = mac[1];
-        net->mac[2] = mac[2];
-        net->mac[3] = mac[3];
-        net->mac[4] = mac[4];
-        net->mac[5] = mac[5];
-
-        xmlFree(macaddr);
-        macaddr = NULL;
-    } else {
-        qemudRandomMAC(net);
-    }
-
-    if (net->type == QEMUD_NET_NETWORK) {
-        int len;
-
-        if (network == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("No <source> 'network' attribute specified with <interface type='network'/>"));
-            goto error;
-        } else if ((len = xmlStrlen(network)) >= (QEMUD_MAX_NAME_LEN-1)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("Network name '%s' too long"), network);
-            goto error;
-        } else {
-            strncpy(net->dst.network.name, (char *)network, len);
-            net->dst.network.name[len] = '\0';
-        }
-
-        if (network) {
-            xmlFree(network);
-            network = NULL;
-        }
-
-        if (ifname != NULL) {
-            if ((len = xmlStrlen(ifname)) >= (BR_IFNAME_MAXLEN-1)) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("TAP interface name '%s' is too long"),
-                                 ifname);
-                goto error;
-            } else {
-                strncpy(net->dst.network.ifname, (char *)ifname, len);
-                net->dst.network.ifname[len] = '\0';
-            }
-            xmlFree(ifname);
-            ifname = NULL;
-        }
-    } else if (net->type == QEMUD_NET_ETHERNET) {
-        int len;
-
-        if (script != NULL) {
-            if ((len = xmlStrlen(script)) >= (PATH_MAX-1)) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("TAP script path '%s' is too long"), script);
-                goto error;
-            } else {
-                strncpy(net->dst.ethernet.script, (char *)script, len);
-                net->dst.ethernet.script[len] = '\0';
-            }
-            xmlFree(script);
-            script = NULL;
-        }
-        if (ifname != NULL) {
-            if ((len = xmlStrlen(ifname)) >= (BR_IFNAME_MAXLEN-1)) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("TAP interface name '%s' is too long"),
-                                 ifname);
-                goto error;
-            } else {
-                strncpy(net->dst.ethernet.ifname, (char *)ifname, len);
-                net->dst.ethernet.ifname[len] = '\0';
-            }
-            xmlFree(ifname);
-        }
-    } else if (net->type == QEMUD_NET_BRIDGE) {
-        int len;
-
-        if (bridge == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("No <source> 'dev' attribute specified with <interface type='bridge'/>"));
-            goto error;
-        } else if ((len = xmlStrlen(bridge)) >= (BR_IFNAME_MAXLEN-1)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("TAP bridge path '%s' is too long"), bridge);
-            goto error;
-        } else {
-            strncpy(net->dst.bridge.brname, (char *)bridge, len);
-            net->dst.bridge.brname[len] = '\0';
-        }
-
-        xmlFree(bridge);
-        bridge = NULL;
-
-        if (ifname != NULL) {
-            if ((len = xmlStrlen(ifname)) >= (BR_IFNAME_MAXLEN-1)) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("TAP interface name '%s' is too long"), ifname);
-                goto error;
-            } else {
-                strncpy(net->dst.bridge.ifname, (char *)ifname, len);
-                net->dst.bridge.ifname[len] = '\0';
-            }
-            xmlFree(ifname);
-        }
-    } else if (net->type == QEMUD_NET_CLIENT ||
-               net->type == QEMUD_NET_SERVER ||
-               net->type == QEMUD_NET_MCAST) {
-        int len = 0;
-        char *ret;
-
-        if (port == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("No <source> 'port' attribute specified with socket interface"));
-            goto error;
-        }
-        if (!(net->dst.socket.port = strtol((char*)port, &ret, 10)) &&
-            ret == (char*)port) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("Cannot parse <source> 'port' attribute with socket interface"));
-            goto error;
-        }
-        xmlFree(port);
-        port = NULL;
-
-        if (address == NULL) {
-            if (net->type == QEMUD_NET_CLIENT ||
-                net->type == QEMUD_NET_MCAST) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("No <source> 'address' attribute specified with socket interface"));
-                goto error;
-            }
-        } else if ((len = xmlStrlen(address)) >= (BR_INET_ADDR_MAXLEN)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("IP address '%s' is too long"), address);
-            goto error;
-        }
-        if (address == NULL) {
-            net->dst.socket.address[0] = '\0';
-        } else {
-            strncpy(net->dst.socket.address, (char*)address,len);
-            net->dst.socket.address[len] = '\0';
-        }
-        xmlFree(address);
-    }
-
-    /* NIC model (see -net nic,model=?).  We only check that it looks
-     * reasonable, not that it is a supported NIC type.  FWIW kvm
-     * supports these types as of April 2008:
-     * i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio
-     */
-    if (model != NULL) {
-        int i, len;
-
-        len = xmlStrlen (model);
-        if (len >= QEMUD_MODEL_MAX_LEN) {
-            qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG,
-                              _("Model name '%s' is too long"), model);
-            goto error;
-        }
-        for (i = 0; i < len; ++i) {
-            int char_ok = c_isalnum(model[i]) || model[i] == '_';
-            if (!char_ok) {
-                qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG, "%s",
-                                  _("Model name contains invalid characters"));
-                goto error;
-            }
-        }
-        strncpy (net->model, (const char*) model, len);
-        net->model[len] = '\0';
-
-        xmlFree (model);
-        model = NULL;
-    } else
-        net->model[0] = '\0';
-
-    return 0;
-
- error:
-    xmlFree(network);
-    xmlFree(address);
-    xmlFree(port);
-    xmlFree(ifname);
-    xmlFree(script);
-    xmlFree(bridge);
-    xmlFree(model);
-    return -1;
-}
-
-
-/* Parse the XML definition for a character device
- * @param net pre-allocated & zero'd net record
- * @param node XML nodeset to parse for net definition
- * @return 0 on success, -1 on failure
- *
- * The XML we're dealing with looks like
- *
- * <serial type="pty">
- *   <source path="/dev/pts/3"/>
- *   <target port="1"/>
- * </serial>
- *
- * <serial type="dev">
- *   <source path="/dev/ttyS0"/>
- *   <target port="1"/>
- * </serial>
- *
- * <serial type="tcp">
- *   <source mode="connect" host="0.0.0.0" service="2445"/>
- *   <target port="1"/>
- * </serial>
- *
- * <serial type="tcp">
- *   <source mode="bind" host="0.0.0.0" service="2445"/>
- *   <target port="1"/>
- * </serial>
- *
- * <serial type="udp">
- *   <source mode="bind" host="0.0.0.0" service="2445"/>
- *   <source mode="connect" host="0.0.0.0" service="2445"/>
- *   <target port="1"/>
- * </serial>
- *
- * <serial type="unix">
- *   <source mode="bind" path="/tmp/foo"/>
- *   <target port="1"/>
- * </serial>
- *
- */
-static int qemudParseCharXML(virConnectPtr conn,
-                             struct qemud_vm_chr_def *chr,
-                             int portNum,
-                             xmlNodePtr node) {
-    xmlNodePtr cur;
-    xmlChar *type = NULL;
-    xmlChar *bindHost = NULL;
-    xmlChar *bindService = NULL;
-    xmlChar *connectHost = NULL;
-    xmlChar *connectService = NULL;
-    xmlChar *path = NULL;
-    xmlChar *mode = NULL;
-    xmlChar *protocol = NULL;
-    int ret = -1;
-
-    chr->srcType = QEMUD_CHR_SRC_TYPE_PTY;
-    type = xmlGetProp(node, BAD_CAST "type");
-    if (type != NULL) {
-        if (xmlStrEqual(type, BAD_CAST "null"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_NULL;
-        else if (xmlStrEqual(type, BAD_CAST "vc"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_VC;
-        else if (xmlStrEqual(type, BAD_CAST "pty"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_PTY;
-        else if (xmlStrEqual(type, BAD_CAST "dev"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_DEV;
-        else if (xmlStrEqual(type, BAD_CAST "file"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_FILE;
-        else if (xmlStrEqual(type, BAD_CAST "pipe"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_PIPE;
-        else if (xmlStrEqual(type, BAD_CAST "stdio"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_STDIO;
-        else if (xmlStrEqual(type, BAD_CAST "udp"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_UDP;
-        else if (xmlStrEqual(type, BAD_CAST "tcp"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_TCP;
-        else if (xmlStrEqual(type, BAD_CAST "unix"))
-            chr->srcType = QEMUD_CHR_SRC_TYPE_UNIX;
-        else
-            chr->srcType = QEMUD_CHR_SRC_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");
-
-                switch (chr->srcType) {
-                case QEMUD_CHR_SRC_TYPE_PTY:
-                case QEMUD_CHR_SRC_TYPE_DEV:
-                case QEMUD_CHR_SRC_TYPE_FILE:
-                case QEMUD_CHR_SRC_TYPE_PIPE:
-                case QEMUD_CHR_SRC_TYPE_UNIX:
-                    if (path == NULL)
-                        path = xmlGetProp(cur, BAD_CAST "path");
-
-                    break;
-
-                case QEMUD_CHR_SRC_TYPE_UDP:
-                case QEMUD_CHR_SRC_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 (chr->srcType == QEMUD_CHR_SRC_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;
-    }
-
-
-    chr->dstPort = portNum;
-
-    switch (chr->srcType) {
-    case QEMUD_CHR_SRC_TYPE_NULL:
-        /* Nada */
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_VC:
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_PTY:
-        /* @path attribute is an output only property - pty is auto-allocted */
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_DEV:
-    case QEMUD_CHR_SRC_TYPE_FILE:
-    case QEMUD_CHR_SRC_TYPE_PIPE:
-        if (path == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("Missing source path attribute for char device"));
-            goto cleanup;
-        }
-
-        strncpy(chr->srcData.file.path, (const char *)path,
-                sizeof(chr->srcData.file.path));
-        NUL_TERMINATE(chr->srcData.file.path);
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_STDIO:
-        /* Nada */
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_TCP:
-        if (mode == NULL ||
-            STREQ((const char *)mode, "connect")) {
-            if (connectHost == NULL) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("Missing source host attribute for char device"));
-                goto cleanup;
-            }
-            if (connectService == NULL) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("Missing source service attribute for char device"));
-                goto cleanup;
-            }
-
-            strncpy(chr->srcData.tcp.host, (const char *)connectHost,
-                    sizeof(chr->srcData.tcp.host));
-            NUL_TERMINATE(chr->srcData.tcp.host);
-            strncpy(chr->srcData.tcp.service, (const char *)connectService,
-                    sizeof(chr->srcData.tcp.service));
-            NUL_TERMINATE(chr->srcData.tcp.service);
-
-            chr->srcData.tcp.listen = 0;
-        } else {
-            if (bindHost == NULL) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("Missing source host attribute for char device"));
-                goto cleanup;
-            }
-            if (bindService == NULL) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("Missing source service attribute for char device"));
-                goto cleanup;
-            }
-
-            strncpy(chr->srcData.tcp.host, (const char *)bindHost,
-                    sizeof(chr->srcData.tcp.host));
-            NUL_TERMINATE(chr->srcData.tcp.host);
-            strncpy(chr->srcData.tcp.service, (const char *)bindService,
-                    sizeof(chr->srcData.tcp.service));
-            NUL_TERMINATE(chr->srcData.tcp.service);
-
-            chr->srcData.tcp.listen = 1;
-        }
-        if (protocol != NULL &&
-            STREQ((const char *)protocol, "telnet"))
-            chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET;
-        else
-            chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_RAW;
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_UDP:
-        if (connectService == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("Missing source service attribute for char device"));
-            goto cleanup;
-        }
-
-        if (connectHost != NULL) {
-            strncpy(chr->srcData.udp.connectHost, (const char *)connectHost,
-                    sizeof(chr->srcData.udp.connectHost));
-            NUL_TERMINATE(chr->srcData.udp.connectHost);
-        }
-        strncpy(chr->srcData.udp.connectService, (const char *)connectService,
-                sizeof(chr->srcData.udp.connectService));
-        NUL_TERMINATE(chr->srcData.udp.connectService);
-
-        if (bindHost != NULL) {
-            strncpy(chr->srcData.udp.bindHost, (const char *)bindHost,
-                    sizeof(chr->srcData.udp.bindHost));
-            NUL_TERMINATE(chr->srcData.udp.bindHost);
-        }
-        if (bindService != NULL) {
-            strncpy(chr->srcData.udp.bindService, (const char *)bindService,
-                    sizeof(chr->srcData.udp.bindService));
-            NUL_TERMINATE(chr->srcData.udp.bindService);
-        }
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_UNIX:
-        if (path == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("Missing source path attribute for char device"));
-            goto cleanup;
-        }
-
-        if (mode != NULL &&
-            STRNEQ((const char *)mode, "connect"))
-            chr->srcData.nix.listen = 1;
-        else
-            chr->srcData.nix.listen = 0;
-
-        strncpy(chr->srcData.nix.path, (const char *)path,
-                sizeof(chr->srcData.nix.path));
-        NUL_TERMINATE(chr->srcData.nix.path);
-        break;
-    }
-
-    ret = 0;
-
-cleanup:
-    xmlFree(mode);
-    xmlFree(protocol);
-    xmlFree(type);
-    xmlFree(bindHost);
-    xmlFree(bindService);
-    xmlFree(connectHost);
-    xmlFree(connectService);
-    xmlFree(path);
-
-    return ret;
-}
-
-
-static int qemudParseCharXMLDevices(virConnectPtr conn,
-                                    xmlXPathContextPtr ctxt,
-                                    const char *xpath,
-                                    unsigned int *ndevs,
-                                    struct qemud_vm_chr_def **devs)
-{
-    xmlXPathObjectPtr obj;
-    int i, ret = -1;
-
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
-        struct qemud_vm_chr_def *prev = *devs;
-        if (ndevs == NULL &&
-            obj->nodesetval->nodeNr > 1) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("too many character devices"));
-            goto cleanup;
-        }
-
-        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-            struct qemud_vm_chr_def *chr;
-            if (VIR_ALLOC(chr) < 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                                 "%s",
-                                 _("failed to allocate space for char device"));
-                goto cleanup;
-            }
-
-            if (qemudParseCharXML(conn, chr, i, obj->nodesetval->nodeTab[i]) < 0) {
-                VIR_FREE(chr);
-                goto cleanup;
-            }
-            if (ndevs)
-                (*ndevs)++;
-            chr->next = NULL;
-            if (i == 0) {
-                *devs = chr;
-            } else {
-                prev->next = chr;
-            }
-            prev = chr;
-        }
-    }
-
-    ret = 0;
-
-cleanup:
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-
-/* Parse the XML definition for a network interface */
-static int qemudParseInputXML(virConnectPtr conn,
-                              const struct qemud_vm_def *vm,
-                              struct qemud_vm_input_def *input,
-                              xmlNodePtr node) {
-    xmlChar *type = NULL;
-    xmlChar *bus = NULL;
-
-    type = xmlGetProp(node, BAD_CAST "type");
-    bus = xmlGetProp(node, BAD_CAST "bus");
-
-    if (!type) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("missing input device type"));
-        goto error;
-    }
-
-    if (STREQ((const char *)type, "mouse")) {
-        input->type = QEMU_INPUT_TYPE_MOUSE;
-    } else if (STREQ((const char *)type, "tablet")) {
-        input->type = QEMU_INPUT_TYPE_TABLET;
-    } else {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("unsupported input device type %s"),
-                         (const char*)type);
-        goto error;
-    }
-
-    if (bus) {
-        if (STREQ(vm->os.type, "hvm")) {
-            if (STREQ((const char*)bus, "ps2")) { /* Only allow mouse */
-                if (input->type != QEMU_INPUT_TYPE_MOUSE) {
-                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                     _("ps2 bus does not support %s input device"),
-                                     (const char*)type);
-                    goto error;
-                }
-                input->bus = QEMU_INPUT_BUS_PS2;
-            } else if (STREQ((const char *)bus, "usb")) { /* Allow mouse & tablet */
-                input->bus = QEMU_INPUT_BUS_USB;
-            } else {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("unsupported input bus %s"), (const char*)bus);
-                goto error;
-            }
-        } else {
-            if (STREQ((const char *)bus, "xen")) { /* Allow mouse only */
-                input->bus = QEMU_INPUT_BUS_XEN;
-                if (input->type != QEMU_INPUT_TYPE_MOUSE) {
-                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                     _("xen bus does not support %s input device"),
-                                     (const char*)type);
-                    goto error;
-                }
-            } else {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("unsupported input bus %s"), (const char*)bus);
-                goto error;
-            }
-        }
-    } else {
-        if (STREQ(vm->os.type, "hvm")) {
-            if (input->type == QEMU_INPUT_TYPE_MOUSE)
-                input->bus = QEMU_INPUT_BUS_PS2;
-            else
-                input->bus = QEMU_INPUT_BUS_USB;
-        } else {
-            input->bus = QEMU_INPUT_BUS_XEN;
-        }
-    }
-
-    xmlFree(type);
-    xmlFree(bus);
-
-    return 0;
-
- error:
-    xmlFree(type);
-    xmlFree(bus);
-
-    return -1;
-}
-
-static int qemudDiskCompare(const void *aptr, const void *bptr) {
-    struct qemud_vm_disk_def *a = (struct qemud_vm_disk_def *) aptr;
-    struct qemud_vm_disk_def *b = (struct qemud_vm_disk_def *) bptr;
-    if (a->bus == b->bus)
-        return virDiskNameToIndex(a->dst) - virDiskNameToIndex(b->dst);
-    else
-        return a->bus - b->bus;
-}
-
-static const char *qemudBusIdToName(int busId, int qemuIF) {
-    const char *busnames[] = { "ide",
-                               (qemuIF ? "floppy" : "fdc"),
-                               "scsi",
-                               "virtio",
-                               "xen"};
-    verify_true(ARRAY_CARDINALITY(busnames) == QEMUD_DISK_BUS_LAST);
-
-    return busnames[busId];
-}
-
-/* Sound device helper functions */
-static int qemudSoundModelFromString(const char *model) {
-    if (STREQ(model, "sb16")) {
-        return QEMU_SOUND_SB16;
-    } else if (STREQ(model, "es1370")) {
-        return QEMU_SOUND_ES1370;
-    } else if (STREQ(model, "pcspk")) {
-        return QEMU_SOUND_PCSPK;
-    }
-
-    return -1;
-}
-
-static const char *qemudSoundModelToString(const int model) {
-
-    if (model == QEMU_SOUND_SB16) {
-        return "sb16";
-    } else if (model == QEMU_SOUND_ES1370) {
-        return "es1370";
-    } else if (model == QEMU_SOUND_PCSPK) {
-        return "pcspk";
-    }
-
-    return NULL;
-}
-
-
-static int qemudParseSoundXML(virConnectPtr conn,
-                              struct qemud_vm_sound_def *sound,
-                              const xmlNodePtr node) {
-
-    int err = -1;
-    xmlChar *model = NULL;
-    model = xmlGetProp(node, BAD_CAST "model");
-
-    if (!model) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("missing sound model"));
-        goto error;
-    }
-    if ((sound->model = qemudSoundModelFromString((char *) model)) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("invalid sound model '%s'"), (char *) model);
-        goto error;
-    }
-
-    err = 0;
- error:
-    xmlFree(model);
-    return err;
-}
-
-/*
- * Parses a libvirt XML definition of a guest, and populates the
- * the qemud_vm struct with matching data about the guests config
- */
-static struct qemud_vm_def *qemudParseXML(virConnectPtr conn,
-                                          struct qemud_driver *driver,
-                                          xmlDocPtr xml) {
-    xmlNodePtr root = NULL;
-    xmlChar *prop = NULL;
-    xmlXPathContextPtr ctxt = NULL;
-    xmlXPathObjectPtr obj = NULL;
-    char *conv = NULL;
-    int i;
-    struct qemud_vm_def *def;
-
-    if (VIR_ALLOC(def) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                         "%s", _("failed to allocate space for xmlXPathContext"));
-        return NULL;
-    }
-
-    /* Prepare parser / xpath context */
-    root = xmlDocGetRootElement(xml);
-    if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("incorrect root element"));
-        goto error;
-    }
-
-    ctxt = xmlXPathNewContext(xml);
-    if (ctxt == NULL) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                         "%s", _("failed to allocate space for xmlXPathContext"));
-        goto error;
-    }
-
-
-    /* Find out what type of QEMU virtualization to use */
-    if (!(prop = xmlGetProp(root, BAD_CAST "type"))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("missing domain type attribute"));
-        goto error;
-    }
-
-    if (STREQ((char *)prop, "qemu"))
-        def->virtType = QEMUD_VIRT_QEMU;
-    else if (STREQ((char *)prop, "kqemu"))
-        def->virtType = QEMUD_VIRT_KQEMU;
-    else if (STREQ((char *)prop, "kvm"))
-        def->virtType = QEMUD_VIRT_KVM;
-    else {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("invalid domain type attribute"));
-        goto error;
-    }
-    VIR_FREE(prop);
-
-
-    /* Extract domain name */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_NAME, NULL);
-        goto error;
-    }
-    if (strlen((const char *)obj->stringval) >= (QEMUD_MAX_NAME_LEN-1)) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("domain name length too long"));
-        goto error;
-    }
-    strcpy(def->name, (const char *)obj->stringval);
-    xmlXPathFreeObject(obj);
-
-
-    /* Extract domain uuid */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/uuid[1])", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        int err;
-        if ((err = virUUIDGenerate(def->uuid))) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("Failed to generate UUID: %s"), strerror(err));
-            goto error;
-        }
-    } else if (virUUIDParse((const char *)obj->stringval, def->uuid) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("malformed uuid element"));
-        goto error;
-    }
-    xmlXPathFreeObject(obj);
-
-
-    /* Extract domain memory */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/memory[1])", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("missing memory element"));
-        goto error;
-    } else {
-        conv = NULL;
-        def->maxmem = strtoll((const char*)obj->stringval, &conv, 10);
-        if (conv == (const char*)obj->stringval) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("malformed memory information"));
-            goto error;
-        }
-    }
-    xmlXPathFreeObject(obj);
-
-
-    /* Extract domain memory */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/currentMemory[1])", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        def->memory = def->maxmem;
-    } else {
-        conv = NULL;
-        def->memory = strtoll((const char*)obj->stringval, &conv, 10);
-        if (def->memory > def->maxmem)
-            def->memory = def->maxmem;
-        if (conv == (const char*)obj->stringval) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("malformed memory information"));
-            goto error;
-        }
-    }
-    xmlXPathFreeObject(obj);
-
-    /* Extract domain vcpu info */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        def->vcpus = 1;
-    } else {
-        conv = NULL;
-        def->vcpus = strtoll((const char*)obj->stringval, &conv, 10);
-        if (conv == (const char*)obj->stringval) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("malformed vcpu information"));
-            goto error;
-        }
-    }
-    xmlXPathFreeObject(obj);
-
-    /* Extract domain vcpu info */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1]/@cpuset)", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        /* Allow use on all CPUS */
-        memset(def->cpumask, 1, QEMUD_CPUMASK_LEN);
-    } else {
-        char *set = (char *)obj->stringval;
-        memset(def->cpumask, 0, QEMUD_CPUMASK_LEN);
-        if (virParseCpuSet(conn, (const char **)&set,
-                           0, def->cpumask,
-                           QEMUD_CPUMASK_LEN) < 0) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("malformed vcpu mask information"));
-            goto error;
-        }
-    }
-    xmlXPathFreeObject(obj);
-
-    /* See if ACPI feature is requested */
-    obj = xmlXPathEval(BAD_CAST "/domain/features/acpi", ctxt);
-    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
-        def->features |= QEMUD_FEATURE_ACPI;
-    }
-    xmlXPathFreeObject(obj);
-
-
-    /* See if we disable reboots */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/on_reboot)", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        def->noReboot = 0;
-    } else {
-        if (STREQ((char*)obj->stringval, "destroy"))
-            def->noReboot = 1;
-        else
-            def->noReboot = 0;
-    }
-    xmlXPathFreeObject(obj);
-
-    /* See if we set clock to localtime */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/clock/@offset)", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        def->localtime = 0;
-    } else {
-        if (STREQ((char*)obj->stringval, "localtime"))
-            def->localtime = 1;
-        else
-            def->localtime = 0;
-    }
-    xmlXPathFreeObject(obj);
-
-
-    /* Extract bootloader */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/bootloader)", ctxt);
-    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-        strncpy(def->os.bootloader, (const char*)obj->stringval, sizeof(def->os.bootloader));
-        NUL_TERMINATE(def->os.bootloader);
-
-        /* Set a default OS type, since <type> is optional with bootloader */
-        strcpy(def->os.type, "xen");
-    }
-    xmlXPathFreeObject(obj);
-
-    /* Extract OS type info */
-    obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1])", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        if (!def->os.type[0]) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
-                             "%s", _("no OS type"));
-            goto error;
-        }
-    } else {
-        strcpy(def->os.type, (const char *)obj->stringval);
-    }
-    xmlXPathFreeObject(obj);
-    obj = NULL;
-
-    if (!virCapabilitiesSupportsGuestOSType(driver->caps, def->os.type)) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
-                         "%s", def->os.type);
-        goto error;
-    }
-
-    obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1]/@arch)", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        const char *defaultArch = virCapabilitiesDefaultGuestArch(driver->caps, def->os.type);
-        if (defaultArch == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("unsupported architecture"));
-            goto error;
-        }
-        if (strlen(defaultArch) >= (QEMUD_OS_TYPE_MAX_LEN-1)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("architecture type too long"));
-            goto error;
-        }
-        strcpy(def->os.arch, defaultArch);
-    } else {
-        if (strlen((const char *)obj->stringval) >= (QEMUD_OS_TYPE_MAX_LEN-1)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("architecture type too long"));
-            goto error;
-        }
-        strcpy(def->os.arch, (const char *)obj->stringval);
-    }
-    xmlXPathFreeObject(obj);
-
-    obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1]/@machine)", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        const char *defaultMachine = virCapabilitiesDefaultGuestMachine(driver->caps,
-                                                                        def->os.type,
-                                                                        def->os.arch);
-        if (defaultMachine == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("unsupported architecture"));
-            goto error;
-        }
-        if (strlen(defaultMachine) >= (QEMUD_OS_MACHINE_MAX_LEN-1)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("machine type too long"));
-            goto error;
-        }
-        strcpy(def->os.machine, defaultMachine);
-    } else {
-        if (strlen((const char *)obj->stringval) >= (QEMUD_OS_MACHINE_MAX_LEN-1)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("architecture type too long"));
-            goto error;
-        }
-        strcpy(def->os.machine, (const char *)obj->stringval);
-    }
-    xmlXPathFreeObject(obj);
-
-
-    if (!def->os.bootloader[0]) {
-        obj = xmlXPathEval(BAD_CAST "string(/domain/os/kernel[1])", ctxt);
-        if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-            (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-            if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("kernel path too long"));
-                goto error;
-            }
-            strcpy(def->os.kernel, (const char *)obj->stringval);
-        }
-        xmlXPathFreeObject(obj);
-
-
-        obj = xmlXPathEval(BAD_CAST "string(/domain/os/initrd[1])", ctxt);
-        if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-            (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-            if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("initrd path too long"));
-                goto error;
-            }
-            strcpy(def->os.initrd, (const char *)obj->stringval);
-        }
-        xmlXPathFreeObject(obj);
-
-
-        obj = xmlXPathEval(BAD_CAST "string(/domain/os/cmdline[1])", ctxt);
-        if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-            (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-            if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("cmdline arguments too long"));
-                goto error;
-            }
-            strcpy(def->os.cmdline, (const char *)obj->stringval);
-        }
-        xmlXPathFreeObject(obj);
-
-
-        /* analysis of the disk devices */
-        obj = xmlXPathEval(BAD_CAST "/domain/os/boot", ctxt);
-        if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-            (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
-            for (i = 0; i < obj->nodesetval->nodeNr && i < QEMUD_MAX_BOOT_DEVS ; i++) {
-                if (!(prop = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "dev")))
-                    continue;
-                if (STREQ((char *)prop, "hd")) {
-                    def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_DISK;
-                } else if (STREQ((char *)prop, "fd")) {
-                    def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
-                } else if (STREQ((char *)prop, "cdrom")) {
-                    def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_CDROM;
-                } else if (STREQ((char *)prop, "network")) {
-                    def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_NET;
-                } else {
-                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                     _("unknown boot device \'%s\'"), (char*)prop);
-                    goto error;
-                }
-                xmlFree(prop);
-                prop = NULL;
-            }
-        }
-        xmlXPathFreeObject(obj);
-        if (def->os.nBootDevs == 0) {
-            def->os.nBootDevs = 1;
-            def->os.bootDevs[0] = QEMUD_BOOT_DISK;
-        }
-    }
-
-    obj = xmlXPathEval(BAD_CAST "string(/domain/devices/emulator[1])", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        const char *type = qemudVirtTypeToString(def->virtType);
-        if (!type) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("unknown virt type"));
-            goto error;
-        }
-        const char *emulator = virCapabilitiesDefaultGuestEmulator(driver->caps,
-                                                                   def->os.type,
-                                                                   def->os.arch,
-                                                                   type);
-        if (!emulator) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("unsupported guest type"));
-            goto error;
-        }
-        strcpy(def->os.binary, emulator);
-    } else {
-        if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("emulator path too long"));
-            goto error;
-        }
-        strcpy(def->os.binary, (const char *)obj->stringval);
-    }
-    xmlXPathFreeObject(obj);
-
-    obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics", ctxt);
-    if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
-        (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) {
-        def->graphicsType = QEMUD_GRAPHICS_NONE;
-    } else if ((prop = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "type"))) {
-        if (STREQ((char *)prop, "vnc")) {
-            xmlChar *vncport, *vnclisten;
-            def->graphicsType = QEMUD_GRAPHICS_VNC;
-            vncport = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "port");
-            if (vncport) {
-                conv = NULL;
-                def->vncPort = strtoll((const char*)vncport, &conv, 10);
-            } else {
-                def->vncPort = -1;
-            }
-            vnclisten = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "listen");
-            if (vnclisten && *vnclisten)
-                strncpy(def->vncListen, (char *)vnclisten, BR_INET_ADDR_MAXLEN-1);
-            else
-                strcpy(def->vncListen, driver->vncListen);
-            def->vncListen[BR_INET_ADDR_MAXLEN-1] = '\0';
-            def->keymap = (char *) xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "keymap");
-            xmlFree(vncport);
-            xmlFree(vnclisten);
-        } else if (STREQ((char *)prop, "sdl")) {
-            def->graphicsType = QEMUD_GRAPHICS_SDL;
-        } else {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("Unsupported graphics type %s"), prop);
-            goto error;
-        }
-        xmlFree(prop);
-        prop = NULL;
-    }
-    xmlXPathFreeObject(obj);
-
-    /* analysis of the disk devices */
-    obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
-    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
-        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-            struct qemud_vm_disk_def *disk;
-            if (VIR_ALLOC(disk) < 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                           "%s", _("failed to allocate space for disk string"));
-                goto error;
-            }
-            if (qemudParseDiskXML(conn, disk, obj->nodesetval->nodeTab[i]) < 0) {
-                VIR_FREE(disk);
-                goto error;
-            }
-            def->ndisks++;
-            if (i == 0) {
-                disk->next = NULL;
-                def->disks = disk;
-            } else {
-                struct qemud_vm_disk_def *ptr = def->disks;
-                while (ptr) {
-                    if (!ptr->next || qemudDiskCompare(disk, ptr->next) < 0) {
-                        disk->next = ptr->next;
-                        ptr->next = disk;
-                        break;
-                    }
-                    ptr = ptr->next;
-                }
-            }
-        }
-    }
-    xmlXPathFreeObject(obj);
-    obj = NULL;
-
-    /* analysis of the character devices */
-    if (qemudParseCharXMLDevices(conn, ctxt,
-                                 "/domain/devices/parallel",
-                                 &def->nparallels,
-                                 &def->parallels) < 0)
-        goto error;
-    if (qemudParseCharXMLDevices(conn, ctxt,
-                                 "/domain/devices/serial",
-                                 &def->nserials,
-                                 &def->serials) < 0)
-        goto error;
-
-    /*
-     * If no serial devices were listed, then look for console
-     * devices which is the legacy syntax for the same thing
-     */
-    if (def->nserials == 0) {
-        obj = xmlXPathEval(BAD_CAST "/domain/devices/console", ctxt);
-        if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-            (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
-            struct qemud_vm_chr_def *chr;
-            if (VIR_ALLOC(chr) < 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                                 "%s",
-                                 _("failed to allocate space for char device"));
-                goto error;
-            }
-
-            if (qemudParseCharXML(conn, chr, 0, obj->nodesetval->nodeTab[0]) < 0) {
-                VIR_FREE(chr);
-                goto error;
-            }
-            def->nserials = 1;
-            def->serials = chr;
-        }
-        xmlXPathFreeObject(obj);
-    }
-
-
-    /* analysis of the network devices */
-    obj = xmlXPathEval(BAD_CAST "/domain/devices/interface", ctxt);
-    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
-        struct qemud_vm_net_def *prev = NULL;
-        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-            struct qemud_vm_net_def *net;
-            if (VIR_ALLOC(net) < 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                           "%s", _("failed to allocate space for net string"));
-                goto error;
-            }
-            if (qemudParseInterfaceXML(conn, net, obj->nodesetval->nodeTab[i]) < 0) {
-                VIR_FREE(net);
-                goto error;
-            }
-            def->nnets++;
-            net->next = NULL;
-            if (i == 0) {
-                def->nets = net;
-            } else {
-                prev->next = net;
-            }
-            prev = net;
-        }
-    }
-    xmlXPathFreeObject(obj);
-
-    /* analysis of the input devices */
-    obj = xmlXPathEval(BAD_CAST "/domain/devices/input", ctxt);
-    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
-        struct qemud_vm_input_def *prev = NULL;
-        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-            struct qemud_vm_input_def *input;
-            if (VIR_ALLOC(input) < 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                         "%s", _("failed to allocate space for input string"));
-                goto error;
-            }
-            if (qemudParseInputXML(conn, def, input, obj->nodesetval->nodeTab[i]) < 0) {
-                VIR_FREE(input);
-                goto error;
-            }
-            /* Mouse + PS/2 is implicit with graphics, so don't store it */
-            if (input->bus == QEMU_INPUT_BUS_PS2 &&
-                input->type == QEMU_INPUT_TYPE_MOUSE) {
-                VIR_FREE(input);
-                continue;
-            }
-            def->ninputs++;
-            input->next = NULL;
-            if (def->inputs == NULL) {
-                def->inputs = input;
-            } else {
-                prev->next = input;
-            }
-            prev = input;
-        }
-    }
-    xmlXPathFreeObject(obj);
-
-    /* Parse sound driver xml */
-    obj = xmlXPathEval(BAD_CAST "/domain/devices/sound", ctxt);
-    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
-        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
-        struct qemud_vm_sound_def *prev = NULL;
-        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-
-            struct qemud_vm_sound_def *sound;
-            struct qemud_vm_sound_def *check = def->sounds;
-            int collision = 0;
-            if (VIR_ALLOC(sound) < 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                         "%s", _("failed to allocate space for sound dev"));
-                goto error;
-            }
-            if (qemudParseSoundXML(conn, sound,
-                                   obj->nodesetval->nodeTab[i]) < 0) {
-                VIR_FREE(sound);
-                goto error;
-            }
-
-            // Check that model type isn't already present in sound dev list
-            while(check) {
-                if (check->model == sound->model) {
-                    collision = 1;
-                    break;
-                }
-                check = check->next;
-            }
-            if (collision) {
-                VIR_FREE(sound);
-                continue;
-            }
-
-            def->nsounds++;
-            sound->next = NULL;
-            if (def->sounds == NULL) {
-                def->sounds = sound;
-            } else {
-                prev->next = sound;
-            }
-            prev = sound;
-        }
-    }
-    xmlXPathFreeObject(obj);
-    obj = NULL;
-
-    /* If graphics are enabled, there's an implicit PS2 mouse */
-    if (def->graphicsType != QEMUD_GRAPHICS_NONE) {
-        int hasPS2mouse = 0;
-        struct qemud_vm_input_def *input = def->inputs;
-        while (input) {
-            if (input->type == QEMU_INPUT_TYPE_MOUSE &&
-                input->bus == QEMU_INPUT_BUS_PS2)
-                hasPS2mouse = 1;
-            input = input->next;
-        }
-
-        if (!hasPS2mouse) {
-            if (VIR_ALLOC(input) < 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                         "%s", _("failed to allocate space for input string"));
-                goto error;
-            }
-            input->type = QEMU_INPUT_TYPE_MOUSE;
-            input->bus = QEMU_INPUT_BUS_PS2;
-            input->next = def->inputs;
-            def->inputs = input;
-            def->ninputs++;
-        }
-    }
-
-    xmlXPathFreeContext(ctxt);
-
-    return def;
-
- error:
-    VIR_FREE(prop);
-    xmlXPathFreeObject(obj);
-    xmlXPathFreeContext(ctxt);
-    qemudFreeVMDef(def);
-    return NULL;
-}
-
 
 static char *
 qemudNetworkIfaceConnect(virConnectPtr conn,
                          struct qemud_driver *driver,
-                         struct qemud_vm *vm,
-                         struct qemud_vm_net_def *net,
+                         int **tapfds,
+                         int *ntapfds,
+                         virDomainNetDefPtr net,
                          int vlan)
 {
     virNetworkObjPtr network = NULL;
@@ -2236,7 +560,7 @@
     int err;
     int tapfd = -1;
 
-    if (net->type == QEMUD_NET_NETWORK) {
+    if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
         if (!(network = virNetworkFindByName(driver->networks, net->dst.network.name))) {
             qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                              _("Network '%s' not found"),
@@ -2249,15 +573,15 @@
             goto error;
         }
         brname = network->def->bridge;
-        if (net->dst.network.ifname[0] == '\0' ||
+        if (!net->dst.network.ifname ||
             STRPREFIX(net->dst.network.ifname, "vnet") ||
             strchr(net->dst.network.ifname, '%')) {
             strcpy(net->dst.network.ifname, "vnet%d");
         }
         ifname = net->dst.network.ifname;
-    } else if (net->type == QEMUD_NET_BRIDGE) {
+    } else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
         brname = net->dst.bridge.brname;
-        if (net->dst.bridge.ifname[0] == '\0' ||
+        if (!net->dst.bridge.ifname ||
             STRPREFIX(net->dst.bridge.ifname, "vnet") ||
             strchr(net->dst.bridge.ifname, '%')) {
             strcpy(net->dst.bridge.ifname, "vnet%d");
@@ -2291,11 +615,10 @@
     if (!(retval = strdup(tapfdstr)))
         goto no_memory;
 
-    if (VIR_ALLOC_N(vm->tapfds, vm->ntapfds+2) < 0)
+    if (VIR_REALLOC_N(*tapfds, (*ntapfds)+1) < 0)
         goto no_memory;
 
-    vm->tapfds[vm->ntapfds++] = tapfd;
-    vm->tapfds[vm->ntapfds]   = -1;
+    (*tapfds)[(*ntapfds)++] = tapfd;
 
     return retval;
 
@@ -2309,71 +632,71 @@
     return NULL;
 }
 
-static int qemudBuildCommandLineChrDevStr(struct qemud_vm_chr_def *dev,
+static int qemudBuildCommandLineChrDevStr(virDomainChrDefPtr dev,
                                           char *buf,
                                           int buflen)
 {
-    switch (dev->srcType) {
-    case QEMUD_CHR_SRC_TYPE_NULL:
+    switch (dev->type) {
+    case VIR_DOMAIN_CHR_TYPE_NULL:
         strncpy(buf, "null", buflen);
         buf[buflen-1] = '\0';
         break;
 
-    case QEMUD_CHR_SRC_TYPE_VC:
+    case VIR_DOMAIN_CHR_TYPE_VC:
         strncpy(buf, "vc", buflen);
         buf[buflen-1] = '\0';
         break;
 
-    case QEMUD_CHR_SRC_TYPE_PTY:
+    case VIR_DOMAIN_CHR_TYPE_PTY:
         strncpy(buf, "pty", buflen);
         buf[buflen-1] = '\0';
         break;
 
-    case QEMUD_CHR_SRC_TYPE_DEV:
+    case VIR_DOMAIN_CHR_TYPE_DEV:
         if (snprintf(buf, buflen, "%s",
-                     dev->srcData.file.path) >= buflen)
+                     dev->data.file.path) >= buflen)
             return -1;
         break;
 
-    case QEMUD_CHR_SRC_TYPE_FILE:
+    case VIR_DOMAIN_CHR_TYPE_FILE:
         if (snprintf(buf, buflen, "file:%s",
-                     dev->srcData.file.path) >= buflen)
+                     dev->data.file.path) >= buflen)
             return -1;
         break;
 
-    case QEMUD_CHR_SRC_TYPE_PIPE:
+    case VIR_DOMAIN_CHR_TYPE_PIPE:
         if (snprintf(buf, buflen, "pipe:%s",
-                     dev->srcData.file.path) >= buflen)
+                     dev->data.file.path) >= buflen)
             return -1;
         break;
 
-    case QEMUD_CHR_SRC_TYPE_STDIO:
+    case VIR_DOMAIN_CHR_TYPE_STDIO:
         strncpy(buf, "stdio", buflen);
         buf[buflen-1] = '\0';
         break;
 
-    case QEMUD_CHR_SRC_TYPE_UDP:
+    case VIR_DOMAIN_CHR_TYPE_UDP:
         if (snprintf(buf, buflen, "udp:%s:%s@%s:%s",
-                     dev->srcData.udp.connectHost,
-                     dev->srcData.udp.connectService,
-                     dev->srcData.udp.bindHost,
-                     dev->srcData.udp.bindService) >= buflen)
+                     dev->data.udp.connectHost,
+                     dev->data.udp.connectService,
+                     dev->data.udp.bindHost,
+                     dev->data.udp.bindService) >= buflen)
             return -1;
         break;
 
-    case QEMUD_CHR_SRC_TYPE_TCP:
+    case VIR_DOMAIN_CHR_TYPE_TCP:
         if (snprintf(buf, buflen, "%s:%s:%s%s",
-                     dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET ? "telnet" : "tcp",
-                     dev->srcData.tcp.host,
-                     dev->srcData.tcp.service,
-                     dev->srcData.tcp.listen ? ",listen" : "") >= buflen)
+                     dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET ? "telnet" : "tcp",
+                     dev->data.tcp.host,
+                     dev->data.tcp.service,
+                     dev->data.tcp.listen ? ",listen" : "") >= buflen)
             return -1;
         break;
 
-    case QEMUD_CHR_SRC_TYPE_UNIX:
+    case VIR_DOMAIN_CHR_TYPE_UNIX:
         if (snprintf(buf, buflen, "unix:%s%s",
-                     dev->srcData.nix.path,
-                     dev->srcData.nix.listen ? ",listen" : "") >= buflen)
+                     dev->data.nix.path,
+                     dev->data.nix.listen ? ",listen" : "") >= buflen)
             return -1;
         break;
     }
@@ -2387,29 +710,26 @@
  */
 int qemudBuildCommandLine(virConnectPtr conn,
                           struct qemud_driver *driver,
-                          struct qemud_vm *vm,
-                          char ***retargv) {
+                          virDomainObjPtr vm,
+                          int qemuCmdFlags,
+                          char ***retargv,
+                          int **tapfds,
+                          int *ntapfds,
+                          const char *migrateFrom) {
     int i;
     char memory[50];
     char vcpus[50];
-    char boot[QEMUD_MAX_BOOT_DEVS+1];
-    struct qemud_vm_disk_def *disk = vm->def->disks;
-    struct qemud_vm_net_def *net = vm->def->nets;
-    struct qemud_vm_input_def *input = vm->def->inputs;
-    struct qemud_vm_sound_def *sound = vm->def->sounds;
-    struct qemud_vm_chr_def *serial = vm->def->serials;
-    struct qemud_vm_chr_def *parallel = vm->def->parallels;
+    char boot[VIR_DOMAIN_BOOT_LAST];
+    virDomainDiskDefPtr disk = vm->def->disks;
+    virDomainNetDefPtr net = vm->def->nets;
+    virDomainInputDefPtr input = vm->def->inputs;
+    virDomainSoundDefPtr sound = vm->def->sounds;
+    virDomainChrDefPtr serial = vm->def->serials;
+    virDomainChrDefPtr parallel = vm->def->parallels;
     struct utsname ut;
     int disableKQEMU = 0;
     int qargc = 0, qarga = 0;
     char **qargv = NULL;
-
-    if (vm->qemuVersion == 0) {
-        if (qemudExtractVersionInfo(vm->def->os.binary,
-                                    &(vm->qemuVersion),
-                                    &(vm->qemuCmdFlags)) < 0)
-            return -1;
-    }
 
     uname(&ut);
 
@@ -2425,9 +745,9 @@
      * 2. Guest is 'qemu'
      * 3. The qemu binary has the -no-kqemu flag
      */
-    if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
+    if ((qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
         STREQ(ut.machine, vm->def->os.arch) &&
-        vm->def->virtType == QEMUD_VIRT_QEMU)
+        vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
         disableKQEMU = 1;
 
 #define ADD_ARG_SPACE                                                   \
@@ -2453,10 +773,10 @@
     } while (0)
 
     snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
-    snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus);
+    snprintf(vcpus, sizeof(vcpus), "%lu", vm->def->vcpus);
 
 
-    ADD_ARG_LIT(vm->def->os.binary);
+    ADD_ARG_LIT(vm->def->emulator);
     ADD_ARG_LIT("-S");
     ADD_ARG_LIT("-M");
     ADD_ARG_LIT(vm->def->os.machine);
@@ -2467,7 +787,7 @@
     ADD_ARG_LIT("-smp");
     ADD_ARG_LIT(vcpus);
 
-    if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NAME) {
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_NAME) {
         ADD_ARG_LIT("-name");
         ADD_ARG_LIT(vm->def->name);
     }
@@ -2478,7 +798,7 @@
      * if you ask for nographic. So we have to make sure we override
      * these defaults ourselves...
      */
-    if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE)
+    if (!vm->def->graphics)
         ADD_ARG_LIT("-nographic");
 
     ADD_ARG_LIT("-monitor");
@@ -2487,26 +807,26 @@
     if (vm->def->localtime)
         ADD_ARG_LIT("-localtime");
 
-    if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
-        vm->def->noReboot)
+    if ((qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
+        vm->def->onReboot != VIR_DOMAIN_LIFECYCLE_RESTART)
         ADD_ARG_LIT("-no-reboot");
 
-    if (!(vm->def->features & QEMUD_FEATURE_ACPI))
+    if (!(vm->def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)))
         ADD_ARG_LIT("-no-acpi");
 
-    if (!vm->def->os.bootloader[0]) {
+    if (!vm->def->os.bootloader) {
         for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
             switch (vm->def->os.bootDevs[i]) {
-            case QEMUD_BOOT_CDROM:
+            case VIR_DOMAIN_BOOT_CDROM:
                 boot[i] = 'd';
                 break;
-            case QEMUD_BOOT_FLOPPY:
+            case VIR_DOMAIN_BOOT_FLOPPY:
                 boot[i] = 'a';
                 break;
-            case QEMUD_BOOT_DISK:
+            case VIR_DOMAIN_BOOT_DISK:
                 boot[i] = 'c';
                 break;
-            case QEMUD_BOOT_NET:
+            case VIR_DOMAIN_BOOT_NET:
                 boot[i] = 'n';
                 break;
             default:
@@ -2518,15 +838,15 @@
         ADD_ARG_LIT("-boot");
         ADD_ARG_LIT(boot);
 
-        if (vm->def->os.kernel[0]) {
+        if (vm->def->os.kernel) {
             ADD_ARG_LIT("-kernel");
             ADD_ARG_LIT(vm->def->os.kernel);
         }
-        if (vm->def->os.initrd[0]) {
+        if (vm->def->os.initrd) {
             ADD_ARG_LIT("-initrd");
             ADD_ARG_LIT(vm->def->os.initrd);
         }
-        if (vm->def->os.cmdline[0]) {
+        if (vm->def->os.cmdline) {
             ADD_ARG_LIT("-append");
             ADD_ARG_LIT(vm->def->os.cmdline);
         }
@@ -2536,20 +856,20 @@
     }
 
     /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
-    if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
         int bootCD = 0, bootFloppy = 0, bootDisk = 0;
 
         /* If QEMU supports boot=on for -drive param... */
-        if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_BOOT) {
+        if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_BOOT) {
             for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
                 switch (vm->def->os.bootDevs[i]) {
-                case QEMUD_BOOT_CDROM:
+                case VIR_DOMAIN_BOOT_CDROM:
                     bootCD = 1;
                     break;
-                case QEMUD_BOOT_FLOPPY:
+                case VIR_DOMAIN_BOOT_FLOPPY:
                     bootFloppy = 1;
                     break;
-                case QEMUD_BOOT_DISK:
+                case VIR_DOMAIN_BOOT_DISK:
                     bootDisk = 1;
                     break;
                 }
@@ -2561,6 +881,7 @@
             const char *media = NULL;
             int bootable = 0;
             int idx = virDiskNameToIndex(disk->dst);
+            const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
 
             if (idx < 0) {
                 qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
@@ -2568,26 +889,26 @@
                 goto error;
             }
 
-            if (disk->device == QEMUD_DISK_CDROM)
+            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                 media = "media=cdrom,";
 
             switch (disk->device) {
-            case QEMUD_DISK_CDROM:
+            case VIR_DOMAIN_DISK_DEVICE_CDROM:
                 bootable = bootCD;
                 bootCD = 0;
                 break;
-            case QEMUD_DISK_FLOPPY:
+            case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
                 bootable = bootFloppy;
                 bootFloppy = 0;
                 break;
-            case QEMUD_DISK_DISK:
+            case VIR_DOMAIN_DISK_DEVICE_DISK:
                 bootable = bootDisk;
                 bootDisk = 0;
                 break;
             }
 
             snprintf(opt, PATH_MAX, "file=%s,if=%s,%sindex=%d%s",
-                     disk->src, qemudBusIdToName(disk->bus, 1),
+                     disk->src, bus,
                      media ? media : "",
                      idx,
                      bootable ? ",boot=on" : "");
@@ -2602,8 +923,8 @@
             char file[PATH_MAX];
 
             if (STREQ(disk->dst, "hdc") &&
-                disk->device == QEMUD_DISK_CDROM) {
-                if (disk->src[0]) {
+                disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+                if (disk->src) {
                     snprintf(dev, NAME_MAX, "-%s", "cdrom");
                 } else {
                     disk = disk->next;
@@ -2643,7 +964,8 @@
                          net->mac[2], net->mac[3],
                          net->mac[4], net->mac[5],
                          vlan,
-                         (net->model[0] ? ",model=" : ""), net->model) >= sizeof(nic))
+                         (net->model ? ",model=" : ""),
+                         (net->model ? net->model : "")) >= sizeof(nic))
                 goto error;
 
             ADD_ARG_LIT("-net");
@@ -2651,17 +973,19 @@
             ADD_ARG_LIT("-net");
 
             switch (net->type) {
-            case QEMUD_NET_NETWORK:
-            case QEMUD_NET_BRIDGE:
+            case VIR_DOMAIN_NET_TYPE_NETWORK:
+            case VIR_DOMAIN_NET_TYPE_BRIDGE:
                 {
-                    char *tap = qemudNetworkIfaceConnect(conn, driver, vm, net, vlan);
+                    char *tap = qemudNetworkIfaceConnect(conn, driver,
+                                                         tapfds, ntapfds,
+                                                         net, vlan);
                     if (tap == NULL)
                         goto error;
                     ADD_ARG(tap);
                     break;
                 }
 
-            case QEMUD_NET_ETHERNET:
+            case VIR_DOMAIN_NET_TYPE_ETHERNET:
                 {
                     char arg[PATH_MAX];
                     if (snprintf(arg, PATH_MAX-1, "tap,ifname=%s,script=%s,vlan=%d",
@@ -2674,20 +998,20 @@
                 }
                 break;
 
-            case QEMUD_NET_CLIENT:
-            case QEMUD_NET_SERVER:
-            case QEMUD_NET_MCAST:
+            case VIR_DOMAIN_NET_TYPE_CLIENT:
+            case VIR_DOMAIN_NET_TYPE_SERVER:
+            case VIR_DOMAIN_NET_TYPE_MCAST:
                 {
                     char arg[PATH_MAX];
                     const char *mode = NULL;
                     switch (net->type) {
-                    case QEMUD_NET_CLIENT:
+                    case VIR_DOMAIN_NET_TYPE_CLIENT:
                         mode = "connect";
                         break;
-                    case QEMUD_NET_SERVER:
+                    case VIR_DOMAIN_NET_TYPE_SERVER:
                         mode = "listen";
                         break;
-                    case QEMUD_NET_MCAST:
+                    case VIR_DOMAIN_NET_TYPE_MCAST:
                         mode = "mcast";
                         break;
                     }
@@ -2702,7 +1026,7 @@
                 }
                 break;
 
-            case QEMUD_NET_USER:
+            case VIR_DOMAIN_NET_TYPE_USER:
             default:
                 {
                     char arg[PATH_MAX];
@@ -2754,19 +1078,20 @@
 
     ADD_ARG_LIT("-usb");
     while (input) {
-        if (input->bus == QEMU_INPUT_BUS_USB) {
+        if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
             ADD_ARG_LIT("-usbdevice");
-            ADD_ARG_LIT(input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
+            ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
         }
 
         input = input->next;
     }
 
-    if (vm->def->graphicsType == QEMUD_GRAPHICS_VNC) {
+    if (vm->def->graphics &&
+        vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
         char vncdisplay[PATH_MAX];
         int ret;
 
-        if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
+        if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
             char options[PATH_MAX] = "";
             if (driver->vncTLS) {
                 strcat(options, ",tls");
@@ -2780,25 +1105,24 @@
                 options[sizeof(options)-1] = '\0';
             }
             ret = snprintf(vncdisplay, sizeof(vncdisplay), "%s:%d%s",
-                           vm->def->vncListen,
-                           vm->def->vncActivePort - 5900,
+                           vm->def->graphics->data.vnc.listenAddr,
+                           vm->def->graphics->data.vnc.port - 5900,
                            options);
         } else {
             ret = snprintf(vncdisplay, sizeof(vncdisplay), "%d",
-                           vm->def->vncActivePort - 5900);
+                           vm->def->graphics->data.vnc.port - 5900);
         }
         if (ret < 0 || ret >= (int)sizeof(vncdisplay))
             goto error;
 
         ADD_ARG_LIT("-vnc");
         ADD_ARG_LIT(vncdisplay);
-        if (vm->def->keymap) {
+        if (vm->def->graphics->data.vnc.keymap) {
             ADD_ARG_LIT("-k");
-            ADD_ARG_LIT(vm->def->keymap);
+            ADD_ARG_LIT(vm->def->graphics->data.vnc.keymap);
         }
-    } else if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
-        /* Nada - we added -nographic earlier in this function */
-    } else {
+    } else if (vm->def->graphics &&
+               vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
         /* SDL is the default. no args needed */
     }
 
@@ -2810,7 +1134,7 @@
             goto no_memory;
 
         while(sound && size > 0) {
-            const char *model = qemudSoundModelToString(sound->model);
+            const char *model = virDomainSoundModelTypeToString(sound->model);
             if (!model) {
                 VIR_FREE(modstr);
                 qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
@@ -2827,9 +1151,9 @@
         ADD_ARG(modstr);
     }
 
-    if (vm->migrateFrom[0]) {
+    if (migrateFrom) {
         ADD_ARG_LIT("-incoming");
-        ADD_ARG_LIT(vm->migrateFrom);
+        ADD_ARG_LIT(migrateFrom);
     }
 
     ADD_ARG(NULL);
@@ -2841,12 +1165,11 @@
     qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
                      "%s", _("failed to allocate space for argv string"));
  error:
-    if (vm->tapfds) {
-        for (i = 0; vm->tapfds[i] != -1; i++)
-            close(vm->tapfds[i]);
-        VIR_FREE(vm->tapfds);
-        vm->tapfds = NULL;
-        vm->ntapfds = 0;
+    if (*tapfds) {
+        for (i = 0; ntapfds; i++)
+            close((*tapfds)[i]);
+        VIR_FREE(*tapfds);
+        *ntapfds = 0;
     }
     if (qargv) {
         for (i = 0 ; i < qargc ; i++)
@@ -2863,14 +1186,16 @@
 
 /* Save a guest's config data into a persistent file */
 static int qemudSaveConfig(virConnectPtr conn,
-                           struct qemud_driver *driver,
-                           struct qemud_vm *vm,
-                           struct qemud_vm_def *def) {
+                           struct qemud_driver *driver ATTRIBUTE_UNUSED,
+                           virDomainObjPtr vm,
+                           int active) {
     char *xml;
     int fd = -1, ret = -1;
     int towrite;
 
-    if (!(xml = qemudGenerateXML(conn, driver, vm, def, 0)))
+    if (!(xml = virDomainDefFormat(conn,
+                                   !active && vm->newDef ? vm->newDef : vm->def,
+                                   1)))
         return -1;
 
     if ((fd = open(vm->configFile,
@@ -2908,6 +1233,7 @@
     return ret;
 }
 
+#if 0
 struct qemud_vm_device_def *
 qemudParseVMDeviceDef(virConnectPtr conn,
                       const struct qemud_vm_def *def,
@@ -2963,102 +1289,16 @@
     return NULL;
 }
 
-struct qemud_vm_def *
-qemudParseVMDef(virConnectPtr conn,
-                struct qemud_driver *driver,
-                const char *xmlStr,
-                const char *displayName) {
-    xmlDocPtr xml;
-    struct qemud_vm_def *def = NULL;
+#endif
 
-    if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "domain.xml", NULL,
-                           XML_PARSE_NOENT | XML_PARSE_NONET |
-                           XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, NULL);
-        return NULL;
-    }
-
-    def = qemudParseXML(conn, driver, xml);
-
-    xmlFreeDoc(xml);
-
-    return def;
-}
-
-struct qemud_vm *
-qemudAssignVMDef(virConnectPtr conn,
-                 struct qemud_driver *driver,
-                 struct qemud_vm_def *def)
-{
-    struct qemud_vm *vm = NULL;
-
-    if ((vm = qemudFindVMByName(driver, def->name))) {
-        if (!qemudIsActiveVM(vm)) {
-            qemudFreeVMDef(vm->def);
-            vm->def = def;
-        } else {
-            if (vm->newDef)
-                qemudFreeVMDef(vm->newDef);
-            vm->newDef = def;
-        }
-        /* Reset version, because the emulator path might have changed */
-        vm->qemuVersion = 0;
-        vm->qemuCmdFlags = 0;
-        return vm;
-    }
-
-    if (VIR_ALLOC(vm) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                         "%s", _("failed to allocate space for vm string"));
-        return NULL;
-    }
-
-    vm->stdin = -1;
-    vm->stdout = -1;
-    vm->stderr = -1;
-    vm->monitor = -1;
-    vm->pid = -1;
-    vm->id = -1;
-    vm->state = VIR_DOMAIN_SHUTOFF;
-    vm->def = def;
-    vm->next = driver->vms;
-
-    driver->vms = vm;
-    driver->ninactivevms++;
-
-    return vm;
-}
-
-void
-qemudRemoveInactiveVM(struct qemud_driver *driver,
-                      struct qemud_vm *vm)
-{
-    struct qemud_vm *prev = NULL, *curr;
-
-    curr = driver->vms;
-    while (curr != vm) {
-        prev = curr;
-        curr = curr->next;
-    }
-
-    if (curr) {
-        if (prev)
-            prev->next = curr->next;
-        else
-            driver->vms = curr->next;
-
-        driver->ninactivevms--;
-    }
-
-    qemudFreeVM(vm);
-}
 
 int
-qemudSaveVMDef(virConnectPtr conn,
-               struct qemud_driver *driver,
-               struct qemud_vm *vm,
-               struct qemud_vm_def *def) {
-    if (vm->configFile[0] == '\0') {
+qemudSaveDomainDef(virConnectPtr conn,
+                   struct qemud_driver *driver,
+                   virDomainObjPtr domain,
+                   int active) {
+    if (!domain->configFile) {
+        char buf[PATH_MAX];
         int err;
 
         if ((err = virFileMakePath(driver->configDir))) {
@@ -3068,23 +1308,31 @@
             return -1;
         }
 
-        if (virFileBuildPath(driver->configDir, def->name, ".xml",
-                             vm->configFile, PATH_MAX) < 0) {
+        if (virFileBuildPath(driver->configDir, domain->def->name, ".xml",
+                             buf, sizeof(buf)) < 0) {
             qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                              "%s", _("cannot construct config file path"));
             return -1;
         }
+        if (!(domain->configFile = strdup(buf))) {
+            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+            return -1;
+        }
 
-        if (virFileBuildPath(driver->autostartDir, def->name, ".xml",
-                             vm->autostartLink, PATH_MAX) < 0) {
+        if (virFileBuildPath(driver->autostartDir, domain->def->name, ".xml",
+                             buf, sizeof(buf)) < 0) {
             qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                              "%s", _("cannot construct autostart link path"));
-            vm->configFile[0] = '\0';
+            return -1;
+        }
+        if (!(domain->autostartLink = strdup(buf))) {
+            VIR_FREE(domain->configFile);
+            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
             return -1;
         }
     }
 
-    return qemudSaveConfig(conn, driver, vm, def);
+    return qemudSaveConfig(conn, driver, domain, active);
 }
 
 static int qemudSaveNetworkConfig(virConnectPtr conn,
@@ -3186,16 +1434,16 @@
 }
 
 
-static struct qemud_vm *
+static virDomainObjPtr
 qemudLoadConfig(struct qemud_driver *driver,
                 const char *file,
                 const char *path,
                 const char *xml,
                 const char *autostartLink) {
-    struct qemud_vm_def *def;
-    struct qemud_vm *vm;
+    virDomainDefPtr def;
+    virDomainObjPtr vm;
 
-    if (!(def = qemudParseVMDef(NULL, driver, xml, file))) {
+    if (!(def = virDomainDefParse(NULL, driver->caps, xml, file))) {
         virErrorPtr err = virGetLastError();
         qemudLog(QEMUD_WARN, _("Error parsing QEMU guest config '%s' : %s"),
                  path, (err ? err->message :
@@ -3208,23 +1456,30 @@
                  _("QEMU guest config filename '%s'"
                    " does not match guest name '%s'"),
                  path, def->name);
-        qemudFreeVMDef(def);
+        virDomainDefFree(def);
         return NULL;
     }
 
-    if (!(vm = qemudAssignVMDef(NULL, driver, def))) {
+    if (!(vm = virDomainAssignDef(NULL,
+                                  &driver->domains,
+                                  def))) {
         qemudLog(QEMUD_WARN,
                  _("Failed to load QEMU guest config '%s': out of memory"),
                  path);
-        qemudFreeVMDef(def);
+        virDomainDefFree(def);
         return NULL;
     }
 
-    strncpy(vm->configFile, path, PATH_MAX);
-    vm->configFile[PATH_MAX-1] = '\0';
-
-    strncpy(vm->autostartLink, autostartLink, PATH_MAX);
-    vm->autostartLink[PATH_MAX-1] = '\0';
+    if (!(vm->configFile = strdup(path))) {
+        virDomainRemoveInactive(&driver->domains,
+                                vm);
+        return NULL;
+    }
+    if (!(vm->autostartLink = strdup(autostartLink))) {
+        virDomainRemoveInactive(&driver->domains,
+                                vm);
+        return NULL;
+    }
 
     vm->autostart = virFileLinkPointsTo(vm->autostartLink, vm->configFile);
 
@@ -3321,7 +1576,7 @@
             continue;
         }
 
-        if (virFileReadAll(path, QEMUD_MAX_XML_LEN, &xml) < 0)
+        if (virFileReadAll(path,16000, &xml) < 0)
             continue;
 
         if (isGuest)
@@ -3348,411 +1603,12 @@
     return 0;
 }
 
-static int qemudGenerateXMLChar(virBufferPtr buf,
-                                const struct qemud_vm_chr_def *dev,
-                                const char *type)
-{
-    const char *const types[] = {
-        "null",
-        "vc",
-        "pty",
-        "dev",
-        "file",
-        "pipe",
-        "stdio",
-        "udp",
-        "tcp",
-        "unix"
-    };
-    verify_true(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);
-
-    /* Compat with legacy  <console tty='/dev/pts/5'/> syntax */
-    if (STREQ(type, "console") &&
-        dev->srcType == QEMUD_CHR_SRC_TYPE_PTY &&
-        dev->srcData.file.path[0] != '\0') {
-        virBufferVSprintf(buf, "    <%s type='%s' tty='%s'>\n",
-                          type, types[dev->srcType],
-                          dev->srcData.file.path);
-    } else {
-        virBufferVSprintf(buf, "    <%s type='%s'>\n",
-                          type, types[dev->srcType]);
-    }
-
-    switch (dev->srcType) {
-    case QEMUD_CHR_SRC_TYPE_NULL:
-    case QEMUD_CHR_SRC_TYPE_VC:
-    case QEMUD_CHR_SRC_TYPE_STDIO:
-        /* nada */
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_PTY:
-    case QEMUD_CHR_SRC_TYPE_DEV:
-    case QEMUD_CHR_SRC_TYPE_FILE:
-    case QEMUD_CHR_SRC_TYPE_PIPE:
-        if (dev->srcType != QEMUD_CHR_SRC_TYPE_PTY ||
-            dev->srcData.file.path[0]) {
-            virBufferVSprintf(buf, "      <source path='%s'/>\n",
-                              dev->srcData.file.path);
-        }
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_UDP:
-        if (dev->srcData.udp.bindService[0] != '\0' &&
-            dev->srcData.udp.bindHost[0] != '\0') {
-            virBufferVSprintf(buf, "      <source mode='bind' host='%s' service='%s'/>\n",
-                              dev->srcData.udp.bindHost,
-                              dev->srcData.udp.bindService);
-        } else if (dev->srcData.udp.bindHost[0] !='\0') {
-            virBufferVSprintf(buf, "      <source mode='bind' host='%s'/>\n",
-                              dev->srcData.udp.bindHost);
-        } else if (dev->srcData.udp.bindService[0] != '\0') {
-            virBufferVSprintf(buf, "      <source mode='bind' service='%s'/>\n",
-                              dev->srcData.udp.bindService);
-        }
-
-        if (dev->srcData.udp.connectService[0] != '\0' &&
-            dev->srcData.udp.connectHost[0] != '\0') {
-            virBufferVSprintf(buf, "      <source mode='connect' host='%s' service='%s'/>\n",
-                              dev->srcData.udp.connectHost,
-                              dev->srcData.udp.connectService);
-        } else if (dev->srcData.udp.connectHost[0] != '\0') {
-            virBufferVSprintf(buf, "      <source mode='connect' host='%s'/>\n",
-                              dev->srcData.udp.connectHost);
-        } else if (dev->srcData.udp.connectService[0] != '\0') {
-            virBufferVSprintf(buf, "      <source mode='connect' service='%s'/>\n",
-                              dev->srcData.udp.connectService);
-        }
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_TCP:
-        virBufferVSprintf(buf, "      <source mode='%s' host='%s' service='%s'/>\n",
-                          dev->srcData.tcp.listen ? "bind" : "connect",
-                          dev->srcData.tcp.host,
-                          dev->srcData.tcp.service);
-        virBufferVSprintf(buf, "      <protocol type='%s'/>\n",
-                          dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET
-                          ? "telnet" : "raw");
-        break;
-
-    case QEMUD_CHR_SRC_TYPE_UNIX:
-        virBufferVSprintf(buf, "      <source mode='%s' path='%s'/>\n",
-                          dev->srcData.nix.listen ? "bind" : "connect",
-                          dev->srcData.nix.path);
-        break;
-    }
-
-    virBufferVSprintf(buf, "      <target port='%d'/>\n",
-                      dev->dstPort);
-
-    virBufferVSprintf(buf, "    </%s>\n",
-                      type);
-
-    return 0;
-}
-
-
-/* Generate an XML document describing the guest's configuration */
-char *qemudGenerateXML(virConnectPtr conn,
-                       struct qemud_driver *driver ATTRIBUTE_UNUSED,
-                       struct qemud_vm *vm,
-                       struct qemud_vm_def *def,
-                       int live) {
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    unsigned char *uuid;
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-    const struct qemud_vm_disk_def *disk;
-    const struct qemud_vm_net_def *net;
-    const struct qemud_vm_input_def *input;
-    const struct qemud_vm_sound_def *sound;
-    const struct qemud_vm_chr_def *chr;
-    const char *type = NULL, *tmp;
-    int n, allones = 1;
-
-    if (!(type = qemudVirtTypeToString(def->virtType))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("unexpected domain type %d"), def->virtType);
-        goto cleanup;
-    }
-
-    if (qemudIsActiveVM(vm) && live)
-        virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->id);
-    else
-        virBufferVSprintf(&buf, "<domain type='%s'>\n", type);
-
-    virBufferVSprintf(&buf, "  <name>%s</name>\n", def->name);
-
-    uuid = def->uuid;
-    virUUIDFormat(uuid, uuidstr);
-    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
-
-    virBufferVSprintf(&buf, "  <memory>%lu</memory>\n", def->maxmem);
-    virBufferVSprintf(&buf, "  <currentMemory>%lu</currentMemory>\n", def->memory);
-
-    for (n = 0 ; n < QEMUD_CPUMASK_LEN ; n++)
-        if (def->cpumask[n] != 1)
-            allones = 0;
-
-    if (allones) {
-        virBufferVSprintf(&buf, "  <vcpu>%d</vcpu>\n", def->vcpus);
-    } else {
-        char *cpumask = NULL;
-        if ((cpumask = virSaveCpuSet(conn, def->cpumask, QEMUD_CPUMASK_LEN)) == NULL) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                             "%s", _("allocating cpu mask"));
-            goto cleanup;
-        }
-        virBufferVSprintf(&buf, "  <vcpu cpuset='%s'>%d</vcpu>\n", cpumask, def->vcpus);
-        VIR_FREE(cpumask);
-    }
-
-    if (def->os.bootloader[0])
-        virBufferVSprintf(&buf, "  <bootloader>%s</bootloader>\n", def->os.bootloader);
-    virBufferAddLit(&buf, "  <os>\n");
-
-    if (def->virtType == QEMUD_VIRT_QEMU)
-        virBufferVSprintf(&buf, "    <type arch='%s' machine='%s'>%s</type>\n",
-                          def->os.arch, def->os.machine, def->os.type);
-    else
-        virBufferVSprintf(&buf, "    <type>%s</type>\n", def->os.type);
-
-    if (!def->os.bootloader[0]) {
-        if (def->os.kernel[0])
-            virBufferVSprintf(&buf, "    <kernel>%s</kernel>\n", def->os.kernel);
-        if (def->os.initrd[0])
-            virBufferVSprintf(&buf, "    <initrd>%s</initrd>\n", def->os.initrd);
-        if (def->os.cmdline[0])
-            virBufferVSprintf(&buf, "    <cmdline>%s</cmdline>\n", def->os.cmdline);
-
-        for (n = 0 ; n < def->os.nBootDevs ; n++) {
-            const char *boottype = "hd";
-            switch (def->os.bootDevs[n]) {
-            case QEMUD_BOOT_FLOPPY:
-                boottype = "fd";
-                break;
-            case QEMUD_BOOT_DISK:
-                boottype = "hd";
-                break;
-            case QEMUD_BOOT_CDROM:
-                boottype = "cdrom";
-                break;
-            case QEMUD_BOOT_NET:
-                boottype = "network";
-                break;
-            }
-            virBufferVSprintf(&buf, "    <boot dev='%s'/>\n", boottype);
-        }
-    }
-
-    virBufferAddLit(&buf, "  </os>\n");
-
-    if (def->features & QEMUD_FEATURE_ACPI) {
-        virBufferAddLit(&buf, "  <features>\n");
-        virBufferAddLit(&buf, "    <acpi/>\n");
-        virBufferAddLit(&buf, "  </features>\n");
-    }
-
-    virBufferVSprintf(&buf, "  <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
-
-    virBufferAddLit(&buf, "  <on_poweroff>destroy</on_poweroff>\n");
-    if (def->noReboot)
-        virBufferAddLit(&buf, "  <on_reboot>destroy</on_reboot>\n");
-    else
-        virBufferAddLit(&buf, "  <on_reboot>restart</on_reboot>\n");
-
-    virBufferAddLit(&buf, "  <on_crash>destroy</on_crash>\n");
-    virBufferAddLit(&buf, "  <devices>\n");
-
-    virBufferVSprintf(&buf, "    <emulator>%s</emulator>\n", def->os.binary);
-
-    disk = def->disks;
-    while (disk) {
-        const char *types[] = {
-            "block",
-            "file",
-        };
-        const char *typeAttrs[] = {
-            "dev",
-            "file",
-        };
-        const char *devices[] = {
-            "disk",
-            "cdrom",
-            "floppy",
-        };
-        virBufferVSprintf(&buf, "    <disk type='%s' device='%s'>\n",
-                          types[disk->type], devices[disk->device]);
-
-        if (disk->src[0])
-            virBufferVSprintf(&buf, "      <source %s='%s'/>\n",
-                              typeAttrs[disk->type], disk->src);
-
-        virBufferVSprintf(&buf, "      <target dev='%s' bus='%s'/>\n",
-                          disk->dst, qemudBusIdToName(disk->bus, 0));
-
-        if (disk->readonly)
-            virBufferAddLit(&buf, "      <readonly/>\n");
-
-        virBufferAddLit(&buf, "    </disk>\n");
-
-        disk = disk->next;
-    }
-
-    net = def->nets;
-    while (net) {
-        const char *types[] = {
-            "user",
-            "ethernet",
-            "server",
-            "client",
-            "mcast",
-            "network",
-            "bridge",
-        };
-        virBufferVSprintf(&buf, "    <interface type='%s'>\n",
-                          types[net->type]);
-
-        virBufferVSprintf(&buf, "      <mac address='%02x:%02x:%02x:%02x:%02x:%02x'/>\n",
-                          net->mac[0], net->mac[1], net->mac[2],
-                          net->mac[3], net->mac[4], net->mac[5]);
-
-        switch (net->type) {
-        case QEMUD_NET_NETWORK:
-            virBufferVSprintf(&buf, "      <source network='%s'/>\n", net->dst.network.name);
-
-            if (net->dst.network.ifname[0] != '\0')
-                virBufferVSprintf(&buf, "      <target dev='%s'/>\n", net->dst.network.ifname);
-            break;
-
-        case QEMUD_NET_ETHERNET:
-            if (net->dst.ethernet.ifname[0] != '\0')
-                virBufferVSprintf(&buf, "      <target dev='%s'/>\n", net->dst.ethernet.ifname);
-            if (net->dst.ethernet.script[0] != '\0')
-                virBufferVSprintf(&buf, "      <script path='%s'/>\n", net->dst.ethernet.script);
-            break;
-
-        case QEMUD_NET_BRIDGE:
-            virBufferVSprintf(&buf, "      <source bridge='%s'/>\n", net->dst.bridge.brname);
-            if (net->dst.bridge.ifname[0] != '\0')
-                virBufferVSprintf(&buf, "      <target dev='%s'/>\n", net->dst.bridge.ifname);
-            break;
-
-        case QEMUD_NET_SERVER:
-        case QEMUD_NET_CLIENT:
-        case QEMUD_NET_MCAST:
-            if (net->dst.socket.address[0] != '\0')
-                virBufferVSprintf(&buf, "      <source address='%s' port='%d'/>\n",
-                                  net->dst.socket.address, net->dst.socket.port);
-            else
-                virBufferVSprintf(&buf, "      <source port='%d'/>\n",
-                                  net->dst.socket.port);
-        }
-
-        if (net->model && net->model[0] != '\0') {
-            virBufferVSprintf(&buf, "      <model type='%s'/>\n",
-                              net->model);
-        }
-
-        virBufferAddLit(&buf, "    </interface>\n");
-
-        net = net->next;
-    }
-
-    chr = def->serials;
-    while (chr) {
-        if (qemudGenerateXMLChar(&buf, chr, "serial") < 0)
-            goto no_memory;
-
-        chr = chr->next;
-    }
-
-    chr = def->parallels;
-    while (chr) {
-        if (qemudGenerateXMLChar(&buf, chr, "parallel") < 0)
-            goto no_memory;
-
-        chr = chr->next;
-    }
-
-    /* First serial device is the primary console */
-    if (def->nserials > 0 &&
-        qemudGenerateXMLChar(&buf, def->serials, "console") < 0)
-        goto no_memory;
-
-    input = def->inputs;
-    while (input) {
-        if (input->bus == QEMU_INPUT_BUS_USB)
-            virBufferVSprintf(&buf, "    <input type='%s' bus='usb'/>\n",
-                              input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
-        input = input->next;
-    }
-    /* If graphics is enable, add implicit mouse */
-    if (def->graphicsType != QEMUD_GRAPHICS_NONE)
-        virBufferVSprintf(&buf, "    <input type='mouse' bus='%s'/>\n",
-                          STREQ(def->os.type, "hvm") ? "ps2" : "xen");
-
-    switch (def->graphicsType) {
-    case QEMUD_GRAPHICS_VNC:
-        virBufferAddLit(&buf, "    <graphics type='vnc'");
-
-        if (def->vncPort)
-            virBufferVSprintf(&buf, " port='%d'",
-                              qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort);
-
-        if (def->vncListen[0])
-            virBufferVSprintf(&buf, " listen='%s'",
-                              def->vncListen);
-
-        if (def->keymap)
-            virBufferVSprintf(&buf, " keymap='%s'",
-                              def->keymap);
-
-        virBufferAddLit(&buf, "/>\n");
-        break;
-
-    case QEMUD_GRAPHICS_SDL:
-        virBufferAddLit(&buf, "    <graphics type='sdl'/>\n");
-        break;
-
-    case QEMUD_GRAPHICS_NONE:
-    default:
-        break;
-    }
-
-    sound = def->sounds;
-    while(sound) {
-        const char *model = qemudSoundModelToString(sound->model);
-        if (!model) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             "%s", _("invalid sound model"));
-            goto cleanup;
-        }
-        virBufferVSprintf(&buf, "    <sound model='%s'/>\n", model);
-        sound = sound->next;
-    }
-
-    virBufferAddLit(&buf, "  </devices>\n");
-    virBufferAddLit(&buf, "</domain>\n");
-
-    if (virBufferError(&buf))
-        goto no_memory;
-
-    return virBufferContentAndReset(&buf);
-
- no_memory:
-    qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                     "%s", _("failed to generate XML: out of memory"));
- cleanup:
-    tmp = virBufferContentAndReset(&buf);
-    VIR_FREE(tmp);
-    return NULL;
-}
-
 
 int qemudDeleteConfig(virConnectPtr conn,
                       struct qemud_driver *driver ATTRIBUTE_UNUSED,
                       const char *configFile,
                       const char *name) {
-    if (!configFile[0]) {
+    if (!configFile) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                          _("no config file for %s"), name);
         return -1;
diff -r 286320a1cbc8 src/qemu_conf.h
--- a/src/qemu_conf.h	Sun Jun 22 18:04:01 2008 -0400
+++ b/src/qemu_conf.h	Sun Jun 22 18:08:24 2008 -0400
@@ -29,217 +29,15 @@
 #ifdef WITH_QEMU
 
 #include "internal.h"
+#include "iptables.h"
 #include "bridge.h"
-#include "iptables.h"
 #include "capabilities.h"
 #include "network_conf.h"
-#include <netinet/in.h>
-#include <sched.h>
+#include "domain_conf.h"
 
 #define qemudDebug(fmt, ...) do {} while(0)
 
-/* Different types of QEMU acceleration possible */
-enum qemud_vm_virt_type {
-    QEMUD_VIRT_QEMU,
-    QEMUD_VIRT_KQEMU,
-    QEMUD_VIRT_KVM,
-};
-
-/* Two types of disk backends */
-enum qemud_vm_disk_type {
-    QEMUD_DISK_BLOCK,
-    QEMUD_DISK_FILE
-};
-
-/* Three types of disk frontend */
-enum qemud_vm_disk_device {
-    QEMUD_DISK_DISK,
-    QEMUD_DISK_CDROM,
-    QEMUD_DISK_FLOPPY,
-};
-
-enum qemud_vm_disk_bus {
-    QEMUD_DISK_BUS_IDE,
-    QEMUD_DISK_BUS_FDC,
-    QEMUD_DISK_BUS_SCSI,
-    QEMUD_DISK_BUS_VIRTIO,
-    QEMUD_DISK_BUS_XEN,
-
-    QEMUD_DISK_BUS_LAST
-};
-
-/* Stores the virtual disk configuration */
-struct qemud_vm_disk_def {
-    int type;
-    int device;
-    int bus;
-    char src[PATH_MAX];
-    char dst[NAME_MAX];
-    int readonly;
-
-    struct qemud_vm_disk_def *next;
-};
-
-#define QEMUD_MAC_ADDRESS_LEN 6
-#define QEMUD_MODEL_MAX_LEN 10
-#define QEMUD_OS_TYPE_MAX_LEN 10
-#define QEMUD_OS_ARCH_MAX_LEN 10
-#define QEMUD_OS_MACHINE_MAX_LEN 10
-
-/* 5 different types of networking config */
-enum qemud_vm_net_type {
-    QEMUD_NET_USER,
-    QEMUD_NET_ETHERNET,
-    QEMUD_NET_SERVER,
-    QEMUD_NET_CLIENT,
-    QEMUD_NET_MCAST,
-    QEMUD_NET_NETWORK,
-    QEMUD_NET_BRIDGE,
-};
-
-#define QEMUD_MAX_NAME_LEN 50
-#define QEMUD_MAX_XML_LEN 4096
-#define QEMUD_MAX_ERROR_LEN 1024
 #define QEMUD_CPUMASK_LEN CPU_SETSIZE
-
-/* Stores the virtual network interface configuration */
-struct qemud_vm_net_def {
-    int type;
-    unsigned char mac[QEMUD_MAC_ADDRESS_LEN];
-    char model[QEMUD_MODEL_MAX_LEN];
-    union {
-        struct {
-            char ifname[BR_IFNAME_MAXLEN];
-            char script[PATH_MAX];
-        } ethernet;
-        struct {
-            char address[BR_INET_ADDR_MAXLEN];
-            int port;
-        } socket; /* any of NET_CLIENT or NET_SERVER or NET_MCAST */
-        struct {
-            char name[QEMUD_MAX_NAME_LEN];
-            char ifname[BR_IFNAME_MAXLEN];
-        } network;
-        struct {
-            char brname[BR_IFNAME_MAXLEN];
-            char ifname[BR_IFNAME_MAXLEN];
-        } bridge;
-    } dst;
-
-    struct qemud_vm_net_def *next;
-};
-
-enum qemu_vm_chr_dst_type {
-    QEMUD_CHR_SRC_TYPE_NULL,
-    QEMUD_CHR_SRC_TYPE_VC,
-    QEMUD_CHR_SRC_TYPE_PTY,
-    QEMUD_CHR_SRC_TYPE_DEV,
-    QEMUD_CHR_SRC_TYPE_FILE,
-    QEMUD_CHR_SRC_TYPE_PIPE,
-    QEMUD_CHR_SRC_TYPE_STDIO,
-    QEMUD_CHR_SRC_TYPE_UDP,
-    QEMUD_CHR_SRC_TYPE_TCP,
-    QEMUD_CHR_SRC_TYPE_UNIX,
-
-    QEMUD_CHR_SRC_TYPE_LAST,
-};
-
-enum {
-    QEMUD_CHR_SRC_TCP_PROTOCOL_RAW,
-    QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET,
-};
-
-struct qemud_vm_chr_def {
-    int dstPort;
-
-    int srcType;
-    union {
-        struct {
-            char path[PATH_MAX];
-        } file; /* pty, file, pipe, or device */
-        struct {
-            char host[BR_INET_ADDR_MAXLEN];
-            char service[BR_INET_ADDR_MAXLEN];
-            int listen;
-            int protocol;
-        } tcp;
-        struct {
-            char bindHost[BR_INET_ADDR_MAXLEN];
-            char bindService[BR_INET_ADDR_MAXLEN];
-            char connectHost[BR_INET_ADDR_MAXLEN];
-            char connectService[BR_INET_ADDR_MAXLEN];
-        } udp;
-        struct {
-            char path[PATH_MAX];
-            int listen;
-        } nix;
-    } srcData;
-
-    struct qemud_vm_chr_def *next;
-};
-
-enum qemu_vm_input_type {
-    QEMU_INPUT_TYPE_MOUSE,
-    QEMU_INPUT_TYPE_TABLET,
-};
-
-enum qemu_vm_input_bus {
-    QEMU_INPUT_BUS_PS2,
-    QEMU_INPUT_BUS_USB,
-    QEMU_INPUT_BUS_XEN,
-};
-
-struct qemud_vm_input_def {
-    int type;
-    int bus;
-    struct qemud_vm_input_def *next;
-};
-
-enum qemu_vm_sound_model {
-    QEMU_SOUND_NONE   = 0,
-    QEMU_SOUND_SB16,
-    QEMU_SOUND_ES1370,
-    QEMU_SOUND_PCSPK,
-};
-
-struct qemud_vm_sound_def {
-    int model;
-    struct qemud_vm_sound_def *next;
-};
-
-/* Flags for the 'type' field in next struct */
-enum qemud_vm_device_type {
-    QEMUD_DEVICE_DISK,
-    QEMUD_DEVICE_NET,
-    QEMUD_DEVICE_INPUT,
-    QEMUD_DEVICE_SOUND,
-};
-
-struct qemud_vm_device_def {
-    int type;
-    union {
-        struct qemud_vm_disk_def disk;
-        struct qemud_vm_net_def net;
-        struct qemud_vm_input_def input;
-        struct qemud_vm_sound_def sound;
-    } data;
-};
-
-#define QEMUD_MAX_BOOT_DEVS 4
-
-/* 3 possible boot devices */
-enum qemud_vm_boot_order {
-    QEMUD_BOOT_FLOPPY,
-    QEMUD_BOOT_CDROM,
-    QEMUD_BOOT_DISK,
-    QEMUD_BOOT_NET,
-};
-/* 3 possible graphics console modes */
-enum qemud_vm_graphics_type {
-    QEMUD_GRAPHICS_NONE,
-    QEMUD_GRAPHICS_SDL,
-    QEMUD_GRAPHICS_VNC,
-};
 
 /* Internal flags to keep track of qemu command line capabilities */
 enum qemud_cmd_flags {
@@ -251,107 +49,12 @@
     QEMUD_CMD_FLAG_NAME           = (1 << 5),
 };
 
-
-enum qemud_vm_features {
-    QEMUD_FEATURE_ACPI = 1,
-};
-
-/* Operating system configuration data & machine / arch */
-struct qemud_vm_os_def {
-    char type[QEMUD_OS_TYPE_MAX_LEN];
-    char arch[QEMUD_OS_ARCH_MAX_LEN];
-    char machine[QEMUD_OS_MACHINE_MAX_LEN];
-    int nBootDevs;
-    int bootDevs[QEMUD_MAX_BOOT_DEVS];
-    char kernel[PATH_MAX];
-    char initrd[PATH_MAX];
-    char cmdline[PATH_MAX];
-    char binary[PATH_MAX];
-    char bootloader[PATH_MAX];
-};
-
-/* Guest VM main configuration */
-struct qemud_vm_def {
-    int virtType;
-    unsigned char uuid[VIR_UUID_BUFLEN];
-    char name[QEMUD_MAX_NAME_LEN];
-
-    unsigned long memory;
-    unsigned long maxmem;
-    int vcpus;
-    char cpumask[QEMUD_CPUMASK_LEN];
-
-    int noReboot;
-
-    struct qemud_vm_os_def os;
-
-    int localtime;
-    int features;
-    int graphicsType;
-    int vncPort;
-    int vncActivePort;
-    char vncListen[BR_INET_ADDR_MAXLEN];
-    char *keymap;
-
-    unsigned int ndisks;
-    struct qemud_vm_disk_def *disks;
-
-    unsigned int nnets;
-    struct qemud_vm_net_def *nets;
-
-    unsigned int ninputs;
-    struct qemud_vm_input_def *inputs;
-
-    unsigned int nsounds;
-    struct qemud_vm_sound_def *sounds;
-
-    unsigned int nserials;
-    struct qemud_vm_chr_def *serials;
-
-    unsigned int nparallels;
-    struct qemud_vm_chr_def *parallels;
-};
-
-/* Guest VM runtime state */
-struct qemud_vm {
-    int stdin;
-    int stdout;
-    int stderr;
-    int monitor;
-    int logfile;
-    int pid;
-    int id;
-    int state;
-
-    int *tapfds;
-    int ntapfds;
-
-    int nvcpupids;
-    int *vcpupids;
-
-    int qemuVersion;
-    int qemuCmdFlags; /* values from enum qemud_cmd_flags */
-
-    char configFile[PATH_MAX];
-    char autostartLink[PATH_MAX];
-    char migrateFrom[PATH_MAX];
-
-    struct qemud_vm_def *def; /* The current definition */
-    struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
-
-    unsigned int autostart : 1;
-
-    struct qemud_vm *next;
-};
-
 /* Main driver state */
 struct qemud_driver {
     int qemuVersion;
-    int nactivevms;
-    int ninactivevms;
-    struct qemud_vm *vms;
     int nextvmid;
 
+    virDomainObjPtr domains;
     virNetworkObjPtr networks;
 
     brControl *brctl;
@@ -360,21 +63,15 @@
     char *autostartDir;
     char *networkConfigDir;
     char *networkAutostartDir;
-    char logDir[PATH_MAX];
+    char *logDir;
     unsigned int vncTLS : 1;
     unsigned int vncTLSx509verify : 1;
     char *vncTLSx509certdir;
-    char vncListen[BR_INET_ADDR_MAXLEN];
+    char *vncListen;
 
     virCapsPtr caps;
 };
 
-
-static inline int
-qemudIsActiveVM(const struct qemud_vm *vm)
-{
-    return vm->id != -1;
-}
 
 void qemudReportError(virConnectPtr conn,
                       virDomainPtr dom,
@@ -386,21 +83,22 @@
 int qemudLoadDriverConfig(struct qemud_driver *driver,
                           const char *filename);
 
-struct qemud_vm *qemudFindVMByID(const struct qemud_driver *driver,
-                                 int id);
-struct qemud_vm *qemudFindVMByUUID(const struct qemud_driver *driver,
-                                   const unsigned char *uuid);
-struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver,
-                                   const char *name);
-
 virCapsPtr  qemudCapsInit               (void);
 
 int         qemudExtractVersion         (virConnectPtr conn,
                                          struct qemud_driver *driver);
+int         qemudExtractVersionInfo     (const char *qemu,
+                                         int *version,
+                                         int *flags);
+
 int         qemudBuildCommandLine       (virConnectPtr conn,
                                          struct qemud_driver *driver,
-                                         struct qemud_vm *vm,
-                                         char ***argv);
+                                         virDomainObjPtr dom,
+                                         int qemuCmdFlags,
+                                         char ***argv,
+                                         int **tapfds,
+                                         int *ntapfds,
+                                         const char *migrateFrom);
 
 int         qemudScanConfigs            (struct qemud_driver *driver);
 int         qemudDeleteConfig           (virConnectPtr conn,
@@ -408,43 +106,15 @@
                                          const char *configFile,
                                          const char *name);
 
-void        qemudFreeVMDef              (struct qemud_vm_def *vm);
-void        qemudFreeVM                 (struct qemud_vm *vm);
-
-struct qemud_vm *
-            qemudAssignVMDef            (virConnectPtr conn,
+int         qemudSaveDomainDef          (virConnectPtr conn,
                                          struct qemud_driver *driver,
-                                         struct qemud_vm_def *def);
-void        qemudRemoveInactiveVM       (struct qemud_driver *driver,
-                                         struct qemud_vm *vm);
-
-struct qemud_vm_device_def *
-            qemudParseVMDeviceDef       (virConnectPtr conn,
-                                         const struct qemud_vm_def *def,
-                                         const char *xmlStr);
-
-struct qemud_vm_def *
-            qemudParseVMDef             (virConnectPtr conn,
-                                         struct qemud_driver *driver,
-                                         const char *xmlStr,
-                                         const char *displayName);
-int         qemudSaveVMDef              (virConnectPtr conn,
-                                         struct qemud_driver *driver,
-                                         struct qemud_vm *vm,
-                                         struct qemud_vm_def *def);
-char *      qemudGenerateXML            (virConnectPtr conn,
-                                         struct qemud_driver *driver,
-                                         struct qemud_vm *vm,
-                                         struct qemud_vm_def *def,
-                                         int live);
-
+                                         virDomainObjPtr domain,
+                                         int active);
 int         qemudSaveNetworkDef         (virConnectPtr conn,
                                          struct qemud_driver *driver,
                                          virNetworkObjPtr network,
                                          int active);
 
-const char *qemudVirtTypeToString       (int type);
-
 #endif /* WITH_QEMU */
 
 #endif /* __QEMUD_CONF_H */
diff -r 286320a1cbc8 src/qemu_driver.c
--- a/src/qemu_driver.c	Sun Jun 22 18:04:01 2008 -0400
+++ b/src/qemu_driver.c	Sun Jun 22 18:08:24 2008 -0400
@@ -110,11 +110,12 @@
 static void qemudDispatchVMEvent(int fd, int events, void *opaque);
 static int qemudStartVMDaemon(virConnectPtr conn,
                               struct qemud_driver *driver,
-                              struct qemud_vm *vm);
+                              virDomainObjPtr vm,
+                              const char *migrateFrom);
 
 static void qemudShutdownVMDaemon(virConnectPtr conn,
                                   struct qemud_driver *driver,
-                                  struct qemud_vm *vm);
+                                  virDomainObjPtr vm);
 
 static int qemudStartNetworkDaemon(virConnectPtr conn,
                                    struct qemud_driver *driver,
@@ -126,7 +127,7 @@
 
 static int qemudDomainGetMaxVcpus(virDomainPtr dom);
 static int qemudMonitorCommand (const struct qemud_driver *driver,
-                                const struct qemud_vm *vm,
+                                const virDomainObjPtr vm,
                                 const char *cmd,
                                 char **reply);
 
@@ -136,7 +137,7 @@
 static
 void qemudAutostartConfigs(struct qemud_driver *driver) {
     virNetworkObjPtr network;
-    struct qemud_vm *vm;
+    virDomainObjPtr vm;
 
     network = driver->networks;
     while (network != NULL) {
@@ -153,13 +154,13 @@
         network = next;
     }
 
-    vm = driver->vms;
+    vm = driver->domains;
     while (vm != NULL) {
-        struct qemud_vm *next = vm->next;
+        virDomainObjPtr next = vm->next;
 
         if (vm->autostart &&
-            !qemudIsActiveVM(vm) &&
-            qemudStartVMDaemon(NULL, driver, vm) < 0) {
+            !virDomainIsActive(vm) &&
+            qemudStartVMDaemon(NULL, driver, vm, NULL) < 0) {
             virErrorPtr err = virGetLastError();
             qemudLog(QEMUD_ERR, _("Failed to autostart VM '%s': %s"),
                      vm->def->name, err->message);
@@ -188,8 +189,9 @@
     qemu_driver->nextvmid = 1;
 
     if (!uid) {
-        if (snprintf(qemu_driver->logDir, PATH_MAX, "%s/log/libvirt/qemu", LOCAL_STATE_DIR) >= PATH_MAX)
-            goto snprintf_error;
+        if (asprintf(&qemu_driver->logDir,
+                     "%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1)
+            goto out_of_memory;
 
         if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL)
             goto out_of_memory;
@@ -200,8 +202,9 @@
             goto out_of_memory;
         }
 
-        if (snprintf(qemu_driver->logDir, PATH_MAX, "%s/.libvirt/qemu/log", pw->pw_dir) >= PATH_MAX)
-            goto snprintf_error;
+        if (asprintf(&qemu_driver->logDir,
+                     "%s/.libvirt/qemu/log", pw->pw_dir) == -1)
+            goto out_of_memory;
 
         if (asprintf (&base, "%s/.libvirt", pw->pw_dir) == -1) {
             qemudLog (QEMUD_ERR,
@@ -248,11 +251,6 @@
 
     return 0;
 
- snprintf_error:
-    qemudLog(QEMUD_ERR,
-             "%s", _("Resulting path to long for buffer in qemudInitPaths()"));
-    return -1;
-
  out_of_memory:
     qemudLog (QEMUD_ERR,
               "%s", _("qemudStartup: out of memory"));
@@ -292,15 +290,19 @@
  */
 static int
 qemudActive(void) {
+    virDomainObjPtr dom = qemu_driver->domains;
     virNetworkObjPtr net = qemu_driver->networks;
+    while (dom) {
+        if (virDomainIsActive(dom))
+            return 1;
+        dom = dom->next;
+    }
+
     while (net) {
-        if (net->active)
+        if (virNetworkIsActive(net))
             return 1;
         net = net->next;
     }
-
-    if (qemu_driver->nactivevms)
-        return 1;
 
     /* Otherwise we're happy to deal with a shutdown */
     return 0;
@@ -313,7 +315,7 @@
  */
 static int
 qemudShutdown(void) {
-    struct qemud_vm *vm;
+    virDomainObjPtr vm;
     virNetworkObjPtr network;
 
     if (!qemu_driver)
@@ -322,26 +324,25 @@
     virCapabilitiesFree(qemu_driver->caps);
 
     /* shutdown active VMs */
-    vm = qemu_driver->vms;
+    vm = qemu_driver->domains;
     while (vm) {
-        struct qemud_vm *next = vm->next;
-        if (qemudIsActiveVM(vm))
+        virDomainObjPtr next = vm->next;
+        if (virDomainIsActive(vm))
             qemudShutdownVMDaemon(NULL, qemu_driver, vm);
-        if (!vm->configFile[0])
-            qemudRemoveInactiveVM(qemu_driver, vm);
+        if (!vm->configFile)
+            virDomainRemoveInactive(&qemu_driver->domains,
+                                    vm);
         vm = next;
     }
 
     /* free inactive VMs */
-    vm = qemu_driver->vms;
+    vm = qemu_driver->domains;
     while (vm) {
-        struct qemud_vm *next = vm->next;
-        qemudFreeVM(vm);
+        virDomainObjPtr next = vm->next;
+        virDomainObjFree(vm);
         vm = next;
     }
-    qemu_driver->vms = NULL;
-    qemu_driver->nactivevms = 0;
-    qemu_driver->ninactivevms = 0;
+    qemu_driver->domains = NULL;
 
     /* shutdown active networks */
     network = qemu_driver->networks;
@@ -361,6 +362,7 @@
     }
     qemu_driver->networks = NULL;
 
+    VIR_FREE(qemu_driver->logDir);
     VIR_FREE(qemu_driver->configDir);
     VIR_FREE(qemu_driver->autostartDir);
     VIR_FREE(qemu_driver->networkConfigDir);
@@ -380,14 +382,14 @@
 /* Return -1 for error, 1 to continue reading and 0 for success */
 typedef int qemudHandlerMonitorOutput(virConnectPtr conn,
                                       struct qemud_driver *driver,
-                                      struct qemud_vm *vm,
+                                      virDomainObjPtr vm,
                                       const char *output,
                                       int fd);
 
 static int
 qemudReadMonitorOutput(virConnectPtr conn,
                        struct qemud_driver *driver,
-                       struct qemud_vm *vm,
+                       virDomainObjPtr vm,
                        int fd,
                        char *buf,
                        int buflen,
@@ -460,7 +462,7 @@
 static int
 qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
                         struct qemud_driver *driver ATTRIBUTE_UNUSED,
-                        struct qemud_vm *vm,
+                        virDomainObjPtr vm,
                         const char *output,
                         int fd)
 {
@@ -474,7 +476,7 @@
 
 static int qemudOpenMonitor(virConnectPtr conn,
                             struct qemud_driver *driver,
-                            struct qemud_vm *vm,
+                            virDomainObjPtr vm,
                             const char *monitor) {
     int monfd;
     char buf[1024];
@@ -551,13 +553,13 @@
 static int
 qemudFindCharDevicePTYs(virConnectPtr conn,
                         struct qemud_driver *driver,
-                        struct qemud_vm *vm,
+                        virDomainObjPtr vm,
                         const char *output,
                         int fd ATTRIBUTE_UNUSED)
 {
     char monitor[PATH_MAX];
     size_t offset = 0;
-    struct qemud_vm_chr_def *chr;
+    virDomainChrDefPtr chr;
 
     /* The order in which QEMU prints out the PTY paths is
        the order in which it procsses its monitor, serial
@@ -571,10 +573,10 @@
     /* then the serial devices */
     chr = vm->def->serials;
     while (chr) {
-        if (chr->srcType == QEMUD_CHR_SRC_TYPE_PTY) {
+        if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
             if (qemudExtractMonitorPath(output, &offset,
-                                        chr->srcData.file.path,
-                                        sizeof(chr->srcData.file.path)) < 0)
+                                        chr->data.file.path,
+                                        sizeof(chr->data.file.path)) < 0)
                 return 1; /* keep reading */
         }
         chr = chr->next;
@@ -583,10 +585,10 @@
     /* and finally the parallel devices */
     chr = vm->def->parallels;
     while (chr) {
-        if (chr->srcType == QEMUD_CHR_SRC_TYPE_PTY) {
+        if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
             if (qemudExtractMonitorPath(output, &offset,
-                                        chr->srcData.file.path,
-                                        sizeof(chr->srcData.file.path)) < 0)
+                                        chr->data.file.path,
+                                        sizeof(chr->data.file.path)) < 0)
                 return 1; /* keep reading */
         }
         chr = chr->next;
@@ -598,7 +600,7 @@
 
 static int qemudWaitForMonitor(virConnectPtr conn,
                                struct qemud_driver *driver,
-                               struct qemud_vm *vm) {
+                               virDomainObjPtr vm) {
     char buf[1024]; /* Plenty of space to get startup greeting */
     int ret = qemudReadMonitorOutput(conn,
                                      driver, vm, vm->stderr,
@@ -619,14 +621,14 @@
 static int
 qemudDetectVcpuPIDs(virConnectPtr conn,
                     struct qemud_driver *driver,
-                    struct qemud_vm *vm) {
+                    virDomainObjPtr vm) {
     char *qemucpus = NULL;
     char *line;
     int lastVcpu = -1;
 
     /* Only KVM has seperate threads for CPUs,
        others just use main QEMU process for CPU */
-    if (vm->def->virtType != QEMUD_VIRT_KVM)
+    if (vm->def->virtType != VIR_DOMAIN_VIRT_KVM)
         vm->nvcpupids = 1;
     else
         vm->nvcpupids = vm->def->vcpus;
@@ -637,7 +639,7 @@
         return -1;
     }
 
-    if (vm->def->virtType != QEMUD_VIRT_KVM) {
+    if (vm->def->virtType != VIR_DOMAIN_VIRT_KVM) {
         vm->vcpupids[0] = vm->pid;
         return 0;
     }
@@ -719,7 +721,7 @@
 static int
 qemudInitCpus(virConnectPtr conn,
               struct qemud_driver *driver,
-              struct qemud_vm *vm) {
+              virDomainObjPtr vm) {
     char *info = NULL;
 #if HAVE_SCHED_GETAFFINITY
     cpu_set_t mask;
@@ -800,28 +802,33 @@
 
 static int qemudStartVMDaemon(virConnectPtr conn,
                               struct qemud_driver *driver,
-                              struct qemud_vm *vm) {
+                              virDomainObjPtr vm,
+                              const char *migrateFrom) {
     char **argv = NULL, **tmp;
     int i, ret;
     char logfile[PATH_MAX];
     struct stat sb;
+    int *tapfds = NULL;
+    int ntapfds = 0;
+    int qemuCmdFlags;
 
-    if (qemudIsActiveVM(vm)) {
+    if (virDomainIsActive(vm)) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                          "%s", _("VM is already active"));
         return -1;
     }
 
-    if (vm->def->vncPort < 0) {
+    if (vm->def->graphics &&
+        vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+        vm->def->graphics->data.vnc.autoport) {
         int port = qemudNextFreeVNCPort(driver);
         if (port < 0) {
             qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                              "%s", _("Unable to find an unused VNC port"));
             return -1;
         }
-        vm->def->vncActivePort = port;
-    } else
-        vm->def->vncActivePort = vm->def->vncPort;
+        vm->def->graphics->data.vnc.port = port;
+    }
 
     if ((strlen(driver->logDir) + /* path */
          1 + /* Separator */
@@ -865,16 +872,26 @@
      * Technically we could catch the exec() failure, but that's
      * in a sub-process so its hard to feed back a useful error
      */
-    if (stat(vm->def->os.binary, &sb) < 0) {
+    if (stat(vm->def->emulator, &sb) < 0) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                          _("Cannot find QEMU binary %s: %s"),
-                         vm->def->os.binary,
+                         vm->def->emulator,
                          strerror(errno));
         return -1;
     }
 
+    if (qemudExtractVersionInfo(vm->def->emulator,
+                                NULL,
+                                &qemuCmdFlags) < 0) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("Cannot determine QEMU argv syntax %s"),
+                         vm->def->emulator);
+        return -1;
+    }
 
-    if (qemudBuildCommandLine(conn, driver, vm, &argv) < 0) {
+    if (qemudBuildCommandLine(conn, driver, vm,
+                              qemuCmdFlags, &argv,
+                              &tapfds, &ntapfds, migrateFrom) < 0) {
         close(vm->logfile);
         vm->logfile = -1;
         return -1;
@@ -897,24 +914,19 @@
     ret = virExecNonBlock(conn, argv, &vm->pid,
                           vm->stdin, &vm->stdout, &vm->stderr);
     if (ret == 0) {
-        vm->id = driver->nextvmid++;
-        vm->state = vm->migrateFrom[0] ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
-
-        driver->ninactivevms--;
-        driver->nactivevms++;
+        vm->def->id = driver->nextvmid++;
+        vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
     }
 
     for (i = 0 ; argv[i] ; i++)
         VIR_FREE(argv[i]);
     VIR_FREE(argv);
 
-    if (vm->tapfds) {
-        for (i = 0; vm->tapfds[i] != -1; i++) {
-            close(vm->tapfds[i]);
-            vm->tapfds[i] = -1;
+    if (tapfds) {
+        for (i = 0 ; i < ntapfds ; i++) {
+            close(tapfds[i]);
         }
-        VIR_FREE(vm->tapfds);
-        vm->ntapfds = 0;
+        VIR_FREE(tapfds);
     }
 
     if (ret == 0) {
@@ -938,7 +950,7 @@
 }
 
 static int qemudVMData(struct qemud_driver *driver ATTRIBUTE_UNUSED,
-                       struct qemud_vm *vm, int fd) {
+                       virDomainObjPtr vm, int fd) {
     char buf[4096];
     if (vm->pid < 0)
         return 0;
@@ -967,8 +979,8 @@
 
 
 static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
-                                  struct qemud_driver *driver, struct qemud_vm *vm) {
-    if (!qemudIsActiveVM(vm))
+                                  struct qemud_driver *driver, virDomainObjPtr vm) {
+    if (!virDomainIsActive(vm))
         return;
 
     qemudLog(QEMUD_INFO, _("Shutting down VM '%s'"), vm->def->name);
@@ -1002,35 +1014,35 @@
     }
 
     vm->pid = -1;
-    vm->id = -1;
+    vm->def->id = -1;
     vm->state = VIR_DOMAIN_SHUTOFF;
     VIR_FREE(vm->vcpupids);
     vm->nvcpupids = 0;
 
     if (vm->newDef) {
-        qemudFreeVMDef(vm->def);
+        virDomainDefFree(vm->def);
         vm->def = vm->newDef;
+        vm->def->id = -1;
         vm->newDef = NULL;
     }
-
-    driver->nactivevms--;
-    driver->ninactivevms++;
 }
 
-static int qemudDispatchVMLog(struct qemud_driver *driver, struct qemud_vm *vm, int fd) {
+static int qemudDispatchVMLog(struct qemud_driver *driver, virDomainObjPtr vm, int fd) {
     if (qemudVMData(driver, vm, fd) < 0) {
         qemudShutdownVMDaemon(NULL, driver, vm);
-        if (!vm->configFile[0])
-            qemudRemoveInactiveVM(driver, vm);
+        if (!vm->configFile)
+            virDomainRemoveInactive(&driver->domains,
+                                    vm);
     }
     return 0;
 }
 
-static int qemudDispatchVMFailure(struct qemud_driver *driver, struct qemud_vm *vm,
+static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr vm,
                                   int fd ATTRIBUTE_UNUSED) {
     qemudShutdownVMDaemon(NULL, driver, vm);
-    if (!vm->configFile[0])
-        qemudRemoveInactiveVM(driver, vm);
+    if (!vm->configFile)
+        virDomainRemoveInactive(&driver->domains,
+                                vm);
     return 0;
 }
 
@@ -1560,10 +1572,10 @@
 
 static void qemudDispatchVMEvent(int fd, int events, void *opaque) {
     struct qemud_driver *driver = (struct qemud_driver *)opaque;
-    struct qemud_vm *vm = driver->vms;
+    virDomainObjPtr vm = driver->domains;
 
     while (vm) {
-        if (qemudIsActiveVM(vm) &&
+        if (virDomainIsActive(vm) &&
             (vm->stdout == fd ||
              vm->stderr == fd))
             break;
@@ -1582,7 +1594,7 @@
 
 static int
 qemudMonitorCommand (const struct qemud_driver *driver ATTRIBUTE_UNUSED,
-                     const struct qemud_vm *vm,
+                     const virDomainObjPtr vm,
                      const char *cmd,
                      char **reply) {
     int size = 0;
@@ -1852,9 +1864,9 @@
 
 
 static virDomainPtr qemudDomainLookupByID(virConnectPtr conn,
-                                   int id) {
+                                          int id) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByID(driver, id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, id);
     virDomainPtr dom;
 
     if (!vm) {
@@ -1863,13 +1875,13 @@
     }
 
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
-    if (dom) dom->id = vm->id;
+    if (dom) dom->id = vm->def->id;
     return dom;
 }
 static virDomainPtr qemudDomainLookupByUUID(virConnectPtr conn,
-                                     const unsigned char *uuid) {
+                                            const unsigned char *uuid) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, uuid);
     virDomainPtr dom;
 
     if (!vm) {
@@ -1878,13 +1890,13 @@
     }
 
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
-    if (dom) dom->id = vm->id;
+    if (dom) dom->id = vm->def->id;
     return dom;
 }
 static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
-                                     const char *name) {
+                                            const char *name) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByName(driver, name);
+    virDomainObjPtr vm = virDomainFindByName(driver->domains, name);
     virDomainPtr dom;
 
     if (!vm) {
@@ -1893,7 +1905,7 @@
     }
 
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
-    if (dom) dom->id = vm->id;
+    if (dom) dom->id = vm->def->id;
     return dom;
 }
 
@@ -1930,11 +1942,11 @@
 
 static int qemudListDomains(virConnectPtr conn, int *ids, int nids) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    struct qemud_vm *vm = driver->vms;
+    virDomainObjPtr vm = driver->domains;
     int got = 0;
     while (vm && got < nids) {
-        if (qemudIsActiveVM(vm)) {
-            ids[got] = vm->id;
+        if (virDomainIsActive(vm)) {
+            ids[got] = vm->def->id;
             got++;
         }
         vm = vm->next;
@@ -1943,30 +1955,40 @@
 }
 static int qemudNumDomains(virConnectPtr conn) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    return driver->nactivevms;
+    int n = 0;
+    virDomainObjPtr dom = driver->domains;
+    while (dom) {
+        if (virDomainIsActive(dom))
+            n++;
+        dom = dom->next;
+    }
+    return n;
 }
 static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
                                       unsigned int flags ATTRIBUTE_UNUSED) {
-    struct qemud_vm_def *def;
-    struct qemud_vm *vm;
+    virDomainDefPtr def;
+    virDomainObjPtr vm;
     virDomainPtr dom;
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
 
-    if (!(def = qemudParseVMDef(conn, driver, xml, NULL)))
+    if (!(def = virDomainDefParse(conn, driver->caps, xml, NULL)))
         return NULL;
 
-    if (!(vm = qemudAssignVMDef(conn, driver, def))) {
-        qemudFreeVMDef(def);
+    if (!(vm = virDomainAssignDef(conn,
+                                  &driver->domains,
+                                  def))) {
+        virDomainDefFree(def);
         return NULL;
     }
 
-    if (qemudStartVMDaemon(conn, driver, vm) < 0) {
-        qemudRemoveInactiveVM(driver, vm);
+    if (qemudStartVMDaemon(conn, driver, vm, NULL) < 0) {
+        virDomainRemoveInactive(&driver->domains,
+                                vm);
         return NULL;
     }
 
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
-    if (dom) dom->id = vm->id;
+    if (dom) dom->id = vm->def->id;
     return dom;
 }
 
@@ -1974,12 +1996,12 @@
 static int qemudDomainSuspend(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
     char *info;
-    struct qemud_vm *vm = qemudFindVMByID(driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, _("no domain with matching id %d"), dom->id);
         return -1;
     }
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("domain is not running"));
         return -1;
@@ -2002,13 +2024,13 @@
 static int qemudDomainResume(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
     char *info;
-    struct qemud_vm *vm = qemudFindVMByID(driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
                          _("no domain with matching id %d"), dom->id);
         return -1;
     }
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("domain is not running"));
         return -1;
@@ -2029,7 +2051,7 @@
 
 static int qemudDomainShutdown(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByID(driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
     char* info;
 
     if (!vm) {
@@ -2050,7 +2072,7 @@
 
 static int qemudDomainDestroy(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByID(driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2059,8 +2081,9 @@
     }
 
     qemudShutdownVMDaemon(dom->conn, driver, vm);
-    if (!vm->configFile[0])
-        qemudRemoveInactiveVM(driver, vm);
+    if (!vm->configFile)
+        virDomainRemoveInactive(&driver->domains,
+                                vm);
 
     return 0;
 }
@@ -2068,7 +2091,7 @@
 
 static char *qemudDomainGetOSType(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
     char *type;
 
     if (!vm) {
@@ -2088,7 +2111,7 @@
 /* Returns max memory in kb, 0 if error */
 static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2101,7 +2124,7 @@
 
 static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2121,7 +2144,7 @@
 
 static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2129,7 +2152,7 @@
         return -1;
     }
 
-    if (qemudIsActiveVM(vm)) {
+    if (virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
                          "%s", _("cannot set memory of an active domain"));
         return -1;
@@ -2146,9 +2169,9 @@
 }
 
 static int qemudDomainGetInfo(virDomainPtr dom,
-                       virDomainInfoPtr info) {
+                              virDomainInfoPtr info) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
                          "%s", _("no domain with matching uuid"));
@@ -2157,7 +2180,7 @@
 
     info->state = vm->state;
 
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         info->cpuTime = 0;
     } else {
         if (qemudGetProcessInfo(&(info->cpuTime), vm->pid) < 0) {
@@ -2269,7 +2292,7 @@
 static int qemudDomainSave(virDomainPtr dom,
                            const char *path) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByID(driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
     char *command, *info;
     int fd;
     char *safe_path;
@@ -2286,7 +2309,7 @@
         return -1;
     }
 
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("domain is not running"));
         return -1;
@@ -2303,7 +2326,7 @@
     }
 
     /* Get XML for the domain */
-    xml = qemudGenerateXML(dom->conn, driver, vm, vm->def, 0);
+    xml = virDomainDefFormat(dom->conn, vm->def, 1);
     if (!xml) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("failed to get domain xml"));
@@ -2367,8 +2390,9 @@
 
     /* Shut it down */
     qemudShutdownVMDaemon(dom->conn, driver, vm);
-    if (!vm->configFile[0])
-        qemudRemoveInactiveVM(driver, vm);
+    if (!vm->configFile)
+        virDomainRemoveInactive(&driver->domains,
+                                vm);
 
     return 0;
 }
@@ -2376,7 +2400,7 @@
 
 static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
     const struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
     int max;
 
     if (!vm) {
@@ -2385,7 +2409,7 @@
         return -1;
     }
 
-    if (qemudIsActiveVM(vm)) {
+    if (virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
                          _("cannot change vcpu count of an active domain"));
         return -1;
@@ -2416,12 +2440,12 @@
                    unsigned char *cpumap,
                    int maplen) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
     cpu_set_t mask;
     int i, maxcpu;
     virNodeInfo nodeinfo;
 
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
                          "%s",_("cannot pin vcpus on an inactive domain"));
         return -1;
@@ -2469,11 +2493,11 @@
                     unsigned char *cpumaps,
                     int maplen) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
     virNodeInfo nodeinfo;
     int i, v, maxcpu;
 
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
                          "%s",_("cannot pin vcpus on an inactive domain"));
         return -1;
@@ -2534,7 +2558,7 @@
 
 static int qemudDomainGetMaxVcpus(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
     const char *type;
     int ret;
 
@@ -2544,7 +2568,7 @@
         return -1;
     }
 
-    if (!(type = qemudVirtTypeToString(vm->def->virtType))) {
+    if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
                          _("unknown virt type in domain definition '%d'"),
                          vm->def->virtType);
@@ -2562,8 +2586,8 @@
 static int qemudDomainRestore(virConnectPtr conn,
                        const char *path) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    struct qemud_vm_def *def;
-    struct qemud_vm *vm;
+    virDomainDefPtr def;
+    virDomainObjPtr vm;
     int fd;
     int ret;
     char *xml;
@@ -2614,7 +2638,7 @@
     }
 
     /* Create a domain from this XML */
-    if (!(def = qemudParseVMDef(conn, driver, xml, NULL))) {
+    if (!(def = virDomainDefParse(conn, driver->caps, xml, NULL))) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("failed to parse XML"));
         close(fd);
@@ -2624,35 +2648,37 @@
     VIR_FREE(xml);
 
     /* Ensure the name and UUID don't already exist in an active VM */
-    vm = qemudFindVMByUUID(driver, def->uuid);
-    if (!vm) vm = qemudFindVMByName(driver, def->name);
-    if (vm && qemudIsActiveVM(vm)) {
+    vm = virDomainFindByUUID(driver->domains, def->uuid);
+    if (!vm)
+        vm = virDomainFindByName(driver->domains, def->name);
+    if (vm && virDomainIsActive(vm)) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
                          _("domain is already active as '%s'"), vm->def->name);
         close(fd);
         return -1;
     }
 
-    if (!(vm = qemudAssignVMDef(conn, driver, def))) {
+    if (!(vm = virDomainAssignDef(conn,
+                                  &driver->domains,
+                                  def))) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("failed to assign new VM"));
-        qemudFreeVMDef(def);
+        virDomainDefFree(def);
         close(fd);
         return -1;
     }
 
     /* Set the migration source and start it up. */
-    snprintf(vm->migrateFrom, sizeof(vm->migrateFrom), "stdio");
     vm->stdin = fd;
-    ret = qemudStartVMDaemon(conn, driver, vm);
+    ret = qemudStartVMDaemon(conn, driver, vm, "stdio");
     close(fd);
-    vm->migrateFrom[0] = '\0';
     vm->stdin = -1;
     if (ret < 0) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("failed to start VM"));
-        if (!vm->configFile[0])
-            qemudRemoveInactiveVM(driver, vm);
+        if (!vm->configFile)
+            virDomainRemoveInactive(&driver->domains,
+                                    vm);
         return -1;
     }
 
@@ -2673,26 +2699,29 @@
 
 
 static char *qemudDomainDumpXML(virDomainPtr dom,
-                         int flags ATTRIBUTE_UNUSED) {
+                                int flags ATTRIBUTE_UNUSED) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
                          "%s", _("no domain with matching uuid"));
         return NULL;
     }
 
-    return qemudGenerateXML(dom->conn, driver, vm, vm->def, 1);
+    return virDomainDefFormat(dom->conn,
+                              (flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef ?
+                              vm->newDef : vm->def,
+                              (flags & VIR_DOMAIN_XML_SECURE) ? 1 : 0);
 }
 
 
 static int qemudListDefinedDomains(virConnectPtr conn,
                             char **const names, int nnames) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    struct qemud_vm *vm = driver->vms;
+    virDomainObjPtr vm = driver->domains;
     int got = 0, i;
     while (vm && got < nnames) {
-        if (!qemudIsActiveVM(vm)) {
+        if (!virDomainIsActive(vm)) {
             if (!(names[got] = strdup(vm->def->name))) {
                 qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
                      "%s", _("failed to allocate space for VM name string"));
@@ -2713,13 +2742,20 @@
 
 static int qemudNumDefinedDomains(virConnectPtr conn) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    return driver->ninactivevms;
+    int n = 0;
+    virDomainObjPtr dom = driver->domains;
+    while (dom) {
+        if (!virDomainIsActive(dom))
+            n++;
+        dom = dom->next;
+    }
+    return 0;
 }
 
 
 static int qemudDomainStart(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2727,37 +2763,40 @@
         return -1;
     }
 
-    return qemudStartVMDaemon(dom->conn, driver, vm);
+    return qemudStartVMDaemon(dom->conn, driver, vm, NULL);
 }
 
 
 static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    struct qemud_vm_def *def;
-    struct qemud_vm *vm;
+    virDomainDefPtr def;
+    virDomainObjPtr vm;
     virDomainPtr dom;
 
-    if (!(def = qemudParseVMDef(conn, driver, xml, NULL)))
+    if (!(def = virDomainDefParse(conn, driver->caps, xml, NULL)))
         return NULL;
 
-    if (!(vm = qemudAssignVMDef(conn, driver, def))) {
-        qemudFreeVMDef(def);
+    if (!(vm = virDomainAssignDef(conn,
+                                  &driver->domains,
+                                  def))) {
+        virDomainDefFree(def);
         return NULL;
     }
 
-    if (qemudSaveVMDef(conn, driver, vm, def) < 0) {
-        qemudRemoveInactiveVM(driver, vm);
+    if (qemudSaveDomainDef(conn, driver, vm, 1) < 0) {
+        virDomainRemoveInactive(&driver->domains,
+                                vm);
         return NULL;
     }
 
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
-    if (dom) dom->id = vm->id;
+    if (dom) dom->id = vm->def->id;
     return dom;
 }
 
 static int qemudDomainUndefine(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2765,7 +2804,7 @@
         return -1;
     }
 
-    if (qemudIsActiveVM(vm)) {
+    if (virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
                          "%s", _("cannot delete active domain"));
         return -1;
@@ -2778,22 +2817,20 @@
         qemudLog(QEMUD_WARN, _("Failed to delete autostart link '%s': %s"),
                  vm->autostartLink, strerror(errno));
 
-    vm->configFile[0] = '\0';
-    vm->autostartLink[0] = '\0';
-
-    qemudRemoveInactiveVM(driver, vm);
+    virDomainRemoveInactive(&driver->domains,
+                            vm);
 
     return 0;
 }
 
 static int qemudDomainChangeCDROM(virDomainPtr dom,
-                                  struct qemud_vm *vm,
-                                  struct qemud_vm_disk_def *olddisk,
-                                  struct qemud_vm_disk_def *newdisk) {
+                                  virDomainObjPtr vm,
+                                  virDomainDiskDefPtr olddisk,
+                                  virDomainDiskDefPtr newdisk) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
     char *cmd, *reply, *safe_path;
 
-    if (newdisk->src[0]) {
+    if (newdisk->src) {
         safe_path = qemudEscapeMonitorArg(newdisk->src);
         if (!safe_path) {
             qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
@@ -2833,9 +2870,9 @@
 static int qemudDomainAttachDevice(virDomainPtr dom,
                                    const char *xml) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
-    struct qemud_vm_device_def *dev;
-    struct qemud_vm_disk_def *disk;
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
+    virDomainDeviceDefPtr dev;
+    virDomainDiskDefPtr disk;
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2843,18 +2880,19 @@
         return -1;
     }
 
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
                          "%s", _("cannot attach device on inactive domain"));
         return -1;
     }
 
-    dev = qemudParseVMDeviceDef(dom->conn, vm->def, xml);
+    dev = virDomainDeviceDefParse(dom->conn, vm->def, xml);
     if (dev == NULL) {
         return -1;
     }
 
-    if (dev->type != QEMUD_DEVICE_DISK || dev->data.disk.device != QEMUD_DISK_CDROM) {
+    if (dev->type != VIR_DOMAIN_DEVICE_DISK ||
+        dev->data.disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
                          "%s", _("only CDROM disk devices can be attached"));
         VIR_FREE(dev);
@@ -2863,8 +2901,8 @@
 
     disk = vm->def->disks;
     while (disk) {
-        if (disk->device == QEMUD_DISK_CDROM &&
-            STREQ(disk->dst, dev->data.disk.dst))
+        if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+            STREQ(disk->dst, dev->data.disk->dst))
             break;
         disk = disk->next;
     }
@@ -2876,7 +2914,7 @@
         return -1;
     }
 
-    if (qemudDomainChangeCDROM(dom, vm, disk, &dev->data.disk) < 0) {
+    if (qemudDomainChangeCDROM(dom, vm, disk, dev->data.disk) < 0) {
         VIR_FREE(dev);
         return -1;
     }
@@ -2888,7 +2926,7 @@
 static int qemudDomainGetAutostart(virDomainPtr dom,
                             int *autostart) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2904,7 +2942,7 @@
 static int qemudDomainSetAutostart(virDomainPtr dom,
                             int autostart) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2962,14 +3000,14 @@
     const char *p, *eol;
     char qemu_dev_name[32];
     size_t len;
-    const struct qemud_vm *vm = qemudFindVMByID(driver, dom->id);
+    const virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
 
     if (!vm) {
         qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
                           _("no domain with matching id %d"), dom->id);
         return -1;
     }
-    if (!qemudIsActiveVM (vm)) {
+    if (!virDomainIsActive (vm)) {
         qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                           "%s", _("domain is not running"));
         return -1;
@@ -3096,8 +3134,8 @@
 {
 #ifdef __linux__
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByID (driver, dom->id);
-    struct qemud_vm_net_def *net;
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
+    virDomainNetDefPtr net;
 
     if (!vm) {
         qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -3105,7 +3143,7 @@
         return -1;
     }
 
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("domain is not running"));
         return -1;
@@ -3120,15 +3158,15 @@
     /* Check the path is one of the domain's network interfaces. */
     for (net = vm->def->nets; net; net = net->next) {
         switch (net->type) {
-        case QEMUD_NET_NETWORK:
+        case VIR_DOMAIN_NET_TYPE_NETWORK:
             if (STREQ (net->dst.network.ifname, path))
                 goto ok;
             break;
-        case QEMUD_NET_ETHERNET:
+        case VIR_DOMAIN_NET_TYPE_ETHERNET:
             if (STREQ (net->dst.ethernet.ifname, path))
                 goto ok;
             break;
-        case QEMUD_NET_BRIDGE:
+        case VIR_DOMAIN_NET_TYPE_BRIDGE:
             if (STREQ (net->dst.bridge.ifname, path))
                 goto ok;
             break;
@@ -3156,8 +3194,8 @@
                       unsigned int flags ATTRIBUTE_UNUSED)
 {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByUUID (driver, dom->uuid);
-    int i;
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
+    virDomainDiskDefPtr disk;
     int fd, ret = -1;
 
     if (!vm) {
@@ -3173,8 +3211,9 @@
     }
 
     /* Check the path belongs to this domain. */
-    for (i = 0; i < vm->def->ndisks; ++i) {
-        if (STREQ (vm->def->disks[i].src, path)) goto found;
+    for (disk = vm->def->disks ; disk != NULL ; disk = disk->next) {
+        if (disk->src != NULL &&
+            STREQ (disk->src, path)) goto found;
     }
     qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
                       _("invalid path"));
@@ -3213,7 +3252,7 @@
                        unsigned int flags)
 {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
-    struct qemud_vm *vm = qemudFindVMByID (driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
     char cmd[256], *info;
     char tmp[] = TEMPDIR "/qemu.mem.XXXXXX";
     int fd = -1, ret = -1;
@@ -3230,7 +3269,7 @@
         return -1;
     }
 
-    if (!qemudIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                          "%s", _("domain is not running"));
         return -1;
@@ -3387,7 +3426,7 @@
 }
 
 static virNetworkPtr qemudNetworkCreate(virConnectPtr conn, const char *xml) {
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
+ struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
     virNetworkDefPtr def;
     virNetworkObjPtr network;
     virNetworkPtr net;
diff -r 286320a1cbc8 tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml
--- a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml	Sun Jun 22 18:04:01 2008 -0400
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml	Sun Jun 22 18:08:24 2008 -0400
@@ -6,7 +6,7 @@
   <vcpu>1</vcpu>
   <bootloader>/usr/bin/pygrub</bootloader>
   <os>
-    <type>xen</type>
+    <type arch='x86_64' machine='xenner'>xen</type>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
diff -r 286320a1cbc8 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml	Sun Jun 22 18:04:01 2008 -0400
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml	Sun Jun 22 18:08:24 2008 -0400
@@ -19,6 +19,6 @@
       <target dev='hda' bus='ide'/>
     </disk>
     <input type='mouse' bus='ps2'/>
-    <graphics type='vnc' port='5903' listen='127.0.0.1'/>
+    <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/>
   </devices>
 </domain>
diff -r 286320a1cbc8 tests/qemuxml2argvdata/qemuxml2argv-input-xen.args
--- a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.args	Sun Jun 22 18:04:01 2008 -0400
+++ b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.args	Sun Jun 22 18:08:24 2008 -0400
@@ -1,1 +1,1 @@
-/usr/bin/xenner -S -M xenner -m 214 -smp 1 -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc :-5901
\ No newline at end of file
+/usr/bin/xenner -S -M xenner -m 214 -smp 1 -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc 127.0.0.1:3
\ No newline at end of file
diff -r 286320a1cbc8 tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml
--- a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml	Sun Jun 22 18:04:01 2008 -0400
+++ b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml	Sun Jun 22 18:08:24 2008 -0400
@@ -5,7 +5,7 @@
   <currentMemory>219200</currentMemory>
   <vcpu>1</vcpu>
   <os>
-    <type>xen</type>
+    <type arch='x86_64' machine='xenner'>xen</type>
     <boot dev='hd'/>
   </os>
   <clock offset='utc'/>
@@ -19,6 +19,6 @@
       <target dev='hda' bus='ide'/>
     </disk>
     <input type='mouse' bus='xen'/>
-    <graphics type='vnc' port='-1'/>
+    <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/>
   </devices>
 </domain>
diff -r 286320a1cbc8 tests/qemuxml2argvdata/qemuxml2argv-sound.xml
--- a/tests/qemuxml2argvdata/qemuxml2argv-sound.xml	Sun Jun 22 18:04:01 2008 -0400
+++ b/tests/qemuxml2argvdata/qemuxml2argv-sound.xml	Sun Jun 22 18:08:24 2008 -0400
@@ -16,15 +16,10 @@
     <emulator>/usr/bin/qemu</emulator>
     <disk type='block' device='disk'>
       <source dev='/dev/HostVG/QEMUGuest1'/>
-      <target dev='hda'/>
+      <target dev='hda' bus='ide'/>
     </disk>
     <sound model='pcspk'/>
-    <sound model='pcspk'/>
     <sound model='es1370'/>
-    <sound model='pcspk'/>
-    <sound model='sb16'/>
-    <sound model='es1370'/>
-    <sound model='pcspk'/>
     <sound model='sb16'/>
   </devices>
 </domain>
diff -r 286320a1cbc8 tests/qemuxml2argvtest.c
--- a/tests/qemuxml2argvtest.c	Sun Jun 22 18:04:01 2008 -0400
+++ b/tests/qemuxml2argvtest.c	Sun Jun 22 18:08:24 2008 -0400
@@ -30,9 +30,9 @@
     char *actualargv = NULL;
     char **argv = NULL;
     char **tmp = NULL;
-    int ret = -1, len;
-    struct qemud_vm_def *vmdef = NULL;
-    struct qemud_vm vm;
+    int ret = -1, len, flags;
+    virDomainDefPtr vmdef = NULL;
+    virDomainObj vm;
 
     if (virtTestLoadFile(xml, &xmlPtr, MAX_FILE) < 0)
         goto fail;
@@ -40,22 +40,21 @@
     if (virtTestLoadFile(cmd, &expectargv, MAX_FILE) < 0)
         goto fail;
 
-    if (!(vmdef = qemudParseVMDef(NULL, &driver, xmlData, "test")))
+    if (!(vmdef = virDomainDefParse(NULL, driver.caps, xmlData, "test")))
         goto fail;
 
     memset(&vm, 0, sizeof vm);
     vm.def = vmdef;
+    vm.def->id = -1;
     vm.pid = -1;
-    vm.id = -1;
-    vm.qemuVersion = 0 * 1000 * 100 + (8 * 1000) + 1;
-    vm.qemuCmdFlags = QEMUD_CMD_FLAG_VNC_COLON |
-        QEMUD_CMD_FLAG_NO_REBOOT;
-    vm.qemuCmdFlags |= extraFlags;
-    vm.migrateFrom[0] = '\0';
 
-    vmdef->vncActivePort = vmdef->vncPort;
+    flags = QEMUD_CMD_FLAG_VNC_COLON |
+        QEMUD_CMD_FLAG_NO_REBOOT |
+        extraFlags;
 
-    if (qemudBuildCommandLine(NULL, &driver, &vm, &argv) < 0)
+    if (qemudBuildCommandLine(NULL, &driver,
+                              &vm, flags, &argv,
+                              NULL, NULL, NULL) < 0)
         goto fail;
 
     tmp = argv;
@@ -92,8 +91,7 @@
         }
         free(argv);
     }
-    if (vmdef)
-        qemudFreeVMDef(vmdef);
+    virDomainDefFree(vmdef);
     return ret;
 }
 
diff -r 286320a1cbc8 tests/qemuxml2xmltest.c
--- a/tests/qemuxml2xmltest.c	Sun Jun 22 18:04:01 2008 -0400
+++ b/tests/qemuxml2xmltest.c	Sun Jun 22 18:08:24 2008 -0400
@@ -27,25 +27,15 @@
     char *xmlPtr = &(xmlData[0]);
     char *actual = NULL;
     int ret = -1;
-    struct qemud_vm_def *vmdef = NULL;
-    struct qemud_vm vm;
+    virDomainDefPtr vmdef = NULL;
 
     if (virtTestLoadFile(xml, &xmlPtr, MAX_FILE) < 0)
         goto fail;
 
-    if (!(vmdef = qemudParseVMDef(NULL, &driver, xmlData, "test")))
+    if (!(vmdef = virDomainDefParse(NULL, driver.caps, xmlData, "test")))
         goto fail;
 
-    vm.def = vmdef;
-    vm.pid = -1;
-    vm.id = -1;
-    vm.qemuVersion = 0 * 1000 * 100 + (8 * 1000) + 1;
-    vm.qemuCmdFlags = QEMUD_CMD_FLAG_VNC_COLON |
-        QEMUD_CMD_FLAG_NO_REBOOT;
-
-    vmdef->vncActivePort = vmdef->vncPort;
-
-    if (!(actual = qemudGenerateXML(NULL, &driver, &vm, vmdef, 0)))
+    if (!(actual = virDomainDefFormat(NULL, vmdef, 0)))
         goto fail;
 
     if (STRNEQ(xmlData, actual)) {
@@ -57,8 +47,7 @@
 
  fail:
     free(actual);
-    if (vmdef)
-        qemudFreeVMDef(vmdef);
+    virDomainDefFree(vmdef);
     return ret;
 }
 
@@ -115,6 +104,7 @@
     DO_TEST("misc-no-reboot");
     DO_TEST("net-user");
     DO_TEST("net-virtio");
+    DO_TEST("sound");
 
     DO_TEST("serial-vc");
     DO_TEST("serial-pty");

-- 
|: 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 :|




More information about the libvir-list mailing list