supervision - discussion about system services, daemon supervision, init, runlevel management, and tools such as s6 and runit
 help / color / mirror / Atom feed
* s6 xinit replacement?
@ 2022-05-11  3:36 dallinjdahl
  2022-05-14  3:47 ` Guillermo
  0 siblings, 1 reply; 7+ messages in thread
From: dallinjdahl @ 2022-05-11  3:36 UTC (permalink / raw)
  To: supervision

I had the thought to start up all my personal services with s6, and it's
going well.  However, looking at the xinit source code, it appears to
start the X server, wait until it's up, start a client program, wait
until it shuts down, and then kill the X server.  It seems to me that
xinit is effectively performing process supervision on the X server and
client program.

I tried to run X under s6 with the following run file:

~~~
#!/usr/bin/execlineb

backtick -E screen {
	pipeline { tty } sed s:/dev/tty::
}

export DISPLAY :${screen}

X :${screen} vt${screen}
~~~

Unfortunately, the server never starts up, although I can run those
commands just fine from the tty.  The last few lines of my Xorg log are
the following:

~~~
(WW) xf86OpenConsole: VT_ACTIVATE failed: Operation not permitted
(EE) 
Fatal server error:
(EE) xf86OpenConsole: Switching VT failed
(EE) 
(EE) 
Please consult the The X.Org Foundation support 
	 at http://wiki.x.org
 for help. 
(EE) Please also check the log file at (redacted) for additional information.
(EE) 
(WW) xf86CloseConsole: KDSETMODE failed: Operation not permitted
(WW) xf86CloseConsole: VT_SETMODE failed: Operation not permitted
(EE) Server terminated with error (1). Closing log file.
~~~

Does anybody know anything about how s6-svscan and s6-supervise might
change the environment so as to complicate running X?  I've also checked
to see if the tty got modified, but running the tty command under s6
from the tty console gives the same output as running it directly from
the console.

Thanks for your help!
--Dallin

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: s6 xinit replacement?
  2022-05-11  3:36 s6 xinit replacement? dallinjdahl
@ 2022-05-14  3:47 ` Guillermo
  2022-05-14 23:45   ` dallinjdahl
  2022-05-15  2:44   ` Samuel Holland
  0 siblings, 2 replies; 7+ messages in thread
From: Guillermo @ 2022-05-14  3:47 UTC (permalink / raw)
  To: Supervision

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. 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.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: s6 xinit replacement?
  2022-05-14  3:47 ` Guillermo
@ 2022-05-14 23:45   ` dallinjdahl
  2022-05-15  1:52     ` Laurent Bercot
  2022-05-15  2:44   ` Samuel Holland
  1 sibling, 1 reply; 7+ messages in thread
From: dallinjdahl @ 2022-05-14 23:45 UTC (permalink / raw)
  To: supervision

Hello,

Guillermo <gdiazhartusch@gmail.com> 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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: s6 xinit replacement?
  2022-05-14 23:45   ` dallinjdahl
@ 2022-05-15  1:52     ` Laurent Bercot
  2022-05-15 15:02       ` Guillermo
  0 siblings, 1 reply; 7+ messages in thread
From: Laurent Bercot @ 2022-05-15  1:52 UTC (permalink / raw)
  To: supervision

>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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: s6 xinit replacement?
  2022-05-14  3:47 ` Guillermo
  2022-05-14 23:45   ` dallinjdahl
@ 2022-05-15  2:44   ` Samuel Holland
  1 sibling, 0 replies; 7+ messages in thread
From: Samuel Holland @ 2022-05-15  2:44 UTC (permalink / raw)
  To: Guillermo, Supervision

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: s6 xinit replacement?
  2022-05-15  1:52     ` Laurent Bercot
@ 2022-05-15 15:02       ` Guillermo
  2022-05-17  4:10         ` Rio Liu
  0 siblings, 1 reply; 7+ messages in thread
From: Guillermo @ 2022-05-15 15:02 UTC (permalink / raw)
  To: Supervision

El sáb, 14 may 2022 a las 22:52, Laurent Bercot escribió:
>
> [...] it *is* possible to run Xorg under s6; several users are
> doing so, and I hope they will post their setup.

I actually don't run Xorg as a supervised process. I don't know what
systemd-based GNU/Linux distributions do, but on Gentoo with OpenRC,
Xorg is not started by the init system, it is started either by xinit,
or by a display manager, so I kept it that way.

When using startx from an interactive shell:

  PID TT       EUSER    COMMAND
    1 ?        root     s6-svscan -X3 -- /run/service
  107 ?        root     s6-supervise agetty@tty1
  515 tty1     root      \_ /bin/login --
  560 tty1     guiller+      \_ -bash
  567 tty1     guiller+          \_ /bin/sh /usr/bin/startx
  584 tty1     guiller+              \_ xinit /etc/X11/xinit/xinitrc
-- /etc/X11/xinit/xserverrc :0 -auth ...
  585 tty1     guiller+                  \_ /usr/bin/X ...
  589 tty1     guiller+                  \_ /bin/sh /etc/X11/Sessions/openbox
  650 tty1     guiller+                      \_ /usr/bin/openbox --startup ...

When using a display manager (SDDM here):

  PID TT       EUSER    COMMAND
    1 ?        root     s6-svscan -X3 -- /run/service
  106 ?        root     s6-supervise sddm-daemon
  702 ?        root      \_ sddm
  704 tty7     root          \_ /usr/bin/X ...
  718 ?        root          \_ /usr/libexec/sddm-helper --socket ...
--start /usr/bin/openbox-session ...
  719 ?        guiller+          \_ /usr/bin/openbox --startup ...

So only the getty process and the display manager process are
supervised. I'm not sure if supervising Xorg is worth it. Say that
there is a transient event that makes Xorg crash. X11 clients would
likely die because they lost the connection to the X server, and then
xinit would exit, so the screen would just display a shell prompt
again, or the display manager would just spawn the greeter again, so a
graphical login screen would be displayed. If one is running Xorg, it
is likely because one is running a GUI, right? And if one is running a
GUI, it's probably because one is sitting right in front of the
computer, and one would notice the shell prompt / greeter screen, and
just type ''startx' / log in again. I mean, having a GUI on e.g. a
headless server does not seem very useful.

So I'd also be interested in what others think. (Maybe I should get
into this IRC thing :) , and I think I'll reply to Samuel's post
later).

G.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: s6 xinit replacement?
  2022-05-15 15:02       ` Guillermo
