]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: also port session leader tracking over to PidRef
authorLennart Poettering <lennart@poettering.net>
Sat, 9 Sep 2023 10:35:07 +0000 (12:35 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 9 Sep 2023 12:10:58 +0000 (14:10 +0200)
src/login/logind-action.c
src/login/logind-dbus.c
src/login/logind-inhibit.c
src/login/logind-inhibit.h
src/login/logind-session-dbus.c
src/login/logind-session.c
src/login/logind-session.h

index 42dc36b6708991e078f7d54025f35c1a5a16407e..650fce6a7af6da622627e4a96fcb3954fd972d7b 100644 (file)
@@ -239,7 +239,7 @@ int manager_handle_action(
             manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0, &offending)) {
                 _cleanup_free_ char *comm = NULL, *u = NULL;
 
-                (void) get_process_comm(offending->pid, &comm);
+                (void) get_process_comm(offending->pid.pid, &comm);
                 u = uid_to_name(offending->uid);
 
                 /* If this is just a recheck of the lid switch then don't warn about anything */
@@ -248,7 +248,7 @@ int manager_handle_action(
                          handle_action_to_string(handle),
                          inhibit_what_to_string(inhibit_operation),
                          offending->uid, strna(u),
-                         offending->pid, strna(comm));
+                         offending->pid.pid, strna(comm));
 
                 return is_edge ? -EPERM : 0;
         }
index dcbd195fe2d6f3d41a96959e7caa3e65676441b8..1e453205aaac2be371a753fbe969fac1f4db2208 100644 (file)
@@ -665,7 +665,7 @@ static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bu
                                           strempty(inhibitor->why),
                                           strempty(inhibit_mode_to_string(inhibitor->mode)),
                                           (uint32_t) inhibitor->uid,
-                                          (uint32_t) inhibitor->pid);
+                                          (uint32_t) inhibitor->pid.pid);
                 if (r < 0)
                         return r;
         }
@@ -1625,12 +1625,12 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
                 if (!timeout)
                         return 0;
 
-                (void) get_process_comm(offending->pid, &comm);
+                (void) get_process_comm(offending->pid.pid, &comm);
                 u = uid_to_name(offending->uid);
 
                 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
                            offending->uid, strna(u),
-                           offending->pid, strna(comm));
+                           offending->pid.pid, strna(comm));
         }
 
         /* Actually do the operation */
