chiark / gitweb /
logind: add infrastructure to keep track of machines, and move to slices
[elogind.git] / src / login / user-sessions.c
index 91531e8f380048c117156d1f2a59947e5c9c089a..18066ccc39f1c05e2a0498212aec2f73e5e5ec25 100644 (file)
 #include "log.h"
 #include "util.h"
 #include "cgroup-util.h"
+#include "fileio.h"
+
+static int kill_all_users(void) {
+        _cleanup_closedir_ DIR *d = NULL;
+        struct dirent *de;
+        int r = 0;
+
+        d = opendir("/run/systemd/users");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /run/systemd/users: %m");
+                return -errno;
+        }
+
+        FOREACH_DIRENT(de, d, return -errno) {
+                _cleanup_free_ char *cgroup = NULL;
+                char *a;
+                int k;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                a = strappenda("/run/systemd/users/", de->d_name);
+
+                k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL);
+                if (k < 0) {
+                        if (k != -ENOENT) {
+                                log_error("Failed to read user data: %s", strerror(-k));
+                                r = k;
+                        }
+
+                        continue;
+                }
+
+                if (!cgroup) {
+                        log_error("User data did not contain cgroup field.");
+                        r = -ENOENT;
+                        continue;
+                }
+
+                k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true);
+                if (k < 0) {
+                        log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k));
+                        r = k;
+                }
+        }
+
+        return r;
+}
+
+static int kill_all_sessions(void) {
+        _cleanup_closedir_ DIR *d = NULL;
+        struct dirent *de;
+        int r = 0;
+
+        d = opendir("/run/systemd/sessions");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Failed to open /run/systemd/sessions: %m");
+                return -errno;
+        }
+
+        FOREACH_DIRENT(de, d, return -errno) {
+                _cleanup_free_ char *cgroup = NULL;
+                char *a;
+                int k;
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                a = strappenda("/run/systemd/sessions/", de->d_name);
+
+                k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL);
+                if (k < 0) {
+                        if (k != -ENOENT) {
+                                log_error("Failed to read session data: %s", strerror(-k));
+                                r = k;
+                        }
+
+                        continue;
+                }
+
+                if (!cgroup) {
+                        log_error("Session data did not contain cgroup field.");
+                        r = -ENOENT;
+                        continue;
+                }
+
+                k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true);
+                if (k < 0) {
+                        log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k));
+                        r = k;
+                }
+        }
+
+        return r;
+}
 
 int main(int argc, char*argv[]) {
         int ret = EXIT_FAILURE;
@@ -67,27 +168,18 @@ int main(int argc, char*argv[]) {
 
         } else if (streq(argv[1], "stop")) {
                 int r, q;
-                char *cgroup_user_tree = NULL;
 
-                r = write_one_line_file_atomic("/run/nologin", "System is going down.");
+                r = write_string_file_atomic("/run/nologin", "System is going down.");
                 if (r < 0)
                         log_error("Failed to create /run/nologin: %s", strerror(-r));
 
-                q = cg_get_user_path(&cgroup_user_tree);
-                if (q < 0) {
-                        log_error("Failed to determine use path: %s", strerror(-q));
-                        goto finish;
-                }
-
-                q = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup_user_tree, true);
-                free(cgroup_user_tree);
-                if (q < 0) {
-                        log_error("Failed to kill sessions: %s", strerror(-q));
-                        goto finish;
-                }
+                q = kill_all_users();
+                if (q < 0 && r >= 0)
+                        r = q;
 
-                if (r < 0)
-                        goto finish;
+                q = kill_all_sessions();
+                if (q < 0 && r >= 0)
+                        r = q;
 
         } else {
                 log_error("Unknown verb %s.", argv[1]);