@ 2022-05-17  4:10         ` Rio Liu
  0 siblings, 0 replies; 7+ messages in thread
From: Rio Liu @ 2022-05-17  4:10 UTC (permalink / raw)
  To: Supervision

This thread has inspired me to move my desktop setup under s6 this weekend. Here's what I got:

General flow: boot to tty1 -> login -> bash starts bashrc -> bashrc sets DISPLAY and TTY env vars then exec into s6-svscan -> s6-svscan starts xserver, window manager, and other desktop services.

Reading Samuel's reply, I find the easiest way to get around the controlling terminal issue is to give Xorg capability: `setcap cap_sys_tty_config=+eip /usr/lib/Xorg`. (Considering Chromium has cap_sys_admin, letting Xorg control ttys doesn't seem that bad). Setting the owner of tty doesn't quite work in my case because of the login shell is attached to tty1 already.

In my bashrc, I have some logic to check whether X should be started. Eventually, it runs this code:

exec execlineb /dev/stdin << EOF
s6-setsid -q
piperw 4 3
background {
  fdclose 3 fdmove 0 4
  foreground { redirfd -w 1 /dev/null cat }
  foreground { s6-rc-init -l "$S6/live" -c "$S6/compiled" "$S6/service" }
  s6-rc -l "$S6/live" -up change "$1"
}

fdclose 4
s6-svscan -d 3 "$S6/service"
EOF

And I have $HOME/.service/xserver-srv/run that replaces startx/sx:

#!/usr/bin/execlineb -P
fdmove -c 2 1

importas DISPLAY DISPLAY
importas TTY TTY

if { test -r /dev/dri/card0 }
if { test -n "${DISPLAY}" }

backtick -E cookie { xxd -l 16 -ps /dev/urandom }
foreground { xauth add "${DISPLAY}" MIT-MAGIC-COOKIE-1 "${cookie}" }

Xorg "${DISPLAY}" -displayfd 3 "vt${TTY}"

With a finish file:

#!/usr/bin/execlineb -P
if { test -n "$DISPLAY" }
xauth remove "$DISPLAY"

The window manager, pulseaudio server, and a few other services are started together as well, using s6-rc to depend on xserver.

This is what I ended up with:

s6-supervise agetty-tty1
 \_ login -- rio
     \_ s6-svscan -d 3 /tmp/rio/s6/1/service
         \_ s6-supervise xss-lock
         |   \_ xss-lock -- s6-svc -1 /run/service/locker
         \_ s6-supervise xserver-srv
         |   \_ /usr/lib/Xorg :1 -displayfd 3 vt1
         \_ s6-supervise xserver-log
         |   \_ s6-log -- n4 T /tmp/rio/s6/1/log/xserver
         \_ s6-supervise xbanish
         |   \_ xbanish -i mod1 -i mod4 -i control
         \_ s6-supervise syndaemon
         |   \_ syndaemon -tki 0.2
         \_ s6-supervise pulseaudio-srv
         |   \_ pulseaudio --exit-idle-time=-1 --daemonize=no
         |       \_ /usr/lib/pulse/gsettings-helper
         \_ s6-supervise pulseaudio-log
         |   \_ s6-log -- -system_bus_socket T /tmp/rio/s6/1/log/pulseaudio
         \_ s6-supervise gcin
         |   \_ gcin
         \_ s6-supervise awesome
         |   \_ awesome --no-argb
         \_ s6-supervise s6rc-fdholder
         |   \_ s6-fdholderd -1 -i data/rules
         \_ s6-supervise s6rc-oneshot-runner

Now there are probably issues here and there, as I just got it running. Suggestions welcome.

Rio

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-05-17  4:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-11  3:36 s6 xinit replacement? dallinjdahl
2022-05-14  3:47 ` Guillermo
2022-05-14 23:45   ` dallinjdahl
2022-05-15  1:52     ` Laurent Bercot
2022-05-15 15:02       ` Guillermo
2022-05-17  4:10         ` Rio Liu
2022-05-15  2:44   ` Samuel Holland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).