@@ -3207,6 +3207,7 @@ static int method_set_wall_message(
 
 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
         const char *who, *why, *what, *mode;
         _cleanup_free_ char *id = NULL;
         _cleanup_close_ int fifo_fd = -EBADF;
@@ -3279,6 +3280,10 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
         if (r < 0)
                 return r;
 
+        r = pidref_set_pid(&pidref, pid);
+        if (r < 0)
+                return sd_bus_error_set_errnof(error, r, "Failed pin source process "PID_FMT": %m", pid);
+
         if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED,
                                          "Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.",
@@ -3299,7 +3304,7 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
 
         i->what = w;
         i->mode = mm;
-        i->pid = pid;
+        i->pid = TAKE_PIDREF(pidref);
         i->uid = uid;
         i->why = strdup(why);
         i->who = strdup(who);
index 12cd854706d6c5f3b6b924f27bb464f7a18dde3b..81a791cfbb95b963afa04c91a22084a1cbbae582 100644 (file)
@@ -47,6 +47,7 @@ int inhibitor_new(Inhibitor **ret, Manager *m, const char* id) {
                 .mode = _INHIBIT_MODE_INVALID,
                 .uid = UID_INVALID,
                 .fifo_fd = -EBADF,
+                .pid = PIDREF_NULL,
         };
 
         i->state_file = path_join("/run/systemd/inhibit", id);
@@ -81,6 +82,8 @@ Inhibitor* inhibitor_free(Inhibitor *i) {
         free(i->state_file);
         free(i->fifo_path);
 
+        pidref_done(&i->pid);
+
         return mfree(i);
 }
 
@@ -110,7 +113,7 @@ static int inhibitor_save(Inhibitor *i) {
                 inhibit_what_to_string(i->what),
                 inhibit_mode_to_string(i->mode),
                 i->uid,
-                i->pid);
+                i->pid.pid);
 
         if (i->who) {
                 _cleanup_free_ char *cc = NULL;
@@ -177,7 +180,7 @@ int inhibitor_start(Inhibitor *i) {
 
         log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s started.",
                   strna(i->who), strna(i->why),
-                  i->pid, i->uid,
+                  i->pid.pid, i->uid,
                   inhibit_mode_to_string(i->mode));
 
         i->started = true;
@@ -195,7 +198,7 @@ void inhibitor_stop(Inhibitor *i) {
         if (i->started)
                 log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s stopped.",
                           strna(i->who), strna(i->why),
-                          i->pid, i->uid,
+                          i->pid.pid, i->uid,
                           inhibit_mode_to_string(i->mode));
 
         inhibitor_remove_fifo(i);
@@ -242,7 +245,8 @@ int inhibitor_load(Inhibitor *i) {
         }
 
         if (pid) {
-                r = parse_pid(pid, &i->pid);
+                pidref_done(&i->pid);
+                r = pidref_set_pidstr(&i->pid, pid);
                 if (r < 0)
                         log_debug_errno(r, "Failed to parse PID of inhibitor: %s", pid);
         }
@@ -417,7 +421,7 @@ bool manager_is_inhibited(
                 if (i->mode != mm)
                         continue;
 
-                if (ignore_inactive && pid_is_active(m, i->pid) <= 0)
+                if (ignore_inactive && pid_is_active(m, i->pid.pid) <= 0)
                         continue;
 
                 if (ignore_uid && i->uid == uid)
index 871e69a03a81784b10d36c5aaac1f11ffd8a96f9..6435d41f819a05c3934a5f14cd31cffaf4743bc9 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include "pidref.h"
+
 typedef struct Inhibitor Inhibitor;
 
 typedef enum InhibitWhat {
@@ -40,7 +42,7 @@ struct Inhibitor {
         char *why;
         InhibitMode mode;
 
-        pid_t pid;
+        PidRef pid;
         uid_t uid;
 
         dual_timestamp since;
index 53a96731331faeda6bcda86218f8d05cc8cce0ae..fe52cfa64e1064833f0bd585679869f70163b3a8 100644 (file)
@@ -877,7 +877,7 @@ static const sd_bus_vtable session_vtable[] = {
         SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader.pid), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
index 4e885ce03bdb999a5a1d0e30bed3c1dc6918eaff..c957c93a46aafd8d6a29b2c9ce75317e37c87d95 100644 (file)
@@ -66,6 +66,7 @@ int session_new(Session **ret, Manager *m, const char *id) {
                 .vtfd = -EBADF,
                 .audit_id = AUDIT_SESSION_INVALID,
                 .tty_validity = _TTY_VALIDITY_INVALID,
+                .leader = PIDREF_NULL,
         };
 
         s->state_file = path_join("/run/systemd/sessions", id);
@@ -128,8 +129,10 @@ 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 (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);
 
@@ -168,6 +171,7 @@ void session_set_user(Session *s, User *u) {
 }
 
 int session_set_leader(Session *s, pid_t pid) {
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
         int r;
 
         assert(s);
@@ -175,18 +179,24 @@ int session_set_leader(Session *s, pid_t pid) {
         if (!pid_is_valid(pid))
                 return -EINVAL;
 
-        if (s->leader == pid)
+        if (s->leader.pid == pid)
                 return 0;
 
-        r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s);
+        r = pidref_set_pid(&pidref, pid);
         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);
+        r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pidref.pid), s);
+        if (r < 0)
+                return r;
+
+        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 = pid;
-        (void) audit_session_from_pid(pid, &s->audit_id);
+        s->leader = TAKE_PIDREF(pidref);
+        (void) audit_session_from_pid(s->leader.pid, &s->audit_id);
 
         return 1;
 }
@@ -323,8 +333,8 @@ int session_save(Session *s) {
         if (!s->vtnr)
                 fprintf(f, "POSITION=%u\n", s->position);
 
-        if (pid_is_valid(s->leader))
-                fprintf(f, "LEADER="PID_FMT"\n", s->leader);
+        if (pidref_is_set(&s->leader))
+                fprintf(f, "LEADER="PID_FMT"\n", s->leader.pid);
 
         if (audit_session_is_valid(s->audit_id))
                 fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id);
@@ -674,7 +684,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er
                 r = manager_start_scope(
                                 s->manager,
                                 scope,
-                                s->leader,
+                                s->leader.pid,
                                 s->user->slice,
                                 description,
                                 /* These two have StopWhenUnneeded= set, hence add a dep towards them */
@@ -779,7 +789,7 @@ int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) {
                    "MESSAGE_ID=" SD_MESSAGE_SESSION_START_STR,
                    "SESSION_ID=%s", s->id,
                    "USER_ID=%s", s->user->user_record->user_name,
-                   "LEADER="PID_FMT, s->leader,
+                   "LEADER="PID_FMT, s->leader.pid,
                    LOG_MESSAGE("New session %s of user %s.", s->id, s->user->user_record->user_name));
 
         if (!dual_timestamp_is_set(&s->timestamp))
@@ -849,7 +859,7 @@ static int session_stop_scope(Session *s, bool force) {
                 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
                            "SESSION_ID=%s", s->id,
                            "USER_ID=%s", s->user->user_record->user_name,
-                           "LEADER="PID_FMT, s->leader,
+                           "LEADER="PID_FMT, s->leader.pid,
                            LOG_MESSAGE("Session %s logged out. Waiting for processes to exit.", s->id));
         }
 
@@ -907,7 +917,7 @@ int session_finalize(Session *s) {
                            "MESSAGE_ID=" SD_MESSAGE_SESSION_STOP_STR,
                            "SESSION_ID=%s", s->id,
                            "USER_ID=%s", s->user->user_record->user_name,
-                           "LEADER="PID_FMT, s->leader,
+                           "LEADER="PID_FMT, s->leader.pid,
                            LOG_MESSAGE("Removed session %s.", s->id));
 
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
@@ -1036,8 +1046,8 @@ 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 (pid_is_valid(s->leader)) {
-                r = get_process_ctty_atime(s->leader, &atime);
+        if (pidref_is_set(&s->leader)) {
+                r = get_process_ctty_atime(s->leader.pid, &atime);
                 if (r >= 0)
                         goto found_atime;
         }
index bf45301705ac13c435cae09e4ae56f55f7ad365b..7a4e66ff153f1dd5dc8b3d9010ffaa851b53d3f2 100644 (file)
@@ -7,6 +7,7 @@ typedef enum KillWho KillWho;
 #include "list.h"
 #include "login-util.h"
 #include "logind-user.h"
+#include "pidref.h"
 #include "string-util.h"
 
 typedef enum SessionState {
@@ -87,7 +88,7 @@ struct Session {
         unsigned vtnr;
         int vtfd;
 
-        pid_t leader;
+        PidRef leader;
         uint32_t audit_id;
 
         int fifo_fd;