]> git.ipfire.org Git - pakfire.git/commitdiff
execute: Create a new cgroup for each process launched
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Mar 2021 18:14:48 +0000 (18:14 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Mar 2021 18:14:48 +0000 (18:14 +0000)
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 <michael.tremer@ipfire.org>
src/libpakfire/execute.c

index 4bda89417f283fc1006c47d5d695f0476b9073e1..8ba178d549559f7e0840301a0312c0697d652591 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <linux/limits.h>
 #include <sched.h>
 #include <stdlib.h>
 #include <string.h>
@@ -31,6 +32,7 @@
 #include <unistd.h>
 
 #include <pakfire/arch.h>
+#include <pakfire/cgroup.h>
 #include <pakfire/execute.h>
 #include <pakfire/logging.h>
 #include <pakfire/private.h>
@@ -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]);