summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bash-completion/unshare1
-rw-r--r--sys-utils/unshare.117
-rw-r--r--sys-utils/unshare.c14
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)