From: Karel Zak Date: Thu, 12 Aug 2021 10:12:39 +0000 (+0200) Subject: libmount: change propagation of /run for X-mount.subdir X-Git-Tag: v2.38-rc1~304 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=315e8f634a7936532d08cd5ab056cd875d2a262e;p=thirdparty%2Futil-linux.git libmount: change propagation of /run for X-mount.subdir We do not need to create a new mount node from /run/mount/tmptgt (where we mount filesystem root), because /run is already mount node in all mainstream distros, and we can use MS_PRIVATE for this top-level directory. There is still fallback if /run is on root filesystem. This solution reduces number of mount operations, with the patch the subdir implementation is: * open current namespace from /proc/self/ns/mnt * mkdir /run/mount/tmptg (if it does not exist) * make /run private by mount(MS_PRIVATE) * mount filesystem to /run/mount/tmptg * bind mount /run/mount/tmptg/ to * umount /run/mount/tmptg * setns() to the original namespace Signed-off-by: Karel Zak --- diff --git a/libmount/src/utils.c b/libmount/src/utils.c index 1a8a294636..dc8f7c9eb3 100644 --- a/libmount/src/utils.c +++ b/libmount/src/utils.c @@ -1141,17 +1141,12 @@ done: */ int mnt_tmptgt_unshare(int *old_ns_fd) { - int rc = 0, fd = -1, mounted = 0; + int rc = 0, fd = -1; assert(old_ns_fd); *old_ns_fd = -1; - /* create directory */ - rc = ul_mkdir_p(MNT_PATH_TMPTGT, S_IRWXU); - if (rc) - goto fail; - /* remember the current namespace */ fd = open("/proc/self/ns/mnt", O_RDONLY | O_CLOEXEC); if (fd < 0) @@ -1161,25 +1156,30 @@ int mnt_tmptgt_unshare(int *old_ns_fd) if (unshare(CLONE_NEWNS) != 0) goto fail; - /* make the directory private */ - mounted = mount(MNT_PATH_TMPTGT, MNT_PATH_TMPTGT, "none", MS_BIND, NULL) == 0; - if (!mounted) - goto fail; - if (mount("none", MNT_PATH_TMPTGT, NULL, MS_PRIVATE, NULL) != 0) + /* create directory */ + rc = ul_mkdir_p(MNT_PATH_TMPTGT, S_IRWXU); + if (rc) goto fail; + /* try to set top-level directory as private, this is possible if + * MNT_RUNTIME_TOPDIR (/run) is a separated filesystem. */ + if (mount("none", MNT_RUNTIME_TOPDIR, NULL, MS_PRIVATE, NULL) != 0) { + + /* failed; create a mountpoint from MNT_PATH_TMPTGT */ + if (mount(MNT_PATH_TMPTGT, MNT_PATH_TMPTGT, "none", MS_BIND, NULL) != 0) + goto fail; + if (mount("none", MNT_PATH_TMPTGT, NULL, MS_PRIVATE, NULL) != 0) + goto fail; + } + DBG(UTILS, ul_debug(MNT_PATH_TMPTGT " unshared")); *old_ns_fd = fd; return 0; fail: if (rc == 0) rc = errno ? -errno : -EINVAL; - if (mounted) - umount(MNT_PATH_TMPTGT); - if (fd >= 0) { - setns(fd, CLONE_NEWNS); /* restore original NS */ - close(fd); - } + + mnt_tmptgt_cleanup(fd); DBG(UTILS, ul_debug(MNT_PATH_TMPTGT " unshare failed")); return rc; }