]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Switch LXC driver over to generic domain XML processing APIs
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 13 Aug 2008 12:50:55 +0000 (12:50 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 13 Aug 2008 12:50:55 +0000 (12:50 +0000)
ChangeLog
src/lxc_conf.c
src/lxc_conf.h
src/lxc_container.c
src/lxc_container.h
src/lxc_controller.c
src/lxc_controller.h
src/lxc_driver.c

index 4b2883daf74393cb7d94f442bdb22043eb1b5396..677904d2c9b031d5cbe3d83c8056ee99664f9de0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Wed Aug 13 13:40:36 BST 2008 Daniel Berrange <berrange@redhat.com>
+
+       * src/lxc_conf.c, src/lxc_conf.h: Remove all domain XML
+       parsing / formatting methods, and all helpers for loading
+       and saving files on disk. Added capabilities data object
+       * src/lxc_container.c, src/lxc_container.h, src/lxc_driver.c,
+       src/lxc_controller.h, src/lxc_controller.c: Switch over
+       to use generic domain XML processing APIs.
+
 Wed Aug 13 11:48:36 BST 2008 Daniel Berrange <berrange@redhat.com>
 
        * configure.in: Add check for termios.h
index 875651eaedb12a60d6d839136b9b044a9d429c29..94837d90c1f4f532b94652ff65bc5121d31ffea9 100644 (file)
 
 #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 @@ void lxcError(virConnectPtr conn, virDomainPtr dom, int code,
               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,771 +57,42 @@ void lxcError(virConnectPtr conn, virDomainPtr dom, int code,
                     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)
-{
-    int rc = -1;
-    xmlNodePtr cur;
-    xmlChar *type = NULL;
-    xmlChar *parentIfName = NULL;
-    xmlChar *network = NULL;
-    xmlChar *bridge = NULL;
-    xmlChar *macaddr = NULL;
-
-    netDef->type = LXC_NET_NETWORK;
-
-    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;
-        }
-    }
-
-    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 (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;
-        }
-
-        netDef->txName = strdup((char *)network);
-        if (NULL == netDef->txName) {
-            lxcError(conn, NULL, VIR_ERR_NO_MEMORY,
-                     _("No storage for network name"));
-            goto error_out;
-        }
-
-    } 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)
+virCapsPtr lxcCapsInit(void)
 {
-    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;
-        }
+    struct utsname utsname;
+    virCapsPtr caps;
+    virCapsGuestPtr guest;
 
-        /* verify the container process still exists */
-        if (1 != lxcCheckContainerProcess(containerDef)) {
-            containerDef->id = -1;
-        }
+    uname(&utsname);
 
-    } 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);
+    if ((caps = virCapabilitiesNew(utsname.machine,
+                                   0, 0)) == NULL)
+        goto no_memory;
 
-    return containerDef;
+    if ((guest = virCapabilitiesAddGuest(caps,
+                                         "exe",
+                                         utsname.machine,
+                                         sizeof(int) == 4 ? 32 : 8,
+                                         NULL,
+                                         NULL,
+                                         0,
+                                         NULL)) == NULL)
+        goto no_memory;
 
- error:
-    VIR_FREE(xmlProp);
-    xmlXPathFreeContext(contextPtr);
-    lxcFreeVMDef(containerDef);
+    if (virCapabilitiesAddGuestDomain(guest,
+                                      "lxc",
+                                      NULL,
+                                      NULL,
+                                      0,
+                                      NULL) == NULL)
+        goto no_memory;
+    return caps;
 
+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 */
@@ -853,254 +110,5 @@ no_memory:
     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 */
index b3fe86b36425e22b1c91fcf74cd46cbdcc779990..931f24f15b4a1dccdfa19ad1dbfcd2b885f1a9b8 100644 (file)
 #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,
