From: Lennart Poettering Date: Sat, 9 Sep 2023 10:35:07 +0000 (+0200) Subject: logind: also port session leader tracking over to PidRef X-Git-Tag: v255-rc1~535^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=89bad70f712a6c931b3143ff4504ac2327b569c7;p=thirdparty%2Fsystemd.git logind: also port session leader tracking over to PidRef --- diff --git a/src/login/logind-action.c b/src/login/logind-action.c index 42dc36b6708..650fce6a7af 100644 --- a/src/login/logind-action.c +++ b/src/login/logind-action.c @@ -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; } diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index dcbd195fe2d..1e453205aaa 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -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); diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index 12cd854706d..81a791cfbb9 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -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) diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h index 871e69a03a8..6435d41f819 100644 --- a/src/login/logind-inhibit.h +++ b/src/login/logind-inhibit.h @@ -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; diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 53a96731331..fe52cfa64e1 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -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), diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 4e885ce03bd..c957c93a46a 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -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; } diff --git a/src/login/logind-session.h b/src/login/logind-session.h index bf45301705a..7a4e66ff153 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -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;