mirror of
https://github.com/troglobit/finit.git
synced 2026-10-29 12:40:44 +00:00
Refactor, clean up removed top-level cgroups
The main purpose of this patch is to remove top-level cgroups when they are remvoed from finit.conf. However, this is tricky, becasue there may still be supervised services (and children of them) running. We must postpone removal until a cgroup.events change. To make matters worse, events may arrive out-of-order, i.e. the last-child event for the parent cgroup before the sub-group. A spin-off from this patch is that we can now support arbitrarily long group names and group config. (Only applies to top-level cgroups, not run/task/services.) Limitations: - Processes in "removed" cgroups are not migrated/orphaned, the reasons are several: overhead and complexity and the fact that memory cannot be migrated - A lingering child of a moved service may prevent an old top-level cgroup from being removed. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
d77c014723
commit
a42a789d29
4 files changed
+194
-82
No files matched your search
+13
-55
@@ -51,8 +51,6 @@ int logfile_count_max = 5;
|
||||
struct rlimit initial_rlimit[RLIMIT_NLIMITS];
|
||||
struct rlimit global_rlimit[RLIMIT_NLIMITS];
|
||||
|
||||
struct cgroup cgroups[8];
|
||||
size_t cgroups_num;
|
||||
char cgroup_current[16]; /* cgroup.NAME sets current cgroup for a set of services */
|
||||
|
||||
struct conf_change {
|
||||
@@ -428,65 +426,27 @@ error:
|
||||
logit(LOG_WARNING, "rlimit: parse error");
|
||||
}
|
||||
|
||||
/* reset defaults */
|
||||
static void init_cgroups(void)
|
||||
{
|
||||
struct cgroup init[3] = {
|
||||
{ .name = "init", .cfg = "cpu.weight:100" },
|
||||
{ .name = "user", .cfg = "cpu.weight:100" },
|
||||
{ .name = "system", .cfg = "cpu.weight:9800" },
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < NELEMS(init); i++)
|
||||
memcpy(&cgroups[i], &init[i], sizeof(struct cgroup));
|
||||
|
||||
cgroups_num = i;
|
||||
}
|
||||
|
||||
struct cgroup *conf_cgfind(char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < cgroups_num; i++) {
|
||||
if (strcmp(cgroups[i].name, name))
|
||||
continue;
|
||||
|
||||
return &cgroups[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* cgroup NAME ctrl.prop:value,ctrl.prop:value ... */
|
||||
static void conf_parse_cgroup(char *line)
|
||||
{
|
||||
struct cgroup *cg;
|
||||
char config[strlen(line)];
|
||||
char *ptr, *name;
|
||||
|
||||
name = strtok(line, " \t");
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
cg = conf_cgfind(name);
|
||||
if (!cg) {
|
||||
if (strstr(name, "..") || strchr(name, '/'))
|
||||
return; /* illegal */
|
||||
if (cgroups_num + 1 == NELEMS(cgroups))
|
||||
return; /* exhausted */
|
||||
if (strstr(name, "..") || strchr(name, '/'))
|
||||
return; /* illegal */
|
||||
|
||||
cg = &cgroups[cgroups_num++];
|
||||
strlcpy(cg->name, name, sizeof(cg->name));
|
||||
}
|
||||
|
||||
cg->cfg[0] = 0;
|
||||
config[0] = 0;
|
||||
while ((ptr = strtok(NULL, " \t"))) {
|
||||
if (cg->cfg[0])
|
||||
strlcat(cg->cfg, ",", sizeof(cg->cfg));
|
||||
strlcat(cg->cfg, ptr, sizeof(cg->cfg));
|
||||
if (config[0])
|
||||
strlcat(config, ",", sizeof(config));
|
||||
strlcat(config, ptr, sizeof(config));
|
||||
}
|
||||
|
||||
_d("cg->cfg: %s", cg->cfg);
|
||||
cgroup_add(name, config, 0);
|
||||
}
|
||||
|
||||
static void parse_static(char *line, int is_rcsd)
|
||||
@@ -702,6 +662,7 @@ int conf_reload(void)
|
||||
daylight, timezone, tzname[0], tzname[1]);
|
||||
|
||||
/* Mark and sweep */
|
||||
cgroup_mark_all();
|
||||
svc_mark_dynamic();
|
||||
tty_mark();
|
||||
|
||||
@@ -710,9 +671,6 @@ int conf_reload(void)
|
||||
*/
|
||||
memcpy(global_rlimit, initial_rlimit, sizeof(global_rlimit));
|
||||
|
||||
/* Initialize default cgroups */
|
||||
init_cgroups();
|
||||
|
||||
if (rescue) {
|
||||
int rc;
|
||||
char line[80] = "tty [12345] @console noclear nologin";
|
||||
@@ -784,8 +742,11 @@ int conf_reload(void)
|
||||
service_update_rdeps();
|
||||
|
||||
/* Set up top-level cgroups */
|
||||
cgroup_config(cgroups_num, cgroups);
|
||||
cgroup_config();
|
||||
done:
|
||||
/* Remove all unused top-level cgroups */
|
||||
cgroup_cleanup();
|
||||
|
||||
/* Drop record of all .conf changes */
|
||||
drop_changes();
|
||||
|
||||
@@ -997,9 +958,6 @@ int conf_init(uev_ctx_t *ctx)
|
||||
/* Initialize global rlimits, e.g. for built-in services */
|
||||
memcpy(global_rlimit, initial_rlimit, sizeof(global_rlimit));
|
||||
|
||||
/* Initialize default cgroups */
|
||||
init_cgroups();
|
||||
|
||||
/* Read global rlimits and global cgroup setup from /etc/finit.conf */
|
||||
parse_conf(FINIT_CONF, 0);
|
||||
|
||||
|
||||
Reference in new issue
Block a user