Unverified Commit ea0f0c84 by Serge Hallyn Committed by GitHub

Merge pull request #2606 from brauner/2018-09-09/cgroup_escape

cgroups: scoping for cgroup v2
parents e52f28af d28779d9
...@@ -483,7 +483,7 @@ AC_ARG_WITH([cgroup-pattern], ...@@ -483,7 +483,7 @@ AC_ARG_WITH([cgroup-pattern],
[AC_HELP_STRING( [AC_HELP_STRING(
[--with-cgroup-pattern=pattern], [--with-cgroup-pattern=pattern],
[pattern for container cgroups] [pattern for container cgroups]
)], [], [with_cgroup_pattern=['lxc/%n']]) )], [], [with_cgroup_pattern=['lxc.payload/%n']])
# The path for the apparmor_parser's cache for generated apparmor profiles # The path for the apparmor_parser's cache for generated apparmor profiles
AC_ARG_WITH([apparmor-cache-dir], AC_ARG_WITH([apparmor-cache-dir],
......
...@@ -573,7 +573,7 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) ...@@ -573,7 +573,7 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
if (slash) if (slash)
*slash = '\0'; *slash = '\0';
cgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL); cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
if (slash) if (slash)
*slash = '/'; *slash = '/';
...@@ -810,7 +810,7 @@ static char **cg_unified_get_controllers(const char *file) ...@@ -810,7 +810,7 @@ static char **cg_unified_get_controllers(const char *file)
} }
static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char *mountpoint, static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char *mountpoint,
char *base_cgroup, int type) char *container_base_path, int type)
{ {
struct hierarchy *new; struct hierarchy *new;
int newentry; int newentry;
...@@ -818,8 +818,9 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char ...@@ -818,8 +818,9 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char
new = must_alloc(sizeof(*new)); new = must_alloc(sizeof(*new));
new->controllers = clist; new->controllers = clist;
new->mountpoint = mountpoint; new->mountpoint = mountpoint;
new->base_cgroup = base_cgroup; new->container_base_path = container_base_path;
new->fullcgpath = NULL; new->container_full_path = NULL;
new->monitor_full_path = NULL;
new->version = type; new->version = type;
newentry = append_null_to_list((void ***)h); newentry = append_null_to_list((void ***)h);
...@@ -1015,7 +1016,7 @@ static void lxc_cgfsng_print_hierarchies(struct cgroup_ops *ops) ...@@ -1015,7 +1016,7 @@ static void lxc_cgfsng_print_hierarchies(struct cgroup_ops *ops)
int j; int j;
char **cit; char **cit;
TRACE(" %d: base_cgroup: %s", i, (*it)->base_cgroup ? (*it)->base_cgroup : "(null)"); TRACE(" %d: base_cgroup: %s", i, (*it)->container_base_path ? (*it)->container_base_path : "(null)");
TRACE(" mountpoint: %s", (*it)->mountpoint ? (*it)->mountpoint : "(null)"); TRACE(" mountpoint: %s", (*it)->mountpoint ? (*it)->mountpoint : "(null)");
TRACE(" controllers:"); TRACE(" controllers:");
for (j = 0, cit = (*it)->controllers; cit && *cit; cit++, j++) for (j = 0, cit = (*it)->controllers; cit && *cit; cit++, j++)
...@@ -1051,15 +1052,15 @@ static int cgroup_rmdir(struct hierarchy **hierarchies, ...@@ -1051,15 +1052,15 @@ static int cgroup_rmdir(struct hierarchy **hierarchies,
int ret; int ret;
struct hierarchy *h = hierarchies[i]; struct hierarchy *h = hierarchies[i];
if (!h->fullcgpath) if (!h->container_full_path)
continue; continue;
ret = recursive_destroy(h->fullcgpath); ret = recursive_destroy(h->container_full_path);
if (ret < 0) if (ret < 0)
WARN("Failed to destroy \"%s\"", h->fullcgpath); WARN("Failed to destroy \"%s\"", h->container_full_path);
free(h->fullcgpath); free(h->container_full_path);
h->fullcgpath = NULL; h->container_full_path = NULL;
} }
return 0; return 0;
...@@ -1167,7 +1168,7 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname) ...@@ -1167,7 +1168,7 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname)
if (parts_len > 0) if (parts_len > 0)
parts_len--; parts_len--;
cgroup = must_make_path(h->mountpoint, h->base_cgroup, NULL); cgroup = must_make_path(h->mountpoint, h->container_base_path, NULL);
for (i = 0; i < parts_len; i++) { for (i = 0; i < parts_len; i++) {
int ret; int ret;
char *target; char *target;
...@@ -1192,13 +1193,30 @@ on_error: ...@@ -1192,13 +1193,30 @@ on_error:
return bret; return bret;
} }
static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname) static bool monitor_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
{ {
int ret; int ret;
h->fullcgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL); h->monitor_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
if (dir_exists(h->fullcgpath)) { if (dir_exists(h->monitor_full_path))
ERROR("The cgroup \"%s\" already existed", h->fullcgpath); return true;
ret = mkdir_p(h->monitor_full_path, 0755);
if (ret < 0) {
ERROR("Failed to create cgroup \"%s\"", h->monitor_full_path);
return false;
}
return cg_unified_create_cgroup(h, cgname);
}
static bool container_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
{
int ret;
h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
if (dir_exists(h->container_full_path)) {
ERROR("The cgroup \"%s\" already existed", h->container_full_path);
return false; return false;
} }
...@@ -1207,31 +1225,77 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname) ...@@ -1207,31 +1225,77 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
return false; return false;
} }
ret = mkdir_p(h->fullcgpath, 0755); ret = mkdir_p(h->container_full_path, 0755);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create cgroup \"%s\"", h->fullcgpath); ERROR("Failed to create cgroup \"%s\"", h->container_full_path);
return false; return false;
} }
return cg_unified_create_cgroup(h, cgname); return cg_unified_create_cgroup(h, cgname);
} }
static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname) static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname, bool monitor)
{ {
int ret; int ret;
char *full_path;
ret = rmdir(h->fullcgpath); if (monitor)
full_path = h->monitor_full_path;
else
full_path = h->container_full_path;
ret = rmdir(full_path);
if (ret < 0) if (ret < 0)
SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", h->fullcgpath); SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", full_path);
free(h->fullcgpath); free(full_path);
h->fullcgpath = NULL;
if (monitor)
h->monitor_full_path = NULL;
else
h->container_full_path = NULL;
}
__cgfsng_ops__ static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
struct lxc_handler *handler)
{
char *monitor_cgroup;
bool bret = false;
struct lxc_conf *conf = handler->conf;
if (!conf)
return bret;
if (conf->cgroup_meta.dir)
monitor_cgroup = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, ops->monitor_pattern, handler->name, NULL}, false);
else
monitor_cgroup = must_make_path(ops->monitor_pattern, handler->name, NULL);
if (!monitor_cgroup)
return bret;
for (int i = 0; ops->hierarchies[i]; i++) {
if (!monitor_create_path_for_hierarchy(ops->hierarchies[i], monitor_cgroup)) {
ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->monitor_full_path);
free(ops->hierarchies[i]->container_full_path);
ops->hierarchies[i]->container_full_path = NULL;
for (int j = 0; j < i; j++)
remove_path_for_hierarchy(ops->hierarchies[j], monitor_cgroup, true);
goto on_error;
}
}
bret = true;
on_error:
free(monitor_cgroup);
return bret;
} }
/* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern; /* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
* next cgroup_pattern-1, -2, ..., -999. * next cgroup_pattern-1, -2, ..., -999.
*/ */
__cgfsng_ops__ static inline bool cgfsng_create(struct cgroup_ops *ops, __cgfsng_ops__ static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
struct lxc_handler *handler) struct lxc_handler *handler)
{ {
int i; int i;
...@@ -1285,13 +1349,12 @@ again: ...@@ -1285,13 +1349,12 @@ again:
} }
for (i = 0; ops->hierarchies[i]; i++) { for (i = 0; ops->hierarchies[i]; i++) {
if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) { if (!container_create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) {
int j; ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->container_full_path);
ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->fullcgpath); free(ops->hierarchies[i]->container_full_path);
free(ops->hierarchies[i]->fullcgpath); ops->hierarchies[i]->container_full_path = NULL;
ops->hierarchies[i]->fullcgpath = NULL; for (int j = 0; j < i; j++)
for (j = 0; j < i; j++) remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup, false);
remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup);
idx++; idx++;
goto again; goto again;
} }
...@@ -1307,33 +1370,48 @@ out_free: ...@@ -1307,33 +1370,48 @@ out_free:
return false; return false;
} }
__cgfsng_ops__ static bool cgfsng_enter(struct cgroup_ops *ops, pid_t pid) __cgfsng_ops__ static bool __do_cgroup_enter(struct cgroup_ops *ops, pid_t pid,
bool monitor)
{ {
int i, len; int len;
char pidstr[25]; char pidstr[25];
len = snprintf(pidstr, 25, "%d", pid); len = snprintf(pidstr, 25, "%d", pid);
if (len < 0 || len >= 25) if (len < 0 || len >= 25)
return false; return false;
for (i = 0; ops->hierarchies[i]; i++) { for (int i = 0; ops->hierarchies[i]; i++) {
int ret; int ret;
char *fullpath; char *path;
fullpath = must_make_path(ops->hierarchies[i]->fullcgpath, if (monitor)
path = must_make_path(ops->hierarchies[i]->monitor_full_path,
"cgroup.procs", NULL); "cgroup.procs", NULL);
ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666); else
path = must_make_path(ops->hierarchies[i]->container_full_path,
"cgroup.procs", NULL);
ret = lxc_write_to_file(path, pidstr, len, false, 0666);
if (ret != 0) { if (ret != 0) {
SYSERROR("Failed to enter cgroup \"%s\"", fullpath); SYSERROR("Failed to enter cgroup \"%s\"", path);
free(fullpath); free(path);
return false; return false;
} }
free(fullpath); free(path);
} }
return true; return true;
} }
__cgfsng_ops__ static bool cgfsng_monitor_enter(struct cgroup_ops *ops, pid_t pid)
{
return __do_cgroup_enter(ops, pid, true);
}
static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid)
{
return __do_cgroup_enter(ops, pid, false);
}
static int chowmod(char *path, uid_t chown_uid, gid_t chown_gid, static int chowmod(char *path, uid_t chown_uid, gid_t chown_gid,
mode_t chmod_mode) mode_t chmod_mode)
{ {
...@@ -1395,7 +1473,7 @@ static int chown_cgroup_wrapper(void *data) ...@@ -1395,7 +1473,7 @@ static int chown_cgroup_wrapper(void *data)
for (i = 0; arg->hierarchies[i]; i++) { for (i = 0; arg->hierarchies[i]; i++) {
char *fullpath; char *fullpath;
char *path = arg->hierarchies[i]->fullcgpath; char *path = arg->hierarchies[i]->container_full_path;
ret = chowmod(path, destuid, nsgid, 0775); ret = chowmod(path, destuid, nsgid, 0775);
if (ret < 0) if (ret < 0)
...@@ -1498,7 +1576,7 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, ...@@ -1498,7 +1576,7 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
INFO("Remounted %s read-only", controllerpath); INFO("Remounted %s read-only", controllerpath);
} }
sourcepath = must_make_path(h->mountpoint, h->base_cgroup, sourcepath = must_make_path(h->mountpoint, h->container_base_path,
container_cgroup, NULL); container_cgroup, NULL);
if (type == LXC_AUTO_CGROUP_RO) if (type == LXC_AUTO_CGROUP_RO)
flags |= MS_RDONLY; flags |= MS_RDONLY;
...@@ -1669,7 +1747,7 @@ __cgfsng_ops__ static bool cgfsng_mount(struct cgroup_ops *ops, ...@@ -1669,7 +1747,7 @@ __cgfsng_ops__ static bool cgfsng_mount(struct cgroup_ops *ops,
continue; continue;
} }
path2 = must_make_path(controllerpath, h->base_cgroup, path2 = must_make_path(controllerpath, h->container_base_path,
ops->container_cgroup, NULL); ops->container_cgroup, NULL);
ret = mkdir_p(path2, 0755); ret = mkdir_p(path2, 0755);
if (ret < 0) { if (ret < 0) {
...@@ -1742,7 +1820,7 @@ __cgfsng_ops__ static int cgfsng_nrtasks(struct cgroup_ops *ops) ...@@ -1742,7 +1820,7 @@ __cgfsng_ops__ static int cgfsng_nrtasks(struct cgroup_ops *ops)
if (!ops->container_cgroup || !ops->hierarchies) if (!ops->container_cgroup || !ops->hierarchies)
return -1; return -1;
path = must_make_path(ops->hierarchies[0]->fullcgpath, NULL); path = must_make_path(ops->hierarchies[0]->container_full_path, NULL);
count = recursive_count_nrtasks(path); count = recursive_count_nrtasks(path);
free(path); free(path);
return count; return count;
...@@ -1762,7 +1840,7 @@ __cgfsng_ops__ static bool cgfsng_escape(const struct cgroup_ops *ops, ...@@ -1762,7 +1840,7 @@ __cgfsng_ops__ static bool cgfsng_escape(const struct cgroup_ops *ops,
char *fullpath; char *fullpath;
fullpath = must_make_path(ops->hierarchies[i]->mountpoint, fullpath = must_make_path(ops->hierarchies[i]->mountpoint,
ops->hierarchies[i]->base_cgroup, ops->hierarchies[i]->container_base_path,
"cgroup.procs", NULL); "cgroup.procs", NULL);
ret = lxc_write_to_file(fullpath, "0", 2, false, 0666); ret = lxc_write_to_file(fullpath, "0", 2, false, 0666);
if (ret != 0) { if (ret != 0) {
...@@ -1816,7 +1894,7 @@ __cgfsng_ops__ static bool cgfsng_unfreeze(struct cgroup_ops *ops) ...@@ -1816,7 +1894,7 @@ __cgfsng_ops__ static bool cgfsng_unfreeze(struct cgroup_ops *ops)
if (!h) if (!h)
return false; return false;
fullpath = must_make_path(h->fullcgpath, "freezer.state", NULL); fullpath = must_make_path(h->container_full_path, "freezer.state", NULL);
ret = lxc_write_to_file(fullpath, THAWED, THAWED_LEN, false, 0666); ret = lxc_write_to_file(fullpath, THAWED, THAWED_LEN, false, 0666);
free(fullpath); free(fullpath);
if (ret < 0) if (ret < 0)
...@@ -1837,7 +1915,7 @@ __cgfsng_ops__ static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, ...@@ -1837,7 +1915,7 @@ __cgfsng_ops__ static const char *cgfsng_get_cgroup(struct cgroup_ops *ops,
return NULL; return NULL;
} }
return h->fullcgpath ? h->fullcgpath + strlen(h->mountpoint) : NULL; return h->container_full_path ? h->container_full_path + strlen(h->mountpoint) : NULL;
} }
/* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path, /* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path,
...@@ -2162,7 +2240,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, ...@@ -2162,7 +2240,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
return -ENOENT; return -ENOENT;
} }
fullpath = must_make_path(h->fullcgpath, filename, NULL); fullpath = must_make_path(h->container_full_path, filename, NULL);
ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666);
free(fullpath); free(fullpath);
return ret; return ret;
...@@ -2230,7 +2308,7 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops, ...@@ -2230,7 +2308,7 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops,
char *fullpath; char *fullpath;
struct lxc_cgroup *cg = iterator->elem; struct lxc_cgroup *cg = iterator->elem;
fullpath = must_make_path(h->fullcgpath, cg->subsystem, NULL); fullpath = must_make_path(h->container_full_path, cg->subsystem, NULL);
ret = lxc_write_to_file(fullpath, cg->value, strlen(cg->value), false, 0666); ret = lxc_write_to_file(fullpath, cg->value, strlen(cg->value), false, 0666);
free(fullpath); free(fullpath);
if (ret < 0) { if (ret < 0) {
...@@ -2569,6 +2647,7 @@ __cgfsng_ops__ static bool cgfsng_data_init(struct cgroup_ops *ops) ...@@ -2569,6 +2647,7 @@ __cgfsng_ops__ static bool cgfsng_data_init(struct cgroup_ops *ops)
return false; return false;
} }
ops->cgroup_pattern = must_copy_string(cgroup_pattern); ops->cgroup_pattern = must_copy_string(cgroup_pattern);
ops->monitor_pattern = must_copy_string("lxc.monitor");
return true; return true;
} }
...@@ -2591,8 +2670,10 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf) ...@@ -2591,8 +2670,10 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
cgfsng_ops->data_init = cgfsng_data_init; cgfsng_ops->data_init = cgfsng_data_init;
cgfsng_ops->destroy = cgfsng_destroy; cgfsng_ops->destroy = cgfsng_destroy;
cgfsng_ops->create = cgfsng_create; cgfsng_ops->monitor_create = cgfsng_monitor_create;
cgfsng_ops->enter = cgfsng_enter; cgfsng_ops->monitor_enter = cgfsng_monitor_enter;
cgfsng_ops->payload_create = cgfsng_payload_create;
cgfsng_ops->payload_enter = cgfsng_payload_enter;
cgfsng_ops->escape = cgfsng_escape; cgfsng_ops->escape = cgfsng_escape;
cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies; cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies;
cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies; cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -75,6 +76,7 @@ void cgroup_exit(struct cgroup_ops *ops) ...@@ -75,6 +76,7 @@ void cgroup_exit(struct cgroup_ops *ops)
free(ops->cgroup_pattern); free(ops->cgroup_pattern);
free(ops->container_cgroup); free(ops->container_cgroup);
free(ops->monitor_pattern);
for (it = ops->hierarchies; it && *it; it++) { for (it = ops->hierarchies; it && *it; it++) {
char **ctrlr; char **ctrlr;
...@@ -84,8 +86,9 @@ void cgroup_exit(struct cgroup_ops *ops) ...@@ -84,8 +86,9 @@ void cgroup_exit(struct cgroup_ops *ops)
free((*it)->controllers); free((*it)->controllers);
free((*it)->mountpoint); free((*it)->mountpoint);
free((*it)->base_cgroup); free((*it)->container_base_path);
free((*it)->fullcgpath); free((*it)->container_full_path);
free((*it)->monitor_full_path);
free(*it); free(*it);
} }
free(ops->hierarchies); free(ops->hierarchies);
......
...@@ -57,14 +57,17 @@ typedef enum { ...@@ -57,14 +57,17 @@ typedef enum {
* depending on whether this is a hybrid cgroup layout (mix of legacy and * depending on whether this is a hybrid cgroup layout (mix of legacy and
* unified hierarchies) or a pure unified cgroup layout. * unified hierarchies) or a pure unified cgroup layout.
* *
* @base_cgroup * @container_base_path
* - The cgroup under which the container cgroup path * - The cgroup under which the container cgroup path
* is created. This will be either the caller's cgroup (if not root), or * is created. This will be either the caller's cgroup (if not root), or
* init's cgroup (if root). * init's cgroup (if root).
* *
* @fullcgpath * @container_full_path
* - The full path to the containers cgroup. * - The full path to the containers cgroup.
* *
* @monitor_full_path
* - The full path to the monitor's cgroup.
*
* @version * @version
* - legacy hierarchy * - legacy hierarchy
* If the hierarchy is a legacy hierarchy this will be set to * If the hierarchy is a legacy hierarchy this will be set to
...@@ -76,8 +79,9 @@ typedef enum { ...@@ -76,8 +79,9 @@ typedef enum {
struct hierarchy { struct hierarchy {
char **controllers; char **controllers;
char *mountpoint; char *mountpoint;
char *base_cgroup; char *container_base_path;
char *fullcgpath; char *container_full_path;
char *monitor_full_path;
int version; int version;
}; };
...@@ -92,6 +96,7 @@ struct cgroup_ops { ...@@ -92,6 +96,7 @@ struct cgroup_ops {
char **cgroup_use; char **cgroup_use;
char *cgroup_pattern; char *cgroup_pattern;
char *container_cgroup; char *container_cgroup;
char *monitor_pattern;
/* @hierarchies /* @hierarchies
* - A NULL-terminated array of struct hierarchy, one per legacy * - A NULL-terminated array of struct hierarchy, one per legacy
...@@ -124,8 +129,10 @@ struct cgroup_ops { ...@@ -124,8 +129,10 @@ struct cgroup_ops {
bool (*data_init)(struct cgroup_ops *ops); bool (*data_init)(struct cgroup_ops *ops);
void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*create)(struct cgroup_ops *ops, struct lxc_handler *handler); bool (*monitor_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*enter)(struct cgroup_ops *ops, pid_t pid); bool (*monitor_enter)(struct cgroup_ops *ops, pid_t pid);
bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid);
const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller); const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller);
bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf); bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf);
int (*num_hierarchies)(struct cgroup_ops *ops); int (*num_hierarchies)(struct cgroup_ops *ops);
......
...@@ -972,7 +972,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ ...@@ -972,7 +972,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
goto out_fini_handler; goto out_fini_handler;
handler->cgroup_ops = cgroup_ops; handler->cgroup_ops = cgroup_ops;
if (!cgroup_ops->create(cgroup_ops, handler)) { if (!cgroup_ops->payload_create(cgroup_ops, handler)) {
ERROR("failed creating groups"); ERROR("failed creating groups");
goto out_fini_handler; goto out_fini_handler;
} }
......
...@@ -101,7 +101,7 @@ const char *lxc_global_config_value(const char *option_name) ...@@ -101,7 +101,7 @@ const char *lxc_global_config_value(const char *option_name)
sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home); sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home); sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home); sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
user_cgroup_pattern = strdup("lxc/%n"); user_cgroup_pattern = strdup("lxc.payload/%n");
} }
else { else {
user_config_path = strdup(LXC_GLOBAL_CONF); user_config_path = strdup(LXC_GLOBAL_CONF);
......
...@@ -1678,7 +1678,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1678,7 +1678,7 @@ static int lxc_spawn(struct lxc_handler *handler)
} }
} }
if (!cgroup_ops->create(cgroup_ops, handler)) { if (!cgroup_ops->payload_create(cgroup_ops, handler)) {
ERROR("Failed creating cgroups"); ERROR("Failed creating cgroups");
goto out_delete_net; goto out_delete_net;
} }
...@@ -1772,7 +1772,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1772,7 +1772,7 @@ static int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net; goto out_delete_net;
} }
if (!cgroup_ops->enter(cgroup_ops, handler->pid)) if (!cgroup_ops->payload_enter(cgroup_ops, handler->pid))
goto out_delete_net; goto out_delete_net;
if (!cgroup_ops->chown(cgroup_ops, handler->conf)) if (!cgroup_ops->chown(cgroup_ops, handler->conf))
...@@ -1949,6 +1949,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler, ...@@ -1949,6 +1949,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
{ {
int ret, status; int ret, status;
struct lxc_conf *conf = handler->conf; struct lxc_conf *conf = handler->conf;
struct cgroup_ops *cgroup_ops;
ret = lxc_init(name, handler); ret = lxc_init(name, handler);
if (ret < 0) { if (ret < 0) {
...@@ -1958,12 +1959,23 @@ int __lxc_start(const char *name, struct lxc_handler *handler, ...@@ -1958,12 +1959,23 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
handler->ops = ops; handler->ops = ops;
handler->data = data; handler->data = data;
handler->daemonize = daemonize; handler->daemonize = daemonize;
cgroup_ops = handler->cgroup_ops;
if (!attach_block_device(handler->conf)) { if (!attach_block_device(handler->conf)) {
ERROR("Failed to attach block device"); ERROR("Failed to attach block device");
goto out_fini_nonet; goto out_fini_nonet;
} }
if (!cgroup_ops->monitor_create(cgroup_ops, handler)) {
ERROR("Failed to create monitor cgroup");
goto out_fini_nonet;
}
if (!cgroup_ops->monitor_enter(cgroup_ops, lxc_raw_getpid())) {
ERROR("Failed to enter monitor cgroup");
goto out_fini_nonet;
}
if (geteuid() == 0 && !lxc_list_empty(&conf->id_map)) { if (geteuid() == 0 && !lxc_list_empty(&conf->id_map)) {
/* If the backing store is a device, mount it here and now. */ /* If the backing store is a device, mount it here and now. */
if (rootfs_is_blockdev(conf)) { if (rootfs_is_blockdev(conf)) {
......
...@@ -59,7 +59,7 @@ static int test_running_container(const char *lxcpath, ...@@ -59,7 +59,7 @@ static int test_running_container(const char *lxcpath,
char value[NAME_MAX], value_save[NAME_MAX]; char value[NAME_MAX], value_save[NAME_MAX];
struct cgroup_ops *cgroup_ops; struct cgroup_ops *cgroup_ops;
sprintf(relpath, "%s/%s", group ? group : "lxc", name); sprintf(relpath, "%s/%s", group ? group : "lxc.payload", name);
if ((c = lxc_container_new(name, lxcpath)) == NULL) { if ((c = lxc_container_new(name, lxcpath)) == NULL) {
TSTERR("container %s couldn't instantiate", name); TSTERR("container %s couldn't instantiate", name);
......
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