Previously, the X-mount.subdir option would fail (mount exited with code 0, but the target was not mounted) when a helper was used. In addition to fixing X-mount.subdir, this allows dropping the fallback behaviour previously implemented specifically by the set_vfsflags and set_propagation hooks. I realise this patch is not acceptable as is, since I just exported the previously private open_mount_tree symbol from hook_mount.c without even adding it to a header (so builds with sensible warning configurations, with -Werror=implicit-function-declaration, won't even compile this); but I'm submitting this as is in hopes that someone who knows their way around libmount will suggest a sensible way to shuffle the code around. --- libmount/src/context_mount.c | 15 ++++++++++++++- libmount/src/hook_mount.c | 20 +------------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 676287733..ef66f47af 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -482,8 +482,21 @@ static int exec_helper(struct libmnt_context *cxt) DBG(CXT, ul_debugobj(cxt, "%s forked [status=%d, rc=%d]", cxt->helper, cxt->helper_status, rc)); + + struct libmnt_sysapi *api = mnt_context_get_sysapi(cxt); + assert(api); + + /* a mount helper, unlike an internal mount, won't provide the mount fd. + * This is, however, needed by hooks like subdir -- so let's open the tree + * that was mounted by our helper child. */ + if (api->fd_tree < 0 && mnt_fs_get_target(cxt->fs)) { + api->fd_tree = open_mount_tree(cxt, NULL, (unsigned long) -1); + if (api->fd_tree > 0) { + rc = 0; + } + } + break; } - break; } case -1: diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index 6b7caff85..b80fe4839 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -255,7 +255,7 @@ static int open_fs_configuration_context(struct libmnt_context *cxt, return api->fd_fs; } -static int open_mount_tree(struct libmnt_context *cxt, const char *path, unsigned long mflg) +int open_mount_tree(struct libmnt_context *cxt, const char *path, unsigned long mflg) { unsigned long oflg = OPEN_TREE_CLOEXEC; int rc = 0, fd = -1; @@ -416,15 +416,6 @@ static int set_vfsflags(struct libmnt_context *cxt, api = get_sysapi(cxt); assert(api); - /* fallback only; necessary when init_sysapi() during preparation - * cannot open the tree -- for example when we call /sbin/mount.<type> */ - if (api->fd_tree < 0 && mnt_fs_get_target(cxt->fs)) { - rc = api->fd_tree = open_mount_tree(cxt, NULL, (unsigned long) -1); - if (rc < 0) - return rc; - rc = 0; - } - if (recursive) callflags |= AT_RECURSIVE; @@ -494,15 +485,6 @@ static int hook_set_propagation(struct libmnt_context *cxt, api = get_sysapi(cxt); assert(api); - /* fallback only; necessary when init_sysapi() during preparation - * cannot open the tree -- for example when we call /sbin/mount.<type> */ - if (api->fd_tree < 0 && mnt_fs_get_target(cxt->fs)) { - rc = api->fd_tree = open_mount_tree(cxt, NULL, (unsigned long) -1); - if (rc < 0) - goto done; - rc = 0; - } - mnt_reset_iter(&itr, MNT_ITER_FORWARD); while (mnt_optlist_next_opt(ol, &itr, &opt) == 0) { -- 2.42.0