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;
}
/* 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++) {
/* 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;
/* 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");
}
/* 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");
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;
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);
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) {
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)
return true;
}
-struct cgroup_ops *cgfsng_ops_init(void)
+struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
{
struct cgroup_ops *cgfsng_ops;
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;
}
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;
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,
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);
* /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;
}
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;
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);
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];
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;
}
}
-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);
}
* @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
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;
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;
if (is_stopped(c))
return false;
- cgroup_ops = cgroup_init(NULL);
+ cgroup_ops = cgroup_init(c->lxc_conf);
if (!cgroup_ops)
return false;
if (is_stopped(c))
return -1;
- cgroup_ops = cgroup_init(NULL);
+ cgroup_ops = cgroup_init(c->lxc_conf);
if (!cgroup_ops)
return -1;
}
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;
goto err3;
}
- cgroup_ops = cgroup_init(NULL);
+ cgroup_ops = cgroup_init(c->lxc_conf);
if (!cgroup_ops)
goto err3;