diff options
author | Niklas Hambüchen | 2017-09-19 20:39:00 +0200 |
---|---|---|
committer | Niklas Hambüchen | 2017-10-14 04:46:13 +0200 |
commit | 8e8f0fa59a884c7dc7c54d0711861e479981ed1a (patch) | |
tree | 35224fd3da98a97eeb23d03a24e007f0397514d2 /sys-utils/unshare.c | |
parent | signames: Make input char buffers const (diff) | |
download | kernel-qcow2-util-linux-8e8f0fa59a884c7dc7c54d0711861e479981ed1a.tar.gz kernel-qcow2-util-linux-8e8f0fa59a884c7dc7c54d0711861e479981ed1a.tar.xz kernel-qcow2-util-linux-8e8f0fa59a884c7dc7c54d0711861e479981ed1a.zip |
unshare: Add --kill-child option.
This allows to conveniently kill the entire process tree
below the forked program, a common problem when scripting
tasks that need to reliably fully terminate without leaving
reparented subprocesses behind.
The example added to the man page shows the most common use.
Implemented using prctl(PR_SET_PDEATHSIG, ...).
Diffstat (limited to 'sys-utils/unshare.c')
-rw-r--r-- | sys-utils/unshare.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c index b5e0d6608..b7448420b 100644 --- a/sys-utils/unshare.c +++ b/sys-utils/unshare.c @@ -28,6 +28,7 @@ #include <sys/mount.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/prctl.h> /* we only need some defines missing in sys/mount.h, no libmount linkage */ #include <libmount.h> @@ -258,6 +259,7 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -U, --user[=<file>] unshare user namespace\n"), out); fputs(_(" -C, --cgroup[=<file>] unshare cgroup namespace\n"), out); fputs(_(" -f, --fork fork before launching <program>\n"), out); + fputs(_(" --kill-child when dying, kill the forked child (implies --fork)\n"), out); fputs(_(" --mount-proc[=<dir>] mount proc filesystem first (implies --mount)\n"), out); fputs(_(" -r, --map-root-user map current user to root (implies --user)\n"), out); fputs(_(" --propagation slave|shared|private|unchanged\n" @@ -276,7 +278,8 @@ int main(int argc, char *argv[]) enum { OPT_MOUNTPROC = CHAR_MAX + 1, OPT_PROPAGATION, - OPT_SETGROUPS + OPT_SETGROUPS, + OPT_KILLCHILD }; static const struct option longopts[] = { { "help", no_argument, NULL, 'h' }, @@ -291,6 +294,7 @@ int main(int argc, char *argv[]) { "cgroup", optional_argument, NULL, 'C' }, { "fork", no_argument, NULL, 'f' }, + { "kill-child", no_argument, NULL, OPT_KILLCHILD }, { "mount-proc", optional_argument, NULL, OPT_MOUNTPROC }, { "map-root-user", no_argument, NULL, 'r' }, { "propagation", required_argument, NULL, OPT_PROPAGATION }, @@ -301,6 +305,7 @@ int main(int argc, char *argv[]) int setgrpcmd = SETGROUPS_NONE; int unshare_flags = 0; int c, forkit = 0, maproot = 0; + int kill_child = 0; const char *procmnt = NULL; pid_t pid = 0; int fds[2]; @@ -373,6 +378,10 @@ int main(int argc, char *argv[]) case OPT_PROPAGATION: propagation = parse_propagation(optarg); break; + case OPT_KILLCHILD: + kill_child = 1; + forkit = 1; + break; default: errtryhelp(EXIT_FAILURE); } @@ -430,6 +439,9 @@ int main(int argc, char *argv[]) } } + if (kill_child) + if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) + err(EXIT_FAILURE, "prctl failed"); if (maproot) { if (setgrpcmd == SETGROUPS_ALLOW) |