Unverified Commit 7ee4b4b8 by Stéphane Graber Committed by GitHub

Merge pull request #2574 from brauner/2018-08-26/cgroup_keep

confile: add lxc.cgroup.keep
parents 40a6212e 5a087e05
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -76,6 +76,7 @@ struct lxc_cgroup {
struct /* meta */ {
char *controllers;
char *dir;
bool keep;
};
};
};
......
......@@ -92,6 +92,7 @@ lxc_config_define(cap_keep);
lxc_config_define(cgroup_controller);
lxc_config_define(cgroup2_controller);
lxc_config_define(cgroup_dir);
lxc_config_define(cgroup_keep);
lxc_config_define(console_buffer_size);
lxc_config_define(console_logfile);
lxc_config_define(console_path);
......@@ -167,6 +168,7 @@ static struct lxc_config_t config[] = {
{ "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, },
{ "lxc.cgroup2", set_config_cgroup2_controller, get_config_cgroup2_controller, clr_config_cgroup2_controller, },
{ "lxc.cgroup.dir", set_config_cgroup_dir, get_config_cgroup_dir, clr_config_cgroup_dir, },
{ "lxc.cgroup.keep", set_config_cgroup_keep, get_config_cgroup_keep, clr_config_cgroup_keep, },
{ "lxc.cgroup", set_config_cgroup_controller, get_config_cgroup_controller, clr_config_cgroup_controller, },
{ "lxc.console.buffer.size", set_config_console_buffer_size, get_config_console_buffer_size, clr_config_console_buffer_size, },
{ "lxc.console.logfile", set_config_console_logfile, get_config_console_logfile, clr_config_console_logfile, },
......@@ -1395,6 +1397,32 @@ static int set_config_cgroup_dir(const char *key, const char *value,
return set_config_string_item(&lxc_conf->cgroup_meta.dir, value);
}
static int set_config_cgroup_keep(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
unsigned int converted;
int ret;
if (lxc_config_value_empty(value))
return clr_config_cgroup_keep(key, lxc_conf, NULL);
ret = lxc_safe_uint(value, &converted);
if (ret < 0)
return -ret;
if (converted == 1) {
lxc_conf->cgroup_meta.keep = true;
return 0;
}
if (converted == 0) {
lxc_conf->cgroup_meta.keep = false;
return 0;
}
return -EINVAL;
}
static int set_config_prlimit(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
......@@ -3187,6 +3215,13 @@ static int get_config_cgroup_dir(const char *key, char *retv, int inlen,
return fulllen;
}
static inline int get_config_cgroup_keep(const char *key, char *retv, int inlen,
struct lxc_conf *lxc_conf, void *data)
{
return lxc_get_conf_int(lxc_conf, retv, inlen,
lxc_conf->cgroup_meta.keep);
}
static int get_config_idmaps(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
......@@ -3927,6 +3962,13 @@ static int clr_config_cgroup_dir(const char *key, struct lxc_conf *lxc_conf,
return 0;
}
static inline int clr_config_cgroup_keep(const char *key,
struct lxc_conf *lxc_conf, void *data)
{
lxc_conf->cgroup_meta.keep = false;
return 0;
}
static inline int clr_config_idmaps(const char *key, struct lxc_conf *c,
void *data)
{
......
......@@ -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);
......
......@@ -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);
}
......@@ -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
......
......@@ -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;
......
......@@ -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;
......@@ -1694,11 +1694,6 @@ static int lxc_spawn(struct lxc_handler *handler)
}
}
if (!cgroup_init(handler)) {
ERROR("Failed initializing cgroup support");
goto out_delete_net;
}
if (!cgroup_ops->create(cgroup_ops, handler)) {
ERROR("Failed creating cgroups");
goto out_delete_net;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment