From: Serge Hallyn <serge.hal...@ubuntu.com> This is needed if we're going to have unprivileged users create containers inside cgroups which they own.
Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com> --- src/lxc/cgroup.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/lxc/cgroup.h | 1 + src/lxc/start.c | 11 ++++++++--- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index 38ed514..c707519 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -706,10 +706,13 @@ again: if (ret < 0 || ret >= MAXPATHLEN) goto fail; + INFO("lxcgroup %s name %s tail %s, makes path .%s.", + lxcgroup ? lxcgroup : "lxc", name, tail, path); + if (access(path, F_OK) == 0) goto next; if (mkdir(path, 0755)) { - ERROR("Error creating cgroups"); + ERROR("Error creating cgroup %s", path); goto fail; } @@ -934,3 +937,49 @@ bool is_in_subcgroup(int pid, const char *subsystem, const char *cgpath) fclose(f); return false; } + +/* + * Return cgroup of current task. + * This assumes that task is in the same cgroup for each controller. This + * may or may not *always* be a reasonable assumption - it generally is, + * and handling or at least checking for this condition is a TODO. + */ +int lxc_curcgroup(char *cgroup, int inlen) +{ + FILE *f; + char *line = NULL, *p, *p2; + int ret = 0; + size_t len; + + f = fopen("/proc/self/cgroup", "r"); + if (!f) + return -1; + + while (getline(&line, &len, f) != -1) { + if (strstr(line, ":freezer:") == NULL && strstr(line, ":devices:") == NULL) + continue; + p = rindex(line, ':'); + if (!p) + continue; + p++; + len = strlen(p) + 1; + p2 = p + len - 2; + while (*p2 == '\n') { len--; *p2 = '\0'; p2--; } + if (!cgroup || inlen <= 0) { + ret = len; + break; + } + if (cgroup && len > inlen) { + ret = -1; + break; + } + strncpy(cgroup, p, len); + ret = len; + cgroup[len-1] = '\0'; + break; + } + + if (line) + free(line); + return ret; +} diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h index c08b2f7..77c44cd 100644 --- a/src/lxc/cgroup.h +++ b/src/lxc/cgroup.h @@ -34,4 +34,5 @@ extern int lxc_cgroup_enter(const char *cgpath, pid_t pid); extern int lxc_cgroup_attach(pid_t pid, const char *name, const char *lxcpath); extern char *cgroup_path_get(const char *subsystem, const char *cgpath); extern bool is_in_subcgroup(int pid, const char *subsystem, const char *cgpath); +extern int lxc_curcgroup(char *cgroup, int inlen); #endif diff --git a/src/lxc/start.c b/src/lxc/start.c index defa87b..c91b231 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -600,8 +600,9 @@ int save_phys_nics(struct lxc_conf *conf) extern bool is_in_subcgroup(int pid, const char *subsystem, const char *cgpath); int lxc_spawn(struct lxc_handler *handler) { - int failed_before_rename = 0; + int failed_before_rename = 0, len; const char *name = handler->name; + char *curcgroup = NULL; if (lxc_sync_init(handler)) return -1; @@ -663,8 +664,12 @@ int lxc_spawn(struct lxc_handler *handler) if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE)) failed_before_rename = 1; - /* TODO - pass lxc.cgroup.dir (or user's pam cgroup) in for first argument */ - if ((handler->cgroup = lxc_cgroup_path_create(NULL, name)) == NULL) + if ((len = lxc_curcgroup(NULL, 0)) > 1) { + curcgroup = alloca(len); + if (lxc_curcgroup(curcgroup, len) <= 1) + curcgroup = NULL; + } + if ((handler->cgroup = lxc_cgroup_path_create(curcgroup, name)) == NULL) goto out_delete_net; if (setup_cgroup(handler->cgroup, &handler->conf->cgroup)) { -- 1.8.3.2 ------------------------------------------------------------------------------ See everything from the browser to the database with AppDynamics Get end-to-end visibility with application monitoring from AppDynamics Isolate bottlenecks and diagnose root cause in seconds. Start your free trial of AppDynamics Pro today! http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel