keep track of duplicate cgroups (cgroups with same name) and enable the first available when any cgroup is removed; fixes #874
Costa Tsaousis (ktsaou) committed
Sep 3, 2016 at 00:40 UTC
c7d97dde89ddb2fc40f077705052762d91c35040
1 file changed
+27
-13
src/sys_fs_cgroup.c
+27
-13
@@ -160,9 +160,12 @@ struct cpuacct_usage {
160
unsigned long long *cpu_percpu;
161
};
162
163
+#define CGROUP_OPTIONS_DISABLED_DUPLICATE 0x00000001
164
+
165
struct cgroup {
166
+ uint32_t options;
167
+
168
char available; // found in the filesystem
165
- char last_available; // found in the filesystem the last time
169
char enabled; // enabled in the config
170
171
char *id;
@@ -715,18 +718,18 @@ struct cgroup *cgroup_add(const char *id) {
718
if (!strncmp(t->chart_id, "/system.slice/", 14) && !strncmp(cg->chart_id, "/init.scope/system.slice/", 25)) {
719
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'.",
720
cg->chart_id, t->id, cg->id, t->id);
721
+ 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'.",
722
+ cg->chart_id, t->id, cg->id, t->id);
723
t->enabled = 0;
719
- } else {
720
- if(t->last_available) {
721
- error("Control group with chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.",
722
- cg->chart_id, t->id, cg->id);
723
- cg->enabled = 0;
724
- }
725
- else {
726
- error("Control group with chart id '%s' already exists with id '%s' but is not available. Enabling cgroup with id '%s'.",
727
- cg->chart_id, t->id, cg->id);
728
- t->enabled = 0;
729
- }
724
+ t->options |= CGROUP_OPTIONS_DISABLED_DUPLICATE;
725
+ }
726
+ else {
727
+ error("Control group with chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.",
728
+ cg->chart_id, t->id, cg->id);
729
+ debug(D_CGROUP, "Control group with chart id '%s' already exists with id '%s' and is enabled and available. Disabling cgroup with id '%s'.",
730
+ cg->chart_id, t->id, cg->id);
731
+ cg->enabled = 0;
732
+ cg->options |= CGROUP_OPTIONS_DISABLED_DUPLICATE;
733
}
734
735
break;
@@ -874,7 +877,6 @@ void mark_all_cgroups_as_not_available() {
877
878
// mark all as not available
879
for(cg = cgroup_root; cg ; cg = cg->next) {
877
- cg->last_available = cg->available;
880
cg->available = 0;
881
}
882
}
@@ -884,6 +886,18 @@ void cleanup_all_cgroups() {
886
887
for(; cg ;) {
888
if(!cg->available) {
889
+ // enable the first duplicate cgroup
890
+ {
891
+ struct cgroup *t;
892
+ for(t = cgroup_root; t ; t = t->next) {
893
+ 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)) {
894
+ 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);
895
+ t->enabled = 1;
896
+ t->options &= ~CGROUP_OPTIONS_DISABLED_DUPLICATE;
897
+ break;
898
+ }
899
+ }
900
+ }
901
902
if(!last)
903
cgroup_root = cg->next;