summaryrefslogtreecommitdiff
path: root/src/login/user-sessions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/login/user-sessions.c')
-rw-r--r--src/login/user-sessions.c121
1 files changed, 106 insertions, 15 deletions
diff --git a/src/login/user-sessions.c b/src/login/user-sessions.c
index 41d32044e9..18066ccc39 100644
--- a/src/login/user-sessions.c
+++ b/src/login/user-sessions.c
@@ -28,6 +28,106 @@
#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;
@@ -68,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_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]);