diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-16 18:20:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-16 18:20:20 +0000 |
commit | 8612d3d858fa108e5732a586d4e2d0227ae34422 (patch) | |
tree | 33e7f8b3d5caa6c44b4d6759cb25d3eff4b2d975 /src/login | |
parent | Adding debian version 256.2-1. (diff) | |
download | systemd-8612d3d858fa108e5732a586d4e2d0227ae34422.tar.xz systemd-8612d3d858fa108e5732a586d4e2d0227ae34422.zip |
Merging upstream version 256.4.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/login')
-rw-r--r-- | src/login/logind-dbus.c | 5 | ||||
-rw-r--r-- | src/login/logind-user.c | 26 |
2 files changed, 17 insertions, 14 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index a657b6e..0521863 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -1484,8 +1484,11 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu return -errno; u = hashmap_get(m->users, UID_TO_PTR(uid)); - if (u) + if (u) { + /* Make sure that disabling lingering will terminate the user tracking if no sessions pin it. */ + u->gc_mode = USER_GC_BY_PIN; user_add_to_gc_queue(u); + } } return sd_bus_reply_method_return(message, NULL); diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 8066b3e..276d5b8 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -821,30 +821,30 @@ UserState user_get_state(User *u) { if (!u->started || u->runtime_dir_job) return USER_OPENING; - bool any = false, all_closing = true; + /* USER_GC_BY_PIN: Only pinning sessions count. None -> closing + * USER_GC_BY_ANY: 'manager' sessions also count. However, if lingering is enabled, 'lingering' state + * shall be preferred. 'online' if the manager is manually started by user. */ + + bool has_pinning = false, all_closing = true; LIST_FOREACH(sessions_by_user, i, u->sessions) { - SessionState state; + bool pinned = SESSION_CLASS_PIN_USER(i->class); - /* Ignore sessions that don't pin the user, i.e. are not supposed to have an effect on user state */ - if (!SESSION_CLASS_PIN_USER(i->class)) + if (u->gc_mode == USER_GC_BY_PIN && !pinned) continue; - state = session_get_state(i); - if (state == SESSION_ACTIVE) + has_pinning = has_pinning || pinned; + + SessionState state = session_get_state(i); + if (state == SESSION_ACTIVE && pinned) return USER_ACTIVE; if (state != SESSION_CLOSING) all_closing = false; - - any = true; } - if (any) - return all_closing ? USER_CLOSING : USER_ONLINE; - - if (user_check_linger_file(u) > 0 && user_unit_active(u)) + if (!has_pinning && user_check_linger_file(u) > 0 && user_unit_active(u)) return USER_LINGERING; - return USER_CLOSING; + return all_closing ? USER_CLOSING : USER_ONLINE; } int user_kill(User *u, int signo) { |