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 vast majority of lxc_conf.h/c is simply deleted - this is all redundant when using the domain_conf.h APIs. Then, 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. lxc_conf.c | 1052 +------------------------------------------------------ lxc_conf.h | 121 ------ lxc_container.c | 23 - lxc_container.h | 2 lxc_controller.c | 4 lxc_controller.h | 2 lxc_driver.c | 289 ++++++++------- 7 files changed, 215 insertions(+), 1278 deletions(-) Daniel diff -r 72ff3545be62 src/lxc_conf.c --- a/src/lxc_conf.c Tue Aug 05 16:50:44 2008 +0100 +++ b/src/lxc_conf.c Tue Aug 05 16:50:49 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,769 +57,40 @@ 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; + 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; + return caps; - 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) -{ - 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) @@ -853,254 +110,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 72ff3545be62 src/lxc_conf.h --- a/src/lxc_conf.h Tue Aug 05 16:50:44 2008 +0100 +++ b/src/lxc_conf.h Tue Aug 05 16:50:49 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 72ff3545be62 src/lxc_container.c --- a/src/lxc_container.c Tue Aug 05 16:50:44 2008 +0100 +++ b/src/lxc_container.c Tue Aug 05 16:50:49 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 72ff3545be62 src/lxc_container.h --- a/src/lxc_container.h Tue Aug 05 16:50:44 2008 +0100 +++ b/src/lxc_container.h Tue Aug 05 16:50:49 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 72ff3545be62 src/lxc_controller.c --- a/src/lxc_controller.c Tue Aug 05 16:50:44 2008 +0100 +++ b/src/lxc_controller.c Tue Aug 05 16:50:49 2008 +0100 @@ -339,7 +339,7 @@ static int lxcControllerRun(const char *stateDir, - lxc_vm_def_t *def, + virDomainDefPtr def, int nveths, char **veths, int monitor, @@ -401,7 +401,7 @@ int lxcControllerStart(const char *stateDir, - lxc_vm_def_t *def, + virDomainDefPtr def, int nveths, char **veths, int monitor, diff -r 72ff3545be62 src/lxc_controller.h --- a/src/lxc_controller.h Tue Aug 05 16:50:44 2008 +0100 +++ b/src/lxc_controller.h Tue Aug 05 16:50:49 2008 +0100 @@ -31,7 +31,7 @@ int lxcControllerClientHandshake(int monitor); int lxcControllerStart(const char *stateDir, - lxc_vm_def_t *def, + virDomainDefPtr def, int nveths, char **veths, int monitor, diff -r 72ff3545be62 src/lxc_driver.c --- a/src/lxc_driver.c Tue Aug 05 16:50:44 2008 +0100 +++ b/src/lxc_driver.c Tue Aug 05 16:50:49 2008 +0100 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ 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,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, @@ -335,7 +332,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); } @@ -350,12 +365,12 @@ * Returns 0 on success or -1 in case of error */ static int lxcVMCleanup(virConnectPtr conn, - lxc_driver_t *driver, - lxc_vm_t * vm) + virDomainObjPtr vm) { int rc = -1; int waitRc; int childStatus = -1; + lxc_driver_t *driver = (lxc_driver_t *)conn->privateData; while (((waitRc = waitpid(vm->pid, &childStatus, 0)) == -1) && errno == EINTR); @@ -382,8 +397,6 @@ vm->pid = -1; vm->def->id = -1; vm->monitor = -1; - driver->nactivevms--; - driver->ninactivevms++; return rc; } @@ -399,12 +412,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] = ""; @@ -414,8 +427,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; } @@ -423,8 +439,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); @@ -435,8 +454,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))) { @@ -444,15 +463,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; @@ -484,7 +503,7 @@ static int lxcMonitorServer(virConnectPtr conn, lxc_driver_t * driver, - lxc_vm_t *vm) + virDomainObjPtr vm) { char *sockpath = NULL; int fd; @@ -534,7 +553,7 @@ static int lxcMonitorClient(virConnectPtr conn, lxc_driver_t * driver, - lxc_vm_t *vm) + virDomainObjPtr vm) { char *sockpath = NULL; int fd; @@ -583,8 +602,7 @@ static int lxcVmTerminate(virConnectPtr conn, - lxc_driver_t *driver, - lxc_vm_t *vm, + virDomainObjPtr vm, int signum) { if (signum == 0) @@ -601,7 +619,7 @@ vm->state = VIR_DOMAIN_SHUTDOWN; - return lxcVMCleanup(conn, driver, vm); + return lxcVMCleanup(conn, vm); } static void lxcMonitorEvent(int fd, @@ -609,7 +627,7 @@ void *data) { lxc_driver_t *driver = data; - lxc_vm_t *vm = driver->vms; + virDomainObjPtr vm = driver->domains; while (vm) { if (vm->monitor == fd) @@ -621,7 +639,7 @@ return; } - if (lxcVmTerminate(NULL, driver, vm, SIGINT) < 0) + if (lxcVmTerminate(NULL, vm, SIGINT) < 0) virEventRemoveHandle(fd); } @@ -638,11 +656,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; int logfd = -1; int nveths = 0; @@ -665,12 +684,18 @@ 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) @@ -710,14 +735,12 @@ vm->def->id = vm->pid; vm->state = VIR_DOMAIN_RUNNING; - driver->ninactivevms--; - driver->nactivevms++; if (virEventAddHandle(vm->monitor, POLLERR | POLLHUP, lxcMonitorEvent, driver) < 0) { - lxcVmTerminate(conn, driver, vm, 0); + lxcVmTerminate(conn, vm, 0); goto cleanup; } @@ -756,7 +779,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, @@ -785,26 +808,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; } @@ -828,7 +845,7 @@ 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, @@ -836,7 +853,7 @@ return -1; } - return lxcVmTerminate(dom->conn, driver, vm, 0); + return lxcVmTerminate(dom->conn, vm, 0); } @@ -851,7 +868,7 @@ 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, @@ -859,7 +876,7 @@ return -1; } - return lxcVmTerminate(dom->conn, driver, vm, SIGKILL); + return lxcVmTerminate(dom->conn, vm, SIGKILL); } static int lxcCheckNetNsSupport(void) @@ -880,7 +897,7 @@ static int lxcStartup(void) { uid_t uid = getuid(); - lxc_vm_t *vm; + virDomainObjPtr vm; /* Check that the user is root */ if (0 != uid) { @@ -903,13 +920,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) { int rc; if ((vm->monitor = lxcMonitorClient(NULL, lxc_driver, vm)) < 0) { @@ -928,8 +953,6 @@ 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); @@ -945,6 +968,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); @@ -952,10 +976,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; @@ -971,13 +1000,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 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list