Feature request: return to foreground mode automatically if all chidren died.
I'm interested in adding kmscon support natively to uwsm, but there is a problem with returning to foreground mode: there is nothing left in the login session to issue setForeground sequence (login shell is replaced with waiting systemctl, plus there is a forked waitpid process shielded from TERM signal).
Please consider making kmscon return to foreground mode automatically when its child (login) ended.
Would be extra handy if kmscon waited for all login children to die before returning to foreground and starting new login.
I think that make sense, there is already support to restart the login when it exits. The thing I'm wondering is if that should be optional or not.
Is there any point in staying in background mode when user's session associated with the TTY has ended?
Think makes sense to implement by default, but I am not sure if it will fix the issue with uwsm. When is the login shell replaced with systemctl? If this happens before the graphical session is launched, kmscon with get a sigchld, take graphics back with drmMaster, and restart the login program. This will cause the graphical session to fail when it tries to get drmMaster. I assume replacing the login shell process is needed for systemd login sessions, but is it possible to run without doing this?
Would be extra handy if kmscon waited for all login children to die before returning to foreground and starting new
login.
I am not sure how this could be done. I assume this is for waiting on the forked waitpid process. The problem is that there is no way for a grandchild process to directly communicate with its grandparent. Kmscon only creates one child process, so when it receives a sigchld, it assumes that the child exited, so it restarts it. Waiting would need to be implemented in the child process before it exits.
When is the login shell replaced with systemctl? If this happens before the graphical session is launched, kmscon with get a sigchld, take graphics back with drmMaster, and restart the login program. This will cause the graphical session to fail when it tries to get drmMaster. I assume replacing the login shell process is needed for systemd login sessions, but is it possible to run without doing this?
It's part of a mechanism to bind login session and graphical session together:
-
uwsm start ${wm}isexec-ed by login shell, replacing it (no sigchld here). - It starts a
waitpid-based unit pointing to itself as a dead man's switch for graphical session units. - it also forks a watcher that waits for
wayland-wm@${wm}.serviceto appear withMainPIDandexecs unkillablewaitpidpointing to that. - finally it
execssystemctl --user start --wait wayland-wm@${wm}.service(again, no sigchld here), so login lives.
The end result is: only two lightweight processes are left in login session. One triggers graphical session shutdown if terminated (i.e. if login session is terminated), the other holds login session open until compositor ends. Both exit and end the login session if graphical session is deactivated first. No way to just drop to shell (i.e. by crashing a locked compositor) or have one counterpart continue without the other.
Anyway, if systemctl process ends, this means both login and compositor also end. Or at least, compositor will end very soon.
Is there a way to probe if drmMaster is still taken?
Or at least, compositor will end very soon.
I need more sleep, the solution for this async situation stared me in the face. I just have to flip which process is unkillable and which calls waitpid-based unit on itself! This way the session will be held open synchronously by a direct login child.
But the question about probing drmMaster is still valid. Is it possible to probe before grabbing it?
I just have to flip which process is unkillable and which calls waitpid-based unit on itself!
...no, that will also make getty or DM unstoppable or behaving badly. I guess I can not solve this properly with just tiny dumb processes, have to leave something that handles signals.
What is the proper way of checking if running in kmscon? case "$TERM_SESSION_TYPE" in kms|fb) ...? Or is there something more straightforward?
Is there a way to probe if drmMaster is still taken?
From what I understand no. The only way is for a program to try taking and if it fails, assume it is taken. The problem is with the privileges needed to take drmMaster. It used to require root, but it seems like that has changed, since kmscon can aquire it when running as non root. Not sure what exactly the requirements are for this.
What is the proper way of checking if running in kmscon?
case "$TERM_SESSION_TYPE" in kms|fb) ...? Or is there something more straightforward?
I don't think kmscon currently supports any way to do this. Environment varibales could do altered by the user, so they aren't the most reliable method. I think using an escape sequence would be best, but would need to be implemented. I think ESC [ 21 t looks promising, but there is CVE that I'll need to look into. Another option is the tertiary decice attribute (DA3). For either of these libtsm would need a way to get the name of the terminal using it, so both kmscon and libtsm would need to be updated.
Still had to decide on whether to send control sequences somehow, so case "$TERM_SESSION_TYPE" in kms) it is for now.
Released with kmscon support, will daily-drive with it. No immediate need for automatic return to foreground, but that feature would still be useful to get usable console back in cases where something crashed in the login session and setForeground never came.
Thanks for directions!
Yes, I think using $TERM_SESSION_TYPE is good enough for now.
Thanks a lot for integrating kmscon with uwsm.
Thanks for a cool console!