chiark / gitweb /
systemd: unset HOME and TERM set from the kernel
[elogind.git] / src / cgroup-util.c
index 828b30414a67a004eaf83243ea286b5daf462ac5..2167cdd6d052c2a8954747b6572f2d2e0793b095 100644 (file)
@@ -1,4 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
 /***
   This file is part of systemd.
@@ -25,6 +25,8 @@
 #include <string.h>
 #include <stdlib.h>
 #include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include "cgroup-util.h"
 #include "log.h"
@@ -164,12 +166,12 @@ int cg_rmdir(const char *controller, const char *path) {
         return r < 0 ? -errno : 0;
 }
 
-int cg_kill(const char *controller, const char *path, int sig, bool ignore_self) {
+int cg_kill(const char *controller, const char *path, int sig, bool ignore_self, Set *s) {
         bool done = false;
-        Set *s;
         int r, ret = 0;
         pid_t my_pid;
         FILE *f = NULL;
+        Set *allocated_set = NULL;
 
         assert(controller);
         assert(path);
@@ -179,8 +181,9 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self)
          * is repeated until no further processes are added to the
          * tasks list, to properly handle forking processes */
 
-        if (!(s = set_new(trivial_hash_func, trivial_compare_func)))
-                return -ENOMEM;
+        if (!s)
+                if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+                        return -ENOMEM;
 
         my_pid = getpid();
 
@@ -238,7 +241,8 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self)
         } while (!done);
 
 finish:
-        set_free(s);
+        if (allocated_set)
+                set_free(allocated_set);
 
         if (f)
                 fclose(f);
@@ -246,16 +250,21 @@ finish:
         return ret;
 }
 
-int cg_kill_recursive(const char *controller, const char *path, int sig, bool ignore_self, bool rem) {
+int cg_kill_recursive(const char *controller, const char *path, int sig, bool ignore_self, bool rem, Set *s) {
         int r, ret = 0;
         DIR *d = NULL;
         char *fn;
+        Set *allocated_set = NULL;
 
         assert(path);
         assert(controller);
         assert(sig >= 0);
 
-        ret = cg_kill(controller, path, sig, ignore_self);
+        if (!s)
+                if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+                        return -ENOMEM;
+
+        ret = cg_kill(controller, path, sig, ignore_self, s);
 
         if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) {
                 if (ret >= 0 && r != -ENOENT)
@@ -277,7 +286,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool ig
                         goto finish;
                 }
 
-                r = cg_kill_recursive(controller, p, sig, ignore_self, rem);
+                r = cg_kill_recursive(controller, p, sig, ignore_self, rem, s);
                 free(p);
 
                 if (r != 0 && ret >= 0)
@@ -297,6 +306,9 @@ finish:
         if (d)
                 closedir(d);
 
+        if (allocated_set)
+                set_free(allocated_set);
+
         return ret;
 }
 
@@ -321,7 +333,7 @@ int cg_kill_recursive_and_wait(const char *controller, const char *path, bool re
                 else
                         sig = 0;
 
-                if ((r = cg_kill_recursive(controller, path, sig, true, rem)) <= 0)
+                if ((r = cg_kill_recursive(controller, path, sig, true, rem, NULL)) <= 0)
                         return r;
 
                 usleep(50 * USEC_PER_MSEC);
@@ -479,7 +491,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
         else
                 p = controller;
 
-        if (asprintf(&mp, "/cgroup/%s", p) < 0)
+        if (asprintf(&mp, "/sys/fs/cgroup/%s", p) < 0)
                 return -ENOMEM;
 
         if ((r = path_is_mount_point(mp)) <= 0) {
@@ -546,7 +558,17 @@ int cg_create(const char *controller, const char *path) {
         if ((r = cg_get_path(controller, path, NULL, &fs)) < 0)
                 return r;
 
-        r = mkdir_p(fs, 0755);
+        r = mkdir_parents(fs, 0755);
+
+        if (r >= 0) {
+                if (mkdir(fs, 0755) >= 0)
+                        r = 1;
+                else if (errno == EEXIST)
+                        r = 0;
+                else
+                        r = -errno;
+        }
+
         free(fs);
 
         return r;
@@ -577,7 +599,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
 }
 
 int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
-        int r;
+        int r, q;
 
         assert(controller);
         assert(path);
@@ -586,8 +608,8 @@ int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
         if ((r = cg_create(controller, path)) < 0)
                 return r;
 
-        if ((r = cg_attach(controller, path, pid)) < 0)
-                return r;
+        if ((q = cg_attach(controller, path, pid)) < 0)
+                return q;
 
         /* This does not remove the cgroup on failure */
 
@@ -725,10 +747,8 @@ int cg_install_release_agent(const char *controller, const char *agent) {
 
         free(fs);
         fs = NULL;
-        if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0) {
-                r = -ENOMEM;
+        if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0)
                 goto finish;
-        }
 
         free(contents);
         contents = NULL;
@@ -917,7 +937,7 @@ int cg_fix_path(const char *path, char **result) {
 
         /* First check if it already is a filesystem path */
         if (path_is_absolute(path) &&
-            path_startswith(path, "/cgroup") &&
+            path_startswith(path, "/sys/fs/cgroup") &&
             access(path, F_OK) >= 0) {
 
                 if (!(t = strdup(path)))