From d59766a64806d3acc409bd27cdd6a58e2d6e405f Mon Sep 17 00:00:00 2001 From: Vaclav Dolezal Date: Fri, 20 Apr 2018 17:57:39 +0200 Subject: [PATCH] mount: allow PID as --namespace argument [[kzak@redhat.com: - update code] Signed-off-by: Karel Zak Signed-off-by: Vaclav Dolezal --- sys-utils/mount.8 | 4 +++- sys-utils/mount.c | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/sys-utils/mount.8 b/sys-utils/mount.8 index 488403717..1a05f71c0 100644 --- a/sys-utils/mount.8 +++ b/sys-utils/mount.8 @@ -646,7 +646,9 @@ is on a read-only filesystem. .TP .BR \-N , " \-\-namespace " \fIns Perform mount in namespace specified by \fIns\fR. -\fIns\fR is typically in form \fI/proc/[pid]/ns/mnt\fR. +\fIns\fR is either PID of process running in that namespace +or special file representing that namespace. +See \fBnamespaces\fR(7) for more information. .TP .BR \-O , " \-\-test\-opts " \fIopts Limit the set of filesystems to which the diff --git a/sys-utils/mount.c b/sys-utils/mount.c index a0dba721a..5e139e896 100644 --- a/sys-utils/mount.c +++ b/sys-utils/mount.c @@ -512,6 +512,19 @@ static long osrc2mask(const char *str, size_t len) return -EINVAL; } +static pid_t parse_pid(const char *str) +{ + char *end; + pid_t ret; + + errno = 0; + ret = strtoul(str, &end, 10); + + if (ret < 0 || errno || end == str || (end && *end)) + return 0; + return ret; +} + int main(int argc, char **argv) { int c, rc = MNT_EX_SUCCESS, all = 0, show_labels = 0; @@ -694,9 +707,17 @@ int main(int argc, char **argv) append_option(cxt, "rbind"); break; case 'N': - if (mnt_context_set_target_ns(cxt, optarg)) - err(MNT_EX_SYSERR, _("failed to set target namespace")); + { + char path[PATH_MAX]; + pid_t pid = parse_pid(optarg); + + if (pid) + snprintf(path, sizeof(path), "/proc/%i/ns/mnt", pid); + + if (mnt_context_set_target_ns(cxt, pid ? path : optarg)) + err(MNT_EX_SYSERR, _("failed to set target namespace to %s"), pid ? path : optarg); break; + } case MOUNT_OPT_SHARED: append_option(cxt, "shared"); propa = 1;