Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion doc/config/cgroups.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ the above three. We leave `init/` and `user/` as-is reducing weight of
cgroup maint { cpu.weight = 100 }

By default, the `system/` cgroup is selected for almost everything. The
`init/` cgroup is reserved for PID 1 itself and its closest relatives.
`init/` cgroup is reserved for the early boot helpers Finit drives
itself, like udev and mdev. PID 1 runs in the root cgroup, since a
cgroup holding processes cannot delegate controllers to its children.
The `user/` cgroup is for local TTY logins spawned by getty.

Joining a Cgroup
Expand Down
27 changes: 9 additions & 18 deletions src/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,10 @@ static int cgroup_create(const char *group, const char *name, const char *cfg,
NULL
};

/* non-root delegated services needs permission to mkdir() */
if (chown(path, uid, gid))
warn("Failed chown %s to %d:%d", path, uid, gid);

for (int i = 0; files[i]; i++) {
snprintf(filepath, sizeof(filepath), "%s/%s", path, files[i]);
if (chown(filepath, uid, gid))
Expand Down Expand Up @@ -410,9 +414,6 @@ int cgroup_service(const char *name, int pid, struct cgroup *cg, char *username,
if (!strcmp(cg->name, "root"))
return fnwrite(str("%d", pid), FINIT_CGPATH "/cgroup.procs");

if (!strcmp(cg->name, "init"))
return fnwrite(str("%d", pid), FINIT_CGPATH "/init/cgroup.procs");

snprintf(path, sizeof(path), "/sys/fs/cgroup/%s", cg->name);
if (fisdir(path))
group = cg->name;
Expand Down Expand Up @@ -814,7 +815,6 @@ int cgroup_del_svc(svc_t *svc, const char *name)
return cgroup_del(path);
}

/* the top-level init cgroup is a leaf, that's ensured in cgroup_init() */
void cgroup_config(void)
{
struct cg *cg;
Expand All @@ -824,15 +824,12 @@ void cgroup_config(void)

TAILQ_FOREACH(cg, &cgroups, link) {
char path[256];
int leaf = 0;

if (!cg->active)
continue;
if (!strcmp(cg->name, "init"))
leaf = 1; /* reserved */

snprintf(path, sizeof(path), "%s/%s", FINIT_CGPATH, cg->name);
group_init(path, leaf, cg->cfg);
group_init(path, 0, cg->cfg);

strlcat(path, "/cgroup.events", sizeof(path));
iwatch_add(&iw_cgroup, path, 0);
Expand Down Expand Up @@ -936,20 +933,14 @@ void cgroup_init(uev_ctx_t *ctx)
goto abort;
}

/* Default (protected) groups, PID 1, services, and user/login processes */
/*
* Protected groups. PID 1 stays in the root cgroup, a group with
* processes in it cannot delegate controllers to its children.
*/
cgroup_add("init", "cpu.weight:100", 1);
cgroup_add("system", "cpu.weight:9800", 1);
cgroup_add("user", "cpu.weight:100", 1);
cgroup_config();

/* Move ourselves to init (best effort, otherwise run in 'root' group */
if (fnwrite("1", FINIT_CGPATH "/init/cgroup.procs")) {
err(1, "Failed moving PID 1 to cgroup %s", FINIT_CGPATH "/init");
uev_io_stop(&cgw);
iwatch_exit(&iw_cgroup);
close(fd);
goto abort;
}
}

/**
Expand Down
Loading