This patch adds the lxc_driver source files. -- Best Regards, Dave Leskovec IBM Linux Technology Center Open Virtualization
--- src/lxc_driver.c | 484 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lxc_driver.h | 45 +++++ 2 files changed, 529 insertions(+) Index: b/src/lxc_driver.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/src/lxc_driver.c 2008-03-14 11:24:45.000000000 -0700 @@ -0,0 +1,484 @@ +/* + * Copyright IBM Corp. 2008 + * + * lxc_driver.c: linux container driver functions + * + * Authors: + * David L. Leskovec <dlesko at linux.vnet.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <config.h> + +#ifdef WITH_LXC + +#include <sched.h> +#include <sys/utsname.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> +#include <wait.h> + +#include "lxc_conf.h" +#include "lxc_driver.h" +#include "driver.h" +#include "internal.h" + +/* debug macros */ +#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__) +#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg) + +static int lxcStartup(virConnectPtr conn); +static int lxcShutdown(virConnectPtr conn); + +/* Functions */ +static int lxcDummyChild( void *argv ATTRIBUTE_UNUSED ) +{ + exit(0); +} + +static int lxcCheckContainerSupport( void ) +{ + int rc = 0; + int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER| + CLONE_NEWIPC|SIGCHLD; + int cpid; + char *childStack; + char *stack; + int childStatus; + + stack = malloc(getpagesize() * 4); + if(!stack) { + DEBUG0("Unable to allocate stack"); + rc = -1; + goto check_complete; + } + + childStack = stack + (getpagesize() * 4); + + cpid = clone(lxcDummyChild, childStack, flags, NULL); + if ((0 > cpid) && (EINVAL == errno)) { + DEBUG0("clone call returned EINVAL, container support is not enabled"); + rc = -1; + } else { + waitpid(cpid, &childStatus, 0); + } + + free(stack); + +check_complete: + return rc; +} + +static const char *lxcProbe(void) +{ +#ifdef __linux__ + if (0 == lxcCheckContainerSupport()) { + return("lxc:///"); + } +#endif + return(NULL); +} + +static virDrvOpenStatus lxcOpen(virConnectPtr conn, + xmlURIPtr uri, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED) +{ + uid_t uid = getuid(); + + /* Check that the user is root */ + if (0 != uid) { + goto declineConnection; + } + + /* Verify uri was specified */ + if ((NULL == uri) || (NULL == uri->scheme)) { + goto declineConnection; + } + + /* Check that the uri scheme is lxc */ + if (STRNEQ(uri->scheme, "lxc")) { + goto declineConnection; + } + + /* Check that this is a container enabled kernel */ + if(0 != lxcCheckContainerSupport()) { + goto declineConnection; + } + + /* initialize driver data */ + if (0 > lxcStartup(conn)) { + goto declineConnection; + } + + return VIR_DRV_OPEN_SUCCESS; + +declineConnection: + return VIR_DRV_OPEN_DECLINED; +} + +static int lxcClose(virConnectPtr conn) +{ + return lxcShutdown(conn); +} + +static virDomainPtr lxcDomainLookupByID(virConnectPtr conn, + int id) +{ + lxc_driver_t *driver = (lxc_driver_t *)conn->privateData; + lxc_vm_t *vm = lxcFindVMByID(driver, id); + virDomainPtr dom; + + if (!vm) { + lxcError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL); + return NULL; + } + + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); + if (dom) { + dom->id = vm->def->id; + } + + return dom; +} + +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); + virDomainPtr dom; + + if (!vm) { + lxcError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL); + return NULL; + } + + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); + if (dom) { + dom->id = vm->def->id; + } + + return dom; +} + +static virDomainPtr lxcDomainLookupByName(virConnectPtr conn, + const char *name) +{ + lxc_driver_t *driver = (lxc_driver_t *)conn->privateData; + lxc_vm_t *vm = lxcFindVMByName(driver, name); + virDomainPtr dom; + + if (!vm) { + lxcError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL); + return NULL; + } + + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); + if (dom) { + dom->id = vm->def->id; + } + + return dom; +} + +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++; + } + } + + return numDoms; +} + +static int lxcNumDomains(virConnectPtr conn) +{ + lxc_driver_t *driver = (lxc_driver_t *)conn->privateData; + return driver->nactivevms; +} + +static int lxcListDefinedDomains(virConnectPtr conn, + 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"); + goto cleanup; + } + + numDoms++; + } + + } + + return numDoms; + + cleanup: + for (i = 0 ; i < numDoms ; i++) { + free(names[i]); + } + + return -1; +} + + +static int lxcNumDefinedDomains(virConnectPtr conn) +{ + lxc_driver_t *driver = (lxc_driver_t *)conn->privateData; + return driver->ninactivevms; +} + +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; + virDomainPtr dom; + + if (!(def = lxcParseVMDef(conn, xml, NULL))) { + return NULL; + } + + if (!(vm = lxcAssignVMDef(conn, driver, def))) { + lxcFreeVMDef(def); + return NULL; + } + + if (lxcSaveVMDef(conn, driver, vm, def) < 0) { + lxcRemoveInactiveVM(driver, vm); + return NULL; + } + + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); + if (dom) { + dom->id = vm->def->id; + } + + return dom; +} + +static int lxcDomainUndefine(virDomainPtr dom) +{ + lxc_driver_t *driver = (lxc_driver_t *)dom->conn->privateData; + lxc_vm_t *vm = lxcFindVMByUUID(driver, dom->uuid); + + if (!vm) { + lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN, + _("no domain with matching uuid")); + return -1; + } + + if (lxcIsActiveVM(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) { + return -1; + } + + vm->configFile[0] = '\0'; + + lxcRemoveInactiveVM(driver, vm); + + return 0; +} + +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); + + if (!vm) { + lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN, + _("no domain with matching uuid")); + return -1; + } + + info->state = vm->state; + + if (!lxcIsActiveVM(vm)) { + info->cpuTime = 0; + } else { + info->cpuTime = 0; + } + + info->maxMem = vm->def->maxMemory; + info->memory = vm->def->maxMemory; + 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) +{ + lxc_driver_t *driver = (lxc_driver_t *)dom->conn->privateData; + lxc_vm_t *vm = lxcFindVMByUUID(driver, dom->uuid); + + if (!vm) { + lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN, + _("no domain with matching uuid")); + return NULL; + } + + return lxcGenerateXML(dom->conn, driver, vm, vm->def); +} + +static int lxcStartup(virConnectPtr conn) +{ + lxc_driver_t *driver; + + driver = calloc(1, sizeof(lxc_driver_t)); + if (NULL == driver) { + return -1; + } + + conn->privateData = driver; + + /* Call function to load lxc driver configuration information */ + if (lxcLoadDriverConfig(conn) < 0) { + lxcShutdown(conn); + return -1; + } + + /* Call function to load the container configuration files */ + if (lxcLoadContainerInfo(conn) < 0) { + lxcShutdown(conn); + return -1; + } + + return 0; +} + +static void lxcFreeDriver(lxc_driver_t *driver) +{ + free(driver->configDir); + free(driver); +} + +static int lxcShutdown(virConnectPtr conn) +{ + lxc_driver_t *driver = (lxc_driver_t *)conn->privateData; + lxc_vm_t *vms = driver->vms; + + lxcFreeVMs(vms); + driver->vms = NULL; + lxcFreeDriver(driver); + conn->privateData = NULL; + + return 0; +} + +/* Function Tables */ +static virDriver lxcDriver = { + VIR_DRV_LXC, /* the number virDrvNo */ + "LXC", /* the name of the driver */ + LIBVIR_VERSION_NUMBER, /* the version of the backend */ + lxcProbe, /* probe */ + lxcOpen, /* open */ + lxcClose, /* close */ + NULL, /* supports_feature */ + NULL, /* type */ + NULL, /* version */ + NULL, /* getHostname */ + NULL, /* getURI */ + NULL, /* getMaxVcpus */ + NULL, /* nodeGetInfo */ + NULL, /* getCapabilities */ + lxcListDomains, /* listDomains */ + lxcNumDomains, /* numOfDomains */ + NULL/*lxcDomainCreateLinux*/, /* domainCreateLinux */ + lxcDomainLookupByID, /* domainLookupByID */ + lxcDomainLookupByUUID, /* domainLookupByUUID */ + lxcDomainLookupByName, /* domainLookupByName */ + NULL, /* domainSuspend */ + NULL, /* domainResume */ + NULL, /* domainShutdown */ + NULL, /* domainReboot */ + NULL, /* domainDestroy */ + lxcGetOSType, /* domainGetOSType */ + NULL, /* domainGetMaxMemory */ + NULL, /* domainSetMaxMemory */ + NULL, /* domainSetMemory */ + lxcDomainGetInfo, /* domainGetInfo */ + NULL, /* domainSave */ + NULL, /* domainRestore */ + NULL, /* domainCoreDump */ + NULL, /* domainSetVcpus */ + NULL, /* domainPinVcpu */ + NULL, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ + lxcDomainDumpXML, /* domainDumpXML */ + lxcListDefinedDomains, /* listDefinedDomains */ + lxcNumDefinedDomains, /* numOfDefinedDomains */ + NULL, /* domainCreate */ + lxcDomainDefine, /* domainDefineXML */ + lxcDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ + NULL, /* domainDetachDevice */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ + NULL, /* domainGetSchedulerParameters */ + NULL, /* domainSetSchedulerParameters */ + NULL, /* domainMigratePrepare */ + NULL, /* domainMigratePerform */ + NULL, /* domainMigrateFinish */ + NULL, /* domainBlockStats */ + NULL, /* domainInterfaceStats */ + NULL, /* nodeGetCellsFreeMemory */ + NULL, /* getFreeMemory */ +}; + +int lxcRegister(void) +{ + virRegisterDriver(&lxcDriver); + return 0; +} + +#endif /* WITH_LXC */ + +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ Index: b/src/lxc_driver.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/src/lxc_driver.h 2008-03-14 11:24:45.000000000 -0700 @@ -0,0 +1,45 @@ +/* + * Copyright IBM Corp. 2008 + * + * lxc_driver.h: header file for linux container driver functions + * + * Authors: + * David L. Leskovec <dlesko at linux.vnet.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef LXC_DRIVER_H +#define LXC_DRIVER_H + +#include <config.h> + +#ifdef WITH_LXC + +/* Function declarations */ +int lxcRegister(void); + +#endif /* WITH_LXC */ + +#endif /* LXC_DRIVER_H */ + +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list