From: Lubomir Rintel Date: Mon, 12 Feb 2018 19:23:12 +0000 (+0100) Subject: lib/namespace: don't try to mount rw /sys over a ro one X-Git-Tag: v4.16.0~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f0807023d067e2bb585a2ae8da93e59689d10f1;p=thirdparty%2Fiproute2.git lib/namespace: don't try to mount rw /sys over a ro one It will fail with EPERM on Linux 4.15. Signed-off-by: Lubomir Rintel Acked-by: Phil Sutter Signed-off-by: Stephen Hemminger --- diff --git a/lib/namespace.c b/lib/namespace.c index 30b513889..6f3356d0f 100644 --- a/lib/namespace.c +++ b/lib/namespace.c @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. */ +#include #include #include #include @@ -46,6 +47,8 @@ int netns_switch(char *name) { char net_path[PATH_MAX]; int netns; + unsigned long mountflags = 0; + struct statvfs fsstat; snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name); netns = open(net_path, O_RDONLY | O_CLOEXEC); @@ -73,12 +76,25 @@ int netns_switch(char *name) strerror(errno)); return -1; } + /* Mount a version of /sys that describes the network namespace */ - if (umount2("/sys", MNT_DETACH) < 0) { - fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno)); + + if (statvfs("/sys", &fsstat) < 0) { + fprintf(stderr, "could not stat /sys (not mounted?): %s\n",strerror(errno)); return -1; } - if (mount(name, "/sys", "sysfs", 0, NULL) < 0) { + if (fsstat.f_flag & ST_RDONLY) { + /* If /sys is not writable (e.g. in a container), we can't + * unmount the old /sys instance, but we can still mount a new + * read-only instance over it. */ + mountflags = MS_RDONLY; + } else { + if (umount2("/sys", MNT_DETACH) < 0) { + fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno)); + return -1; + } + } + if (mount(name, "/sys", "sysfs", mountflags, NULL) < 0) { fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno)); return -1; }