mirror of
https://github.com/clearlinux/systemd-stable.git
synced 2026-09-06 05:32:02 +00:00
logind: handle closing sessions over daemon restarts
It may happen that you have several sessions with the same VT: - Open a session c1 which leaves some processes around, and log out. The session will stay in State=closing and become Active=no. - Log back in on the same VT, get a new session "c2" which is State=active and Active=yes. When restarting logind after that, the first session that matches the current VT becomes Active=yes, which will be c1; c2 thus is Active=no and does not get the usual polkit/device ACL privileges. Restore the "closing" state in session_load(), to avoid treating all restored sessions as State=active. In seat_active_vt_changed(), prefer active sessions over closing ones if more than one session matches the current VT. Finally, fix the confusing comment in session_load() and explain it a bit better. https://launchpad.net/bugs/1415104
This commit is contained in:
committed by
Lennart Poettering
parent
40672b99c7
commit
be94d95499
+13
-1
@@ -340,12 +340,24 @@ int seat_active_vt_changed(Seat *s, unsigned int vtnr) {
|
||||
|
||||
log_debug("VT changed to %u", vtnr);
|
||||
|
||||
/* we might have earlier closing sessions on the same VT, so try to
|
||||
* find a running one first */
|
||||
LIST_FOREACH(sessions_by_seat, i, s->sessions)
|
||||
if (i->vtnr == vtnr) {
|
||||
if (i->vtnr == vtnr && !i->stopping) {
|
||||
new_active = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!new_active) {
|
||||
/* no running one? then we can't decide which one is the
|
||||
* active one, let the first one win */
|
||||
LIST_FOREACH(sessions_by_seat, i, s->sessions)
|
||||
if (i->vtnr == vtnr) {
|
||||
new_active = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = seat_set_active(s, new_active);
|
||||
manager_spawn_autovt(s->manager, vtnr);
|
||||
|
||||
|
||||
@@ -301,6 +301,7 @@ int session_load(Session *s) {
|
||||
_cleanup_free_ char *remote = NULL,
|
||||
*seat = NULL,
|
||||
*vtnr = NULL,
|
||||
*state = NULL,
|
||||
*pos = NULL,
|
||||
*leader = NULL,
|
||||
*type = NULL,
|
||||
@@ -327,6 +328,7 @@ int session_load(Session *s) {
|
||||
"SERVICE", &s->service,
|
||||
"DESKTOP", &s->desktop,
|
||||
"VTNR", &vtnr,
|
||||
"STATE", &state,
|
||||
"POS", &pos,
|
||||
"LEADER", &leader,
|
||||
"TYPE", &type,
|
||||
@@ -415,13 +417,18 @@ int session_load(Session *s) {
|
||||
s->class = c;
|
||||
}
|
||||
|
||||
if (state && streq(state, "closing"))
|
||||
s->stopping = true;
|
||||
|
||||
if (s->fifo_path) {
|
||||
int fd;
|
||||
|
||||
/* If we open an unopened pipe for reading we will not
|
||||
get an EOF. to trigger an EOF we hence open it for
|
||||
reading, but close it right-away which then will
|
||||
trigger the EOF. */
|
||||
writing, but close it right away which then will
|
||||
trigger the EOF. This will happen immediately if no
|
||||
other process has the FIFO open for writing, i. e.
|
||||
when the session died before logind (re)started. */
|
||||
|
||||
fd = session_create_fifo(s);
|
||||
safe_close(fd);
|
||||
|
||||
Reference in New Issue
Block a user