Discussion:
pid namespaces, systemd and signals on reboot(2)
Add Reply
Michał Zegan
2017-05-27 18:51:04 UTC
Reply
Permalink
Raw Message
Hello.

I came across the following:
The manpage reboot(2) says, that inside of a pid namespace, a reboot
call that normally would trigger restart actually triggers sending
sighup to the init of a namespace, and sigint is sent in case of
halt/poweroff.
I have verified that reboot actually triggers sighup. does it mean you
cannot "reboot -f" in a pid namespace, because it will actually trigger
something like "systemctl daemon-reload"? (confusing behavior)...
About poweroff, I used unshare -Upfr and then typed poweroff -f, and the
bash started by unshare exited. Bash does not exit on sigint, so not
sure what was sent? sigkill?
Also, how does systemd handle this case when you tell systemd to power
off/reboot? it probably exits instead of calling reboot(2), but does it
make it possible to distinguish reboot from power off?
Sorry for such an partially offtopic question.
Mike Gilbert
2017-05-28 18:43:45 UTC
Reply
Permalink
Raw Message
On Sat, May 27, 2017 at 2:51 PM, Michał Zegan
Post by Michał Zegan
Hello.
The manpage reboot(2) says, that inside of a pid namespace, a reboot
call that normally would trigger restart actually triggers sending
sighup to the init of a namespace, and sigint is sent in case of
halt/poweroff.
I have verified that reboot actually triggers sighup. does it mean you
cannot "reboot -f" in a pid namespace, because it will actually trigger
something like "systemctl daemon-reload"? (confusing behavior)...
About poweroff, I used unshare -Upfr and then typed poweroff -f, and the
bash started by unshare exited. Bash does not exit on sigint, so not
sure what was sent? sigkill?
Also, how does systemd handle this case when you tell systemd to power
off/reboot? it probably exits instead of calling reboot(2), but does it
make it possible to distinguish reboot from power off?
Sorry for such an partially offtopic question.
I think that section of reboot(2) is inaccurate. I don't see any
trappable signal actually being sent to the init process.

What actually seems to happen is this:

- All processes in the PID namespace are terminated by the kernel (SIGKILL?).
- The exit status on the "init" process is set so that it appears to
have been killed using SIGHUP or SIGINT. The parent process can use
this to distinguish between a reboot and a halt request.
Michał Zegan
2017-05-28 19:39:29 UTC
Reply
Permalink
Raw Message
On Sat, May 27, 2017 at 2:51 PM, Michał Zegan
Post by Michał Zegan
Hello.
The manpage reboot(2) says, that inside of a pid namespace, a reboot
call that normally would trigger restart actually triggers sending
sighup to the init of a namespace, and sigint is sent in case of
halt/poweroff.
I have verified that reboot actually triggers sighup. does it mean you
cannot "reboot -f" in a pid namespace, because it will actually trigger
something like "systemctl daemon-reload"? (confusing behavior)...
About poweroff, I used unshare -Upfr and then typed poweroff -f, and the
bash started by unshare exited. Bash does not exit on sigint, so not
sure what was sent? sigkill?
Also, how does systemd handle this case when you tell systemd to power
off/reboot? it probably exits instead of calling reboot(2), but does it
make it possible to distinguish reboot from power off?
Sorry for such an partially offtopic question.
I think that section of reboot(2) is inaccurate. I don't see any
trappable signal actually being sent to the init process.
- All processes in the PID namespace are terminated by the kernel (SIGKILL?).
- The exit status on the "init" process is set so that it appears to
have been killed using SIGHUP or SIGINT. The parent process can use
this to distinguish between a reboot and a halt request.
Oooh, well, it seems you are probably right.
Tested by setting a trap on bash level (bash is pidns pid1), and sending
it sighup. It didn't kill it, but reboot -f did kill it as though sighup
would happen, but without actually sending sighup (trap not called).
Someone could verify that, and knowing how systemd handles
reboot/poweroff in pidns is still interesting to me.
Lennart Poettering
2017-05-29 09:37:55 UTC
Reply
Permalink
Raw Message
Post by Michał Zegan
Hello.
The manpage reboot(2) says, that inside of a pid namespace, a reboot
call that normally would trigger restart actually triggers sending
sighup to the init of a namespace, and sigint is sent in case of
halt/poweroff.
That's misleading. This is not what happens. Instead, PID 1's parent
(i.e. the container manager) will be notified about reboot() being
called inside the container by a waitid() event of the container's PID
1, where the exit cause is reported to be an uncaught SIGHUP.

It's quite hacky to report it that way, since there's no way to
distuingish a real SIGHUP exit from a reboot() exit this way, but it's
how the the kernel decided to do it.

Or in other words: SIGHUP on the container's PID 1 is how the reboot()
is *reported*, not what actually happened.

Lennart
--
Lennart Poettering, Red Hat
Michał Zegan
2017-05-29 13:09:54 UTC
Reply
Permalink
Raw Message
Post by Lennart Poettering
Post by Michał Zegan
Hello.
The manpage reboot(2) says, that inside of a pid namespace, a reboot
call that normally would trigger restart actually triggers sending
sighup to the init of a namespace, and sigint is sent in case of
halt/poweroff.
That's misleading. This is not what happens. Instead, PID 1's parent
(i.e. the container manager) will be notified about reboot() being
called inside the container by a waitid() event of the container's PID
1, where the exit cause is reported to be an uncaught SIGHUP.
It's quite hacky to report it that way, since there's no way to
distuingish a real SIGHUP exit from a reboot() exit this way, but it's
how the the kernel decided to do it.
Or in other words: SIGHUP on the container's PID 1 is how the reboot()
is *reported*, not what actually happened.
Lennart
what you just said means a man-pages doc bug and I have reported it
yesterday, thank you.

Loading...