[libvirt] PATCH: 4/5: Switch to generic domain API

Daniel P. Berrange berrange at redhat.com
Tue Jul 15 14:15:12 UTC 2008


The re-architecting of the LXC controller/container process relationship
in the previous patch removed the last obstacle to switching over to the
generic domain XML routines. So this patch switches the driver over.

First the domain_conf.c file gets support for a new type of device, a
'filesystem'. This contains a source, and a mount point. The source can
be either an existing directory, or a file or a block device. If it is
a directory the source is just bind mounted into the container; for a
block device just a regular filesystem mount is done. A file must first
be attached to a loop device. LXC only handles directory bind mounts
at this time, but it seemed sensible to let the XML parser handle all
three options.

Then the vast majority of lxc_conf.h/c is deleted - this is all redundant
when using the domain_conf.h APIs. Finally, all references to lxc_vm_t
are changed to virDomainObj, and lxc_vm_def_t switches to virDomainDef.
Finally the LXC driver registers its capabilities data. For this I have
chosen an OS type of 'exe', since the 'operating system' we're running
in the container is just any plain executable process.

 domain_conf.c    |  178 +++++++++
 domain_conf.h    |   27 +
 lxc_conf.c       | 1054 +------------------------------------------------------
 lxc_conf.h       |  121 ------
 lxc_container.c  |   23 -
 lxc_container.h  |    2 
 lxc_controller.c |    4 
 lxc_controller.h |    2 
 lxc_driver.c     |  276 ++++++++------
 9 files changed, 416 insertions(+), 1271 deletions(-)


Daniel

diff -r 7059fd49ed7e src/domain_conf.c
--- a/src/domain_conf.c	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/domain_conf.c	Mon Jul 14 21:34:06 2008 +0100
@@ -86,6 +86,11 @@
               "virtio",
               "xen")
 
+VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
+              "mount",
+              "block",
+              "file")
+
 VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
               "user",
               "ethernet",
@@ -230,6 +235,18 @@
     VIR_FREE(def->driverType);
 
     virDomainDiskDefFree(def->next);
+    VIR_FREE(def);
+}
+
+void virDomainFSDefFree(virDomainFSDefPtr def)
+{
+    if (!def)
+        return;
+
+    VIR_FREE(def->src);
+    VIR_FREE(def->dst);
+
+    virDomainFSDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -341,6 +358,7 @@
     virDomainGraphicsDefFree(def->graphics);
     virDomainInputDefFree(def->inputs);
     virDomainDiskDefFree(def->disks);
+    virDomainFSDefFree(def->fss);
     virDomainNetDefFree(def->nets);
     virDomainChrDefFree(def->serials);
     virDomainChrDefFree(def->parallels);
@@ -351,6 +369,7 @@
     VIR_FREE(def->os.type);
     VIR_FREE(def->os.arch);
     VIR_FREE(def->os.machine);
+    VIR_FREE(def->os.init);
     VIR_FREE(def->os.kernel);
     VIR_FREE(def->os.initrd);
     VIR_FREE(def->os.cmdline);
@@ -610,6 +629,87 @@
 
  error:
     virDomainDiskDefFree(def);
+    def = NULL;
+    goto cleanup;
+}
+
+
+/* Parse the XML definition for a disk
+ * @param node XML nodeset to parse for disk definition
+ */
+static virDomainFSDefPtr
+virDomainFSDefParseXML(virConnectPtr conn,
+                       xmlNodePtr node) {
+    virDomainFSDefPtr def;
+    xmlNodePtr cur;
+    char *type = NULL;
+    char *source = NULL;
+    char *target = NULL;
+
+    if (VIR_ALLOC(def) < 0) {
+        virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+        return NULL;
+    }
+
+    type = virXMLPropString(node, "type");
+    if (type) {
+        if ((def->type = virDomainFSTypeFromString(type)) < 0) {
+            virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                 _("unknown filesystem type '%s'"), type);
+            goto error;
+        }
+    } else {
+        def->type = VIR_DOMAIN_FS_TYPE_MOUNT;
+    }
+
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE) {
+            if ((source == NULL) &&
+                (xmlStrEqual(cur->name, BAD_CAST "source"))) {
+
+                if (def->type == VIR_DOMAIN_FS_TYPE_MOUNT)
+                    source = virXMLPropString(cur, "dir");
+                else if (def->type == VIR_DOMAIN_FS_TYPE_FILE)
+                    source = virXMLPropString(cur, "file");
+                else if (def->type == VIR_DOMAIN_FS_TYPE_BLOCK)
+                    source = virXMLPropString(cur, "dev");
+            } else if ((target == NULL) &&
+                       (xmlStrEqual(cur->name, BAD_CAST "target"))) {
+                target = virXMLPropString(cur, "dir");
+            } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
+                def->readonly = 1;
+            }
+        }
+        cur = cur->next;
+    }
+
+    if (source == NULL) {
+        virDomainReportError(conn, VIR_ERR_NO_SOURCE,
+                             target ? "%s" : NULL, target);
+        goto error;
+    }
+
+    if (target == NULL) {
+        virDomainReportError(conn, VIR_ERR_NO_TARGET,
+                             source ? "%s" : NULL, source);
+        goto error;
+    }
+
+    def->src = source;
+    source = NULL;
+    def->dst = target;
+    target = NULL;
+
+cleanup:
+    VIR_FREE(type);
+    VIR_FREE(target);
+    VIR_FREE(source);
+
+    return def;
+
+ error:
+    virDomainFSDefFree(def);
     def = NULL;
     goto cleanup;
 }
@@ -1344,6 +1444,10 @@
         dev->type = VIR_DOMAIN_DEVICE_DISK;
         if (!(dev->data.disk = virDomainDiskDefParseXML(conn, node)))
             goto error;
+    } else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) {
+        dev->type = VIR_DOMAIN_DEVICE_FS;
+        if (!(dev->data.fs = virDomainFSDefParseXML(conn, node)))
+            goto error;
     } else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
         dev->type = VIR_DOMAIN_DEVICE_NET;
         if (!(dev->data.net = virDomainNetDefParseXML(conn, node)))
@@ -1554,6 +1658,7 @@
     }
 
     if (!def->os.bootloader) {
+        def->os.init = virXPathString(conn, "string(./os/init[1])", ctxt);
         def->os.kernel = virXPathString(conn, "string(./os/kernel[1])", ctxt);
         def->os.initrd = virXPathString(conn, "string(./os/initrd[1])", ctxt);
         def->os.cmdline = virXPathString(conn, "string(./os/cmdline[1])", ctxt);
@@ -1603,12 +1708,15 @@
                                                                    def->os.type,
                                                                    def->os.arch,
                                                                    type);
+#if 0
         if (!emulator) {
             virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
                                  "%s", _("unsupported guest type"));
             goto error;
         }
-        if (!(def->emulator = strdup(emulator))) {
+#endif
+        if (emulator &&
+            !(def->emulator = strdup(emulator))) {
             virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL);
             goto error;
         }
@@ -1641,6 +1749,23 @@
                 ptr = ptr->next;
             }
         }
+    }
+    VIR_FREE(nodes);
+
+    /* analysis of the filesystems */
+    if ((n = virXPathNodeSet(conn, "./devices/filesystem", ctxt, &nodes)) < 0) {
+        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                             "%s", _("cannot extract filesystem devices"));
+        goto error;
+    }
+    for (i = n - 1 ; i >= 0 ; i--) {
+        virDomainFSDefPtr fs = virDomainFSDefParseXML(conn,
+                                                      nodes[i]);
+        if (!fs)
+            goto error;
+
+        fs->next = def->fss;
+        def->fss = fs;
     }
     VIR_FREE(nodes);
 
@@ -2195,6 +2320,46 @@
 }
 
 static int
+virDomainFSDefFormat(virConnectPtr conn,
+                     virBufferPtr buf,
+                     virDomainFSDefPtr def)
+{
+    const char *type = virDomainFSTypeToString(def->type);
+
+    if (!type) {
+        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                             _("unexpected filesystem type %d"), def->type);
+        return -1;
+    }
+
+    virBufferVSprintf(buf,
+                      "    <filesystem type='%s'>\n",
+                      type);
+
+    if (def->src) {
+        if (def->type == VIR_DOMAIN_FS_TYPE_MOUNT)
+            virBufferEscapeString(buf, "      <source dir='%s'/>\n",
+                                  def->src);
+        else if (def->type == VIR_DOMAIN_FS_TYPE_BLOCK)
+            virBufferEscapeString(buf, "      <source dev='%s'/>\n",
+                                  def->src);
+        else
+            virBufferEscapeString(buf, "      <source file='%s'/>\n",
+                                  def->src);
+    }
+
+    virBufferVSprintf(buf, "      <target dir='%s'/>\n",
+                      def->dst);
+
+    if (def->readonly)
+        virBufferAddLit(buf, "      <readonly/>\n");
+
+    virBufferAddLit(buf, "    </filesystem>\n");
+
+    return 0;
+}
+
+static int
 virDomainNetDefFormat(virConnectPtr conn,
                       virBufferPtr buf,
                       virDomainNetDefPtr def)
