diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-08-07 12:08:24 +0200 |
---|---|---|
committer | Sven Eden <sven.eden@prydeworx.com> | 2018-10-29 10:18:37 +0100 |
commit | 729a2fa913640bea3376d9afc73a9b4bff371085 (patch) | |
tree | d232e32f5d9d5a7ca3b9c7b71785ffb39a1575aa | |
parent | 11fb2bd433c0f2f4aa9705a4d5327b6fab7daa07 (diff) |
logind: add hashtable for finding session by leader PID
This is useful later on, when we quickly want to find the session for a
leader PID.
(cherry picked from commit 238794b15082e6f61d0ce2943d39205289fff7f0)
-rw-r--r-- | src/login/logind-core.c | 16 | ||||
-rw-r--r-- | src/login/logind-dbus.c | 3 | ||||
-rw-r--r-- | src/login/logind-session.c | 41 | ||||
-rw-r--r-- | src/login/logind-session.h | 1 | ||||
-rw-r--r-- | src/login/logind.c | 4 | ||||
-rw-r--r-- | src/login/logind.h | 1 |
6 files changed, 53 insertions, 13 deletions
diff --git a/src/login/logind-core.c b/src/login/logind-core.c index c75c96c01..b24bc29c6 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -342,18 +342,20 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) { return -EINVAL; #if 0 /// elogind does not support systemd units, but its own session system - r = cg_pid_get_unit(pid, &unit); - if (r < 0) - goto not_found; - - s = hashmap_get(m->session_units, unit); - if (!s) - goto not_found; + s = hashmap_get(m->session_units, unit); + if (!s) + goto not_found; + } #else log_debug_elogind("Searching session for PID %u", pid); r = cg_pid_get_session(pid, &session_name); if (r < 0) goto not_found; + s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(pid)); + if (!s) { + r = cg_pid_get_unit(pid, &unit); + if (r < 0) + goto not_found; s = hashmap_get(m->sessions, session_name); log_debug_elogind("Session Name \"%s\" -> Session \"%s\"", diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 333eb5a8c..855268a63 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -784,9 +784,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus goto fail; session_set_user(session, user); + session_set_leader(session, leader); - session->leader = leader; - session->audit_id = audit_id; session->type = t; session->class = c; session->remote = remote; diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 8c478cb3e..d3bdbebb5 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -124,6 +124,9 @@ Session* session_free(Session *s) { free(s->scope); } + if (pid_is_valid(s->leader)) + (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s); + #if 0 /// elogind does not support systemd scope_jobs free(s->scope_job); #endif // 0 @@ -154,6 +157,30 @@ void session_set_user(Session *s, User *u) { user_update_last_session_timer(u); } +int session_set_leader(Session *s, pid_t pid) { + int r; + + assert(s); + + if (!pid_is_valid(pid)) + return -EINVAL; + + if (s->leader == pid) + return 0; + + r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s); + if (r < 0) + return r; + + if (pid_is_valid(s->leader)) + (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s); + + s->leader = pid; + (void) audit_session_from_pid(pid, &s->audit_id); + + return 1; +} + static void session_save_devices(Session *s, FILE *f) { SessionDevice *sd; Iterator i; @@ -467,8 +494,16 @@ int session_load(Session *s) { } if (leader) { - if (parse_pid(leader, &s->leader) >= 0) - (void) audit_session_from_pid(s->leader, &s->audit_id); + pid_t pid; + + r = parse_pid(leader, &pid); + if (r < 0) + log_debug_errno(r, "Failed to parse leader PID of session: %s", leader); + else { + r = session_set_leader(s, pid); + if (r < 0) + log_warning_errno(r, "Failed to set session leader PID, ignoring: %m"); + } } if (type) { @@ -953,7 +988,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) { /* For sessions with a leader but no explicitly configured * tty, let's check the controlling tty of the leader */ - if (s->leader > 0) { + if (pid_is_valid(s->leader)) { r = get_process_ctty_atime(s->leader, &atime); if (r >= 0) goto found_atime; diff --git a/src/login/logind-session.h b/src/login/logind-session.h index 2a082c111..74cda3c57 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -118,6 +118,7 @@ Session* session_free(Session *s); DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free); void session_set_user(Session *s, User *u); +int session_set_leader(Session *s, pid_t pid); bool session_may_gc(Session *s, bool drop_not_started); void session_add_to_gc_queue(Session *s); int session_activate(Session *s); diff --git a/src/login/logind.c b/src/login/logind.c index 7a9f5c577..5320820a5 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -61,6 +61,7 @@ static int manager_new(Manager **ret) { m->devices = hashmap_new(&string_hash_ops); m->seats = hashmap_new(&string_hash_ops); m->sessions = hashmap_new(&string_hash_ops); + m->sessions_by_leader = hashmap_new(NULL); m->users = hashmap_new(NULL); m->inhibitors = hashmap_new(&string_hash_ops); m->buttons = hashmap_new(&string_hash_ops); @@ -68,7 +69,7 @@ static int manager_new(Manager **ret) { m->user_units = hashmap_new(&string_hash_ops); m->session_units = hashmap_new(&string_hash_ops); - if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units) + if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units) return -ENOMEM; #if 1 /// elogind needs some more data @@ -132,6 +133,7 @@ static Manager* manager_unref(Manager *m) { hashmap_free(m->devices); hashmap_free(m->seats); hashmap_free(m->sessions); + hashmap_free(m->sessions_by_leader); hashmap_free(m->users); hashmap_free(m->inhibitors); hashmap_free(m->buttons); diff --git a/src/login/logind.h b/src/login/logind.h index 5b9e22b9b..111a3dab0 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -37,6 +37,7 @@ struct Manager { Hashmap *devices; Hashmap *seats; Hashmap *sessions; + Hashmap *sessions_by_leader; Hashmap *users; Hashmap *inhibitors; Hashmap *buttons; |