Signal handling (like SIGINT) and guix shell --container: PID 1

  • Open
  • quality assurance status badge
Details
One participant
  • ingar
Owner
unassigned
Submitted by
ingar
Severity
normal

Debbugs page

ingar wrote 4 weeks ago
(address . bug-guix@gnu.org)
kh3kmmcpuzm7br17l1ebqp1oj8@onionmail.info
# Bug and reproducer
There is a discrepancy between (expected) signal handling of programs when running them directly,
vs. using `guix shell --container -- program`.

An example program can be used to illustrate:
```
; test.scm
; Test guix shell to catch ctrl-C signal

(while #t
(display "In infinite loop...\n")
(sleep 1))
```

It uses guile, since bash does some extra funky signal-related things, which not every program does.
My usecase is `typst watch`, a program which only exits on ctrl-C, else it loops.

1) Run as `guile test.scm` and use ctrl-C
It terminates as expected.
Same when using `guix shell --container guile` and then `guile test.scm` inside the container shell.
2) Run `guix shell --container guile -- guile test.scm` and use ctrl-C
It doesn't terminate as expected. Only method is to get the PID and use SIGKILL (`kill -KILL <pid>`)

# Reason (as far as I know):
`guix shell --container -- program` starts the program with PID 1 in it's dedicated namespace.
However, PID 1 is handled specially by the kernel when it comes to signal handlers.
Only explicitly registered handlers are used and the default handlers
are not executed for PID 1 (except SIGKILL & SIGSTOP).

You can use `cat /proc/<PID in parent namespace>/status | grep ^NStgid`
to verify the PID seen by the process (rightmost number).

# Sources:
- https://lwn.net/Articles/532748/("Signals and the init process")

# Possible fixes:
- Document the behaviour (and nothing more?)
This is the minimum, and I'll see if I can send a patch.
This lengthy bugreport is due to undocumented & unexpected behaviour, leading down a rabbit hole ;)
- Add an `--init` argument, like in docker?
This adds some minimal init process to forward signals and reap processes...
Not sure how minimal the shepherd is?
- Do this by default, and add a --no-init argument?
- ...

# Workaround:
Add "tini" or "catatonit" as a minimal PID 1 process.
- guix shell --container guile tini -- tini guile test.scm
- guix shell --container guile catatonit -- catatonit guile test.scm

Best regards,
Ingar
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send an email to 76282@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 76282
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch
You may also tag this issue. See list of standard tags. For example, to set the confirmed and easy tags
mumi command -t +confirmed -t +easy
Or, remove the moreinfo tag and set the help tag
mumi command -t -moreinfo -t +help