@@ -2472,6 +2637,7 @@
     unsigned char *uuid;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     virDomainDiskDefPtr disk;
+    virDomainFSDefPtr fs;
     virDomainNetDefPtr net;
     virDomainSoundDefPtr sound;
     virDomainInputDefPtr input;
@@ -2541,6 +2707,9 @@
     else
         virBufferVSprintf(&buf, ">%s</type>\n", def->os.type);
 
+    if (def->os.init)
+        virBufferEscapeString(&buf, "    <init>%s</init>\n",
+                              def->os.init);
     if (def->os.loader)
         virBufferEscapeString(&buf, "    <loader>%s</loader>\n",
                               def->os.loader);
@@ -2614,6 +2783,13 @@
         if (virDomainDiskDefFormat(conn, &buf, disk) < 0)
             goto cleanup;
         disk = disk->next;
+    }
+
+    fs = def->fss;
+    while (fs) {
+        if (virDomainFSDefFormat(conn, &buf, fs) < 0)
+            goto cleanup;
+        fs = fs->next;
     }
 
     net = def->nets;
diff -r 7059fd49ed7e src/domain_conf.h
--- a/src/domain_conf.h	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/domain_conf.h	Mon Jul 14 21:34:06 2008 +0100
@@ -91,6 +91,27 @@
     unsigned int shared : 1;
 
     virDomainDiskDefPtr next;
+};
+
+
+/* Two types of disk backends */
+enum virDomainFSType {
+    VIR_DOMAIN_FS_TYPE_MOUNT,
+    VIR_DOMAIN_FS_TYPE_BLOCK,
+    VIR_DOMAIN_FS_TYPE_FILE,
+
+    VIR_DOMAIN_FS_TYPE_LAST
+};
+
+typedef struct _virDomainFSDef virDomainFSDef;
+typedef virDomainFSDef *virDomainFSDefPtr;
+struct _virDomainFSDef {
+    int type;
+    char *src;
+    char *dst;
+    unsigned int readonly : 1;
+
+    virDomainFSDefPtr next;
 };
 
 
@@ -262,6 +283,7 @@
 /* Flags for the 'type' field in next struct */
 enum virDomainDeviceType {
     VIR_DOMAIN_DEVICE_DISK,
+    VIR_DOMAIN_DEVICE_FS,
     VIR_DOMAIN_DEVICE_NET,
     VIR_DOMAIN_DEVICE_INPUT,
     VIR_DOMAIN_DEVICE_SOUND,
@@ -273,6 +295,7 @@
     int type;
     union {
         virDomainDiskDefPtr disk;
+        virDomainFSDefPtr fs;
         virDomainNetDefPtr net;
         virDomainInputDefPtr input;
         virDomainSoundDefPtr sound;
@@ -318,6 +341,7 @@
     char *machine;
     int nBootDevs;
     int bootDevs[VIR_DOMAIN_BOOT_LAST];
+    char *init;
     char *kernel;
     char *initrd;
     char *cmdline;
@@ -357,6 +381,7 @@
 
     virDomainGraphicsDefPtr graphics;
     virDomainDiskDefPtr disks;
+    virDomainFSDefPtr fss;
     virDomainNetDefPtr nets;
     virDomainInputDefPtr inputs;
     virDomainSoundDefPtr sounds;
@@ -411,6 +436,7 @@
 void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
 void virDomainInputDefFree(virDomainInputDefPtr def);
 void virDomainDiskDefFree(virDomainDiskDefPtr def);
+void virDomainFSDefFree(virDomainFSDefPtr def);
 void virDomainNetDefFree(virDomainNetDefPtr def);
 void virDomainChrDefFree(virDomainChrDefPtr def);
 void virDomainSoundDefFree(virDomainSoundDefPtr def);
@@ -481,6 +507,7 @@
 VIR_ENUM_DECL(virDomainDisk)
 VIR_ENUM_DECL(virDomainDiskDevice)
 VIR_ENUM_DECL(virDomainDiskBus)
+VIR_ENUM_DECL(virDomainFS)
 VIR_ENUM_DECL(virDomainNet)
 VIR_ENUM_DECL(virDomainChr)
 VIR_ENUM_DECL(virDomainSoundModel)
diff -r 7059fd49ed7e src/lxc_conf.c
--- a/src/lxc_conf.c	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/lxc_conf.c	Mon Jul 14 21:34:06 2008 +0100
@@ -27,22 +27,8 @@
 
 #ifdef WITH_LXC
 
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
+#include <sys/utsname.h>
 
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/uri.h>
-#include <libxml/xpath.h>
-
-#include "buf.h"
-#include "util.h"
-#include "uuid.h"
-#include "xml.h"
-#include "memory.h"
 #include "lxc_conf.h"
 
 /* debug macros */
@@ -54,12 +40,12 @@
               const char *fmt, ...)
 {
     va_list args;
-    char errorMessage[LXC_MAX_ERROR_LEN];
+    char errorMessage[1024];
     const char *codeErrorMessage;
 
     if (fmt) {
         va_start(args, fmt);
-        vsnprintf(errorMessage, LXC_MAX_ERROR_LEN-1, fmt, args);
+        vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args);
         va_end(args);
     } else {
         errorMessage[0] = '\0';
@@ -71,775 +57,51 @@
                     codeErrorMessage, errorMessage);
 }
 
