aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmount/src/hook_subdir.c21
-rw-r--r--sys-utils/mount.8.adoc4
2 files changed, 19 insertions, 6 deletions
diff --git a/libmount/src/hook_subdir.c b/libmount/src/hook_subdir.c
index 1e5d79958a..7cbb2c88d4 100644
--- a/libmount/src/hook_subdir.c
+++ b/libmount/src/hook_subdir.c
@@ -313,6 +313,7 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir
struct libmnt_optlist *ol;
struct libmnt_opt *opt;
const char *dir = NULL;
+ unsigned long flags = 0;
assert(cxt);
assert(rc);
@@ -328,16 +329,26 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir
return 0;
dir = mnt_opt_get_value(opt);
-
if (!dir || !*dir) {
DBG(HOOK, ul_debug("failed to parse X-mount.subdir '%s'", dir));
*rc = -MNT_ERR_MOUNTOPT;
- } else {
- *subdir = strdup(dir);
- if (!*subdir)
- *rc = -ENOMEM;
+ return 0;
+ }
+
+ *rc = mnt_optlist_get_flags(ol, &flags, cxt->map_linux, 0);
+ if (*rc)
+ return 0;
+
+ if (flags & MS_REMOUNT || flags & MS_BIND || flags & MS_MOVE
+ || mnt_context_propagation_only(cxt)) {
+ DBG(HOOK, ul_debug("ignore subdir= (bind/move/remount/..)"));
+ return 0;
}
+ *subdir = strdup(dir);
+ if (!*subdir)
+ *rc = -ENOMEM;
+
return *rc == 0;
}
diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc
index bb4151225a..95998ce2ad 100644
--- a/sys-utils/mount.8.adoc
+++ b/sys-utils/mount.8.adoc
@@ -767,7 +767,9 @@ Note that *mount*(8) still sanitizes and canonicalizes the source and target pat
Do not create and mount a loop device, even if the source of the mount is a regular file.
**X-mount.subdir=**_directory_::
-Allow mounting a sub-directory of a filesystem instead of the root directory. For now, this feature is implemented by a temporary filesystem root-directory mount in an unshared namespace and then binding the sub-directory to the final mount point and unmounting the root of the filesystem. The sub-directory mount shows up atomically for the rest of the system although it is implemented by multiple *mount*(2) syscalls.
+Allow mounting a subdirectory of a filesystem instead of the root directory. This is effective only when a new instance of a filesystem is attached to the system. The option is silently ignored for operations like remount, bind mount, or move.
++
+For now, this feature is implemented by a temporary filesystem root-directory mount in an unshared namespace and then binding the sub-directory to the final mount point and unmounting the root of the filesystem. The sub-directory mount shows up atomically for the rest of the system although it is implemented by multiple *mount*(2) syscalls.
+
Note that this feature will not work in session with an unshared private mount namespace (after *unshare --mount*) on old kernels or with *mount*(8) without support for file-descriptors-based mount kernel API. In this case, you need *unshare --mount --propagation shared*.
+