Re: s6 xinit replacement?
On 5/13/22 10:47 PM, Guillermo wrote: > Hello, > > El mié, 11 may 2022 a las 0:43, dallinjdahl escribió: >> >> I tried to run X under s6 with the following run file: >> >> ~~~ >> #!/usr/bin/execlineb >> [...] >> X :${screen} vt${screen} >> ~~~ >> [...] >> (WW) xf86OpenConsole: VT_ACTIVATE failed: Operation not permitted >> (EE) >> Fatal server error: >> (EE) xf86OpenConsole: Switching VT failed >> [...] >> Does anybody know anything about how s6-svscan and s6-supervise might >> change the environment so as to complicate running X? > > If the Xorg process does not run as root, the tty specified in the vt > argument must be its controlling terminal. Yes, this is effectively the requirement. You can override it with a capability, but doing so is not necessary (see below). Here is the relevant kernel source for reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/tty/vt/vt_ioctl.c?h=v5.17#n744 > It works if you run X from > an interactive shell (perhaps indirectly through 'startx'), because it > inherits the shell's controlling terminal. It doesn't when run by > s6-supervise, because s6-supervise executes the 'run' file in a new > session, so there is no controlling terminal. It also works if X has permission to open the tty device read/write. Opening a tty as a session leader without a controlling terminal will set the controlling terminal to that tty. Relevant kernel code: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/tty/tty_jobctrl.c?h=v5.17#n129 And X will try to do that at startup (after failing to play with process groups because it is already group leader): https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/hw/xfree86/os-support/linux/lnx_init.c#L207 I use a udev rule to set the tty owner: $ cat /etc/udev/rules.d/99-tty.rules SUBSYSTEM=="tty", KERNEL=="tty1", OWNER="samuel", GROUP="samuel", MODE="0600" And everything Just Works. I am fine with hard coding the tty number because my systems are single-user. X is started at boot from my user supervision tree[1], which is started by the user-* services in my system supervision tree[2]. [1]: https://github.com/smaeul/rc-user [2]: https://github.com/smaeul/rc You could also set the tty permissions at login. Another option is to avoid the privileged IOCTLs by using the "-novtswitch" or "-sharevts" option. These set flags which affect the logic in the other file: https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/hw/xfree86/common/xf86Init.c#L1168 Hope that helps, Samuel
Re: s6 xinit replacement?
Is the purpose of executing setsid() in s6-supervise to allow for the services to continue beyond the termination of the supervision tree? It's actually the opposite: it's to protect the supervision tree against misbehaved services. :) setsid() makes sure the service is isolated, and a killpg() or equivalent won't affect anything outside of it. Of course, it also protects *other* services running under the same supervision tree. If that's the case, could there possibly be a flag to disable that, with the understanding that something like nohup or even s6-setsid would be necessary to replicate that behavior? That would enable a non-root Xorg to be managed by s6. The direction s6 has taken is really the opposite: there was such a flag in earlier versions, but it was causing a lot of special cases and problems I definitely did not want to deal with. The real issue is that a supervision tree should not be run with a controlling terminal. It's not meant to be run from a logged-in user process, but as a background infrastructure that's always there. The whole point of s6 is to make your services *more reliable*; and there are few things less reliable than a whole tree of processes that can die on an accidental ^C. Because users insisted a lot, there are still accommodations for killing a whole supervision tree with ^C when s6-svscan has been launched in a terminal. It is a nice feature to have (and although it was by design that services persisted beyond the ^C, it was unintuitive to most users, so from a pure UI standpoint, killing the entire tree in one go was better). However, I'm not going back on the "each service runs in its own session" thing, because if there's a case for allowing the user who controls s6-svscan to kill the whole tree at once, there is just no case for allowing a service running under the tree to impact other services and the tree itself. Despite this, you're right that the pattern of xinit is similar to what s6 does, and it *is* possible to run Xorg under s6; several users are doing so, and I hope they will post their setup. (You may have more luck by asking in the IRC channel, but it would be nice for the setup to be documented on the mailing-list.) It does not involve running s6-svscan from your own VT; it involves having a supervision tree already running (as your user), and starting the Xorg service, e.g. with a s6-svc -u command, on a given VT, possibly passed to the run script via a file that your xinit emulation script would fill in with the output of `tty`. If you insist on doing hacky things, you could even probably get away with something that looks like: xinit emulation: #!/bin/sh tty | sed s:/dev/tty:: > /home/me/.screen-number s6-supervise /home/me/Xorg & # small race here that disappears when s6-supervise has already run once s6-svwait -U /home/me/Xorg your-X-client s6-svc -dx /home/me/Xorg /home/me/Xorg/notification-fd: 3 /home/me/Xorg/run: #!/bin/execlineb -P backtick -E screen { cat /home/me/.screen-number } export DISPLAY :$screen X -displayfd 3 :$screen vt$screen -displayfd is used as a notification mechanism, unblocking s6-svwait when the X server is ready. Hope this helps (and I hope users who actually have done something similar will share their experience), -- Laurent
Re: s6 xinit replacement?
Hello, Guillermo wrote: > If the Xorg process does not run as root, the tty specified in the vt > argument must be its controlling terminal. It works if you run X from > an interactive shell (perhaps indirectly through 'startx'), because it > inherits the shell's controlling terminal. It doesn't when run by > s6-supervise, because s6-supervise executes the 'run' file in a new > session, so there is no controlling terminal. > > You can see Xorg fail in the same way if you do: > > $ setsid startx > > Using util-linux' setsid(1), or: > > $ execlineb -Pc 'background { s6-setsid startx } exit' > > G. Is the purpose of executing setsid() in s6-supervise to allow for the services to continue beyond the termination of the supervision tree? If that's the case, could there possibly be a flag to disable that, with the understanding that something like nohup or even s6-setsid would be necessary to replicate that behavior? That would enable a non-root Xorg to be managed by s6. I don't know if that has any other implications, other than the fact that it would add a flag to s6-svscan, and maybe to s6-supervise? I don't know if that cost is worth it, but I'm also not sure it warrants having 2 projects that duplicate the effort. Xinit seems to try to do what s6 does, but poorly. Thanks! --Dallin