chiark / gitweb /
systemadm: split the type+status combo box into type combo & status checkbox
[elogind.git] / src / logind-session.c
index cadf93283a064c1c292bc34c737ab88c4ea116ba..b0a09e3d37ea0e3537da7902c128de129ff3c237 100644 (file)
@@ -380,13 +380,15 @@ static int session_link_x11_socket(Session *s) {
                 return -ENOENT;
         }
 
-        t = strappend(s->user->runtime_path, "/display");
+        t = strappend(s->user->runtime_path, "/X11/display");
         if (!t) {
                 log_error("Out of memory");
                 free(f);
                 return -ENOMEM;
         }
 
+        mkdir_parents(t, 0755);
+
         if (link(f, t) < 0) {
                 if (errno == EEXIST) {
                         unlink(t);
@@ -534,7 +536,8 @@ int session_start(Session *s) {
         if (r < 0)
                 return r;
 
-        log_info("New session %s of user %s.", s->id, s->user->name);
+        log_full(s->display || s->tty ? LOG_INFO : LOG_DEBUG,
+                 "New session %s of user %s.", s->id, s->user->name);
 
         /* Create cgroup */
         r = session_create_cgroup(s);
@@ -586,7 +589,7 @@ static bool session_shall_kill(Session *s) {
         return strv_contains(s->manager->kill_only_users, s->user->name);
 }
 
-static int session_kill_cgroup(Session *s) {
+static int session_terminate_cgroup(Session *s) {
         int r;
         char **k;
 
@@ -638,7 +641,7 @@ static int session_unlink_x11_socket(Session *s) {
 
         s->user->display = NULL;
 
-        t = strappend(s->user->runtime_path, "/display");
+        t = strappend(s->user->runtime_path, "/X11/display");
         if (!t) {
                 log_error("Out of memory");
                 return -ENOMEM;
@@ -656,10 +659,11 @@ int session_stop(Session *s) {
         assert(s);
 
         if (s->started)
-                log_info("Removed session %s.", s->id);
+                log_full(s->display || s->tty ? LOG_INFO : LOG_DEBUG,
+                         "Removed session %s.", s->id);
 
         /* Kill cgroup */
-        k = session_kill_cgroup(s);
+        k = session_terminate_cgroup(s);
         if (k < 0)
                 r = k;
 
@@ -884,6 +888,47 @@ void session_add_to_gc_queue(Session *s) {
         s->in_gc_queue = true;
 }
 
+int session_kill(Session *s, KillWho who, int signo) {
+        int r = 0;
+        Set *pid_set = NULL;
+
+        assert(s);
+
+        if (!s->cgroup_path)
+                return -ESRCH;
+
+        if (s->leader <= 0 && who == KILL_LEADER)
+                return -ESRCH;
+
+        if (s->leader > 0)
+                if (kill(s->leader, signo) < 0)
+                        r = -errno;
+
+        if (who == KILL_ALL) {
+                int q;
+
+                pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!pid_set)
+                        return -ENOMEM;
+
+                if (s->leader > 0) {
+                        q = set_put(pid_set, LONG_TO_PTR(s->leader));
+                        if (q < 0)
+                                r = q;
+                }
+
+                q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set);
+                if (q < 0)
+                        if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
+                                r = q;
+        }
+
+        if (pid_set)
+                set_free(pid_set);
+
+        return r;
+}
+
 static const char* const session_type_table[_SESSION_TYPE_MAX] = {
         [SESSION_TTY] = "tty",
         [SESSION_X11] = "x11",
@@ -891,3 +936,10 @@ static const char* const session_type_table[_SESSION_TYPE_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
+
+static const char* const kill_who_table[_KILL_WHO_MAX] = {
+        [KILL_LEADER] = "leader",
+        [KILL_ALL] = "all"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);