]> git.ipfire.org Git - pakfire.git/commitdiff
execute: Fork new processes straight into their cgroup
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 29 Mar 2021 23:14:20 +0000 (23:14 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 29 Mar 2021 23:14:20 +0000 (23:14 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/cgroup.c
src/libpakfire/execute.c
src/libpakfire/include/pakfire/cgroup.h

index 6a16e2a9ed3d086495c2b23f286a57d11e158d84..d68f58827201d4e64053f3eb611d692ad2c3b2bd 100644 (file)
@@ -18,6 +18,7 @@
 #                                                                             #
 #############################################################################*/
 
+#include <dirent.h>
 #include <errno.h>
 #include <linux/limits.h>
 #include <linux/magic.h>
@@ -290,6 +291,16 @@ int pakfire_cgroup_destroy(Pakfire pakfire, const char* group) {
        return 0;
 }
 
+DIR* pakfire_cgroup_opendir(Pakfire pakfire, const char* group) {
+       // Make path
+       char path[PATH_MAX];
+       int r = pakfire_cgroup_make_path(pakfire, path, sizeof(path) - 1, group, NULL);
+       if (r < 0)
+               return NULL;
+
+       return opendir(path);
+}
+
 int pakfire_cgroup_attach(Pakfire pakfire, const char* group, pid_t pid) {
        int r = pakfire_cgroup_fprintf(pakfire, group, "cgroup.procs", "%d", pid);
        if (r < 0) {
@@ -434,8 +445,6 @@ int pakfire_cgroup_cpustat(Pakfire pakfire, const char* group,
                if (bytes_read < 0)
                        break;
 
-               printf("%s", line);
-
                for (const struct keyword* keyword = keywords; keyword->keyword; keyword++) {
                        if (pakfire_string_startswith(line, keyword->keyword)) {
                                const char* p = line + strlen(keyword->keyword) + 1;
index 078b20387eda331aa41921c07d9a6b2041925223..c2db04aeaf18e6022fa73afe5580e9949767ad46 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <linux/limits.h>
+#include <linux/sched.h>
 #include <sched.h>
 #include <stdlib.h>
 #include <string.h>
@@ -65,20 +67,6 @@ struct pakfire_execute_buffer {
 #define __NR_clone3 435
 #endif
 
-struct clone_args {
-       uint64_t flags;
-       uint64_t pidfd;
-       uint64_t child_tid;
-       uint64_t parent_tid;
-       uint64_t exit_signal;
-       uint64_t stack;
-       uint64_t stack_size;
-       uint64_t tls;
-       uint64_t set_tid;
-       uint64_t set_tid_size;
-       uint64_t cgroup;
-};
-
 static int pakfire_execute_buffer_is_full(const struct pakfire_execute_buffer* buffer) {
        return (sizeof(buffer->data) == buffer->used);
 }
@@ -346,6 +334,8 @@ static int pakfire_execute_fork(void* data) {
 
 PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* envp[],
                int flags, pakfire_execute_logging_callback logging_callback, void* data) {
+       DIR* cgroupdir = NULL;
+
        struct pakfire_execute env = {
                .pakfire = pakfire,
                .argv = argv,
@@ -402,6 +392,16 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en
        if (r)
                goto ERROR;
 
+       // Launch the new process straight into their cgroup
+       cgroupdir = pakfire_cgroup_opendir(pakfire, env.cgroup);
+       if (!cgroupdir) {
+               ERROR(pakfire, "Could not open cgroup %s: %s\n", env.cgroup, strerror(errno));
+               goto ERROR;
+       }
+
+       args.flags |= CLONE_INTO_CGROUP;
+       args.cgroup = dirfd(cgroupdir);
+
        // Fork this process
        pid_t pid = syscall(__NR_clone3, &args, sizeof(args));
        if (pid < 0) {
@@ -414,11 +414,6 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en
                exit(r);
        }
 
-       // Attach the process to the cgroup
-       r = pakfire_cgroup_attach(pakfire, env.cgroup, pid);
-       if (r)
-               goto ERROR;
-
        // Set some useful error code
        int exit = -ESRCH;
        int status = 0;
@@ -457,6 +452,10 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en
        r = exit;
 
 ERROR:
+       // Close the cgroup
+       if (cgroupdir)
+               closedir(cgroupdir);
+
        // Destroy the cgroup
        pakfire_cgroup_destroy(pakfire, env.cgroup);
 
index cdbeb047c0e10334a024ec1b2a82e985ea035c05..b86150706e655f8d851bbaf116c74eba9dbbb18c 100644 (file)
@@ -23,6 +23,7 @@
 
 #ifdef PAKFIRE_PRIVATE
 
+#include <dirent.h>
 #include <sys/types.h>
 #include <time.h>
 
@@ -31,6 +32,8 @@
 int pakfire_cgroup_create(Pakfire pakfire, const char* group);
 int pakfire_cgroup_destroy(Pakfire pakfire, const char* group);
 
+DIR* pakfire_cgroup_opendir(Pakfire pakfire, const char* group);
+
 int pakfire_cgroup_attach(Pakfire pakfire, const char* group, pid_t pid);
 int pakfire_cgroup_detach(Pakfire pakfire, const char* group, pid_t pid);