index 36ab654928999696afaa1c2766766a4a1d78aa61..142ae7c3aa9d847d120c859d37d229a5d4454aaa 100644 (file)
@@ -68,7 +68,7 @@ typedef char lxc_message_t;
 
 typedef struct __lxc_child_argv lxc_child_argv_t;
 struct __lxc_child_argv {
-    lxc_vm_def_t *config;
+    virDomainDefPtr config;
     unsigned int nveths;
     char **veths;
     int monitor;
@@ -85,10 +85,10 @@ struct __lxc_child_argv {
  *
  * 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,
     };
 
@@ -269,8 +269,8 @@ static int lxcContainerChild( void *data )
 {
     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) {
@@ -281,17 +281,20 @@ static int lxcContainerChild( void *data )
 
     /* 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;
         }
     }
@@ -329,7 +332,7 @@ static int lxcContainerChild( void *data )
  *
  * Returns PID of container on success or -1 in case of error
  */
-int lxcContainerStart(lxc_vm_def_t *def,
+int lxcContainerStart(virDomainDefPtr def,
                       unsigned int nveths,
                       char **veths,
                       int control,
index 1b492a69ede1f0736e5b6aeb5df81e2b6d97d611..5da3772f1eeef3207a6ce2e20f8b7ff9f45cf923 100644 (file)
@@ -34,7 +34,7 @@ enum {
 
 int lxcContainerSendContinue(int control);
 
-int lxcContainerStart(lxc_vm_def_t *def,
+int lxcContainerStart(virDomainDefPtr def,
                       unsigned int nveths,
                       char **veths,
                       int control,
index b2c07182a8eb9161ca804e7c39e37e8707f9696b..9f67ce574d887cbc73e0f3e8aa76203217f2cc65 100644 (file)
@@ -306,7 +306,7 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths,
 
 static int
 lxcControllerRun(const char *stateDir,
-                 lxc_vm_def_t *def,
+                 virDomainDefPtr def,
                  unsigned int nveths,
                  char **veths,
                  int monitor,
@@ -368,7 +368,7 @@ cleanup:
 
 
 int lxcControllerStart(const char *stateDir,
-                       lxc_vm_def_t *def,
+                       virDomainDefPtr def,
                        unsigned int nveths,
                        char **veths,
                        int monitor,
index d390dc27613dfe97946a17ca885ce7d2424358c7..8bfb8c88a937da52abd76001cc534d3e5655d46a 100644 (file)
@@ -29,7 +29,7 @@
 #include "lxc_conf.h"
 
 int lxcControllerStart(const char *stateDir,
-                       lxc_vm_def_t *def,
+                       virDomainDefPtr def,
                        unsigned int nveths,
                        char **veths,
                        int monitor,
index 515bfd76d67ba1a079d59a9c2d2655afad04ecfb..629f51bcb5fa6afdf9fcb6230b714941eee499e4 100644 (file)
@@ -37,7 +37,6 @@
 #include <unistd.h>
 #include <wait.h>
 
-#include "internal.h"
 #include "lxc_conf.h"
 #include "lxc_container.h"
 #include "lxc_driver.h"
@@ -111,7 +110,7 @@ static virDomainPtr lxcDomainLookupByID(virConnectPtr conn,
                                         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) {
@@ -131,7 +130,7 @@ static virDomainPtr lxcDomainLookupByUUID(virConnectPtr conn,
                                           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) {
@@ -151,7 +150,7 @@ static virDomainPtr lxcDomainLookupByName(virConnectPtr conn,
                                           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) {
@@ -167,90 +166,96 @@ static virDomainPtr lxcDomainLookupByName(virConnectPtr conn,
     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;
     }
 
@@ -265,7 +270,7 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
 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,
@@ -273,19 +278,18 @@ static int lxcDomainUndefine(virDomainPtr dom)
         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;
 }
@@ -294,7 +298,7 @@ static int lxcDomainGetInfo(virDomainPtr dom,
                             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,
@@ -304,30 +308,38 @@ static int lxcDomainGetInfo(virDomainPtr dom,
 
     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)
+static char *lxcGetOSType(virDomainPtr dom)
 {
-    /* Linux containers only run on Linux */
-    return strdup("linux");
+    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 strdup(vm->def->os.type);
 }
 
 static char *lxcDomainDumpXML(virDomainPtr dom,
-                              int flags ATTRIBUTE_UNUSED)
+                              int flags)
 {
     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,
@@ -335,7 +347,10 @@ static char *lxcDomainDumpXML(virDomainPtr dom,
         return NULL;
     }
 
-    return lxcGenerateXML(dom->conn, driver, vm, vm->def);
+    return virDomainDefFormat(dom->conn,
+                              (flags & VIR_DOMAIN_XML_INACTIVE) &&
+                              vm->newDef ? vm->newDef : vm->def,
+                              flags);
 }
 
 
@@ -351,7 +366,7 @@ static char *lxcDomainDumpXML(virDomainPtr dom,
  */
 static int lxcVMCleanup(virConnectPtr conn,
                         lxc_driver_t *driver,
-                        lxc_vm_t * vm)
+                        virDomainObjPtr  vm)
 {
     int rc = -1;
     int waitRc;
@@ -383,8 +398,6 @@ static int lxcVMCleanup(virConnectPtr conn,
     vm->pid = -1;
     vm->def->id = -1;
     vm->monitor = -1;
-    driver->nactivevms--;
-    driver->ninactivevms++;
 
     return rc;
 }
@@ -400,12 +413,12 @@ static int lxcVMCleanup(virConnectPtr conn,
  * Returns 0 on success or -1 in case of error
  */
 static int lxcSetupInterfaces(virConnectPtr conn,
-                              lxc_vm_def_t *def,
+                              virDomainDefPtr def,
                               unsigned 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] = "";
@@ -415,8 +428,11 @@ static int lxcSetupInterfaces(virConnectPtr conn,
         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;
             }
@@ -424,8 +440,11 @@ static int lxcSetupInterfaces(virConnectPtr conn,
             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);
@@ -436,8 +455,8 @@ static int lxcSetupInterfaces(virConnectPtr conn,
         }
 
         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))) {
@@ -445,15 +464,15 @@ static int lxcSetupInterfaces(virConnectPtr conn,
                      _("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;
@@ -485,7 +504,7 @@ error_exit:
 
 static int lxcMonitorServer(virConnectPtr conn,
                             lxc_driver_t * driver,
-                            lxc_vm_t *vm)
+                            virDomainObjPtr vm)
 {
     char *sockpath = NULL;
     int fd;
@@ -535,7 +554,7 @@ error:
 
 static int lxcMonitorClient(virConnectPtr conn,
                             lxc_driver_t * driver,
-                            lxc_vm_t *vm)
+                            virDomainObjPtr vm)
 {
     char *sockpath = NULL;
     int fd;
@@ -578,7 +597,7 @@ error:
 
 static int lxcVmTerminate(virConnectPtr conn,
                           lxc_driver_t *driver,
-                          lxc_vm_t *vm,
+                          virDomainObjPtr vm,
                           int signum)
 {
     if (signum == 0)
@@ -603,7 +622,7 @@ static void lxcMonitorEvent(int fd,
                             void *data)
 {
     lxc_driver_t *driver = data;
-    lxc_vm_t *vm = driver->vms;
+    virDomainObjPtr vm = driver->domains;
 
     while (vm) {
         if (vm->monitor == fd)
@@ -632,12 +651,13 @@ static void lxcMonitorEvent(int fd,
  */
 static int lxcVmStart(virConnectPtr conn,
                       lxc_driver_t * driver,
-                      lxc_vm_t * vm)
+                      virDomainObjPtr  vm)
 {
     int rc = -1;
     unsigned int i;
     int monitor;
     int parentTty;
+    char *parentTtyPath = NULL;
     char *logfile = NULL;
     int logfd = -1;
     unsigned int nveths = 0;
@@ -660,13 +680,19 @@ static int lxcVmStart(virConnectPtr conn,
         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));
         goto cleanup;
     }
+    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)
         goto cleanup;
@@ -705,8 +731,6 @@ static int lxcVmStart(virConnectPtr conn,
 
     vm->def->id = vm->pid;
     vm->state = VIR_DOMAIN_RUNNING;
-    driver->ninactivevms--;
-    driver->nactivevms++;
 
     if (virEventAddHandle(vm->monitor,
                           POLLERR | POLLHUP,
@@ -751,7 +775,7 @@ static int lxcDomainStart(virDomainPtr dom)
     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,
@@ -759,6 +783,12 @@ static int lxcDomainStart(virDomainPtr dom)
         goto cleanup;
     }
 
+    if ((vm->def->nets != NULL) && !(driver->have_netns)) {
+        lxcError(conn, NULL, VIR_ERR_NO_SUPPORT,
+                 _("System lacks NETNS support"));
+        goto cleanup;
+    }
+
     rc = lxcVmStart(conn, driver, vm);
 
 cleanup:
@@ -780,26 +810,28 @@ lxcDomainCreateAndStart(virConnectPtr conn,
                         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 = lxcAssignVMDef(conn, driver, def))) {
-        lxcFreeVMDef(def);
+    if ((def->nets != NULL) && !(driver->have_netns)) {
+        virDomainDefFree(def);
+        lxcError(conn, NULL, VIR_ERR_NO_SUPPORT,
+                 _("System lacks NETNS support"));
         goto return_point;
     }
 
-    if (lxcSaveVMDef(conn, driver, vm, def) < 0) {
-        lxcRemoveInactiveVM(driver, vm);
-        return NULL;
+
+    if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) {
+        virDomainDefFree(def);
+        goto return_point;
     }
 
     if (lxcVmStart(conn, driver, vm) < 0) {
-        lxcRemoveInactiveVM(driver, vm);
+        virDomainRemoveInactive(&driver->domains, vm);
         goto return_point;
     }
 
@@ -823,7 +855,7 @@ return_point:
 static int lxcDomainShutdown(virDomainPtr dom)
 {
     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,
@@ -846,7 +878,7 @@ static int lxcDomainShutdown(virDomainPtr dom)
 static int lxcDomainDestroy(virDomainPtr dom)
 {
     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,
@@ -875,7 +907,7 @@ static int lxcCheckNetNsSupport(void)
 static int lxcStartup(void)
 {
     uid_t uid = getuid();
-    lxc_vm_t *vm;
+    virDomainObjPtr vm;
 
     /* Check that the user is root */
     if (0 != uid) {
@@ -898,13 +930,21 @@ static int lxcStartup(void)
         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) {
         int rc;
         if ((vm->monitor = lxcMonitorClient(NULL, lxc_driver, vm)) < 0) {
@@ -923,8 +963,6 @@ static int lxcStartup(void)
         if (vm->pid != 0) {
             vm->def->id = vm->pid;
             vm->state = VIR_DOMAIN_RUNNING;
-            lxc_driver->ninactivevms--;
-            lxc_driver->nactivevms++;
         } else {
             vm->def->id = -1;
             close(vm->monitor);
@@ -940,6 +978,7 @@ static int lxcStartup(void)
 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);
@@ -947,10 +986,15 @@ static void lxcFreeDriver(lxc_driver_t *driver)
 
 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;
 
@@ -966,13 +1010,17 @@ static int lxcShutdown(void)
  */
 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;