-/**
- * lxcParseInterfaceXML:
- * @conn: pointer to connection
- * @nodePtr: pointer to xml node structure
- * @vm: pointer to net definition structure to fill in
- *
- * Parses the XML for a network interface and places the configuration
- * in the given structure.
- *
- * Returns 0 on success or -1 in case of error
- */
-static int lxcParseInterfaceXML(virConnectPtr conn, xmlNodePtr nodePtr,
-                                lxc_net_def_t *netDef)
+virCapsPtr lxcCapsInit(void)
 {
-    int rc = -1;
-    xmlNodePtr cur;
-    xmlChar *type = NULL;
-    xmlChar *parentIfName = NULL;
-    xmlChar *network = NULL;
-    xmlChar *bridge = NULL;
-    xmlChar *macaddr = NULL;
+    struct utsname utsname;
+    virCapsPtr caps;
+    virCapsGuestPtr guest;
 
-    netDef->type = LXC_NET_NETWORK;
+    /* Really, this never fails - look at the man-page. */
+    uname (&utsname);
 
-    type = xmlGetProp(nodePtr, BAD_CAST "type");
-    if (type != NULL) {
-        if (xmlStrEqual(type, BAD_CAST "network")) {
-            netDef->type = LXC_NET_NETWORK;
-        }
-        else if (xmlStrEqual(type, BAD_CAST "bridge")) {
-            netDef->type = LXC_NET_BRIDGE;
-        }
-        else {
-            lxcError(conn, NULL, VIR_ERR_XML_ERROR,
-                     _("invalid interface type: %s"), type);
-            goto error_out;
-        }
-    }
+    if ((caps = virCapabilitiesNew(utsname.machine,
+                                   0, 0)) == NULL)
+        goto no_memory;
 
-    cur = nodePtr->children;
-    for (cur = nodePtr->children; cur != NULL; cur = cur->next) {
-        if (cur->type == XML_ELEMENT_NODE) {
-            DEBUG("cur->name: %s", (char*)(cur->name));
-            if ((macaddr == NULL) &&
-                (xmlStrEqual(cur->name, BAD_CAST "mac"))) {
-                macaddr = xmlGetProp(cur, BAD_CAST "address");
-            } else if ((network == NULL) &&
-                       (netDef->type == LXC_NET_NETWORK) &&
-                       (xmlStrEqual(cur->name, BAD_CAST "source"))) {
-                network = xmlGetProp(cur, BAD_CAST "network");
-                parentIfName = xmlGetProp(cur, BAD_CAST "dev");
-            } else if ((bridge == NULL) &&
-                       (netDef->type == LXC_NET_BRIDGE) &&
-                       (xmlStrEqual(cur->name, BAD_CAST "source"))) {
-                bridge = xmlGetProp(cur, BAD_CAST "bridge");
-            } else if ((parentIfName == NULL) &&
-                       (xmlStrEqual(cur->name, BAD_CAST "target"))) {
-                parentIfName = xmlGetProp(cur, BAD_CAST "dev");
-            }
-        }
-    }
+    if ((guest = virCapabilitiesAddGuest(caps,
+                                         "exe",
+                                         utsname.machine,
+                                         sizeof(int) == 4 ? 32 : 8,
+                                         NULL,
+                                         NULL,
+                                         0,
+                                         NULL)) == NULL)
+        goto no_memory;
 
-    if (netDef->type == LXC_NET_NETWORK) {
-        if (network == NULL) {
-            lxcError(conn, NULL, VIR_ERR_XML_ERROR,
-                     _("No <source> 'network' attribute specified with <interface type='network'/>"));
-            goto error_out;
-        }
+    if (virCapabilitiesAddGuestDomain(guest,
+                                      "lxc",
+                                      NULL,
+                                      NULL,
+                                      0,
+                                      NULL) == NULL)
+        goto no_memory;
 
-        netDef->txName = strdup((char *)network);
-        if (NULL == netDef->txName) {
-            lxcError(conn, NULL, VIR_ERR_NO_MEMORY,
-                     _("No storage for network name"));
-            goto error_out;
-        }
+    return caps;
 
-    } else if (netDef->type == LXC_NET_BRIDGE) {
-        if (bridge == NULL) {
-            lxcError(conn, NULL, VIR_ERR_XML_ERROR,
-                     _("No <source> 'bridge' attribute specified with <interface type='bridge'/>"));
-            goto error_out;
-        }
-
-        netDef->txName = strdup((char *)bridge);
-        if (NULL == netDef->txName) {
-            lxcError(conn, NULL, VIR_ERR_NO_MEMORY,
-                     _("No storage for bridge name"));
-            goto error_out;
-        }
-    }
-
-    if (parentIfName != NULL) {
-        DEBUG("set netDef->parentVeth: %s", netDef->parentVeth);
-        netDef->parentVeth = strdup((char *)parentIfName);
-        if (NULL == netDef->parentVeth) {
-            lxcError(conn, NULL, VIR_ERR_NO_MEMORY,
-                     _("No storage for parent veth device name"));
-            goto error_out;
-        }
-    } else {
-        netDef->parentVeth = NULL;
-        DEBUG0("set netDef->parentVeth: NULL");
-    }
-
-    rc = 0;
-
-error_out:
-    xmlFree(macaddr);
-    xmlFree(network);
-    xmlFree(bridge);
-    xmlFree(parentIfName);
-
-    return rc;
-}
-
-/**
- * lxcParseDomainInterfaces:
- * @conn: pointer to connection
- * @nets: on success, points to an list of net def structs
- * @contextPtr: pointer to xml context
- *
- * Parses the domain network interfaces and returns the information in a list
- *
- * Returns 0 on success or -1 in case of error
- */
-static int lxcParseDomainInterfaces(virConnectPtr conn,
-                                    lxc_net_def_t **nets,
-                                    xmlXPathContextPtr contextPtr)
-{
-    int rc = -1;
-    int i;
-    lxc_net_def_t *netDef;
-    lxc_net_def_t *prevDef = NULL;
-    int numNets = 0;
-    xmlNodePtr *list;
-    int res;
-
-    DEBUG0("parsing nets");
-
-    res = virXPathNodeSet(conn, "/domain/devices/interface", contextPtr, &list);
-    if (res > 0) {
-        for (i = 0; i < res; ++i) {
-            netDef = calloc(1, sizeof(lxc_net_def_t));
-            if (NULL == netDef) {
-                lxcError(conn, NULL, VIR_ERR_NO_MEMORY,
-                         _("No storage for net def structure"));
-                free(list);
-                goto parse_complete;
-            }
-
-            rc = lxcParseInterfaceXML(conn, list[i], netDef);
-            if (0 > rc) {
-                DEBUG("failed parsing a net: %d", rc);
-
-                free(netDef);
-                free(list);
-                goto parse_complete;
-            }
-
-            DEBUG0("parsed a net");
-
-            /* set the linked list pointers */
-            numNets++;
-            netDef->next = NULL;
-            if (0 == i) {
-                *nets = netDef;
-            } else {
-                prevDef->next = netDef;
-            }
-            prevDef = netDef;
-        }
-        free(list);
-    }
-
-    rc = numNets;
-
-parse_complete:
-    DEBUG("parsed %d nets", rc);
-    return rc;
-}
-
-static int lxcParseMountXML(virConnectPtr conn, xmlNodePtr nodePtr,
-                            lxc_mount_t *lxcMount)
-{
-    xmlChar *fsType = NULL;
-    xmlNodePtr curNode;
-    xmlChar *mountSource = NULL;
-    xmlChar *mountTarget = NULL;
-    int strLen;
-    int rc = -1;
-
-    fsType = xmlGetProp(nodePtr, BAD_CAST "type");
-    if (NULL == fsType) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("missing filesystem type"));
-        goto error;
-    }
-
-    if (xmlStrEqual(fsType, BAD_CAST "mount") == 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("invalid filesystem type"));
-        goto error;
-    }
-
-    for (curNode = nodePtr->children;
-         NULL != curNode;
-         curNode = curNode->next) {
-        if (curNode->type != XML_ELEMENT_NODE) {
-            continue;
-        }
-
-        if ((mountSource == NULL) &&
-            (xmlStrEqual(curNode->name, BAD_CAST "source"))) {
-            mountSource = xmlGetProp(curNode, BAD_CAST "dir");
-        } else if ((mountTarget == NULL) &&
-                  (xmlStrEqual(curNode->name, BAD_CAST "target"))) {
-            mountTarget = xmlGetProp(curNode, BAD_CAST "dir");
-        }
-    }
-
-    if (mountSource == NULL) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("missing mount source"));
-        goto error;
-    }
-
-    strLen = xmlStrlen(mountSource);
-    if ((strLen > (PATH_MAX-1)) || (0 == strLen)) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("empty or invalid mount source"));
-        goto error;
-    }
-
-    strncpy(lxcMount->source, (char *)mountSource, strLen);
-    lxcMount->source[strLen] = '\0';
-
-    if (mountTarget == NULL) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("missing mount target"));
-        goto error;
-    }
-
-    strLen = xmlStrlen(mountTarget);
-    if ((strLen > (PATH_MAX-1)) || (0 == strLen)) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("empty or invalid mount target"));
-        goto error;
-    }
-
-    strncpy(lxcMount->target, (char *)mountTarget, strLen);
-    lxcMount->target[strLen] = '\0';
-
-    rc = 0;
-
-error:
-    xmlFree(fsType);
-    xmlFree(mountSource);
-    xmlFree(mountTarget);
-
-    return rc;
-}
-
-static int lxcParseDomainName(virConnectPtr conn, char **name,
-                              xmlXPathContextPtr contextPtr)
-{
-    char *res;
-
-    res = virXPathString(conn, "string(/domain/name[1])", contextPtr);
-    if (res == NULL) {
-        lxcError(conn, NULL, VIR_ERR_NO_NAME, NULL);
-        return(-1);
-    }
-
-    *name = res;
-    return(0);
-}
-
-static int lxcParseDomainUUID(virConnectPtr conn, unsigned char *uuid,
-                              xmlXPathContextPtr contextPtr)
-{
-    char *res;
-
-    res = virXPathString(conn, "string(/domain/uuid[1])", contextPtr);
-    if (res == NULL) {
-        if (virUUIDGenerate(uuid)) {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to generate uuid"));
-            return(-1);
-        }
-    } else {
-        if (virUUIDParse(res, uuid) < 0) {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("invalid uuid element"));
-            VIR_FREE(res);
-            return(-1);
-        }
-        VIR_FREE(res);
-    }
-    return(0);
-}
-
-static int lxcParseDomainMounts(virConnectPtr conn,
-                                lxc_mount_t **mounts,
-                                xmlXPathContextPtr contextPtr)
-{
-    int rc = -1;
-    int i;
-    lxc_mount_t *mountObj;
-    lxc_mount_t *prevObj = NULL;
-    int nmounts = 0;
-    xmlNodePtr *list;
-    int res;
-
-    res = virXPathNodeSet(conn, "/domain/devices/filesystem", contextPtr, &list);
-    if (res > 0) {
-        for (i = 0; i < res; ++i) {
-            if (VIR_ALLOC(mountObj) < 0) {
-                lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "mount");
-                goto parse_complete;
-            }
-
-            rc = lxcParseMountXML(conn, list[i], mountObj);
-            if (0 > rc) {
-                VIR_FREE(mountObj);
-                goto parse_complete;
-            }
-
-            /* set the linked list pointers */
-            nmounts++;
-            mountObj->next = NULL;
-            if (0 == i) {
-                *mounts = mountObj;
-            } else {
-                prevObj->next = mountObj;
-            }
-            prevObj = mountObj;
-        }
-        VIR_FREE(list);
-    }
-
-    rc = nmounts;
-
-parse_complete:
-    return rc;
-}
-
-static int lxcParseDomainInit(virConnectPtr conn, char** init,
-                              xmlXPathContextPtr contextPtr)
-{
-    char *res;
-
-    res = virXPathString(conn, "string(/domain/os/init[1])", contextPtr);
-    if (res == NULL) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("invalid or missing init element"));
-        return(-1);
-    }
-
-    if (strlen(res) >= PATH_MAX - 1) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("init string too long"));
-        VIR_FREE(res);
-        return(-1);
-    }
-
-    *init = res;
-
-    return(0);
-}
-
-
-static int lxcParseDomainTty(virConnectPtr conn, char **tty, xmlXPathContextPtr contextPtr)
-{
-    char *res;
-
-    res = virXPathString(conn, "string(/domain/devices/console[1]/@tty)", contextPtr);
-    if (res == NULL) {
-        /* make sure the tty string is empty */
-        *tty = strdup("");
-        if (*tty == NULL) {
-            lxcError(conn, NULL, VIR_ERR_NO_MEMORY, NULL);
-            return(-1);
-        }
-    } else {
-        *tty = res;
-    }
-
-    return(0);
-}
-
-static int lxcParseDomainMemory(virConnectPtr conn, int* memory, xmlXPathContextPtr contextPtr)
-{
-    long res;
-    int rc;
-
-    rc = virXPathLong(conn, "string(/domain/memory[1])", contextPtr, &res);
-    if ((rc == -2) || ((rc == 0) && (res <= 0))) {
-        *memory = -1;
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("invalid memory value"));
-    } else if (rc < 0) {
-        /* not an error, default to an invalid value so it's not used */
-        *memory = -1;
-    } else {
-        *memory = (int) res;
-    }
-    return(0);
-}
-
-static lxc_vm_def_t * lxcParseXML(virConnectPtr conn, xmlDocPtr docPtr)
-{
-    xmlNodePtr rootNodePtr = NULL;
-    xmlXPathContextPtr contextPtr = NULL;
-    xmlChar *xmlProp = NULL;
-    lxc_vm_def_t *containerDef;
-
-    if (VIR_ALLOC(containerDef) < 0) {
-        lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "containerDef");
-        return NULL;
-    }
-
-    /* Prepare parser / xpath context */
-    rootNodePtr = xmlDocGetRootElement(docPtr);
-    if ((rootNodePtr == NULL) ||
-       (!xmlStrEqual(rootNodePtr->name, BAD_CAST "domain"))) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("invalid root element"));
-        goto error;
-    }
-
-    contextPtr = xmlXPathNewContext(docPtr);
-    if (contextPtr == NULL) {
-        lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "context");
-        goto error;
-    }
-
-    /* Verify the domain type is linuxcontainer */
-    if (!(xmlProp = xmlGetProp(rootNodePtr, BAD_CAST "type"))) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("missing domain type"));
-        goto error;
-    }
-
-    if (!(xmlStrEqual(xmlProp, BAD_CAST LXC_DOMAIN_TYPE))) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("invalid domain type"));
-        goto error;
-    }
-    VIR_FREE(xmlProp);
-
-    if ((xmlProp = xmlGetProp(rootNodePtr, BAD_CAST "id"))) {
-        if (0 > virStrToLong_i((char*)xmlProp, NULL, 10, &(containerDef->id))) {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("invalid domain id"));
-            goto error;
-        }
-
-        /* verify the container process still exists */
-        if (1 != lxcCheckContainerProcess(containerDef)) {
-            containerDef->id = -1;
-        }
-
-    } else {
-        containerDef->id = -1;
-    }
-    VIR_FREE(xmlProp);
-
-    if (lxcParseDomainName(conn, &(containerDef->name), contextPtr) < 0) {
-        goto error;
-    }
-
-    if (lxcParseDomainInit(conn, &(containerDef->init), contextPtr) < 0) {
-        goto error;
-    }
-
-    if (lxcParseDomainUUID(conn, containerDef->uuid, contextPtr) < 0) {
-        goto error;
-    }
-
-    containerDef->nmounts = lxcParseDomainMounts(conn, &(containerDef->mounts),
-                                                 contextPtr);
-    if (0 > containerDef->nmounts) {
-        goto error;
-    }
-
-    containerDef->numNets = lxcParseDomainInterfaces(conn,
-                                                     &(containerDef->nets),
-                                                     contextPtr);
-    if (0 > containerDef->numNets) {
-        goto error;
-    }
-
-    if (lxcParseDomainTty(conn, &(containerDef->tty), contextPtr) < 0) {
-        goto error;
-    }
-
-    if (lxcParseDomainMemory(conn, &(containerDef->maxMemory), contextPtr) < 0) {
-        goto error;
-    }
-
-    xmlXPathFreeContext(contextPtr);
-
-    return containerDef;
-
- error:
-    VIR_FREE(xmlProp);
-    xmlXPathFreeContext(contextPtr);
-    lxcFreeVMDef(containerDef);
-
+ no_memory:
+    virCapabilitiesFree(caps);
     return NULL;
 }
 
