X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogind-session.c;h=e71ff4f14e9aaca2ca5965653e4912ca4d8cb2ad;hb=a91e4e5337a46db3f0a4f1415c1b60285e5c33a3;hp=42d28016da6e0207bf790dd7ed4647d4ad9fc06a;hpb=98a28fef2618e54a644614c759f371f297381b70;p=elogind.git diff --git a/src/logind-session.c b/src/logind-session.c index 42d28016d..e71ff4f14 100644 --- a/src/logind-session.c +++ b/src/logind-session.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "logind-session.h" #include "strv.h" @@ -83,6 +84,9 @@ void session_free(Session *s) { LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s); } + if (s->cgroup_path) + hashmap_remove(s->manager->cgroups, s->cgroup_path); + free(s->cgroup_path); strv_free(s->controllers); @@ -94,8 +98,7 @@ void session_free(Session *s) { hashmap_remove(s->manager->sessions, s->id); - if (s->pipe_fd >= 0) - close_nointr_nofail(s->pipe_fd); + session_unset_pipe_fd(s); free(s->state_file); free(s); @@ -133,6 +136,11 @@ int session_save(Session *s) { s->remote, s->kill_processes); + if (s->type >= 0) + fprintf(f, + "TYPE=%s\n", + session_type_to_string(s->type)); + if (s->cgroup_path) fprintf(f, "CGROUP=%s\n", @@ -207,7 +215,8 @@ int session_load(Session *s) { *seat = NULL, *vtnr = NULL, *leader = NULL, - *audit_id = NULL; + *audit_id = NULL, + *type = NULL; int k, r; @@ -225,6 +234,7 @@ int session_load(Session *s) { "SERVICE", &s->service, "VTNR", &vtnr, "LEADER", &leader, + "TYPE", &type, NULL); if (r < 0) @@ -269,6 +279,14 @@ int session_load(Session *s) { } } + if (type) { + SessionType t; + + t = session_type_from_string(type); + if (t >= 0) + s->type = t; + } + finish: free(remote); free(kill_processes); @@ -468,6 +486,8 @@ static int session_create_cgroup(Session *s) { } } + hashmap_put(s->manager->cgroups, s->cgroup_path, s); + return 0; } @@ -480,6 +500,10 @@ int session_start(Session *s) { if (s->started) return 0; + r = user_start(s->user); + if (r < 0) + return r; + log_info("New session %s of user %s.", s->id, s->user->name); /* Create cgroup */ @@ -514,7 +538,16 @@ int session_start(Session *s) { static bool session_shall_kill(Session *s) { assert(s); - return s->kill_processes; + if (!s->kill_processes) + return false; + + if (strv_contains(s->manager->kill_exclude_users, s->user->name)) + return false; + + if (strv_isempty(s->manager->kill_only_users)) + return true; + + return strv_contains(s->manager->kill_only_users, s->user->name); } static int session_kill_cgroup(Session *s) { @@ -549,6 +582,8 @@ static int session_kill_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); + free(s->cgroup_path); s->cgroup_path = NULL; @@ -584,10 +619,8 @@ int session_stop(Session *s) { assert(s); - if (!s->started) - return 0; - - log_info("Removed session %s.", s->id); + if (s->started) + log_info("Removed session %s.", s->id); /* Kill cgroup */ k = session_kill_cgroup(s); @@ -599,8 +632,10 @@ int session_stop(Session *s) { unlink(s->state_file); session_add_to_gc_queue(s); + user_add_to_gc_queue(s->user); - session_send_signal(s, false); + if (s->started) + session_send_signal(s, false); if (s->seat) { if (s->seat->active == s) @@ -709,6 +744,45 @@ void session_set_idle_hint(Session *s, bool b) { "IdleSinceHintMonotonic\0"); } +int session_set_pipe_fd(Session *s, int fd) { + struct epoll_event ev; + int r; + + assert(s); + assert(fd >= 0); + assert(s->pipe_fd < 0); + + r = hashmap_put(s->manager->pipe_fds, INT_TO_PTR(fd + 1), s); + if (r < 0) + return r; + + zero(ev); + ev.events = 0; + ev.data.u32 = FD_PIPE_BASE + fd; + + if (epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + assert_se(hashmap_remove(s->manager->pipe_fds, INT_TO_PTR(fd + 1)) == s); + return -errno; + } + + s->pipe_fd = fd; + return 0; +} + +void session_unset_pipe_fd(Session *s) { + assert(s); + + if (s->pipe_fd < 0) + return; + + assert_se(hashmap_remove(s->manager->pipe_fds, INT_TO_PTR(s->pipe_fd + 1)) == s); + + assert_se(epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_DEL, s->pipe_fd, NULL) == 0); + + close_nointr_nofail(s->pipe_fd); + s->pipe_fd = -1; +} + int session_check_gc(Session *s) { int r; @@ -750,7 +824,7 @@ void session_add_to_gc_queue(Session *s) { static const char* const session_type_table[_SESSION_TYPE_MAX] = { [SESSION_TTY] = "tty", [SESSION_X11] = "x11", - [SESSION_OTHER] = "other" + [SESSION_UNSPECIFIED] = "unspecified" }; DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);