X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind-session.c;h=16d4955d5d94bc1f69151140ad689026149ec12b;hb=0d0f0c50d3a1d90f03972a6abb82e6413daaa583;hp=4e0af8656b6a570d95c0fcee501945409a1ecb13;hpb=c9d8629baa09f853fbcc44972c9748e70562270c;p=elogind.git diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 4e0af8656..16d4955d5 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -6,16 +6,16 @@ Copyright 2011 Lennart Poettering systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. systemd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ @@ -25,10 +25,12 @@ #include #include -#include "logind-session.h" #include "strv.h" #include "util.h" +#include "mkdir.h" +#include "path-util.h" #include "cgroup-util.h" +#include "logind-session.h" #define IDLE_THRESHOLD_USEC (5*USEC_PER_MINUTE) @@ -48,10 +50,10 @@ Session* session_new(Manager *m, User *u, const char *id) { return NULL; } - s->id = file_name_from_path(s->state_file); + s->id = path_get_file_name(s->state_file); if (hashmap_put(m->sessions, s->id, s) < 0) { - free(s->id); + free(s->state_file); free(s); return NULL; } @@ -86,7 +88,7 @@ void session_free(Session *s) { } if (s->cgroup_path) - hashmap_remove(s->manager->cgroups, s->cgroup_path); + hashmap_remove(s->manager->session_cgroups, s->cgroup_path); free(s->cgroup_path); strv_free(s->controllers); @@ -98,7 +100,6 @@ void session_free(Session *s) { free(s->service); hashmap_remove(s->manager->sessions, s->id); - session_remove_fifo(s); free(s->state_file); @@ -115,7 +116,7 @@ int session_save(Session *s) { if (!s->started) return 0; - r = safe_mkdir("/run/systemd/sessions", 0755, 0, 0); + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0); if (r < 0) goto finish; @@ -132,11 +133,13 @@ int session_save(Session *s) { "UID=%lu\n" "USER=%s\n" "ACTIVE=%i\n" + "STATE=%s\n" "REMOTE=%i\n" "KILL_PROCESSES=%i\n", (unsigned long) s->user->uid, s->user->name, session_is_active(s), + session_state_to_string(session_get_state(s)), s->remote, s->kill_processes); @@ -286,14 +289,9 @@ int session_load(Session *s) { } if (leader) { - pid_t pid; - - k = parse_pid(leader, &pid); - if (k >= 0 && pid >= 1) { - s->leader = pid; - - audit_session_from_pid(pid, &s->audit_id); - } + k = parse_pid(leader, &s->leader); + if (k >= 0) + audit_session_from_pid(s->leader, &s->audit_id); } if (type) { @@ -325,7 +323,6 @@ int session_load(Session *s) { close_nointr_nofail(fd); } - finish: free(remote); free(kill_processes); @@ -333,6 +330,7 @@ finish: free(vtnr); free(leader); free(audit_id); + free(class); return r; } @@ -376,17 +374,15 @@ static int session_link_x11_socket(Session *s) { k = strspn(s->display+1, "0123456789"); f = new(char, sizeof("/tmp/.X11-unix/X") + k); - if (!f) { - log_error("Out of memory"); - return -ENOMEM; - } + if (!f) + return log_oom(); c = stpcpy(f, "/tmp/.X11-unix/X"); memcpy(c, s->display+1, k); c[k] = 0; if (access(f, F_OK) < 0) { - log_warning("Session %s has display %s with nonexisting socket %s.", s->id, s->display, f); + log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f); free(f); return -ENOENT; } @@ -397,9 +393,8 @@ static int session_link_x11_socket(Session *s) { t = strappend(s->user->runtime_path, "/X11-display"); if (!t) { - log_error("Out of memory"); free(f); - return -ENOMEM; + return log_oom(); } if (link(f, t) < 0) { @@ -470,10 +465,8 @@ static int session_create_cgroup(Session *s) { assert(s->user->cgroup_path); if (!s->cgroup_path) { - if (asprintf(&p, "%s/%s", s->user->cgroup_path, s->id) < 0) { - log_error("Out of memory"); - return -ENOMEM; - } + if (asprintf(&p, "%s/%s", s->user->cgroup_path, s->id) < 0) + return log_oom(); } else p = s->cgroup_path; @@ -531,7 +524,7 @@ static int session_create_cgroup(Session *s) { } } - hashmap_put(s->manager->cgroups, s->cgroup_path, s); + hashmap_put(s->manager->session_cgroups, s->cgroup_path, s); return 0; } @@ -650,7 +643,7 @@ static int session_terminate_cgroup(Session *s) { STRV_FOREACH(k, s->user->manager->controllers) cg_trim(*k, s->cgroup_path, true); - hashmap_remove(s->manager->cgroups, s->cgroup_path); + hashmap_remove(s->manager->session_cgroups, s->cgroup_path); free(s->cgroup_path); s->cgroup_path = NULL; @@ -671,10 +664,8 @@ static int session_unlink_x11_socket(Session *s) { s->user->display = NULL; t = strappend(s->user->runtime_path, "/X11-display"); - if (!t) { - log_error("Out of memory"); - return -ENOMEM; - } + if (!t) + return log_oom(); r = unlink(t); free(t); @@ -771,7 +762,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) { b = u + IDLE_THRESHOLD_USEC < n; if (t) - dual_timestamp_from_realtime(t, u + b ? IDLE_THRESHOLD_USEC : 0); + dual_timestamp_from_realtime(t, u + b*IDLE_THRESHOLD_USEC); return b; @@ -820,7 +811,7 @@ int session_create_fifo(Session *s) { /* Create FIFO */ if (!s->fifo_path) { - r = safe_mkdir("/run/systemd/sessions", 0755, 0, 0); + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0); if (r < 0) return r; @@ -839,13 +830,13 @@ int session_create_fifo(Session *s) { if (s->fifo_fd < 0) return -errno; - r = hashmap_put(s->manager->fifo_fds, INT_TO_PTR(s->fifo_fd + 1), s); + r = hashmap_put(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1), s); if (r < 0) return r; zero(ev); ev.events = 0; - ev.data.u32 = FD_FIFO_BASE + s->fifo_fd; + ev.data.u32 = FD_OTHER_BASE + s->fifo_fd; if (epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_ADD, s->fifo_fd, &ev) < 0) return -errno; @@ -863,7 +854,7 @@ void session_remove_fifo(Session *s) { assert(s); if (s->fifo_fd >= 0) { - assert_se(hashmap_remove(s->manager->fifo_fds, INT_TO_PTR(s->fifo_fd + 1)) == s); + assert_se(hashmap_remove(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1)) == s); assert_se(epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_DEL, s->fifo_fd, NULL) == 0); close_nointr_nofail(s->fifo_fd); s->fifo_fd = -1; @@ -917,6 +908,18 @@ void session_add_to_gc_queue(Session *s) { s->in_gc_queue = true; } +SessionState session_get_state(Session *s) { + assert(s); + + if (s->fifo_fd < 0) + return SESSION_CLOSING; + + if (session_is_active(s)) + return SESSION_ACTIVE; + + return SESSION_ONLINE; +} + int session_kill(Session *s, KillWho who, int signo) { int r = 0; Set *pid_set = NULL; @@ -958,6 +961,14 @@ int session_kill(Session *s, KillWho who, int signo) { return r; } +static const char* const session_state_table[_SESSION_TYPE_MAX] = { + [SESSION_ONLINE] = "online", + [SESSION_ACTIVE] = "active", + [SESSION_CLOSING] = "closing" +}; + +DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState); + static const char* const session_type_table[_SESSION_TYPE_MAX] = { [SESSION_TTY] = "tty", [SESSION_X11] = "x11",