-
-lxc_vm_def_t * lxcParseVMDef(virConnectPtr conn,
-                             const char* xmlString,
-                             const char* fileName)
-{
-    xmlDocPtr xml;
-    lxc_vm_def_t *containerDef;
-
-    xml = xmlReadDoc(BAD_CAST xmlString,
-                     fileName ? fileName : "domain.xml",
-                     NULL, XML_PARSE_NOENT |
-                     XML_PARSE_NONET | XML_PARSE_NOERROR |
-                     XML_PARSE_NOWARNING);
-    if (!xml) {
-        lxcError(conn, NULL, VIR_ERR_XML_ERROR, NULL);
-        return NULL;
-    }
-
-    containerDef = lxcParseXML(conn, xml);
-
-    xmlFreeDoc(xml);
-
-    return containerDef;
-}
-
-lxc_vm_t * lxcAssignVMDef(virConnectPtr conn,
-                          lxc_driver_t *driver,
-                          lxc_vm_def_t *def)
-{
-    lxc_vm_t *vm = NULL;
-
-    if ((vm = lxcFindVMByName(driver, def->name))) {
-        if (!lxcIsActiveVM(vm)) {
-            lxcFreeVMDef(vm->def);
-            vm->def = def;
-        } else {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("Can't redefine active VM with name %s"), def->name);
-            return NULL;
-        }
-
-        return vm;
-    }
-
-    if (VIR_ALLOC(vm) < 0) {
-        lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "vm");
-        return NULL;
-    }
-
-    vm->pid = -1;
-    vm->def = def;
-    vm->next = driver->vms;
-
-    driver->vms = vm;
-
-    if (lxcIsActiveVM(vm)) {
-        vm->state = VIR_DOMAIN_RUNNING;
-        driver->nactivevms++;
-    } else {
-        vm->state = VIR_DOMAIN_SHUTOFF;
-        driver->ninactivevms++;
-    }
-
-    return vm;
-}
-
-/**
- * lxcCheckContainerProcess:
- * @def: Ptr to VM definition
- *
- * Checks if the container process (stored at def->id is running
- *
- * Returns on success or -1 in case of error
- * 0  - no process with id vm->def->id
- * 1  - container process exists
- * -1 - error
- */
-int lxcCheckContainerProcess(lxc_vm_def_t *def)
-{
-    int rc = -1;
-
-    if (1 < def->id) {
-        if (-1 == kill(def->id, 0)) {
-            if (ESRCH == errno) {
-                rc = 0;
-                DEBUG("pid %d no longer exists", def->id);
-                goto done;
-            }
-
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("error checking container process: %d %s"),
-                     def->id, strerror(errno));
-            goto done;
-        }
-
-        DEBUG("pid %d still exists", def->id);
-        rc = 1;
-        goto done;
-    }
-
-    rc = 0;
-
-done:
-    return rc;
-}
-
-void lxcRemoveInactiveVM(lxc_driver_t *driver,
-                         lxc_vm_t *vm)
-{
-    lxc_vm_t *prevVm = NULL;
-    lxc_vm_t *curVm;
-
-    for (curVm = driver->vms;
-         (curVm != vm) && (NULL != curVm);
-         curVm = curVm->next) {
-        prevVm = curVm;
-    }
-
-    if (curVm) {
-        if (prevVm) {
-            prevVm->next = curVm->next;
-        } else {
-            driver->vms = curVm->next;
-        }
-
-        driver->ninactivevms--;
-    }
-
-    lxcFreeVM(vm);
-}
-
-/* Save a container's config data into a persistent file */
-int lxcSaveConfig(virConnectPtr conn,
-                  lxc_driver_t *driver,
-                  lxc_vm_t *vm,
-                  lxc_vm_def_t *def)
-{
-    int rc = -1;
-    char *xmlDef;
-    int fd = -1;
-    int amtToWrite;
-
-    if (!(xmlDef = lxcGenerateXML(conn, driver, vm, def))) {
-        return -1;
-    }
-
-    if ((fd = open(vm->configFile,
-                  O_WRONLY | O_CREAT | O_TRUNC,
-                  S_IRUSR | S_IWUSR )) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("cannot create config file %s: %s"),
-                  vm->configFile, strerror(errno));
-        goto cleanup;
-    }
-
-    amtToWrite = strlen(xmlDef);
-    if (safewrite(fd, xmlDef, amtToWrite) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("cannot write config file %s: %s"),
-                 vm->configFile, strerror(errno));
-        goto cleanup;
-    }
-
-    if (close(fd) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("cannot save config file %s: %s"),
-                 vm->configFile, strerror(errno));
-        goto cleanup;
-    }
-
-    rc = 0;
-
- cleanup:
-    if (fd != -1) {
-        close(fd);
-    }
-
-    VIR_FREE(xmlDef);
-
-    return rc;
-}
-
-int lxcSaveVMDef(virConnectPtr conn,
-                 lxc_driver_t *driver,
-                 lxc_vm_t *vm,
-                 lxc_vm_def_t *def)
-{
-    int rc = -1;
-
-    if (vm->configFile[0] == '\0') {
-        if ((rc = virFileMakePath(driver->configDir))) {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("cannot create config directory %s: %s"),
-                     driver->configDir, strerror(rc));
-            goto save_complete;
-        }
-
-        if (virFileBuildPath(driver->configDir, vm->def->name, ".xml",
-                            vm->configFile, PATH_MAX) < 0) {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("cannot construct config file path"));
-            goto save_complete;
-        }
-
-        strncpy(vm->configFileBase, vm->def->name, PATH_MAX-1);
-        strncat(vm->configFileBase, ".xml", PATH_MAX - strlen(vm->def->name)-1);
-
-    }
-
-    rc = lxcSaveConfig(conn, driver, vm, def);
-
-save_complete:
-    return rc;
-}
-
-
-
-static lxc_vm_t * lxcLoadConfig(lxc_driver_t *driver,
-                                const char *file,
-                                const char *fullFilePath,
-                                const char *xmlData)
-{
-    lxc_vm_def_t *containerDef;
-    lxc_vm_t * vm;
-
-    containerDef = lxcParseVMDef(NULL, xmlData, file);
-    if (NULL == containerDef) {
-        DEBUG0("Error parsing container config");
-        return NULL;
-    }
-
-    if (!virFileMatchesNameSuffix(file, containerDef->name, ".xml")) {
-        DEBUG0("Container name does not match config file name");
-        lxcFreeVMDef(containerDef);
-        return NULL;
-    }
-
-    vm = lxcAssignVMDef(NULL, driver, containerDef);
-    if (NULL == vm) {
-        DEBUG0("Failed to load container config");
-        lxcFreeVMDef(containerDef);
-        return NULL;
-    }
-
-    strncpy(vm->configFile, fullFilePath, PATH_MAX);
-    vm->configFile[PATH_MAX-1] = '\0';
-
-    strncpy(vm->configFileBase, file, PATH_MAX);
-    vm->configFile[PATH_MAX-1] = '\0';
-
-    return vm;
-}
 
 int lxcLoadDriverConfig(lxc_driver_t *driver)
 {
     /* Set the container configuration directory */
     if ((driver->configDir = strdup(SYSCONF_DIR "/libvirt/lxc")) == NULL)
+        goto no_memory;
+    if ((driver->autostartDir = strdup(SYSCONF_DIR "/libvirt/lxc/autostart")) == NULL)
         goto no_memory;
     if ((driver->stateDir = strdup(LOCAL_STATE_DIR "/run/libvirt/lxc")) == NULL)
         goto no_memory;
@@ -853,255 +115,5 @@
     return -1;
 }
 
