From: Serge Hallyn Date: Mon, 20 Jan 2014 15:09:36 +0000 (-0600) Subject: cgmanager: implement setting of cgroup limits X-Git-Tag: lxc-1.0.0.beta3~83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9daf6f5d01d49e656190f9b94467605d5fee6f98;p=thirdparty%2Flxc.git cgmanager: implement setting of cgroup limits Also replace a wrong free of nih-allocated variable with nih_free. Signed-off-by: Serge Hallyn Acked-by: Stéphane Graber --- diff --git a/src/lxc/cgmanager.c b/src/lxc/cgmanager.c index 97bda2c17..61f7f6ff8 100644 --- a/src/lxc/cgmanager.c +++ b/src/lxc/cgmanager.c @@ -55,6 +55,7 @@ lxc_log_define(lxc_cgmanager, lxc); #include #include +#include NihDBusProxy *cgroup_manager = NULL; extern struct cgroup_ops *active_cg_ops; @@ -269,13 +270,25 @@ int cgm_get(const char *filename, char *value, size_t len, const char *name, con strncpy(value, result, len); if (strlen(result) >= len) value[len-1] = '\0'; - free(result); + nih_free(result); return len; } +static int cgm_do_set(const char *controller, const char *file, + const char *cgroup, const char *value) +{ + int ret; + ret = cgmanager_set_value_sync(NULL, cgroup_manager, controller, + cgroup, file, value); + if (ret != 0) + ERROR("Error setting cgroup %s limit %s", file, cgroup); + return ret; +} + int cgm_set(const char *filename, const char *value, const char *name, const char *lxcpath) { char *controller, *key, *cgroup; + int ret; controller = alloca(strlen(filename)+1); strcpy(controller, filename); @@ -291,14 +304,9 @@ int cgm_set(const char *filename, const char *value, const char *name, const cha controller, lxcpath, name); return -1; } - if (cgmanager_set_value_sync(NULL, cgroup_manager, controller, cgroup, filename, value) != 0) { - ERROR("Error setting value for %s from cgmanager for cgroup %s (%s:%s)", - filename, cgroup, lxcpath, name); - free(cgroup); - return -1; - } + ret = cgm_do_set(controller, filename, cgroup, value); free(cgroup); - return 0; + return ret; } /* @@ -367,6 +375,49 @@ static int cgm_unfreeze_fromhandler(struct lxc_handler *handler) return 0; } +static bool setup_limits(struct lxc_handler *h, bool do_devices) +{ + struct lxc_list *iterator; + struct lxc_cgroup *cg; + bool ret = false; + struct lxc_list *cgroup_settings = &h->conf->cgroup; + struct cgm_data *d = h->cgroup_info->data; + + if (lxc_list_empty(cgroup_settings)) + return 0; + + lxc_list_for_each(iterator, cgroup_settings) { + char controller[100], *p; + cg = iterator->elem; + if (do_devices != !strncmp("devices", cg->subsystem, 7)) + continue; + if (strlen(cg->subsystem) > 100) // i smell a rat + goto out; + strcpy(controller, cg->subsystem); + p = strchr(controller, '.'); + if (p) + *p = '\0'; + if (cgm_do_set(controller, cg->subsystem, d->cgroup_path + , cg->value) < 0) { + ERROR("Error setting %s to %s for %s\n", + cg->subsystem, cg->value, h->name); + goto out; + } + + DEBUG("cgroup '%s' set to '%s'", cg->subsystem, cg->value); + } + + ret = true; + INFO("cgroup limits have been setup"); +out: + return ret; +} + +static bool cgm_setup_limits(struct lxc_handler *handler, bool with_devices) +{ + return setup_limits(handler, with_devices); +} + static struct cgroup_ops cgmanager_ops = { .destroy = cgm_destroy, .init = cgm_init, @@ -377,6 +428,7 @@ static struct cgroup_ops cgmanager_ops = { .get = cgm_get, .set = cgm_set, .unfreeze_fromhandler = cgm_unfreeze_fromhandler, + .setup_limits = cgm_setup_limits, .name = "cgmanager" }; #endif diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index 85384fcc1..4482b326b 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -70,7 +70,7 @@ static struct cgroup_process_info *find_info_for_subsystem(struct cgroup_process static int do_cgroup_get(const char *cgroup_path, const char *sub_filename, char *value, size_t len); static int do_cgroup_set(const char *cgroup_path, const char *sub_filename, const char *value); static bool cgroup_devices_has_allow_or_deny(struct lxc_handler *h, char *v, bool for_allow); -static int do_setup_cgroup(struct lxc_handler *h, struct lxc_list *cgroup_settings, bool do_devices); +static int do_setup_cgroup_limits(struct lxc_handler *h, struct lxc_list *cgroup_settings, bool do_devices); static int cgroup_recursive_task_count(const char *cgroup_path); static int count_lines(const char *fn); static int handle_cgroup_settings(struct cgroup_mount_point *mp, char *cgroup_path); @@ -1838,7 +1838,7 @@ static int do_cgroup_set(const char *cgroup_path, const char *sub_filename, return ret; } -static int do_setup_cgroup(struct lxc_handler *h, +static int do_setup_cgroup_limits(struct lxc_handler *h, struct lxc_list *cgroup_settings, bool do_devices) { struct lxc_list *iterator; @@ -2182,6 +2182,11 @@ static int cgfs_unfreeze_fromhandler(struct lxc_handler *handler) return ret; } +bool cgroupfs_setup_limits(struct lxc_handler *h, bool with_devices) +{ + return do_setup_cgroup_limits(h, &h->conf->cgroup, with_devices) == 0; +} + static struct cgroup_ops cgfs_ops = { .destroy = cgfs_destroy, .init = cgfs_init, @@ -2192,6 +2197,7 @@ static struct cgroup_ops cgfs_ops = { .get = lxc_cgroupfs_get, .set = lxc_cgroupfs_set, .unfreeze_fromhandler = cgfs_unfreeze_fromhandler, + .setup_limits = cgroupfs_setup_limits, .name = "cgroupfs", }; static void init_cg_ops(void) @@ -2250,21 +2256,6 @@ bool cgroup_create(struct lxc_handler *handler) return active_cg_ops->create(handler); } -/* - * Set up per-controller configuration excluding the devices - * cgroup - */ -bool cgroup_setup_without_devices(struct lxc_handler *handler) -{ - return do_setup_cgroup(handler, &handler->conf->cgroup, false) == 0; -} - -/* Set up the devices cgroup configuration for the container */ -bool cgroup_setup_devices(struct lxc_handler *handler) -{ - return do_setup_cgroup(handler, &handler->conf->cgroup, true) == 0; -} - /* * Enter the container init into its new cgroups for all * requested controllers */ @@ -2301,3 +2292,8 @@ int lxc_unfreeze_fromhandler(struct lxc_handler *handler) { return active_cg_ops->unfreeze_fromhandler(handler); } + +bool cgroup_setup_limits(struct lxc_handler *handler, bool with_devices) +{ + return active_cg_ops->setup_limits(handler, with_devices); +} diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h index 76dcbd13d..af5a5c833 100644 --- a/src/lxc/cgroup.h +++ b/src/lxc/cgroup.h @@ -179,6 +179,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); int (*unfreeze_fromhandler)(struct lxc_handler *handler); + bool (*setup_limits)(struct lxc_handler *handler, bool with_devices); const char *name; }; @@ -207,8 +208,7 @@ struct cgfs_data { extern void cgroup_destroy(struct lxc_handler *handler); extern bool cgroup_init(struct lxc_handler *handler); extern bool cgroup_create(struct lxc_handler *handler); -extern bool cgroup_setup_without_devices(struct lxc_handler *handler); -extern bool cgroup_setup_devices(struct lxc_handler *handler); +extern bool cgroup_setup_limits(struct lxc_handler *handler, bool with_devices); 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); diff --git a/src/lxc/start.c b/src/lxc/start.c index b09bd9b08..2fcd8457c 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -796,8 +796,8 @@ static int lxc_spawn(struct lxc_handler *handler) ERROR("failed to setup the legacy cgroups for %s", name); goto out_delete_net; } - if (!cgroup_setup_without_devices(handler)) { - ERROR("failed to setup the cgroups for '%s'", name); + if (!cgroup_setup_limits(handler, false)) { + ERROR("failed to setup the cgroup limits for '%s'", name); goto out_delete_net; } @@ -831,7 +831,7 @@ static int lxc_spawn(struct lxc_handler *handler) if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE)) goto out_delete_net; - if (!cgroup_setup_devices(handler)) { + if (!cgroup_setup_limits(handler, true)) { ERROR("failed to setup the devices cgroup for '%s'", name); goto out_delete_net; }