From 6b38e644cb8d4942f16d9a82b72d56a72b9aa81d Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Wed, 31 Jan 2018 16:45:04 +0100 Subject: [PATCH] cgroups: handle limits on the unified hierarchy Signed-off-by: Christian Brauner --- src/lxc/cgroups/cgfs.c | 4 +-- src/lxc/cgroups/cgfsng.c | 58 ++++++++++++++++++++++++++++++++----- src/lxc/cgroups/cgmanager.c | 3 +- src/lxc/cgroups/cgroup.c | 2 +- src/lxc/cgroups/cgroup.h | 5 ++-- 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c index fc25bc9b5..89aec91f7 100644 --- a/src/lxc/cgroups/cgfs.c +++ b/src/lxc/cgroups/cgfs.c @@ -2525,14 +2525,14 @@ static bool cgfs_unfreeze(void *hdata) return ret == 0; } -static bool cgroupfs_setup_limits(void *hdata, struct lxc_list *cgroup_conf, +static bool cgroupfs_setup_limits(void *hdata, struct lxc_conf *conf, bool with_devices) { struct cgfs_data *d = hdata; if (!d) return false; - return do_setup_cgroup_limits(d, cgroup_conf, with_devices) == 0; + return do_setup_cgroup_limits(d, &conf->cgroup, with_devices) == 0; } static bool lxc_cgroupfs_attach(const char *name, const char *lxcpath, pid_t pid) diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index c94257c9f..5ecc3f0d1 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -2161,6 +2161,7 @@ static bool cgfsng_escape() return true; } +/* TODO: handle the unified cgroup hierarchy */ static int cgfsng_num_hierarchies(void) { int i; @@ -2171,15 +2172,15 @@ static int cgfsng_num_hierarchies(void) return i; } +/* TODO: handle the unified cgroup hierarchy */ static bool cgfsng_get_hierarchies(int n, char ***out) { int i; /* sanity check n */ - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) if (!hierarchies[i]) return false; - } *out = hierarchies[i]->controllers; @@ -2541,8 +2542,9 @@ static int lxc_cgroup_set_data(const char *filename, const char *value, struct c return ret; } -static bool cgfsng_setup_limits(void *hdata, struct lxc_list *cgroup_settings, - bool do_devices) +static bool __cgfsng_setup_limits_legacy(void *hdata, + struct lxc_list *cgroup_settings, + bool do_devices) { struct cgfsng_handler_data *d = hdata; struct lxc_list *iterator, *sorted_cgroup_settings, *next; @@ -2553,9 +2555,8 @@ static bool cgfsng_setup_limits(void *hdata, struct lxc_list *cgroup_settings, return true; sorted_cgroup_settings = sort_cgroup_settings(cgroup_settings); - if (!sorted_cgroup_settings) { + if (!sorted_cgroup_settings) return false; - } lxc_list_for_each(iterator, sorted_cgroup_settings) { cg = iterator->elem; @@ -2576,7 +2577,7 @@ static bool cgfsng_setup_limits(void *hdata, struct lxc_list *cgroup_settings, } ret = true; - INFO("cgroup has been setup"); + INFO("Limits for the legacy cgroup hierarchies have been setup"); out: lxc_list_for_each_safe(iterator, sorted_cgroup_settings, next) { lxc_list_del(iterator); @@ -2586,6 +2587,49 @@ out: return ret; } +static bool __cgfsng_setup_limits_unified(void *hdata, + struct lxc_list *cgroup_settings) +{ + struct lxc_list *iterator; + struct hierarchy *h = unified; + + if (lxc_list_empty(cgroup_settings)) + return true; + + if (!h) + return false; + + lxc_list_for_each(iterator, cgroup_settings) { + int ret; + char *fullpath; + struct lxc_cgroup *cg = iterator->elem; + + fullpath = must_make_path(h->fullcgpath, cg->subsystem, NULL); + ret = lxc_write_to_file(fullpath, cg->value, strlen(cg->value), false); + free(fullpath); + if (ret < 0) { + SYSERROR("Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value); + return false; + } + TRACE("Set \"%s\" to \"%s\"", cg->subsystem, cg->value); + } + + INFO("Limits for the unified cgroup hierarchy have been setup"); + return true; +} + +static bool cgfsng_setup_limits(void *hdata, struct lxc_conf *conf, + bool do_devices) +{ + bool bret; + + bret = __cgfsng_setup_limits_legacy(hdata, &conf->cgroup, do_devices); + if (!bret) + return false; + + return __cgfsng_setup_limits_unified(hdata, &conf->cgroup2); +} + static struct cgroup_ops cgfsng_ops = { .init = cgfsng_init, .destroy = cgfsng_destroy, diff --git a/src/lxc/cgroups/cgmanager.c b/src/lxc/cgroups/cgmanager.c index dccc04c3c..c23443c9f 100644 --- a/src/lxc/cgroups/cgmanager.c +++ b/src/lxc/cgroups/cgmanager.c @@ -1479,11 +1479,12 @@ static bool cgm_unfreeze(void *hdata) return ret; } -static bool cgm_setup_limits(void *hdata, struct lxc_list *cgroup_settings, bool do_devices) +static bool cgm_setup_limits(void *hdata, struct lxc_conf *conf, bool do_devices) { struct cgm_data *d = hdata; struct lxc_list *iterator, *sorted_cgroup_settings, *next; struct lxc_cgroup *cg; + struct lxc_list *cgroup_settings = &conf->cgroup; bool ret = false; if (lxc_list_empty(cgroup_settings)) diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c index 36a665b1c..1f78a6317 100644 --- a/src/lxc/cgroups/cgroup.c +++ b/src/lxc/cgroups/cgroup.c @@ -150,7 +150,7 @@ bool cgroup_setup_limits(struct lxc_handler *handler, bool with_devices) { if (ops) return ops->setup_limits(handler->cgroup_data, - &handler->conf->cgroup, with_devices); + handler->conf, with_devices); return false; } diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h index f409eee7c..d288b4c72 100644 --- a/src/lxc/cgroups/cgroup.h +++ b/src/lxc/cgroups/cgroup.h @@ -60,7 +60,7 @@ struct cgroup_ops { int (*set)(const char *filename, const char *value, const char *name, const char *lxcpath); int (*get)(const char *filename, char *value, size_t len, const char *name, const char *lxcpath); bool (*unfreeze)(void *hdata); - bool (*setup_limits)(void *hdata, struct lxc_list *cgroup_conf, bool with_devices); + bool (*setup_limits)(void *hdata, struct lxc_conf *conf, bool with_devices); bool (*chown)(void *hdata, struct lxc_conf *conf); bool (*attach)(const char *name, const char *lxcpath, pid_t pid); bool (*mount_cgroup)(void *hdata, const char *root, int type); @@ -80,7 +80,8 @@ extern bool cgroup_enter(struct lxc_handler *handler); extern void cgroup_cleanup(struct lxc_handler *handler); extern bool cgroup_create_legacy(struct lxc_handler *handler); extern int cgroup_nrtasks(struct lxc_handler *handler); -extern const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem); +extern const char *cgroup_get_cgroup(struct lxc_handler *handler, + const char *subsystem); extern bool cgroup_escape(); extern int cgroup_num_hierarchies(); extern bool cgroup_get_hierarchies(int i, char ***out);