From 5a087e056f945aa2112ebdcad7df05e57ce56c8a Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 26 Aug 2018 18:59:01 +0200 Subject: [PATCH] cgroups: don't escape if lxc.cgroup.keep is true Signed-off-by: Christian Brauner Cc: Felix Abecassis Cc: Jonathan Calmels --- src/lxc/attach.c | 2 +- src/lxc/cgroups/cgfsng.c | 31 ++++++++++++++----------------- src/lxc/cgroups/cgroup.c | 6 +++--- src/lxc/cgroups/cgroup.h | 4 ++-- src/lxc/criu.c | 6 +++--- src/lxc/freezer.c | 13 +++++++------ src/lxc/lxc.h | 6 ++++-- src/lxc/lxccontainer.c | 8 ++++---- src/lxc/start.c | 2 +- src/tests/cgpath.c | 2 +- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 2218a3492..87f14398f 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -1261,7 +1261,7 @@ int lxc_attach(const char *name, const char *lxcpath, if (options->attach_flags & LXC_ATTACH_MOVE_TO_CGROUP) { struct cgroup_ops *cgroup_ops; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(conf); if (!cgroup_ops) goto on_error; diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 56c8db544..e7a242910 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -1742,11 +1742,11 @@ static int cgfsng_nrtasks(struct cgroup_ops *ops) } /* Only root needs to escape to the cgroup of its init. */ -static bool cgfsng_escape(const struct cgroup_ops *ops) +static bool cgfsng_escape(const struct cgroup_ops *ops, struct lxc_conf *conf) { int i; - if (geteuid()) + if (conf->cgroup_meta.keep || geteuid()) return true; for (i = 0; ops->hierarchies[i]; i++) { @@ -2278,11 +2278,10 @@ static bool cgroup_use_wants_controllers(const struct cgroup_ops *ops, /* At startup, parse_hierarchies finds all the info we need about cgroup * mountpoints and current cgroups, and stores it in @d. */ -static bool cg_hybrid_init(struct cgroup_ops *ops) +static bool cg_hybrid_init(struct cgroup_ops *ops, bool keep) { int ret; char *basecginfo; - bool will_escape; FILE *f; size_t len = 0; char *line = NULL; @@ -2291,8 +2290,7 @@ static bool cg_hybrid_init(struct cgroup_ops *ops) /* Root spawned containers escape the current cgroup, so use init's * cgroups as our base in that case. */ - will_escape = (geteuid() == 0); - if (will_escape) + if (!keep && (geteuid() == 0)) basecginfo = read_file("/proc/1/cgroup"); else basecginfo = read_file("/proc/self/cgroup"); @@ -2443,14 +2441,12 @@ static int cg_is_pure_unified(void) } /* Get current cgroup from /proc/self/cgroup for the cgroupfs v2 hierarchy. */ -static char *cg_unified_get_current_cgroup(void) +static char *cg_unified_get_current_cgroup(bool keep) { char *basecginfo, *base_cgroup; - bool will_escape; char *copy = NULL; - will_escape = (geteuid() == 0); - if (will_escape) + if (!keep && (geteuid() == 0)) basecginfo = read_file("/proc/1/cgroup"); else basecginfo = read_file("/proc/self/cgroup"); @@ -2474,7 +2470,7 @@ cleanup_on_err: return copy; } -static int cg_unified_init(struct cgroup_ops *ops) +static int cg_unified_init(struct cgroup_ops *ops, bool keep) { int ret; char *mountpoint, *subtree_path; @@ -2488,7 +2484,7 @@ static int cg_unified_init(struct cgroup_ops *ops) if (ret != CGROUP2_SUPER_MAGIC) return 0; - base_cgroup = cg_unified_get_current_cgroup(); + base_cgroup = cg_unified_get_current_cgroup(keep); if (!base_cgroup) return -EINVAL; prune_init_scope(base_cgroup); @@ -2520,10 +2516,11 @@ static int cg_unified_init(struct cgroup_ops *ops) return CGROUP2_SUPER_MAGIC; } -static bool cg_init(struct cgroup_ops *ops) +static bool cg_init(struct cgroup_ops *ops, struct lxc_conf *conf) { int ret; const char *tmp; + bool keep = conf->cgroup_meta.keep; tmp = lxc_global_config_value("lxc.cgroup.use"); if (tmp) { @@ -2539,14 +2536,14 @@ static bool cg_init(struct cgroup_ops *ops) free(pin); } - ret = cg_unified_init(ops); + ret = cg_unified_init(ops, keep); if (ret < 0) return false; if (ret == CGROUP2_SUPER_MAGIC) return true; - return cg_hybrid_init(ops); + return cg_hybrid_init(ops, keep); } static bool cgfsng_data_init(struct cgroup_ops *ops) @@ -2565,7 +2562,7 @@ static bool cgfsng_data_init(struct cgroup_ops *ops) return true; } -struct cgroup_ops *cgfsng_ops_init(void) +struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf) { struct cgroup_ops *cgfsng_ops; @@ -2576,7 +2573,7 @@ struct cgroup_ops *cgfsng_ops_init(void) memset(cgfsng_ops, 0, sizeof(struct cgroup_ops)); cgfsng_ops->cgroup_layout = CGROUP_LAYOUT_UNKNOWN; - if (!cg_init(cgfsng_ops)) { + if (!cg_init(cgfsng_ops, conf)) { free(cgfsng_ops); return NULL; } diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c index f86bd9be8..7dffeb0cc 100644 --- a/src/lxc/cgroups/cgroup.c +++ b/src/lxc/cgroups/cgroup.c @@ -33,13 +33,13 @@ lxc_log_define(cgroup, lxc); -extern struct cgroup_ops *cgfsng_ops_init(void); +extern struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf); -struct cgroup_ops *cgroup_init(struct lxc_handler *handler) +struct cgroup_ops *cgroup_init(struct lxc_conf *conf) { struct cgroup_ops *cgroup_ops; - cgroup_ops = cgfsng_ops_init(); + cgroup_ops = cgfsng_ops_init(conf); if (!cgroup_ops) { ERROR("Failed to initialize cgroup driver"); return NULL; diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h index 8f4af06c1..0c8b2ea88 100644 --- a/src/lxc/cgroups/cgroup.h +++ b/src/lxc/cgroups/cgroup.h @@ -127,7 +127,7 @@ struct cgroup_ops { bool (*create)(struct cgroup_ops *ops, struct lxc_handler *handler); bool (*enter)(struct cgroup_ops *ops, pid_t pid); const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller); - bool (*escape)(const struct cgroup_ops *ops); + bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf); int (*num_hierarchies)(struct cgroup_ops *ops); bool (*get_hierarchies)(struct cgroup_ops *ops, int n, char ***out); int (*set)(struct cgroup_ops *ops, const char *filename, @@ -145,7 +145,7 @@ struct cgroup_ops { int (*nrtasks)(struct cgroup_ops *ops); }; -extern struct cgroup_ops *cgroup_init(struct lxc_handler *handler); +extern struct cgroup_ops *cgroup_init(struct lxc_conf *conf); extern void cgroup_exit(struct cgroup_ops *ops); extern void prune_init_scope(char *cg); diff --git a/src/lxc/criu.c b/src/lxc/criu.c index 1c2f61547..db9101b0f 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c @@ -190,7 +190,7 @@ static void exec_criu(struct cgroup_ops *cgroup_ops, struct criu_opts *opts) * /actual/ root cgroup so that lxcfs thinks criu has enough rights to * see all cgroups. */ - if (!cgroup_ops->escape(cgroup_ops)) { + if (!cgroup_ops->escape(cgroup_ops, opts->handler->conf)) { ERROR("failed to escape cgroups"); return; } @@ -967,7 +967,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ if (lxc_init(c->name, handler) < 0) goto out; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(c->lxc_conf); if (!cgroup_ops) goto out_fini_handler; handler->cgroup_ops = cgroup_ops; @@ -1272,7 +1272,7 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op h.name = c->name; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(c->lxc_conf); if (!cgroup_ops) { ERROR("failed to cgroup_init()"); _exit(EXIT_FAILURE); diff --git a/src/lxc/freezer.c b/src/lxc/freezer.c index a6b9da061..b6caec178 100644 --- a/src/lxc/freezer.c +++ b/src/lxc/freezer.c @@ -42,7 +42,8 @@ lxc_log_define(freezer, lxc); -static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) +static int do_freeze_thaw(bool freeze, struct lxc_conf *conf, const char *name, + const char *lxcpath) { int ret; char v[100]; @@ -51,7 +52,7 @@ static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) size_t state_len = 6; lxc_state_t new_state = freeze ? FROZEN : THAWED; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(conf); if (!cgroup_ops) return -1; @@ -85,14 +86,14 @@ static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) } } -int lxc_freeze(const char *name, const char *lxcpath) +int lxc_freeze(struct lxc_conf *conf, const char *name, const char *lxcpath) { lxc_cmd_serve_state_clients(name, lxcpath, FREEZING); lxc_monitor_send_state(name, FREEZING, lxcpath); - return do_freeze_thaw(true, name, lxcpath); + return do_freeze_thaw(true, conf, name, lxcpath); } -int lxc_unfreeze(const char *name, const char *lxcpath) +int lxc_unfreeze(struct lxc_conf *conf, const char *name, const char *lxcpath) { - return do_freeze_thaw(false, name, lxcpath); + return do_freeze_thaw(false, conf, name, lxcpath); } diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h index 8ae8c717d..c2a150cf4 100644 --- a/src/lxc/lxc.h +++ b/src/lxc/lxc.h @@ -81,14 +81,16 @@ extern int lxc_monitor_close(int fd); * @name : the container name * Returns 0 on success, < 0 otherwise */ -extern int lxc_freeze(const char *name, const char *lxcpath); +extern int lxc_freeze(struct lxc_conf *conf, const char *name, + const char *lxcpath); /* * Unfreeze all previously frozen tasks. * @name : the name of the container * Return 0 on success, < 0 otherwise */ -extern int lxc_unfreeze(const char *name, const char *lxcpath); +extern int lxc_unfreeze(struct lxc_conf *conf, const char *name, + const char *lxcpath); /* * Retrieve the container state diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 6c0620d8f..2c37caefd 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -529,7 +529,7 @@ static bool do_lxcapi_freeze(struct lxc_container *c) if (!c) return false; - ret = lxc_freeze(c->name, c->config_path); + ret = lxc_freeze(c->lxc_conf, c->name, c->config_path); if (ret < 0) return false; @@ -545,7 +545,7 @@ static bool do_lxcapi_unfreeze(struct lxc_container *c) if (!c) return false; - ret = lxc_unfreeze(c->name, c->config_path); + ret = lxc_unfreeze(c->lxc_conf, c->name, c->config_path); if (ret < 0) return false; @@ -3263,7 +3263,7 @@ static bool do_lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsy if (is_stopped(c)) return false; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(c->lxc_conf); if (!cgroup_ops) return false; @@ -3292,7 +3292,7 @@ static int do_lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys if (is_stopped(c)) return -1; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(c->lxc_conf); if (!cgroup_ops) return -1; diff --git a/src/lxc/start.c b/src/lxc/start.c index c9200f49b..086a874f0 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -856,7 +856,7 @@ int lxc_init(const char *name, struct lxc_handler *handler) } TRACE("Chowned console"); - handler->cgroup_ops = cgroup_init(handler); + handler->cgroup_ops = cgroup_init(handler->conf); if (!handler->cgroup_ops) { ERROR("Failed to initialize cgroup driver"); goto out_delete_terminal; diff --git a/src/tests/cgpath.c b/src/tests/cgpath.c index fa8d47678..8f4c19f38 100644 --- a/src/tests/cgpath.c +++ b/src/tests/cgpath.c @@ -80,7 +80,7 @@ static int test_running_container(const char *lxcpath, goto err3; } - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(c->lxc_conf); if (!cgroup_ops) goto err3;