diff options
-rw-r--r-- | bash-completion/unshare | 1 | ||||
-rw-r--r-- | sys-utils/unshare.1 | 17 | ||||
-rw-r--r-- | sys-utils/unshare.c | 14 |
3 files changed, 31 insertions, 1 deletions
diff --git a/bash-completion/unshare b/bash-completion/unshare index cd73c1d6c..3fda4a194 100644 --- a/bash-completion/unshare +++ b/bash-completion/unshare @@ -27,6 +27,7 @@ _unshare_module() --user --cgroup --fork + --kill-child --mount-proc --map-root-user --propagation diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1 index 79ab96a1b..420b48b73 100644 --- a/sys-utils/unshare.1 +++ b/sys-utils/unshare.1 @@ -138,6 +138,12 @@ by bind mount. Fork the specified \fIprogram\fR as a child process of \fBunshare\fR rather than running it directly. This is useful when creating a new PID namespace. .TP +.BR \-\-kill\-child +When \fBunshare\fR terminates, have \fBSIGKILL\fR be sent to the forked child process. +Combined with \fB--pid\fR this allows for an easy and realiable killing of the entire +process tree below \fBunshare\fR. +This option implies \fB--fork\fR. +.TP .BR \-\-mount\-proc [ =\fImountpoint ] Just before running the program, mount the proc filesystem at \fImountpoint\fP (default is /proc). This is useful when creating a new PID namespace. It also @@ -229,6 +235,17 @@ the bind reference. Establish a persistent mount namespace referenced by the bind mount /root/namespaces/mnt. This example shows a portable solution, because it makes sure that the bind mount is created on a shared filesystem. +.TP +.B # unshare -pf --kill-child -- bash -c "(sleep 999 &) && sleep 1000" & +.TQ +.B # pid=$! +.TQ +.B # kill $pid +.br +Reliable killing of subprocesses of the \fIprogram\fR. +When \fBunshare\fR gets killed, everything below it gets killed as well. +Without it, the children of \fIprogram\fR would have orphaned and +been re-parented to PID 1. .SH SEE ALSO .BR clone (2), 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) |