From: Michael Tremer Date: Sat, 27 Mar 2021 18:14:48 +0000 (+0000) Subject: execute: Create a new cgroup for each process launched X-Git-Tag: 0.9.28~1285^2~454 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95641a8e437ee6ce3e85ef9fbc8ffe8af39bf231;p=pakfire.git execute: Create a new cgroup for each process launched The cgroup will be destroyed after we are done and if the main process exits, all other processes will be killed. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/execute.c b/src/libpakfire/execute.c index 4bda89417..8ba178d54 100644 --- a/src/libpakfire/execute.c +++ b/src/libpakfire/execute.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include +#include #include #include #include @@ -47,6 +49,8 @@ struct pakfire_execute { const char** argv; char** envp; + char cgroup[PATH_MAX]; + // File descriptors int stdout[2]; int stderr[2]; @@ -330,6 +334,9 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en .envp = envp, }; + // Make cgroup name + snprintf(env.cgroup, sizeof(env.cgroup) - 1, "%s", "pakfire/execute-XXXXXX"); + // Allocate stack char stack[4096]; @@ -344,7 +351,8 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en logging_callback = &default_logging_callback; // Configure the new namespace - int cflags = CLONE_VFORK | SIGCHLD | CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWUTS; + int cflags = CLONE_VFORK | SIGCHLD | CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWUTS + | CLONE_NEWCGROUP; // Enable network? if (!(flags & PAKFIRE_EXECUTE_ENABLE_NETWORK)) @@ -367,6 +375,11 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en } } + // Create cgroup + int r = pakfire_cgroup_create(pakfire, env.cgroup); + if (r) + goto ERROR; + // Fork this process pid_t pid = clone(pakfire_execute_fork, stack + sizeof(stack), cflags, &env); if (pid < 0) { @@ -374,8 +387,13 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en return -errno; } + // Attach the process to the cgroup + r = pakfire_cgroup_attach(pakfire, env.cgroup, pid); + if (r) + goto ERROR; + // Set some useful error code - int r = -ESRCH; + int exit = -ESRCH; int status = 0; DEBUG(pakfire, "Waiting for PID %d to finish its work\n", pid); @@ -396,13 +414,25 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en waitpid(pid, &status, 0); if (WIFEXITED(status)) { - r = WEXITSTATUS(status); + exit = WEXITSTATUS(status); DEBUG(pakfire, "Child process exited with code: %d\n", r); } else { ERROR(pakfire, "Could not determine the exit status of process %d\n", pid); } + // Kill any remaining processes in this cgroup + r = pakfire_cgroup_killall(pakfire, env.cgroup); + if (r) + goto ERROR; + + // Return the exit code of the application + r = exit; + +ERROR: + // Destroy the cgroup + pakfire_cgroup_destroy(pakfire, env.cgroup); + // Close any file descriptors if (env.stdout[0]) close(env.stdout[0]);