-int lxcLoadContainerConfigFile(lxc_driver_t *driver,
-                               const char *file)
-{
-    int rc = -1;
-    char tempPath[PATH_MAX];
-    char* xmlData;
-
-    rc = virFileBuildPath(driver->configDir, file, NULL, tempPath,
-                          PATH_MAX);
-    if (0 > rc) {
-        DEBUG0("config file name too long");
-        goto load_complete;
-    }
-
-    if ((rc = virFileReadAll(tempPath, LXC_MAX_XML_LENGTH, &xmlData)) < 0) {
-        goto load_complete;
-    }
-
-    lxcLoadConfig(driver, file, tempPath, xmlData);
-
-    VIR_FREE(xmlData);
-
-load_complete:
-    return rc;
-}
-
-int lxcLoadContainerInfo(lxc_driver_t *driver)
-{
-    int rc = -1;
-    DIR *dir;
-    struct dirent *dirEntry;
-
-    if (!(dir = opendir(driver->configDir))) {
-        if (ENOENT == errno) {
-            /* no config dir => no containers */
-            rc = 0;
-        } else {
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to open config directory %s: %s"),
-                     driver->configDir, strerror(errno));
-        }
-
-        goto load_complete;
-    }
-
-    while ((dirEntry = readdir(dir))) {
-        if (dirEntry->d_name[0] == '.') {
-            continue;
-        }
-
-        if (!virFileHasSuffix(dirEntry->d_name, ".xml")) {
-            continue;
-        }
-
-        lxcLoadContainerConfigFile(driver, dirEntry->d_name);
-    }
-
-    closedir(dir);
-
-    rc = 0;
-
-load_complete:
-    return rc;
-}
-
-/* Generate an XML document describing the vm's configuration */
-char *lxcGenerateXML(virConnectPtr conn,
-                     lxc_driver_t *driver ATTRIBUTE_UNUSED,
-                     lxc_vm_t *vm,
-                     lxc_vm_def_t *def)
-{
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    unsigned char *uuid;
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-    lxc_mount_t *mount;
-    lxc_net_def_t *net;
-
-    if (lxcIsActiveVM(vm))
-        virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n",
-                          LXC_DOMAIN_TYPE, vm->def->id);
-    else
-        virBufferVSprintf(&buf, "<domain type='%s'>\n",
-                          LXC_DOMAIN_TYPE);
-
-    virBufferVSprintf(&buf, "    <name>%s</name>\n", def->name);
-
-    uuid = def->uuid;
-    virUUIDFormat(uuid, uuidstr);
-    virBufferVSprintf(&buf, "    <uuid>%s</uuid>\n", uuidstr);
-    virBufferAddLit(&buf, "    <os>\n");
-    virBufferVSprintf(&buf, "        <init>%s</init>\n", def->init);
-    virBufferAddLit(&buf, "    </os>\n");
-    virBufferVSprintf(&buf, "    <memory>%d</memory>\n", def->maxMemory);
-    virBufferAddLit(&buf, "    <devices>\n");
-
-    /* loop adding mounts */
-    for (mount = def->mounts; mount; mount = mount->next) {
-        virBufferAddLit(&buf, "        <filesystem type='mount'>\n");
-        virBufferVSprintf(&buf, "            <source dir='%s'/>\n",
-                          mount->source);
-        virBufferVSprintf(&buf, "            <target dir='%s'/>\n",
-                          mount->target);
-        virBufferAddLit(&buf, "        </filesystem>\n");
-    }
-
-    /* loop adding nets */
-    for (net = def->nets; net; net = net->next) {
-        if (net->type == LXC_NET_NETWORK) {
-            virBufferAddLit(&buf, "        <interface type='network'>\n");
-            virBufferVSprintf(&buf, "            <source network='%s'/>\n",
-                              net->txName);
-        } else {
-            virBufferAddLit(&buf, "        <interface type='bridge'>\n");
-            virBufferVSprintf(&buf, "            <source bridge='%s'/>\n",
-                              net->txName);
-        }
-
-        if (NULL != net->parentVeth) {
-            virBufferVSprintf(&buf, "            <target dev='%s'/>\n",
-                              net->parentVeth);
-        }
-
-        virBufferAddLit(&buf, "        </interface>\n");
-
-    }
-
-    virBufferVSprintf(&buf, "        <console tty='%s'/>\n", def->tty);
-    virBufferAddLit(&buf, "    </devices>\n");
-    virBufferAddLit(&buf, "</domain>\n");
-
-    if (virBufferError(&buf)) {
-        lxcError(conn, NULL, VIR_ERR_NO_MEMORY,_("allocate buffer"));
-        return NULL;
-    }
-
-    return virBufferContentAndReset(&buf);
-}
-
-void lxcFreeVMDef(lxc_vm_def_t *vmdef)
-{
-    lxc_mount_t *curMount;
-    lxc_mount_t *nextMount;
-    lxc_net_def_t *curNet;
-    lxc_net_def_t *nextNet;
-
-    if (vmdef == NULL)
-        return;
-
-    curMount = vmdef->mounts;
-    while (curMount) {
-        nextMount = curMount->next;
-        VIR_FREE(curMount);
-        curMount = nextMount;
-    }
-
-    curNet = vmdef->nets;
-    while (curNet) {
-        nextNet = curNet->next;
-        VIR_FREE(curNet->parentVeth);
-        VIR_FREE(curNet->txName);
-        VIR_FREE(curNet);
-        curNet = nextNet;
-    }
-
-    VIR_FREE(vmdef->name);
-    VIR_FREE(vmdef->init);
-    VIR_FREE(vmdef->tty);
-    VIR_FREE(vmdef);
-}
-
-void lxcFreeVMs(lxc_vm_t *vms)
-{
-    lxc_vm_t *curVm = vms;
-    lxc_vm_t *nextVm;
-
-    while (curVm) {
-        nextVm = curVm->next;
-        lxcFreeVM(curVm);
-        curVm = nextVm;
-    }
-}
-
-void lxcFreeVM(lxc_vm_t *vm)
-{
-    lxcFreeVMDef(vm->def);
-    VIR_FREE(vm);
-}
-
-lxc_vm_t *lxcFindVMByID(const lxc_driver_t *driver, int id)
-{
-    lxc_vm_t *vm;
-
-    for (vm = driver->vms; vm; vm = vm->next) {
-        if (lxcIsActiveVM(vm) && (vm->def->id == id)) {
-            return vm;
-        }
-
-    }
-
-    return NULL;
-}
-
-lxc_vm_t *lxcFindVMByUUID(const lxc_driver_t *driver,
-                          const unsigned char *uuid)
-{
-    lxc_vm_t *vm;
-
-    for (vm = driver->vms; vm; vm = vm->next) {
-        if (!memcmp(vm->def->uuid, uuid, VIR_UUID_BUFLEN)) {
-            return vm;
-        }
-    }
-
-    return NULL;
-}
-
-lxc_vm_t *lxcFindVMByName(const lxc_driver_t *driver,
-                          const char *name)
-{
-    lxc_vm_t *vm;
-
-    for (vm = driver->vms; vm; vm = vm->next) {
-        if (STREQ(vm->def->name, name)) {
-            return vm;
-        }
-    }
-
-    return NULL;
-}
-
-int lxcDeleteConfig(virConnectPtr conn,
-                    lxc_driver_t *driver ATTRIBUTE_UNUSED,
-                    const char *configFile,
-                    const char *name)
-{
-    if (!configFile[0]) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("no config file for %s"), name);
-        return -1;
-    }
-
-    if (unlink(configFile) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("cannot remove config for %s"), name);
-        return -1;
-    }
-
-    return 0;
-}
-
 
 #endif /* WITH_LXC */
