# HG changeset patch # User danms # Date 1223052361 0 # Node ID a28490b116b0430aa0d4f579bba57d52793312ed # Parent 47378698026980b5734c81f9480b50c783dde68a [r2008-10-03 16:46:01 by danms] Add cgroup manipulation and LXC driver diff -r 473786980269 -r a28490b116b0 src/Makefile.am --- a/src/Makefile.am Thu Oct 02 15:04:11 2008 +0000 +++ b/src/Makefile.am Fri Oct 03 16:46:01 2008 +0000 @@ -90,13 +90,15 @@ lxc_conf.c lxc_conf.h \ lxc_container.c lxc_container.h \ lxc_driver.c lxc_driver.h \ - veth.c veth.h + veth.c veth.h \ + cgroup.c cgroup.h LXC_CONTROLLER_SOURCES = \ lxc_conf.c lxc_conf.h \ lxc_container.c lxc_container.h \ lxc_controller.c \ - veth.c veth.h + veth.c veth.h \ + cgroup.c cgroup.h OPENVZ_DRIVER_SOURCES = \ openvz_conf.c openvz_conf.h \ diff -r 473786980269 -r a28490b116b0 src/lxc_container.c --- a/src/lxc_container.c Thu Oct 02 15:04:11 2008 +0000 +++ b/src/lxc_container.c Fri Oct 03 16:46:01 2008 +0000 @@ -320,12 +320,12 @@ mode_t mode; const char *path; } devs[] = { - { 1, 3, 0666, "/dev/null" }, - { 1, 5, 0666, "/dev/zero" }, - { 1, 7, 0666, "/dev/full" }, - { 5, 1, 0600, "/dev/console" }, - { 1, 8, 0666, "/dev/random" }, - { 1, 9, 0666, "/dev/urandom" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_NULL, 0666, "/dev/null" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_ZERO, 0666, "/dev/zero" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_FULL, 0666, "/dev/full" }, + { LXC_DEV_MAJ_TTY, LXC_DEV_MIN_CONSOLE, 0600, "/dev/console" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM, 0666, "/dev/random" }, + { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/dev/urandom" }, }; if (virFileMakePath("/dev") < 0 || diff -r 473786980269 -r a28490b116b0 src/lxc_container.h --- a/src/lxc_container.h Thu Oct 02 15:04:11 2008 +0000 +++ b/src/lxc_container.h Fri Oct 03 16:46:01 2008 +0000 @@ -30,6 +30,16 @@ LXC_CONTAINER_FEATURE_NET = (1 << 0), }; +#define LXC_DEV_MAJ_MEMORY 1 +#define LXC_DEV_MIN_NULL 3 +#define LXC_DEV_MIN_ZERO 5 +#define LXC_DEV_MIN_FULL 7 +#define LXC_DEV_MIN_RANDOM 8 +#define LXC_DEV_MIN_URANDOM 9 + +#define LXC_DEV_MAJ_TTY 5 +#define LXC_DEV_MIN_CONSOLE 1 + int lxcContainerSendContinue(int control); int lxcContainerStart(virDomainDefPtr def, diff -r 473786980269 -r a28490b116b0 src/lxc_controller.c --- a/src/lxc_controller.c Thu Oct 02 15:04:11 2008 +0000 +++ b/src/lxc_controller.c Fri Oct 03 16:46:01 2008 +0000 @@ -42,12 +42,82 @@ #include "veth.h" #include "memory.h" #include "util.h" - +#include "cgroup.h" #define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__) #define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg) int debugFlag = 0; + +struct cgroup_device_policy { + char type; + int major; + int minor; +}; + +/** + * lxcSetContainerResources + * @def: pointer to virtual machine structure + * + * Creates a cgroup for the container, moves the task inside, + * and sets resource limits + * + * Returns 0 on success or -1 in case of error + */ +static int lxcSetContainerResources(virDomainDefPtr def) +{ + virCgroupPtr cgroup; + int rc = -1; + int i; + struct cgroup_device_policy devices[] = { + {'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_NULL}, + {'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_ZERO}, + {'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_FULL}, + {'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM}, + {'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM}, + {'c', LXC_DEV_MAJ_TTY, LXC_DEV_MIN_CONSOLE}, + {0, 0, 0}}; + + if (virCgroupHaveSupport() != 0) + return 0; /* Not supported, so claim success */ + + rc = virCgroupForDomain(def, "lxc", &cgroup); + if (rc != 0) { + lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("Unable to create cgroup for %s\n"), def->name); + return rc; + } + + rc = virCgroupSetMemory(cgroup, def->maxmem); + if (rc != 0) + goto out; + + rc = virCgroupDenyAllDevices(cgroup); + if (rc != 0) + goto out; + + for (i = 0; devices[i].type != 0; i++) { + struct cgroup_device_policy *dev = &devices[i]; + rc = virCgroupAllowDevice(cgroup, + dev->type, + dev->major, + dev->minor); + if (rc != 0) + goto out; + } + + rc = virCgroupAddTask(cgroup, getpid()); +out: + if (rc != 0) { + lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("Failed to set lxc resources: %s\n"), strerror(-rc)); + virCgroupRemove(cgroup); + } + + virCgroupFree(&cgroup); + + return rc; +} static char*lxcMonitorPath(virDomainDefPtr def) { @@ -394,6 +464,9 @@ if (lxcControllerMoveInterfaces(nveths, veths, container) < 0) goto cleanup; + if (lxcSetContainerResources(def) < 0) + goto cleanup; + if (lxcContainerSendContinue(control[0]) < 0) goto cleanup; diff -r 473786980269 -r a28490b116b0 src/lxc_driver.c --- a/src/lxc_driver.c Thu Oct 02 15:04:11 2008 +0000 +++ b/src/lxc_driver.c Fri Oct 03 16:46:01 2008 +0000 @@ -43,6 +43,7 @@ #include "bridge.h" #include "veth.h" #include "event.h" +#include "cgroup.h" /* debug macros */ @@ -376,6 +377,7 @@ int waitRc; int childStatus = -1; virDomainNetDefPtr net; + virCgroupPtr cgroup; while (((waitRc = waitpid(vm->pid, &childStatus, 0)) == -1) && errno == EINTR) @@ -408,6 +410,11 @@ for (net = vm->def->nets; net; net = net->next) { vethInterfaceUpOrDown(net->ifname, 0); vethDelete(net->ifname); + } + + if (virCgroupForDomain(vm->def, "lxc", &cgroup) == 0) { + virCgroupRemove(cgroup); + virCgroupFree(&cgroup); } return rc;