From c7d97dde89ddb2fc40f077705052762d91c35040 Mon Sep 17 00:00:00 2001 From: "Costa Tsaousis (ktsaou)" Date: Sat, 3 Sep 2016 00:40:14 +0300 Subject: [PATCH] keep track of duplicate cgroups (cgroups with same name) and enable the first available when any cgroup is removed; fixes #874 --- src/sys_fs_cgroup.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/sys_fs_cgroup.c b/src/sys_fs_cgroup.c index b972ed12..fe9bbc47 100644 --- a/src/sys_fs_cgroup.c +++ b/src/sys_fs_cgroup.c @@ -160,9 +160,12 @@ struct cpuacct_usage { unsigned long long *cpu_percpu; }; +#define CGROUP_OPTIONS_DISABLED_DUPLICATE 0x00000001 + struct cgroup { + uint32_t options; + char available; // found in the filesystem - char last_available; // found in the filesystem the last time char enabled; // enabled in the config char *id; @@ -715,18 +718,18 @@ struct cgroup *cgroup_add(const char *id) { if (!strncmp(t->chart_id, "/system.slice/", 14) && !strncmp(cg->chart_id, "/init.scope/system.slice/", 25)) { error("Control group with chart id '%s' already exists with id '%s' and is enabled. Swapping them by enabling cgroup with id '%s' and disabling cgroup with id '%s'.", cg->chart_id, t->id, cg->id, t->id); + debug(D_CGROUP, "Control group with chart id '%s' already exists with id '%s' and is enabled. Swapping them by enabling cgroup with id '%s' and disabling cgroup with id '%s'.", + cg->chart_id, t->id, cg->id, t->id); t->enabled = 0; - } else { - if(t->last_available) { - error("Control group with chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.", - cg->chart_id, t->id, cg->id); - cg->enabled = 0; - } - else { - error("Control group with chart id '%s' already exists with id '%s' but is not available. Enabling cgroup with id '%s'.", - cg->chart_id, t->id, cg->id); - t->enabled = 0; - } + t->options |= CGROUP_OPTIONS_DISABLED_DUPLICATE; + } + else { + error("Control group with chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.", + cg->chart_id, t->id, cg->id); + debug(D_CGROUP, "Control group with chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.", + cg->chart_id, t->id, cg->id); + cg->enabled = 0; + cg->options |= CGROUP_OPTIONS_DISABLED_DUPLICATE; } break; @@ -874,7 +877,6 @@ void mark_all_cgroups_as_not_available() { // mark all as not available for(cg = cgroup_root; cg ; cg = cg->next) { - cg->last_available = cg->available; cg->available = 0; } } @@ -884,6 +886,18 @@ void cleanup_all_cgroups() { for(; cg ;) { if(!cg->available) { + // enable the first duplicate cgroup + { + struct cgroup *t; + for(t = cgroup_root; t ; t = t->next) { + if(t != cg && t->available && !t->enabled && t->options & CGROUP_OPTIONS_DISABLED_DUPLICATE && t->hash_chart == cg->hash_chart && !strcmp(t->chart_id, cg->chart_id)) { + debug(D_CGROUP, "Enabling duplicate of cgroup '%s' with id '%s', because the original with id '%s' stopped.", t->chart_id, t->id, cg->id); + t->enabled = 1; + t->options &= ~CGROUP_OPTIONS_DISABLED_DUPLICATE; + break; + } + } + } if(!last) cgroup_root = cg->next; -- 2.39.2