Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cgroup: fix various issues with compatibility with older bst spacetimes #82

Merged
merged 3 commits into from
Aug 31, 2023
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
29 changes: 28 additions & 1 deletion cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
#include "path.h"
#include "util.h"

extern const struct cgroup_driver_funcs cgroup_driver_none;
extern const struct cgroup_driver_funcs cgroup_driver_native;
#ifdef HAVE_SYSTEMD
extern const struct cgroup_driver_funcs cgroup_driver_systemd;
#endif

static const struct cgroup_driver_funcs *cgroup_drivers[] = {
[CGROUP_DRIVER_NONE] = &cgroup_driver_none,
[CGROUP_DRIVER_NATIVE] = &cgroup_driver_native,
#ifdef HAVE_SYSTEMD
[CGROUP_DRIVER_SYSTEMD] = &cgroup_driver_systemd,
Expand All @@ -36,7 +38,11 @@ int cgroup_driver_init(enum cgroup_driver driver, bool fatal)
if (cgroup_detected_driver < 0 || cgroup_detected_driver >= lengthof(cgroup_drivers)) {
errx(1, "unknown cgroup driver ID %d", cgroup_detected_driver);
}
return cgroup_drivers[cgroup_detected_driver]->init(fatal);
int rc = cgroup_drivers[cgroup_detected_driver]->init(fatal);
if (rc < 0 && fatal) {
errx(1, "cgroup_driver_init: cgroup driver failed to initialize");
}
return rc;
}

static enum cgroup_driver attempts[] = {
Expand Down Expand Up @@ -233,3 +239,24 @@ void cgroup_enable_controllers(int cgroupfd)
err(1, "cgroup_enable_controllers: close cgroup.subtree_control");
}
}

static int cgroup_none_driver_init(bool fatal)
{
return -1;
}

static bool cgroup_none_current_path(char *path)
{
return false;
}

static int cgroup_none_join_cgroup(const char *parent, const char *name)
{
return -1;
}

const struct cgroup_driver_funcs cgroup_driver_none = {
.init = cgroup_none_driver_init,
.join_cgroup = cgroup_none_join_cgroup,
.current_path = cgroup_none_current_path,
};
11 changes: 6 additions & 5 deletions cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
# include <stdbool.h>

struct cgroup_driver_funcs {
int (*init)(bool fatal);
int (*join_cgroup)(const char *parent, const char *name);
bool (*current_path)(char *out);
int (*init)(bool fatal);
int (*join_cgroup)(const char *parent, const char *name);
bool (*current_path)(char *out);
};

enum cgroup_driver {
CGROUP_DRIVER_NATIVE,
CGROUP_DRIVER_SYSTEMD,
CGROUP_DRIVER_NONE,
CGROUP_DRIVER_NATIVE,
CGROUP_DRIVER_SYSTEMD,
};

int cgroup_driver_init(enum cgroup_driver driver, bool fatal);
Expand Down
14 changes: 13 additions & 1 deletion cgroup_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,21 @@ static int cgroup_native_driver_init(bool fatal)
if (!cgroup_read_current(NULL)) {
return -1;
}
if (access("/sys/fs/cgroup/cgroup.controllers", F_OK) == -1) {

/* Attempting to open /sys/fs/cgroup/cgroup.procs privileged checks two
things: first, that the cgroup hierarchy is v2 by checking that the
file exists; and second, that the mounted cgroup hierarchy can be
operated on, which might not be the case if bst was left in its
original cgroup. */
make_capable(BST_CAP_DAC_OVERRIDE);
int fd = open("/sys/fs/cgroup/cgroup.procs", O_WRONLY, 0);
reset_capabilities();

if (fd == -1) {
return -1;
}
close(fd);

return 0;
}

Expand Down
3 changes: 2 additions & 1 deletion cgroup_systemd.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,9 @@ static int cgroup_systemd_join_cgroup(const char *parent, const char *name)
ok = ok && dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sv)", &props);

ok = ok && bus_message_append(&props, "(sv)(sv)(sv)(sv)",
"Description", "s", "/usr/bin/true",
"Description", "s", "bst",
"Delegate", "b", 1, /* Delegate all cgroup controllers to us */
"CollectMode", "s", "inactive-or-failed", /* Make sure failed invocations are garbage-collected */
"Slice", "s", parent,
"PIDs", "au", 1, (uint32_t)getpid());

Expand Down
4 changes: 3 additions & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,9 @@ int main(int argc, char *argv[], char *envp[])
break;

case OPTION_CGROUP_DRIVER:
if (strcmp(optarg, "native") == 0) {
if (strcmp(optarg, "none") == 0) {
opts.cgroup_driver = CGROUP_DRIVER_NONE;
} else if (strcmp(optarg, "native") == 0) {
opts.cgroup_driver = CGROUP_DRIVER_NATIVE;
#ifdef HAVE_SYSTEMD
} else if (strcmp(optarg, "systemd") == 0) {
Expand Down
6 changes: 5 additions & 1 deletion man/bst.1.scd
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ spacetime process.
\--cgroup-driver <driver>
Specify the cgroup driver to use.

Valid values are _native_, or _systemd_.
Valid values are _native_, _systemd_, or _none_.

The _native_ driver manages and cleans up cgroups directly, with no
intermediary. It is appropriate to use in situations where nothing is
Expand All @@ -247,6 +247,10 @@ spacetime process.
without informing systemd on these systems causes bst to step on systemd's
toes, and vice-versa.

The _none_ driver disables cgroup support -- *bst* will leave the child
process in the parent control group. Using this driver is not recommended
for typical use, but has worth in testing or maintaining compatibility.

By default, *bst* will attempt to use the _systemd_ driver before falling
back to the _native_ driver.

Expand Down
Loading