More memory cgroup controls
authorJagger <robert@swiecki.net>
Sun, 19 Jun 2016 11:54:36 +0000 (13:54 +0200)
committerJagger <robert@swiecki.net>
Sun, 19 Jun 2016 11:54:36 +0000 (13:54 +0200)
Makefile
cgroup.c
cmdline.c
common.h
util.c

index ae5482880ea23164d9c2f488339ab9e453416e91..b37d808e86bd167c292e93f6399d8e898c383b92 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,7 @@ nsjail.o: nsjail.h common.h cmdline.h log.h net.h subproc.h
 cmdline.o: cmdline.h common.h log.h util.h
 contain.o: contain.h common.h cgroup.h log.h mount.h net.h pid.h util.h uts.h
 log.o: log.h common.h
-cgroup.o: cgroup.h common.h
+cgroup.o: cgroup.h common.h log.h util.h
 mount.o: mount.h common.h log.h
 net.o: net.h common.h log.h
 pid.o: pid.h common.h log.h
index c6323d501cf1a989d452797b27fc33067c6e6607..4aa7f847a5a2600740ca7786a97786105fd1e4e3 100644 (file)
--- a/cgroup.c
+++ b/cgroup.c
 
 #include "cgroup.h"
 
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+
 bool cgroupInitNs(struct nsjconf_t *nsjconf)
 {
-       if (nsjconf == NULL) {
+       if (nsjconf->clone_newcgroup == false) {
+               return true;
+       }
+
+       char fname[PATH_MAX];
+       if (nsjconf->cgroup_mem_max != (size_t) 0) {
+               char mem_max_str[512];
+               snprintf(mem_max_str, sizeof(mem_max_str), "%zu", nsjconf->cgroup_mem_max);
+               snprintf(fname, sizeof(fname), "%s/%s/memory.limit_in_bytes",
+                        nsjconf->cgroup_mem_mount, nsjconf->cgroup_mem_group);
+               if (utilWriteBufToFile(fname, mem_max_str, strlen(mem_max_str), O_WRONLY) == false) {
+                       LOG_E("Could not update memory cgroup max limit");
+                       return false;
+               }
+       }
+
+       char pid_str[512];
+       snprintf(pid_str, sizeof(pid_str), "%ld", syscall(__NR_getpid));
+       snprintf(fname, sizeof(fname), "%s/%s/tasks", nsjconf->cgroup_mem_mount,
+                nsjconf->cgroup_mem_group);
+       if (utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY) == false) {
+               LOG_E("Could not update memory cgroup task list");
                return false;
        }
+
        return true;
 }
index 4c5f75c8591c1e8a569595cfc56edf821de80e57..bb3f48fc35253ea0c7b8f6c4c61722f75984077d 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -291,6 +291,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                .max_conns_per_ip = 0,
                .tmpfs_size = 4 * (1024 * 1024),
                .mount_proc = true,
+               .cgroup_mem_mount = "/cgroup_memory",
+               .cgroup_mem_group = "NSJAIL",
+               .cgroup_mem_max = (size_t)0,
                .iface_no_lo = false,
                .iface = NULL,
                .iface_vs_ip = "0.0.0.0",
@@ -373,6 +376,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                {{"tmpfsmount", required_argument, NULL, 'T'}, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times. Supports 'dest' syntax"},
                {{"tmpfs_size", required_argument, NULL, 0x0602}, "Number of bytes to allocate for tmpfsmounts (default: 4194304)"},
                {{"disable_proc", no_argument, NULL, 0x0603}, "Disable mounting /proc in the jail"},
+               {{"cgroup_mem_mount", required_argument, NULL, 0x0801}, "Where to mount memory cgroup FS (default: '/cgroup_memory'"},
+               {{"cgroup_mem_group", required_argument, NULL, 0x0802}, "Which memory cgroup to use (default: 'NSJAIL')"},
+               {{"cgroup_mem_max", required_argument, NULL, 0x0803}, "Maximum number of bytes to use in the group"},
                {{"iface_no_lo", no_argument, NULL, 0x700}, "Don't bring up the 'lo' interface"},
                {{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'"},
                {{"iface_vs_ip", required_argument, NULL, 0x701}, "IP of the 'vs' interface"},
@@ -608,6 +614,15 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                case 0x703:
                        nsjconf->iface_vs_gw = optarg;
                        break;
+               case 0x801:
+                       nsjconf->cgroup_mem_mount = optarg;
+                       break;
+               case 0x802:
+                       nsjconf->cgroup_mem_group = optarg;
+                       break;
+               case 0x803:
+                       nsjconf->cgroup_mem_max = (size_t) strtoull(optarg, NULL, 0);
+                       break;
                default:
                        cmdlineUsage(argv[0], custom_opts);
                        return false;
@@ -615,6 +630,15 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                }
        }
 
+       if (nsjconf->clone_newcgroup) {
+               struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
+               p->src = NULL;
+               p->dst = nsjconf->cgroup_mem_mount;
+               p->flags = 0;
+               p->options = "memory";
+               p->fs_type = "cgroup";
+               TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
+       }
        if (nsjconf->mount_proc == true) {
                struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
                p->src = NULL;
index 1be6bf8f44b195a557f2aeeb95c75575a4b618f8..43719b54e152e60ee76b5813eef9e9cc7fce5070 100644 (file)
--- a/common.h
+++ b/common.h
@@ -130,6 +130,9 @@ struct nsjconf_t {
        const char *iface_vs_ip;
        const char *iface_vs_nm;
        const char *iface_vs_gw;
+       const char *cgroup_mem_mount;
+       const char *cgroup_mem_group;
+       size_t cgroup_mem_max;
         TAILQ_HEAD(envlist, charptr_t) envs;
         TAILQ_HEAD(pidslist, pids_t) pids;
         TAILQ_HEAD(mountptslist, mounts_t) mountpts;
diff --git a/util.c b/util.c
index be63d53cb57cfc273f1f18274bc022614dec670d..8eeeaf3f53d658fabaee0e275f57032c6175d0fb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -94,7 +94,7 @@ bool utilWriteBufToFile(char *filename, const void *buf, size_t len, int open_fl
        int fd;
        TEMP_FAILURE_RETRY(fd = open(filename, open_flags, 0644));
        if (fd == -1) {
-               PLOG_E("Couldn't open '%s' for R/O", filename);
+               PLOG_E("Couldn't open '%s' for writing", filename);
                return false;
        }
        defer {