Re: How does s6-linux-init-shutdownd.c contact pid 1?

2023-11-20 Thread Laurent Bercot

I've been trying to find out why my "finish" script is not working
(or perhaps it is working but not printing output anywhere I can see)


 The ways of shutdown are mysterious. :)



However, I don't think kill(-1, n) *works* for pid 1.


 Indeed, it does not. That kill is supposed to be sent to every process
*except* s6-svscan, which will survive and restart the supervisor for
s6-linux-init-shutdownd, which will restart s6-linux-init-shutdownd,
which will then execute stage 4.

 If you're not in a container, stage 4 will unmount the filesystems
then hard halt/poweroff/reboot the machine.

https://git.skarnet.org/cgi-bin/cgit.cgi/s6-linux-init/tree/src/shutdown/s6-linux-init-shutdownd.c#n193

 s6-linux-init-shutdownd never tells s6-svscan to exit, so if you're
running s6-linux-init, it's normal that your .s6-svscan/finish script
is not executed.

 The place where you want to hack things is /etc/rc.shutdown.final,
which is run by the stage 4 script right before the hard reboot. At
this point nothing is mounted anymore and the process tree is only

s6-svscan
 \_ s6-supervise s6-linux-init-shutdownd
 \_ foreground { rc.shutdown.final } reboot
 \_ rc.shutdown.final

so you can do dirty stuff like "rm -f 
/run/service/s6-linux-init-shutdownd

&& s6-svc -dxwD /run/service/s6-linux-init-shutdownd &&
s6-svscanctl -b /run/service" which should clean up the s6-supervise
and the foreground, and give control to .s6-svscan/finish.

 Start your finish script with "wait { }" because s6-svscan will 
probably

exec into it before rc.shutdown.final dies, and you don't want a zombie
hanging around.

--
 Laurent



How does s6-linux-init-shutdownd.c contact pid 1?

2023-11-20 Thread dan


[ Apologies if this is a repost. I didn't see it in the archive
so I'm guessing the list silently drops mail from non-subscribers ]

I've been trying to find out why my "finish" script is not working
(or perhaps it is working but not printing output anywhere I can see)
and resorted to reading the s6-linux-init-shutdown.c code

As far as I can tell, when it's ready to start shutting down it
performs these steps:

1) run the rc.shutdown (which in my case calls s6-rc change)

2) runs unsupervise_tree() which walks /run/service (except for
a few explicitly named special-case processes) and sends the
"d" command through /run/service/foo/supervise/control to the
s6-supervise process for each service

3) calls s6_svc_write("/run/service/.s6-svscan/control", "an", 2)
which triggers a rescan (not a terminate)

4) sends TERM and (after a delay) KILL to the destination -1

However, I don't think kill(-1, n) *works* for pid 1. At least on Linux.
If I look at kernel/signal.c (Linux 5.15.71) I see that
SYSCALL_DEFINE2(kill, ... ) (line 3800 or so) calls
kill_something_info() which in the case of -1 iterates for_each_process
but only acts on processes for which task_pid_vnr(p) > 1 - so I don't
believe this is sending anything to pid 1.

Is there some other call to send a "t" to the svscan fifo that I just
haven't found? I'm going to kick myself if so ...


-dan