]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add cgroup manipulation and LXC driver
authorDan Smith <danms@us.ibm.com>
Fri, 3 Oct 2008 16:46:01 +0000 (16:46 +0000)
committerDan Smith <danms@us.ibm.com>
Fri, 3 Oct 2008 16:46:01 +0000 (16:46 +0000)
src/Makefile.am
src/lxc_container.c
src/lxc_container.h
src/lxc_controller.c
src/lxc_driver.c

index 98453327a59a99bfe9d7c2a9a238dd0a2cfc7b0d..9a00e36173fbcb54b23582ba0a2e6e40e5b8f56c 100644 (file)
@@ -90,13 +90,15 @@ LXC_DRIVER_SOURCES =                                                \
                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                     \
index 0e3c049e0ee2e696ff052faadd713202b1660de6..f3ec1663a3a45f1d408274641a5eb1eb7b3c3429 100644 (file)
@@ -320,12 +320,12 @@ static int lxcContainerPopulateDevices(void)
         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 ||
index bd3622176dbf21fb1dccc3b7bc78e92fd7530a6f..12db80f1677308123c5abce9ec98c85821aaaa1a 100644 (file)
@@ -30,6 +30,16 @@ enum {
     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,
index 79270515c787b5df4788339f8b11dcda338e5e72..908ddf1ace3af54439389b729c9014a538395fef 100644 (file)
 #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)
 {
     char *sockpath;
@@ -394,6 +464,9 @@ lxcControllerRun(virDomainDefPtr def,
     if (lxcControllerMoveInterfaces(nveths, veths, container) < 0)
         goto cleanup;
 
+    if (lxcSetContainerResources(def) < 0)
+        goto cleanup;
+
     if (lxcContainerSendContinue(control[0]) < 0)
         goto cleanup;
 
index 9dfe418436daa2d914e2f8decd5a03925b851aef..0f4925afde5afd6a8d3b7a5039423b533e6d5662 100644 (file)
@@ -43,6 +43,7 @@
 #include "bridge.h"
 #include "veth.h"
 #include "event.h"
+#include "cgroup.h"
 
 
 /* debug macros */
@@ -376,6 +377,7 @@ static int lxcVMCleanup(virConnectPtr conn,
     int waitRc;
     int childStatus = -1;
     virDomainNetDefPtr net;
+    virCgroupPtr cgroup;
 
     while (((waitRc = waitpid(vm->pid, &childStatus, 0)) == -1) &&
            errno == EINTR)
@@ -410,6 +412,11 @@ static int lxcVMCleanup(virConnectPtr conn,
         vethDelete(net->ifname);
     }
 
+    if (virCgroupForDomain(vm->def, "lxc", &cgroup) == 0) {
+        virCgroupRemove(cgroup);
+        virCgroupFree(&cgroup);
+    }
+
     return rc;
 }