From: Michael Tremer Date: Wed, 1 Nov 2023 17:08:08 +0000 (+0000) Subject: cgroups: Anchor to the context X-Git-Tag: 0.9.30~1333 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=35bf392c83a58ced27cb16fd99f37c76689f1f20;p=pakfire.git cgroups: Anchor to the context Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/build.c b/src/libpakfire/build.c index 5b8fbc6bb..702fdb426 100644 --- a/src/libpakfire/build.c +++ b/src/libpakfire/build.c @@ -1416,7 +1416,7 @@ static int pakfire_build_setup_cgroup(struct pakfire_build* build) { } // Create a new cgroup - r = pakfire_cgroup_open(&build->cgroup, build->pakfire, path, + r = pakfire_cgroup_open(&build->cgroup, build->ctx, path, PAKFIRE_CGROUP_ENABLE_ACCOUNTING); if (r) { ERROR(build->pakfire, "Could not create cgroup for build %s: %m\n", build->_id); diff --git a/src/libpakfire/cgroup.c b/src/libpakfire/cgroup.c index 6b41baf0f..4ad1bcc12 100644 --- a/src/libpakfire/cgroup.c +++ b/src/libpakfire/cgroup.c @@ -28,9 +28,9 @@ // libbpf #include +#include #include #include -#include #include #include #include @@ -71,7 +71,7 @@ static const enum pakfire_cgroup_controllers pakfire_cgroup_accounting_controlle PAKFIRE_CGROUP_CONTROLLER_IO; struct pakfire_cgroup { - struct pakfire* pakfire; + struct pakfire_ctx* ctx; int nrefs; // Store the root path @@ -119,7 +119,7 @@ static int pakfire_cgroup_set_root(struct pakfire_cgroup* cgroup) { } if (r) - ERROR(cgroup->pakfire, "Could not determine cgroup root: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not determine cgroup root: %m\n"); return r; } @@ -181,7 +181,7 @@ static struct pakfire_cgroup* pakfire_cgroup_parent(struct pakfire_cgroup* cgrou // Determine the path of the parent r = pakfire_path_dirname(path, cgroup->path); if (r) { - ERROR(cgroup->pakfire, "Could not determine path for parent cgroup: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not determine path for parent cgroup: %m\n"); return NULL; } @@ -190,9 +190,9 @@ static struct pakfire_cgroup* pakfire_cgroup_parent(struct pakfire_cgroup* cgrou *path = '\0'; // Open the cgroup - r = pakfire_cgroup_open(&parent, cgroup->pakfire, path, 0); + r = pakfire_cgroup_open(&parent, cgroup->ctx, path, 0); if (r) { - ERROR(cgroup->pakfire, "Could not open parent cgroup: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not open parent cgroup: %m\n"); parent = NULL; } @@ -200,16 +200,16 @@ static struct pakfire_cgroup* pakfire_cgroup_parent(struct pakfire_cgroup* cgrou } static void pakfire_cgroup_free(struct pakfire_cgroup* cgroup) { - DEBUG(cgroup->pakfire, "Releasing cgroup %s at %p\n", + CTX_DEBUG(cgroup->ctx, "Releasing cgroup %s at %p\n", pakfire_cgroup_name(cgroup), cgroup); // Close the file descriptors - if (cgroup->fd > 0) + if (cgroup->fd >= 0) close(cgroup->fd); - if (cgroup->devicesfd > 0) + if (cgroup->devicesfd >= 0) close(cgroup->devicesfd); - - pakfire_unref(cgroup->pakfire); + if (cgroup->ctx) + pakfire_ctx_unref(cgroup->ctx); free(cgroup); } @@ -232,7 +232,7 @@ static int pakfire_cgroup_setup_devices(struct pakfire_cgroup* cgroup) { r = bpf_prog_load(BPF_PROG_TYPE_CGROUP_DEVICE, NULL, "GPL", program, sizeof(program) / sizeof(*program), &opts); if (r < 0) { - ERROR(cgroup->pakfire, "Could not load BPF program: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not load BPF program: %m\n"); return r; } @@ -243,7 +243,7 @@ static int pakfire_cgroup_setup_devices(struct pakfire_cgroup* cgroup) { r = bpf_prog_attach(cgroup->devicesfd, cgroup->fd, BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI); if (r) { - ERROR(cgroup->pakfire, "Could not attach BPF program to cgroup: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not attach BPF program to cgroup: %m\n"); return r; } @@ -253,7 +253,7 @@ static int pakfire_cgroup_setup_devices(struct pakfire_cgroup* cgroup) { static int pakfire_cgroup_open_root(struct pakfire_cgroup* cgroup) { int fd = open(cgroup->root, O_DIRECTORY|O_PATH|O_CLOEXEC); if (fd < 0) { - ERROR(cgroup->pakfire, "Could not open %s: %m\n", cgroup->root); + CTX_ERROR(cgroup->ctx, "Could not open %s: %m\n", cgroup->root); return -1; } @@ -264,7 +264,7 @@ static int __pakfire_cgroup_create(struct pakfire_cgroup* cgroup) { char path[PATH_MAX]; int r; - DEBUG(cgroup->pakfire, "Trying to create cgroup %s\n", pakfire_cgroup_name(cgroup)); + CTX_DEBUG(cgroup->ctx, "Trying to create cgroup %s\n", pakfire_cgroup_name(cgroup)); // Compose the absolute path r = pakfire_path_append(path, cgroup->root, cgroup->path); @@ -310,7 +310,7 @@ RETRY: // Exit on all other errors default: - ERROR(cgroup->pakfire, "Could not open cgroup %s: %m\n", + CTX_ERROR(cgroup->ctx, "Could not open cgroup %s: %m\n", pakfire_cgroup_name(cgroup)); goto ERROR; } @@ -335,7 +335,7 @@ static FILE* pakfire_cgroup_open_file(struct pakfire_cgroup* cgroup, // Open cgroup.procs int fd = openat(cgroup->fd, "cgroup.procs", O_CLOEXEC); if (fd < 0) { - ERROR(cgroup->pakfire, "%s: Could not open %s: %m\n", + CTX_ERROR(cgroup->ctx, "%s: Could not open %s: %m\n", pakfire_cgroup_name(cgroup), path); goto ERROR; } @@ -358,14 +358,14 @@ static ssize_t pakfire_cgroup_read(struct pakfire_cgroup* cgroup, const char* pa // Check if this cgroup has been destroyed already if (!cgroup->fd) { - ERROR(cgroup->pakfire, "Trying to read from destroyed cgroup\n"); + CTX_ERROR(cgroup->ctx, "Trying to read from destroyed cgroup\n"); return -1; } // Open the file int fd = openat(cgroup->fd, path, O_CLOEXEC); if (fd < 0) { - DEBUG(cgroup->pakfire, "Could not open %s/%s: %m\n", + CTX_DEBUG(cgroup->ctx, "Could not open %s/%s: %m\n", pakfire_cgroup_name(cgroup), path); goto ERROR; } @@ -373,7 +373,7 @@ static ssize_t pakfire_cgroup_read(struct pakfire_cgroup* cgroup, const char* pa // Read file content into buffer bytes_read = read(fd, buffer, length); if (bytes_read < 0) { - DEBUG(cgroup->pakfire, "Could not read from %s/%s: %m\n", + CTX_DEBUG(cgroup->ctx, "Could not read from %s/%s: %m\n", pakfire_cgroup_name(cgroup), path); goto ERROR; } @@ -396,7 +396,7 @@ static int pakfire_cgroup_write(struct pakfire_cgroup* cgroup, // Check if this cgroup has been destroyed already if (!cgroup->fd) { - ERROR(cgroup->pakfire, "Trying to write to destroyed cgroup\n"); + CTX_ERROR(cgroup->ctx, "Trying to write to destroyed cgroup\n"); errno = EPERM; return 1; } @@ -404,7 +404,7 @@ static int pakfire_cgroup_write(struct pakfire_cgroup* cgroup, // Open the file int fd = openat(cgroup->fd, path, O_WRONLY|O_CLOEXEC); if (fd < 0) { - DEBUG(cgroup->pakfire, "Could not open %s/%s for writing: %m\n", + CTX_DEBUG(cgroup->ctx, "Could not open %s/%s for writing: %m\n", pakfire_cgroup_name(cgroup), path); return 1; } @@ -416,7 +416,7 @@ static int pakfire_cgroup_write(struct pakfire_cgroup* cgroup, // Check if content was written okay if (bytes_written < 0) { - DEBUG(cgroup->pakfire, "Could not write to %s/%s: %m\n", + CTX_DEBUG(cgroup->ctx, "Could not write to %s/%s: %m\n", pakfire_cgroup_name(cgroup), path); r = 1; } @@ -447,7 +447,7 @@ static int pakfire_cgroup_read_controllers( char* token = strtok_r(buffer, " \n", &p); while (token) { - DEBUG(cgroup->pakfire, "Found controller '%s'\n", token); + CTX_DEBUG(cgroup->ctx, "Found controller '%s'\n", token); // Try finding this controller int controller = pakfire_cgroup_find_controller_by_name(token); @@ -487,7 +487,7 @@ static int pakfire_cgroup_enable_controllers(struct pakfire_cgroup* cgroup, // Find all enabled controllers const int enabled_controllers = pakfire_cgroup_enabled_controllers(cgroup); if (enabled_controllers < 0) { - ERROR(cgroup->pakfire, "Could not fetch enabled controllers: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not fetch enabled controllers: %m\n"); goto ERROR; } @@ -496,20 +496,20 @@ static int pakfire_cgroup_enable_controllers(struct pakfire_cgroup* cgroup, // Exit if everything is already enabled if (!controllers) { - DEBUG(cgroup->pakfire, "All controllers are already enabled\n"); + CTX_DEBUG(cgroup->ctx, "All controllers are already enabled\n"); return 0; } // Find all available controllers const int available_controllers = pakfire_cgroup_available_controllers(cgroup); if (available_controllers < 0) { - ERROR(cgroup->pakfire, "Could not fetch available controllers: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not fetch available controllers: %m\n"); goto ERROR; } // Are all controllers we need available, yet? if (controllers & ~available_controllers) { - DEBUG(cgroup->pakfire, "Not all controllers are available, yet\n"); + CTX_DEBUG(cgroup->ctx, "Not all controllers are available, yet\n"); parent = pakfire_cgroup_parent(cgroup); @@ -533,13 +533,13 @@ static int pakfire_cgroup_enable_controllers(struct pakfire_cgroup* cgroup, // Fetch name const char* name = pakfire_cgroup_controller_name(controller); - DEBUG(cgroup->pakfire, "Enabling controller %s in cgroup %s\n", + CTX_DEBUG(cgroup->ctx, "Enabling controller %s in cgroup %s\n", name, pakfire_cgroup_name(cgroup)); // Try enabling the controller (this will succeed if it already is enabled) r = pakfire_cgroup_write(cgroup, "cgroup.subtree_control", "+%s\n", name); if (r) { - ERROR(cgroup->pakfire, "Could not enable controller %s in cgroup %s\n", + CTX_ERROR(cgroup->ctx, "Could not enable controller %s in cgroup %s\n", name, pakfire_cgroup_name(cgroup)); goto ERROR; } @@ -564,7 +564,7 @@ static int pakfire_cgroup_enable_accounting(struct pakfire_cgroup* cgroup) { If the cgroup doesn't exist, it will be created including any parent cgroups. */ int pakfire_cgroup_open(struct pakfire_cgroup** cgroup, - struct pakfire* pakfire, const char* path, int flags) { + struct pakfire_ctx* ctx, const char* path, int flags) { int r = 1; // Allocate the cgroup struct @@ -572,10 +572,10 @@ int pakfire_cgroup_open(struct pakfire_cgroup** cgroup, if (!c) return 1; - DEBUG(pakfire, "Allocated cgroup %s at %p\n", path, c); + CTX_DEBUG(ctx, "Allocated cgroup %s at %p\n", path, c); - // Keep a reference to pakfire - c->pakfire = pakfire_ref(pakfire); + // Store a reference to the context + c->ctx = pakfire_ctx_ref(ctx); // Initialize reference counter c->nrefs = 1; @@ -650,7 +650,7 @@ int pakfire_cgroup_child(struct pakfire_cgroup** child, return 1; // Open the child group - return pakfire_cgroup_open(child, cgroup->pakfire, path, flags); + return pakfire_cgroup_open(child, cgroup->ctx, path, flags); } static int pakfire_cgroup_procs_callback(struct pakfire_cgroup* cgroup, @@ -696,11 +696,11 @@ static int pakfire_cgroup_procs_callback(struct pakfire_cgroup* cgroup, } static int send_sigkill(struct pakfire_cgroup* cgroup, const pid_t pid, void* data) { - DEBUG(cgroup->pakfire, "Sending signal SIGKILL to PID %d\n", pid); + CTX_DEBUG(cgroup->ctx, "Sending signal SIGKILL to PID %d\n", pid); int r = kill(pid, SIGKILL); if (r < 0 && errno != ESRCH) { - ERROR(cgroup->pakfire, "Could not send signal SIGKILL to PID %d: %m\n", pid); + CTX_ERROR(cgroup->ctx, "Could not send signal SIGKILL to PID %d: %m\n", pid); return r; } @@ -711,7 +711,7 @@ static int send_sigkill(struct pakfire_cgroup* cgroup, const pid_t pid, void* da Immediately kills all processes in this cgroup */ static int pakfire_cgroup_killall(struct pakfire_cgroup* cgroup) { - DEBUG(cgroup->pakfire, "%s: Killing all processes\n", pakfire_cgroup_name(cgroup)); + CTX_DEBUG(cgroup->ctx, "%s: Killing all processes\n", pakfire_cgroup_name(cgroup)); // Do we have support for cgroup.kill? int r = pakfire_cgroup_access(cgroup, "cgroup.kill", F_OK, 0); @@ -736,7 +736,7 @@ int pakfire_cgroup_destroy(struct pakfire_cgroup* cgroup) { return 1; } - DEBUG(cgroup->pakfire, "Destroying cgroup %s\n", pakfire_cgroup_name(cgroup)); + CTX_DEBUG(cgroup->ctx, "Destroying cgroup %s\n", pakfire_cgroup_name(cgroup)); // Kill everything in this group r = pakfire_cgroup_killall(cgroup); @@ -757,7 +757,7 @@ int pakfire_cgroup_destroy(struct pakfire_cgroup* cgroup) { // Delete the directory r = unlinkat(fd, cgroup->path, AT_REMOVEDIR); if (r) - ERROR(cgroup->pakfire, "Could not destroy cgroup: %m\n"); + CTX_ERROR(cgroup->ctx, "Could not destroy cgroup: %m\n"); // Close fd close(fd); @@ -779,13 +779,13 @@ int pakfire_cgroup_set_guaranteed_memory(struct pakfire_cgroup* cgroup, size_t m if (r) return r; - DEBUG(cgroup->pakfire, "%s: Setting guaranteed memory to %zu byte(s)\n", + CTX_DEBUG(cgroup->ctx, "%s: Setting guaranteed memory to %zu byte(s)\n", pakfire_cgroup_name(cgroup), mem); // Set value r = pakfire_cgroup_write(cgroup, "memory.min", "%zu\n", mem); if (r) - ERROR(cgroup->pakfire, "%s: Could not set guaranteed memory: %m\n", + CTX_ERROR(cgroup->ctx, "%s: Could not set guaranteed memory: %m\n", pakfire_cgroup_name(cgroup)); return r; @@ -799,13 +799,13 @@ int pakfire_cgroup_set_memory_limit(struct pakfire_cgroup* cgroup, size_t mem) { if (r) return r; - DEBUG(cgroup->pakfire, "%s: Setting memory limit to %zu byte(s)\n", + CTX_DEBUG(cgroup->ctx, "%s: Setting memory limit to %zu byte(s)\n", pakfire_cgroup_name(cgroup), mem); // Set value r = pakfire_cgroup_write(cgroup, "memory.max", "%zu\n", mem); if (r) - ERROR(cgroup->pakfire, "%s: Could not set memory limit: %m\n", + CTX_ERROR(cgroup->ctx, "%s: Could not set memory limit: %m\n", pakfire_cgroup_name(cgroup)); return r; @@ -821,13 +821,13 @@ int pakfire_cgroup_set_pid_limit(struct pakfire_cgroup* cgroup, size_t limit) { if (r) return r; - DEBUG(cgroup->pakfire, "%s: Setting PID limit to %zu\n", + CTX_DEBUG(cgroup->ctx, "%s: Setting PID limit to %zu\n", pakfire_cgroup_name(cgroup), limit); // Set value r = pakfire_cgroup_write(cgroup, "pids.max", "%zu\n", limit); if (r) - ERROR(cgroup->pakfire, "%s: Could not set PID limit: %m\n", + CTX_ERROR(cgroup->ctx, "%s: Could not set PID limit: %m\n", pakfire_cgroup_name(cgroup)); return r; @@ -840,7 +840,7 @@ static int __pakfire_cgroup_read_stats_line(struct pakfire_cgroup* cgroup, void* data, char* line) { char* p = NULL; - DEBUG(cgroup->pakfire, "Parsing line: %s\n", line); + CTX_DEBUG(cgroup->ctx, "Parsing line: %s\n", line); char key[NAME_MAX]; unsigned long val = 0; @@ -864,7 +864,7 @@ static int __pakfire_cgroup_read_stats_line(struct pakfire_cgroup* cgroup, // Ignore the rest default: - DEBUG(cgroup->pakfire, "%s: Unknown value in cgroup stats (%d): %s\n", + CTX_DEBUG(cgroup->ctx, "%s: Unknown value in cgroup stats (%d): %s\n", pakfire_cgroup_name(cgroup), i, elem); break; } @@ -874,7 +874,7 @@ static int __pakfire_cgroup_read_stats_line(struct pakfire_cgroup* cgroup, // Check if we parsed both fields if (i < 2) { - ERROR(cgroup->pakfire, "Could not parse line\n"); + CTX_ERROR(cgroup->ctx, "Could not parse line\n"); return 1; } @@ -890,7 +890,7 @@ static int __pakfire_cgroup_read_stats(struct pakfire_cgroup* cgroup, const char char buffer[BUFFER_SIZE]; - DEBUG(cgroup->pakfire, "%s: Reading stats from %s\n", pakfire_cgroup_name(cgroup), path); + CTX_DEBUG(cgroup->ctx, "%s: Reading stats from %s\n", pakfire_cgroup_name(cgroup), path); // Open the file r = pakfire_cgroup_read(cgroup, path, buffer, sizeof(buffer)); @@ -935,7 +935,7 @@ static int __pakfire_cgroup_parse_cpu_stats(struct pakfire_cgroup* cgroup, } } - DEBUG(cgroup->pakfire, "Unknown key for CPU stats: %s = %lu\n", key, val); + CTX_DEBUG(cgroup->ctx, "Unknown key for CPU stats: %s = %lu\n", key, val); return 0; } @@ -1001,7 +1001,7 @@ static int __pakfire_cgroup_parse_memory_stats(struct pakfire_cgroup* cgroup, } // Log any unknown keys - DEBUG(cgroup->pakfire, "Unknown key for memory stats: %s = %lu\n", key, val); + CTX_DEBUG(cgroup->ctx, "Unknown key for memory stats: %s = %lu\n", key, val); return 0; } @@ -1030,7 +1030,7 @@ int pakfire_cgroup_stat(struct pakfire_cgroup* cgroup, ERROR: if (r) - ERROR(cgroup->pakfire, "%s: Could not read cgroup stats: %m\n", + CTX_ERROR(cgroup->ctx, "%s: Could not read cgroup stats: %m\n", pakfire_cgroup_name(cgroup)); return r; @@ -1044,7 +1044,7 @@ int pakfire_cgroup_stat_dump(struct pakfire_cgroup* cgroup, return 1; } - DEBUG(cgroup->pakfire, "%s: Total CPU time usage: %lu\n", + CTX_DEBUG(cgroup->ctx, "%s: Total CPU time usage: %lu\n", pakfire_cgroup_name(cgroup), stats->cpu.usage_usec); return 0; diff --git a/src/libpakfire/include/pakfire/cgroup.h b/src/libpakfire/include/pakfire/cgroup.h index 37a4fdf67..9568fdd0a 100644 --- a/src/libpakfire/include/pakfire/cgroup.h +++ b/src/libpakfire/include/pakfire/cgroup.h @@ -23,7 +23,7 @@ #ifdef PAKFIRE_PRIVATE -#include +#include struct pakfire_cgroup; @@ -185,7 +185,7 @@ enum pakfire_cgroup_flags { }; int pakfire_cgroup_open(struct pakfire_cgroup** cgroup, - struct pakfire* pakfire, const char* path, int flags); + struct pakfire_ctx* ctx, const char* path, int flags); struct pakfire_cgroup* pakfire_cgroup_ref(struct pakfire_cgroup* cgroup); struct pakfire_cgroup* pakfire_cgroup_unref(struct pakfire_cgroup* cgroup); diff --git a/tests/libpakfire/cgroup.c b/tests/libpakfire/cgroup.c index afa211c33..f7db3e565 100644 --- a/tests/libpakfire/cgroup.c +++ b/tests/libpakfire/cgroup.c @@ -30,7 +30,7 @@ static int test_create_and_destroy(const struct test* t) { int r = EXIT_FAILURE; // Open a new cgroup - ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", 0)); + ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", 0)); // Destroy the cgroup again ASSERT_SUCCESS(pakfire_cgroup_destroy(cgroup)); @@ -57,7 +57,7 @@ static int test_stats(const struct test* t) { }; // Open the cgroup - ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", + ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", PAKFIRE_CGROUP_ENABLE_ACCOUNTING)); #if 0 @@ -101,7 +101,7 @@ FAIL: } int main(int argc, const char* argv[]) { - testsuite_add_test(test_create_and_destroy, TEST_WANTS_PAKFIRE); + testsuite_add_test(test_create_and_destroy, 0); testsuite_add_test(test_stats, TEST_WANTS_PAKFIRE); return testsuite_run(argc, argv); diff --git a/tests/libpakfire/jail.c b/tests/libpakfire/jail.c index 283d50f79..2993448ca 100644 --- a/tests/libpakfire/jail.c +++ b/tests/libpakfire/jail.c @@ -156,7 +156,7 @@ static int test_launch_into_cgroup(const struct test* t) { int r = EXIT_FAILURE; // Create a new cgroup - ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", 0)); + ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", 0)); // Create a new jail ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire)); @@ -223,7 +223,7 @@ static int test_memory_limit(const struct test* t) { // Create cgroup - ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", 0)); + ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", 0)); // Create jail ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire)); @@ -260,7 +260,7 @@ static int test_pid_limit(const struct test* t) { int r = EXIT_FAILURE; // Create cgroup - ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", 0)); + ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", 0)); // Create jail ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));