diff -r 7059fd49ed7e src/lxc_conf.h
--- a/src/lxc_conf.h	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/lxc_conf.h	Mon Jul 14 21:34:06 2008 +0100
@@ -29,130 +29,23 @@
 #ifdef WITH_LXC
 
 #include "internal.h"
-
-/* Defines */
-#define LXC_MAX_TTY_NAME 32
-#define LXC_MAX_XML_LENGTH 16384
-#define LXC_MAX_ERROR_LEN 1024
-#define LXC_DOMAIN_TYPE "lxc"
-
-/* types of networks for containers */
-enum lxc_net_type {
-    LXC_NET_NETWORK,
-    LXC_NET_BRIDGE
-};
-
-typedef struct __lxc_net_def lxc_net_def_t;
-struct __lxc_net_def {
-    int type;
-    char *parentVeth;       /* veth device in parent namespace */
-    char *txName;           /* bridge or network name */
-
-    lxc_net_def_t *next;
-};
-
-typedef struct __lxc_mount lxc_mount_t;
-struct __lxc_mount {
-    char source[PATH_MAX]; /* user's directory */
-    char target[PATH_MAX];
-
-    lxc_mount_t *next;
-};
-
-typedef struct __lxc_vm_def lxc_vm_def_t;
-struct __lxc_vm_def {
-    unsigned char uuid[VIR_UUID_BUFLEN];
-    char* name;
-    int id;
-
-    /* init command string */
-    char *init;
-
-    int maxMemory;
-
-    /* mounts - list of mount structs */
-    int nmounts;
-    lxc_mount_t *mounts;
-
-    /* tty device */
-    char *tty;
-
-    /* network devices */
-    int numNets;
-    lxc_net_def_t *nets;
-};
-
-typedef struct __lxc_vm lxc_vm_t;
-struct __lxc_vm {
-    int pid;
-    int state;
-    int monitor;
-
-    char configFile[PATH_MAX];
-    char configFileBase[PATH_MAX];
-
-    lxc_vm_def_t *def;
-
-    lxc_vm_t *next;
-};
+#include "domain_conf.h"
+#include "capabilities.h"
 
 typedef struct __lxc_driver lxc_driver_t;
 struct __lxc_driver {
-    lxc_vm_t *vms;
-    int nactivevms;
-    int ninactivevms;
+    virCapsPtr caps;
+
+    virDomainObjPtr domains;
     char *configDir;
+    char *autostartDir;
     char *stateDir;
     char *logDir;
     int have_netns;
 };
 
-/* Types and structs */
-
-/* Inline Functions */
-static inline int lxcIsActiveVM(lxc_vm_t *vm)
-{
-    return vm->def->id != -1;
-}
-
-/* Function declarations */
-lxc_vm_def_t * lxcParseVMDef(virConnectPtr conn,
-                             const char* xmlString,
-                             const char* fileName);
-int lxcSaveVMDef(virConnectPtr conn,
-                 lxc_driver_t *driver,
-                 lxc_vm_t *vm,
-                 lxc_vm_def_t *def);
 int lxcLoadDriverConfig(lxc_driver_t *driver);
