]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: add hashtable for finding session by leader PID
authorLennart Poettering <lennart@poettering.net>
Tue, 7 Aug 2018 10:08:24 +0000 (12:08 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 13 Oct 2018 10:59:29 +0000 (12:59 +0200)
This is useful later on, when we quickly want to find the session for a
leader PID.

src/login/logind-core.c
src/login/logind-dbus.c
src/login/logind-session.c
src/login/logind-session.h
src/login/logind.c
src/login/logind.h

index c0d84c05fd984251dfb83c1476df323b9461f389..f97aa9143091ae998ff6c1d493df1632807a0386 100644 (file)
@@ -339,13 +339,16 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) {
         if (!pid_is_valid(pid))
                 return -EINVAL;
 
-        r = cg_pid_get_unit(pid, &unit);
-        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->session_units, unit);
-        if (!s)
-                goto not_found;
+                s = hashmap_get(m->session_units, unit);
+                if (!s)
+                        goto not_found;
+        }
 
         if (ret)
                 *ret = s;
index b45f4088f2c0a96fa84dd1780384bec51613322e..518cc935aaa3bd72ce43da222ac8d3af761ef6ba 100644 (file)
@@ -782,9 +782,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;
index 0592c29dae7433e12013a3a3f8d42d4e593a3ef7..8c363c119797edb81c5b59a350bd6c1db52d2174 100644 (file)
@@ -120,6 +120,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);
+
         free(s->scope_job);
 
         sd_bus_message_unref(s->create_message);
@@ -148,6 +151,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;
@@ -457,8 +484,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) {
@@ -893,7 +928,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;
index fca42b2e6de03a5394835eb43e124057e9e87fbc..228359c088544370a839aa7aa18a7a2f29c7001e 100644 (file)
@@ -116,6 +116,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);
index da24b16c0f69ac1aca1e13d6b14df89c40132cfd..acb8bdca45e61b6b04abefa8d0ee55f3ae85b44d 100644 (file)
@@ -49,6 +49,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);
@@ -56,7 +57,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;
 
         r = sd_event_default(&m->event);
@@ -111,6 +112,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);
index 69de9040ad1813d1018d1ccb7fdf2d98bd7536f3..9bdfbdfeeefae7a2c21c7f61839c2a1f08dc9e70 100644 (file)
@@ -27,6 +27,7 @@ struct Manager {
         Hashmap *devices;
         Hashmap *seats;
         Hashmap *sessions;
+        Hashmap *sessions_by_leader;
         Hashmap *users;
         Hashmap *inhibitors;
         Hashmap *buttons;