Commit 9daf6f5d by Serge Hallyn Committed by Stéphane Graber

cgmanager: implement setting of cgroup limits

Also replace a wrong free of nih-allocated variable with nih_free. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 755d8d03
......@@ -55,6 +55,7 @@ lxc_log_define(lxc_cgmanager, lxc);
#include <nih-dbus/dbus_connection.h>
#include <cgmanager-client/cgmanager-client.h>
#include <nih/alloc.h>
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
......@@ -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)
......@@ -2251,21 +2257,6 @@ bool cgroup_create(struct lxc_handler *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 */
bool cgroup_enter(struct lxc_handler *handler)
......@@ -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);
}
......@@ -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);
......
......@@ -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;
}
......
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