]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: switch sessions_by_leader to PidRef 29976/head
authorMike Yuan <me@yhndnzj.com>
Thu, 9 Nov 2023 16:51:52 +0000 (00:51 +0800)
committerMike Yuan <me@yhndnzj.com>
Sat, 11 Nov 2023 14:31:00 +0000 (22:31 +0800)
src/login/logind-core.c
src/login/logind-dbus.c
src/login/logind-inhibit.c
src/login/logind-session.c
src/login/logind.c
src/login/logind.h

index e7f1d6c8e4eac98f918b37d52e4ed173f49c2a82..f15008e0df2e116095b927c1a547490353eb2060 100644 (file)
@@ -349,21 +349,27 @@ int manager_process_button_device(Manager *m, sd_device *d) {
         return 0;
 }
 
-int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) {
+int manager_get_session_by_pidref(Manager *m, const PidRef *pid, Session **ret) {
         _cleanup_free_ char *unit = NULL;
         Session *s;
         int r;
 
         assert(m);
 
-        if (!pid_is_valid(pid))
+        if (!pidref_is_set(pid))
                 return -EINVAL;
 
-        s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(pid));
-        if (!s) {
-                r = cg_pid_get_unit(pid, &unit);
-                if (r >= 0)
-                        s = hashmap_get(m->session_units, unit);
+        s = hashmap_get(m->sessions_by_leader, pid);
+        if (s) {
+                r = pidref_verify(pid);
+                if (r < 0)
+                        return r;
+        } else {
+                r = cg_pidref_get_unit(pid, &unit);
+                if (r < 0)
+                        return r;
+
+                s = hashmap_get(m->session_units, unit);
         }
 
         if (ret)
@@ -734,8 +740,7 @@ int manager_read_utmp(Manager *m) {
                 if (isempty(t))
                         continue;
 
-                s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(u->ut_pid));
-                if (!s)
+                if (manager_get_session_by_pidref(m, &PIDREF_MAKE_FROM_PID(u->ut_pid), &s) <= 0)
                         continue;
 
                 if (s->tty_validity == TTY_FROM_UTMP && !streq_ptr(s->tty, t)) {
index dc06d67fef741963d1ff54d7e0ffd9972eb5e74d..6ad6ef912db8facc6d4f840ea246fb9a8e6b1268 100644 (file)
@@ -405,9 +405,9 @@ static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_er
  * as apps may instead belong to a user service unit.  This includes terminal
  * emulators and hence command-line apps. */
 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Manager *m = ASSERT_PTR(userdata);
         _cleanup_free_ char *p = NULL;
         Session *session = NULL;
-        Manager *m = ASSERT_PTR(userdata);
         pid_t pid;
         int r;
 
@@ -426,7 +426,7 @@ static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd
                 if (r < 0)
                         return r;
         } else {
-                r = manager_get_session_by_pid(m, pid, &session);
+                r = manager_get_session_by_pidref(m, &PIDREF_MAKE_FROM_PID(pid), &session);
                 if (r < 0)
                         return r;
 
index 81a791cfbb95b963afa04c91a22084a1cbbae582..62c38f2f1233af38cd7d0c056db9663758242dad 100644 (file)
@@ -376,18 +376,20 @@ InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
         return what;
 }
 
-static int pid_is_active(Manager *m, pid_t pid) {
+static int pidref_is_active_session(Manager *m, const PidRef *pid) {
         Session *s;
         int r;
 
-        /* Get client session.  This is not what you are looking for these days.
+        assert(m);
+        assert(pid);
+
+        /* Get client session. This is not what you are looking for these days.
          * FIXME #6852 */
-        r = manager_get_session_by_pid(m, pid, &s);
+        r = manager_get_session_by_pidref(m, pid, &s);
         if (r < 0)
                 return r;
 
-        /* If there's no session assigned to it, then it's globally
-         * active on all ttys */
+        /* If there's no session assigned to it, then it's globally active on all ttys */
         if (r == 0)
                 return 1;
 
@@ -421,7 +423,7 @@ bool manager_is_inhibited(
                 if (i->mode != mm)
                         continue;
 
-                if (ignore_inactive && pid_is_active(m, i->pid.pid) <= 0)
+                if (ignore_inactive && pidref_is_active_session(m, &i->pid) <= 0)
                         continue;
 
                 if (ignore_uid && i->uid == uid)
index 8c8c5da6fb909edadc9a06ab24191238a00b5a7e..fa62c60a9f29bb0d775c075842a89ad681381b8b 100644 (file)
@@ -87,6 +87,17 @@ int session_new(Session **ret, Manager *m, const char *id) {
         return 0;
 }
 
+static void session_reset_leader(Session *s) {
+        assert(s);
+
+        if (!pidref_is_set(&s->leader))
+                return;
+
+        assert_se(hashmap_remove_value(s->manager->sessions_by_leader, &s->leader, s));
+
+        return pidref_done(&s->leader);
+}
+
 Session* session_free(Session *s) {
         SessionDevice *sd;
 
@@ -129,13 +140,10 @@ Session* session_free(Session *s) {
                 free(s->scope);
         }
 
-        if (pidref_is_set(&s->leader)) {
-                (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader.pid), s);
-                pidref_done(&s->leader);
-        }
-
         free(s->scope_job);
 
+        session_reset_leader(s);
+
         sd_bus_message_unref(s->create_message);
 
         free(s->tty);
@@ -180,16 +188,15 @@ int session_set_leader_consume(Session *s, PidRef _leader) {
         if (pidref_equal(&s->leader, &pidref))
                 return 0;
 
-        r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pidref.pid), s);
+        session_reset_leader(s);
+
+        s->leader = TAKE_PIDREF(pidref);
+
+        r = hashmap_ensure_put(&s->manager->sessions_by_leader, &pidref_hash_ops, &s->leader, s);
         if (r < 0)
                 return r;
+        assert(r > 0);
 
-        if (pidref_is_set(&s->leader)) {
-                (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader.pid), s);
-                pidref_done(&s->leader);
-        }
-
-        s->leader = TAKE_PIDREF(pidref);
         (void) audit_session_from_pid(s->leader.pid, &s->audit_id);
 
         return 1;
@@ -941,7 +948,7 @@ int session_finalize(Session *s) {
                 seat_save(s->seat);
         }
 
-        pidref_done(&s->leader);
+        session_reset_leader(s);
 
         user_save(s->user);
         user_send_changed(s->user, "Display", NULL);
index 0e85bffe2bd9f38d1f6ccd5973a03464a9d4d181..88e05bb769c0c44f618ab6660aff6b75403d5786 100644 (file)
@@ -70,7 +70,6 @@ static int manager_new(Manager **ret) {
         m->devices = hashmap_new(&device_hash_ops);
         m->seats = hashmap_new(&seat_hash_ops);
         m->sessions = hashmap_new(&session_hash_ops);
-        m->sessions_by_leader = hashmap_new(NULL);
         m->users = hashmap_new(&user_hash_ops);
         m->inhibitors = hashmap_new(&inhibitor_hash_ops);
         m->buttons = hashmap_new(&button_hash_ops);
@@ -78,7 +77,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->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
+        if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
                 return -ENOMEM;
 
         r = sd_event_default(&m->event);
@@ -116,7 +115,11 @@ static Manager* manager_free(Manager *m) {
         hashmap_free(m->devices);
         hashmap_free(m->seats);
         hashmap_free(m->sessions);
+
+        /* All records should have been removed by session_free */
+        assert(hashmap_isempty(m->sessions_by_leader));
         hashmap_free(m->sessions_by_leader);
+
         hashmap_free(m->users);
         hashmap_free(m->inhibitors);
         hashmap_free(m->buttons);
index e6a04e0834150006f9dde5eb0c0aa5e539559928..7532d379c01cb615305b9749a2afdc59709b5b63 100644 (file)
@@ -163,7 +163,7 @@ bool manager_shall_kill(Manager *m, const char *user);
 int manager_get_idle_hint(Manager *m, dual_timestamp *t);
 
 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user);
-int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
+int manager_get_session_by_pidref(Manager *m, const PidRef *pid, Session **ret);
 
 bool manager_is_lid_closed(Manager *m);
 bool manager_is_docked_or_external_displays(Manager *m);