-int lxcSaveConfig(virConnectPtr conn,
-                  lxc_driver_t *driver,
-                  lxc_vm_t *vm,
-                  lxc_vm_def_t *def);
-int lxcLoadContainerInfo(lxc_driver_t *driver);
-int lxcLoadContainerConfigFile(lxc_driver_t *driver,
-                               const char *file);
-lxc_vm_t * lxcAssignVMDef(virConnectPtr conn,
-                          lxc_driver_t *driver,
-                          lxc_vm_def_t *def);
-char *lxcGenerateXML(virConnectPtr conn,
-                     lxc_driver_t *driver,
-                     lxc_vm_t *vm,
-                     lxc_vm_def_t *def);
-lxc_vm_t *lxcFindVMByID(const lxc_driver_t *driver, int id);
-lxc_vm_t *lxcFindVMByUUID(const lxc_driver_t *driver,
-                          const unsigned char *uuid);
-lxc_vm_t *lxcFindVMByName(const lxc_driver_t *driver,
-                          const char *name);
-int lxcCheckContainerProcess(lxc_vm_def_t *vm);
-void lxcRemoveInactiveVM(lxc_driver_t *driver,
-                         lxc_vm_t *vm);
-void lxcFreeVMs(lxc_vm_t *vms);
-void lxcFreeVM(lxc_vm_t *vm);
-void lxcFreeVMDef(lxc_vm_def_t *vmdef);
-int lxcDeleteConfig(virConnectPtr conn,
-                    lxc_driver_t *driver,
-                    const char *configFile,
-                    const char *name);
+virCapsPtr lxcCapsInit(void);
 
 void lxcError(virConnectPtr conn,
               virDomainPtr dom,
diff -r 7059fd49ed7e src/lxc_container.c
--- a/src/lxc_container.c	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/lxc_container.c	Mon Jul 14 21:34:06 2008 +0100
@@ -68,7 +68,7 @@
 
 typedef struct __lxc_child_argv lxc_child_argv_t;
 struct __lxc_child_argv {
-    lxc_vm_def_t *config;
+    virDomainDefPtr config;
     int nveths;
     char **veths;
     int monitor;
@@ -85,10 +85,10 @@
  *
  * Does not return
  */
-static int lxcContainerExecInit(const lxc_vm_def_t *vmDef)
+static int lxcContainerExecInit(virDomainDefPtr vmDef)
 {
     const char *const argv[] = {
-        vmDef->init,
+        vmDef->os.init,
         NULL,
     };
 
@@ -268,8 +268,8 @@
 {
     int rc = -1;
     lxc_child_argv_t *argv = data;
-    lxc_vm_def_t *vmDef = argv->config;
-    lxc_mount_t *curMount;
+    virDomainDefPtr vmDef = argv->config;
+    virDomainFSDefPtr curMount;
     int i;
 
     if (NULL == vmDef) {
@@ -280,17 +280,20 @@
 
     /* handle the bind mounts first before doing anything else that may */
     /* then access those mounted dirs */
-    curMount = vmDef->mounts;
+    curMount = vmDef->fss;
     for (i = 0; curMount; curMount = curMount->next) {
-        rc = mount(curMount->source,
-                   curMount->target,
+        // XXX fix
+        if (curMount->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+            continue;
+        rc = mount(curMount->src,
+                   curMount->dst,
                    NULL,
                    MS_BIND,
                    NULL);
         if (0 != rc) {
             lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                      _("failed to mount %s at %s for container: %s"),
-                     curMount->source, curMount->target, strerror(errno));
+                     curMount->src, curMount->dst, strerror(errno));
             return -1;
         }
     }
@@ -328,7 +331,7 @@
  *
  * Returns PID of container on success or -1 in case of error
  */
-int lxcContainerStart(lxc_vm_def_t *def,
+int lxcContainerStart(virDomainDefPtr def,
                       int nveths,
                       char **veths,
                       int control,
diff -r 7059fd49ed7e src/lxc_container.h
--- a/src/lxc_container.h	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/lxc_container.h	Mon Jul 14 21:34:06 2008 +0100
@@ -34,7 +34,7 @@
 
 int lxcContainerSendContinue(int control);
 
-int lxcContainerStart(lxc_vm_def_t *def,
+int lxcContainerStart(virDomainDefPtr def,
                       int nveths,
                       char **veths,
                       int control,
diff -r 7059fd49ed7e src/lxc_controller.c
--- a/src/lxc_controller.c	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/lxc_controller.c	Mon Jul 14 21:34:06 2008 +0100
@@ -320,7 +320,7 @@
 
 
 static int
-lxcControllerRun(lxc_vm_def_t *def,
+lxcControllerRun(virDomainDefPtr def,
                  int nveths,
                  char **veths,
                  int monitor,
@@ -381,7 +381,7 @@
 }
 
 
-int lxcControllerStart(lxc_vm_def_t *def,
+int lxcControllerStart(virDomainDefPtr def,
                        int nveths,
                        char **veths,
                        int monitor,
diff -r 7059fd49ed7e src/lxc_controller.h
--- a/src/lxc_controller.h	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/lxc_controller.h	Mon Jul 14 21:34:06 2008 +0100
@@ -30,7 +30,7 @@
 
 pid_t lxcControllerPID(int monitor);
 
-int lxcControllerStart(lxc_vm_def_t *def,
+int lxcControllerStart(virDomainDefPtr def,
                        int nveths,
                        char **veths,
                        int monitor,
diff -r 7059fd49ed7e src/lxc_driver.c
--- a/src/lxc_driver.c	Mon Jul 14 21:03:46 2008 +0100
+++ b/src/lxc_driver.c	Mon Jul 14 21:34:06 2008 +0100
@@ -36,7 +36,6 @@
 #include <unistd.h>
 #include <wait.h>
 
-#include "internal.h"
 #include "lxc_conf.h"
 #include "lxc_container.h"
 #include "lxc_driver.h"
@@ -108,7 +107,7 @@
                                         int id)
 {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByID(driver, id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, id);
     virDomainPtr dom;
 
     if (!vm) {
@@ -128,7 +127,7 @@
                                           const unsigned char *uuid)
 {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByUUID(driver, uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, uuid);
     virDomainPtr dom;
 
     if (!vm) {
@@ -148,7 +147,7 @@
                                           const char *name)
 {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByName(driver, name);
+    virDomainObjPtr vm = virDomainFindByName(driver->domains, name);
     virDomainPtr dom;
 
     if (!vm) {
@@ -164,90 +163,96 @@
     return dom;
 }
 
-static int lxcListDomains(virConnectPtr conn, int *ids, int nids)
-{
+static int lxcListDomains(virConnectPtr conn, int *ids, int nids) {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    lxc_vm_t *vm;
-    int numDoms = 0;
-
-    for (vm = driver->vms; vm && (numDoms < nids); vm = vm->next) {
-        if (lxcIsActiveVM(vm)) {
-            ids[numDoms] = vm->def->id;
-            numDoms++;
+    virDomainObjPtr vm = driver->domains;
+    int got = 0;
+    while (vm && got < nids) {
+        if (virDomainIsActive(vm)) {
+            ids[got] = vm->def->id;
+            got++;
         }
+        vm = vm->next;
     }
-
-    return numDoms;
+    return got;
 }
-
-static int lxcNumDomains(virConnectPtr conn)
-{
+static int lxcNumDomains(virConnectPtr conn) {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    return driver->nactivevms;
+    int n = 0;
+    virDomainObjPtr dom = driver->domains;
+    while (dom) {
+        if (virDomainIsActive(dom))
+            n++;
+        dom = dom->next;
+    }
+    return n;
 }
 
 static int lxcListDefinedDomains(virConnectPtr conn,
-                                 char **const names, int nnames)
-{
+                                 char **const names, int nnames) {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    lxc_vm_t *vm;
-    int numDoms = 0;
-    int i;
-
-    for (vm = driver->vms; vm && (numDoms < nnames); vm = vm->next) {
-        if (!lxcIsActiveVM(vm)) {
-            if (!(names[numDoms] = strdup(vm->def->name))) {
-                lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "names");
+    virDomainObjPtr vm = driver->domains;
+    int got = 0, i;
+    while (vm && got < nnames) {
+        if (!virDomainIsActive(vm)) {
+            if (!(names[got] = strdup(vm->def->name))) {
+                lxcError(conn, NULL, VIR_ERR_NO_MEMORY, NULL);
                 goto cleanup;
             }
-
-            numDoms++;
+            got++;
         }
-
+        vm = vm->next;
     }
-
-    return numDoms;
+    return got;
 
  cleanup:
-    for (i = 0 ; i < numDoms ; i++) {
+    for (i = 0 ; i < got ; i++)
         VIR_FREE(names[i]);
-    }
-
     return -1;
 }
 
 
-static int lxcNumDefinedDomains(virConnectPtr conn)
-{
+static int lxcNumDefinedDomains(virConnectPtr conn) {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    return driver->ninactivevms;
+    int n = 0;
+    virDomainObjPtr dom = driver->domains;
+    while (dom) {
+        if (!virDomainIsActive(dom))
+            n++;
+        dom = dom->next;
+    }
+    return n;
 }
+
+
 
 static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
 {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    lxc_vm_def_t *def;
-    lxc_vm_t *vm;
+    virDomainDefPtr def;
+    virDomainObjPtr vm;
     virDomainPtr dom;
 
-    if (!(def = lxcParseVMDef(conn, xml, NULL))) {
+    if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
         return NULL;
-    }
 
     if ((def->nets != NULL) && !(driver->have_netns)) {
         lxcError(conn, NULL, VIR_ERR_NO_SUPPORT,
                  _("System lacks NETNS support"));
-        lxcFreeVMDef(def);
+        virDomainDefFree(def);
         return NULL;
     }
 
-    if (!(vm = lxcAssignVMDef(conn, driver, def))) {
-        lxcFreeVMDef(def);
+    if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) {
+        virDomainDefFree(def);
         return NULL;
     }
 
-    if (lxcSaveVMDef(conn, driver, vm, def) < 0) {
-        lxcRemoveInactiveVM(driver, vm);
+    if (virDomainSaveConfig(conn,
+                            driver->configDir,
+                            driver->autostartDir,
+                            vm) < 0) {
+        virDomainRemoveInactive(&driver->domains, vm);
         return NULL;
     }
 
@@ -262,7 +267,7 @@
 static int lxcDomainUndefine(virDomainPtr dom)
 {
     lxc_driver_t *driver = (lxc_driver_t *)dom->conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -270,19 +275,18 @@
         return -1;
     }
 
-    if (lxcIsActiveVM(vm)) {
+    if (virDomainIsActive(vm)) {
         lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
                  _("cannot delete active domain"));
         return -1;
     }
 
-    if (lxcDeleteConfig(dom->conn, driver, vm->configFile, vm->def->name) < 0) {
+    if (virDomainDeleteConfig(dom->conn, vm) <0)
         return -1;
-    }
 
     vm->configFile[0] = '\0';
 
-    lxcRemoveInactiveVM(driver, vm);
+    virDomainRemoveInactive(&driver->domains, vm);
 
     return 0;
 }
@@ -291,7 +295,7 @@
                             virDomainInfoPtr info)
 {
     lxc_driver_t *driver = (lxc_driver_t *)dom->conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -301,30 +305,23 @@
 
     info->state = vm->state;
 
-    if (!lxcIsActiveVM(vm)) {
+    if (!virDomainIsActive(vm)) {
         info->cpuTime = 0;
     } else {
         info->cpuTime = 0;
     }
 
-    info->maxMem = vm->def->maxMemory;
-    info->memory = vm->def->maxMemory;
+    info->maxMem = vm->def->maxmem;
+    info->memory = vm->def->memory;
     info->nrVirtCpu = 1;
 
     return 0;
 }
 
-static char *lxcGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED)
-{
-    /* Linux containers only run on Linux */
-    return strdup("linux");
-}
-
-static char *lxcDomainDumpXML(virDomainPtr dom,
-                              int flags ATTRIBUTE_UNUSED)
+static char *lxcGetOSType(virDomainPtr dom)
 {
     lxc_driver_t *driver = (lxc_driver_t *)dom->conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByUUID(driver, dom->uuid);
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
 
     if (!vm) {
         lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -332,7 +329,25 @@
         return NULL;
     }
 
-    return lxcGenerateXML(dom->conn, driver, vm, vm->def);
+    return strdup(vm->def->os.type);
+}
+
+static char *lxcDomainDumpXML(virDomainPtr dom,
+                              int flags)
+{
+    lxc_driver_t *driver = (lxc_driver_t *)dom->conn->privateData;
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
+
+    if (!vm) {
+        lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
+                 _("no domain with matching uuid"));
+        return NULL;
+    }
+
+    return virDomainDefFormat(dom->conn,
+                              (flags & VIR_DOMAIN_XML_INACTIVE) &&
+                              vm->newDef ? vm->newDef : vm->def,
+                              flags);
 }
 
 
@@ -346,7 +361,7 @@
  *
  * Returns 0 on success or -1 in case of error
  */
-static int lxcVMCleanup(lxc_driver_t *driver, lxc_vm_t * vm)
+static int lxcVMCleanup(virDomainObjPtr  vm)
 {
     int rc = -1;
     int waitRc;
@@ -371,8 +386,6 @@
     vm->state = VIR_DOMAIN_SHUTOFF;
     vm->pid = -1;
     vm->def->id = -1;
-    driver->nactivevms--;
-    driver->ninactivevms++;
 
     return rc;
 }
@@ -388,12 +401,12 @@
  * Returns 0 on success or -1 in case of error
  */
 static int lxcSetupInterfaces(virConnectPtr conn,
-                              lxc_vm_def_t *def,
+                              virDomainDefPtr def,
                               int *nveths,
                               char ***veths)
 {
     int rc = -1;
-    lxc_net_def_t *net;
+    virDomainNetDefPtr net;
     char *bridge = NULL;
     char parentVeth[PATH_MAX] = "";
     char containerVeth[PATH_MAX] = "";
@@ -403,8 +416,11 @@
         return -1;
 
     for (net = def->nets; net; net = net->next) {
-        if (LXC_NET_NETWORK == net->type) {
-            virNetworkPtr network = virNetworkLookupByName(conn, net->txName);
+        switch (net->type) {
+        case VIR_DOMAIN_NET_TYPE_NETWORK:
+        {
+            virNetworkPtr network = virNetworkLookupByName(conn,
+                                                           net->data.network.name);
             if (!network) {
                 goto error_exit;
             }
@@ -412,8 +428,11 @@
             bridge = virNetworkGetBridgeName(network);
 
             virNetworkFree(network);
-        } else {
-            bridge = net->txName;
+            break;
+        }
+        case VIR_DOMAIN_NET_TYPE_BRIDGE:
+            bridge = net->data.bridge.brname;
+            break;
         }
 
         DEBUG("bridge: %s", bridge);
@@ -424,8 +443,8 @@
         }
 
         DEBUG0("calling vethCreate()");
-        if (NULL != net->parentVeth) {
-            strcpy(parentVeth, net->parentVeth);
+        if (NULL != net->ifname) {
+            strcpy(parentVeth, net->ifname);
         }
         DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth);
         if (0 != (rc = vethCreate(parentVeth, PATH_MAX, containerVeth, PATH_MAX))) {
@@ -433,15 +452,15 @@
                      _("failed to create veth device pair: %d"), rc);
             goto error_exit;
         }
-        if (NULL == net->parentVeth) {
-            net->parentVeth = strdup(parentVeth);
+        if (NULL == net->ifname) {
+            net->ifname = strdup(parentVeth);
         }
         if (VIR_REALLOC_N(*veths, (*nveths)+1) < 0)
             goto error_exit;
         if (((*veths)[(*nveths)++] = strdup(containerVeth)) == NULL)
             goto error_exit;
 
-        if (NULL == net->parentVeth) {
+        if (NULL == net->ifname) {
             lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                      _("failed to allocate veth names"));
             goto error_exit;
@@ -473,7 +492,7 @@
 
 static int lxcMonitorServer(virConnectPtr conn,
                             lxc_driver_t * driver,
-                            lxc_vm_t *vm)
+                            virDomainObjPtr vm)
 {
     char *sockpath = NULL;
     int fd;
@@ -523,7 +542,7 @@
 
 static int lxcMonitorClient(virConnectPtr conn,
                             lxc_driver_t * driver,
-                            lxc_vm_t *vm)
+                            virDomainObjPtr vm)
 {
     char *sockpath = NULL;
     int fd;
@@ -576,11 +595,12 @@
  */
 static int lxcVmStart(virConnectPtr conn,
                       lxc_driver_t * driver,
-                      lxc_vm_t * vm)
+                      virDomainObjPtr  vm)
 {
     int rc = -1, i;
     int monitor;
     int parentTty;
+    char *parentTtyPath = NULL;
     char *logfile = NULL;
     pid_t pid;
     int nveths = 0;
@@ -603,11 +623,17 @@
         goto cleanup;
 
     /* open parent tty */
-    VIR_FREE(vm->def->tty);
-    if (virFileOpenTty(&parentTty, &vm->def->tty, 1) < 0) {
+    if (virFileOpenTty(&parentTty, &parentTtyPath, 1) < 0) {
         lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
                  _("failed to allocate tty: %s"),
                  strerror(errno));
+    }
+    if (vm->def->console &&
+        vm->def->console->type == VIR_DOMAIN_CHR_TYPE_PTY) {
+        VIR_FREE(vm->def->console->data.file.path);
+        vm->def->console->data.file.path = parentTtyPath;
+    } else {
+        VIR_FREE(parentTtyPath);
     }
 
     if (lxcSetupInterfaces(conn, vm->def, &nveths, &veths) < 0)
@@ -626,8 +652,6 @@
 
     vm->pid = vm->def->id = pid;
     vm->state = VIR_DOMAIN_RUNNING;
-    driver->ninactivevms--;
-    driver->nactivevms++;
 
     rc = 0;
 
@@ -662,7 +686,7 @@
     int rc = -1;
     virConnectPtr conn = dom->conn;
     lxc_driver_t *driver = (lxc_driver_t *)(conn->privateData);
-    lxc_vm_t *vm = lxcFindVMByName(driver, dom->name);
+    virDomainObjPtr vm = virDomainFindByName(driver->domains, dom->name);
 
     if (!vm) {
         lxcError(conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -691,26 +715,20 @@
                         const char *xml,
                         unsigned int flags ATTRIBUTE_UNUSED) {
     lxc_driver_t *driver = (lxc_driver_t *)conn->privateData;
-    lxc_vm_t *vm;
-    lxc_vm_def_t *def;
+    virDomainObjPtr vm;
+    virDomainDefPtr def;
     virDomainPtr dom = NULL;
 
-    if (!(def = lxcParseVMDef(conn, xml, NULL))) {
+    if (!(def = virDomainDefParseString(conn, driver->caps, xml)))
+        goto return_point;
+
+    if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) {
+        virDomainDefFree(def);
         goto return_point;
     }
 
-    if (!(vm = lxcAssignVMDef(conn, driver, def))) {
-        lxcFreeVMDef(def);
-        goto return_point;
-    }
-
-    if (lxcSaveVMDef(conn, driver, vm, def) < 0) {
-        lxcRemoveInactiveVM(driver, vm);
-        return NULL;
-    }
-
     if (lxcVmStart(conn, driver, vm) < 0) {
-        lxcRemoveInactiveVM(driver, vm);
+        virDomainRemoveInactive(&driver->domains, vm);
         goto return_point;
     }
 
@@ -735,7 +753,7 @@
 {
     int rc = -1;
     lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByID(driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
 
     if (!vm) {
         lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -754,7 +772,7 @@
 
     vm->state = VIR_DOMAIN_SHUTDOWN;
 
-    rc = lxcVMCleanup(driver, vm);
+    rc = lxcVMCleanup(vm);
 
 error_out:
     return rc;
@@ -773,7 +791,7 @@
 {
     int rc = -1;
     lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
-    lxc_vm_t *vm = lxcFindVMByID(driver, dom->id);
+    virDomainObjPtr vm = virDomainFindByID(driver->domains, dom->id);
 
     if (!vm) {
         lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
@@ -792,7 +810,7 @@
 
     vm->state = VIR_DOMAIN_SHUTDOWN;
 
-    rc = lxcVMCleanup(driver, vm);
+    rc = lxcVMCleanup(vm);
 
 error_out:
     return rc;
@@ -816,7 +834,7 @@
 static int lxcStartup(void)
 {
     uid_t uid = getuid();
-    lxc_vm_t *vm;
+    virDomainObjPtr vm;
 
     /* Check that the user is root */
     if (0 != uid) {
@@ -839,13 +857,21 @@
         return -1;
     }
 
-    /* Call function to load the container configuration files */
-    if (lxcLoadContainerInfo(lxc_driver) < 0) {
+    if ((lxc_driver->caps = lxcCapsInit()) == NULL) {
         lxcShutdown();
         return -1;
     }
 
-    vm = lxc_driver->vms;
+    if (virDomainLoadAllConfigs(NULL,
+                                lxc_driver->caps,
+                                &lxc_driver->domains,
+                                lxc_driver->configDir,
+                                lxc_driver->autostartDir) < 0) {
+        lxcShutdown();
+        return -1;
+    }
+
+    vm = lxc_driver->domains;
     while (vm) {
         pid_t pid;
         if ((vm->monitor = lxcMonitorClient(NULL, lxc_driver, vm)) < 0) {
@@ -863,8 +889,6 @@
 
         vm->pid = vm->def->id = pid;
         vm->state = VIR_DOMAIN_RUNNING;
-        lxc_driver->ninactivevms--;
-        lxc_driver->nactivevms++;
 
         vm = vm->next;
     }
@@ -875,6 +899,7 @@
 static void lxcFreeDriver(lxc_driver_t *driver)
 {
     VIR_FREE(driver->configDir);
+    VIR_FREE(driver->autostartDir);
     VIR_FREE(driver->stateDir);
     VIR_FREE(driver->logDir);
     VIR_FREE(driver);
@@ -882,10 +907,15 @@
 
 static int lxcShutdown(void)
 {
+    virDomainObjPtr vm;
     if (lxc_driver == NULL)
         return(-1);
-    lxcFreeVMs(lxc_driver->vms);
-    lxc_driver->vms = NULL;
+    vm = lxc_driver->domains;
+    while (vm) {
+        virDomainObjPtr next = vm->next;
+        virDomainObjFree(vm);
+        vm = next;
+    }
     lxcFreeDriver(lxc_driver);
     lxc_driver = NULL;
 
@@ -901,13 +931,17 @@
  */
 static int
 lxcActive(void) {
+    virDomainObjPtr dom;
+
     if (lxc_driver == NULL)
         return(0);
-    /* If we've any active networks or guests, then we
-     * mark this driver as active
-     */
-    if (lxc_driver->nactivevms)
-        return 1;
+
+    dom = lxc_driver->domains;
+    while (dom) {
+        if (virDomainIsActive(dom))
+            return 1;
+        dom = dom->next;
+    }
 
     /* Otherwise we're happy to deal with a shutdown */
     return 0;

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