nstool: Propagate SIGTERM to processes executed in the namespace

Particularly in shell it's sometimes natural to save the pid from a process
run and later kill it.  If doing this with nstool exec, however, it will
kill nstool itself, not the program it is running, which isn't usually what
you want or expect.

Address this by having nstool propagate SIGTERM to its child process.  It
may make sense to propagate some other signals, but some introduce extra
complications, so we'll worry about them when and if it seems useful.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2024-08-05 22:36:41 +10:00 committed by Stefano Brivio
parent 5ca61c2f34
commit 755f9fd911

View file

@ -345,17 +345,39 @@ static int openns(const char *fmt, ...)
return fd;
}
static pid_t sig_pid;
static void sig_handler(int signum)
{
int err;
err = kill(sig_pid, signum);
if (err)
die("Propagating %s: %s\n", strsignal(signum), strerror(errno));
}
static void wait_for_child(pid_t pid)
{
int status;
struct sigaction sa = {
.sa_handler = sig_handler,
.sa_flags = SA_RESETHAND,
};
int status, err;
sig_pid = pid;
err = sigaction(SIGTERM, &sa, NULL);
if (err)
die("sigaction(SIGTERM): %s\n", strerror(errno));
/* Match the child's exit status, if possible */
for (;;) {
pid_t rc;
rc = waitpid(pid, &status, WUNTRACED);
if (rc < 0)
if (rc < 0) {
if (errno == EINTR)
continue;
die("waitpid() on %d: %s\n", pid, strerror(errno));
}
if (rc != pid)
die("waitpid() on %d returned %d", pid, rc);
if (WIFSTOPPED(status)) {