diff --git a/shlibs/mount/samples/mount.c b/shlibs/mount/samples/mount.c index 1d032a621..eca02d62e 100644 --- a/shlibs/mount/samples/mount.c +++ b/shlibs/mount/samples/mount.c @@ -408,7 +408,7 @@ int main(int argc, char **argv) if (lock) atexit(lock_atexit_cleanup); - rc = mnt_context_do_mount(cxt); + rc = mnt_mount_context(cxt); if (rc) { /* TODO: call mnt_context_strerror() */ rc = EX_FAIL; diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c index d71cbb63c..aad0b3930 100644 --- a/shlibs/mount/src/context.c +++ b/shlibs/mount/src/context.c @@ -1500,7 +1500,7 @@ int test_mount(struct mtest *ts, int argc, char *argv[]) if (lock) atexit(lock_fallback); - rc = mnt_context_do_mount(cxt); + rc = mnt_mount_context(cxt); if (rc) printf("failed to mount %s\n", strerror(errno)); else diff --git a/shlibs/mount/src/context_mount.c b/shlibs/mount/src/context_mount.c index 1180d8eb0..55cf48bf8 100644 --- a/shlibs/mount/src/context_mount.c +++ b/shlibs/mount/src/context_mount.c @@ -343,7 +343,9 @@ static int do_mount(mnt_context *cxt, const char *try_type) src, target, type, flags, cxt->mountdata ? "yes" : "")); - if (!(cxt->flags & MNT_FL_FAKE)) { + if (cxt->flags & MNT_FL_FAKE) + cxt->syscall_status = 0; + else { if (mount(src, target, type, flags, cxt->mountdata)) { cxt->syscall_status = -errno; DBG(CXT, mnt_debug_h(cxt, "mount(2) failed [errno=%d %m]", @@ -420,21 +422,16 @@ static int do_mount_by_pattern(mnt_context *cxt, const char *pattern) } /** - * mnt_context_do_mount: - * @cxt: mount context + * mnt_context_prepare_mount: + * @cxt: context * - * Mount filesystem by mount(2) or fork()+exec(/sbin/mount.type). + * Prepare context for mounting, unnecessary for mnt_context_mount(). * - * See also mnt_context_disable_helpers(). - * - * Returns: 0 on success, and negative number in case of error. WARNING: error - * does not mean that mount(2) syscall or mount.type helper wasn't - * sucessfully called. Check mnt_context_get_status() after error! + * Returns: negative number on error, zero on success */ -int mnt_context_do_mount(mnt_context *cxt) +int mnt_context_prepare_mount(mnt_context *cxt) { - int rc = -EINVAL, x; - const char *type; + int rc = -EINVAL; assert(cxt); assert(cxt->fs); @@ -446,6 +443,9 @@ int mnt_context_do_mount(mnt_context *cxt) if (!mnt_fs_get_source(cxt->fs) && !mnt_fs_get_target(cxt->fs)) return -EINVAL; + if (cxt->flags & MNT_FL_PREPARED) + return 0; + cxt->action = MNT_ACT_MOUNT; DBG(CXT, mnt_debug_h(cxt, "mount: preparing")); @@ -466,13 +466,32 @@ int mnt_context_do_mount(mnt_context *cxt) rc = mnt_context_guess_fstype(cxt); if (!rc) rc = mnt_context_prepare_helper(cxt, "mount", NULL); - if (!rc) - rc = mnt_context_prepare_update(cxt); - if (rc) { DBG(CXT, mnt_debug_h(cxt, "mount: preparing failed")); return rc; } + cxt->flags |= MNT_FL_PREPARED; + return rc; +} + +/** + * mnt_context_do_mount + * @cxt: context + * + * Call mount(2) or mount. helper. Unnecessary for mnt_context_mount(). + * + * Returns: negative number on error, zero on success + */ +int mnt_context_do_mount(mnt_context *cxt) +{ + const char *type; + + assert(cxt); + assert(cxt->fs); + assert(cxt->helper_exec_status == 1); + assert(cxt->syscall_status == 1); + assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); + assert((cxt->flags & MNT_FL_PREPARED)); DBG(CXT, mnt_debug_h(cxt, "mount: do mount")); @@ -481,15 +500,73 @@ int mnt_context_do_mount(mnt_context *cxt) type = mnt_fs_get_fstype(cxt->fs); if (type) - rc = do_mount(cxt, NULL); - else - rc = do_mount_by_pattern(cxt, cxt->fstype_pattern); + return do_mount(cxt, NULL); + + return do_mount_by_pattern(cxt, cxt->fstype_pattern); +} + +/** + * mnt_mount_context: + * @cxt: mount context + * + * Mount filesystem by mount(2) or fork()+exec(/sbin/mount.type). + * + * This is top-level function for FS mounting, similar to: + * + * mnt_context_prepare_mount(cxt); + * mnt_context_do_mount(cxt); + * mnt_context_finalize_mount(cxt); + * + * See also mnt_context_disable_helpers(). + * + * Returns: 0 on success, and negative number in case of error. WARNING: error + * does not mean that mount(2) syscall or mount.type helper wasn't + * sucessfully called. Check mnt_context_get_status() after error! + */ +int mnt_mount_context(mnt_context *cxt) +{ + int rc; + + assert(cxt); + assert(cxt->fs); + assert(cxt->helper_exec_status == 1); + assert(cxt->syscall_status == 1); + + rc = mnt_context_prepare_mount(cxt); + if (!rc) + rc = mnt_context_prepare_update(cxt); + if (!rc) + rc = mnt_context_do_mount(cxt); /* TODO: if mtab update is expected then check if the * target is really mounted read-write to avoid 'ro' in * mtab and 'rw' in /proc/mounts. */ - x = mnt_context_update_tabs(cxt); - return rc ? rc : x; + if (!rc) + rc = mnt_context_update_tabs(cxt); + return rc; +} + +/** + * mnt_context_finalize_mount: + * @cxt: context + * + * Mtab update, etc. Unnecessary for mnt_context_mount(). + * + * Returns: negative number on error, 0 on success. + */ +int mnt_context_finalize_mount(mnt_context *cxt) +{ + int rc; + + assert(cxt); + assert(cxt->fs); + assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); + assert((cxt->flags & MNT_FL_PREPARED)); + + rc = mnt_context_prepare_update(cxt); + if (!rc) + rc = mnt_context_update_tabs(cxt);; + return rc; } diff --git a/shlibs/mount/src/mount.h.in b/shlibs/mount/src/mount.h.in index 828bf7083..84f768477 100644 --- a/shlibs/mount/src/mount.h.in +++ b/shlibs/mount/src/mount.h.in @@ -381,7 +381,12 @@ extern int mnt_context_apply_fstab(mnt_context *cxt); extern int mnt_context_get_status(mnt_context *cxt); extern int mnt_context_strerror(mnt_context *cxt, char *buf, size_t bufsiz); +extern int mnt_mount_context(mnt_context *cxt); + +extern int mnt_context_prepare_mount(mnt_context *cxt); extern int mnt_context_do_mount(mnt_context *cxt); +extern int mnt_context_finalize_mount(mnt_context *cxt); + extern int mnt_context_do_umount(mnt_context *cxt); /* diff --git a/shlibs/mount/src/mount.sym b/shlibs/mount/src/mount.sym index 3ad4a0210..e29372ed5 100644 --- a/shlibs/mount/src/mount.sym +++ b/shlibs/mount/src/mount.sym @@ -22,6 +22,7 @@ global: mnt_context_enable_rdonly_umount; mnt_context_enable_sloppy; mnt_context_enable_verbose; + mnt_context_finalize_mount; mnt_context_get_cache; mnt_context_get_fs; mnt_context_get_fstab; @@ -39,6 +40,7 @@ global: mnt_context_is_restricted; mnt_context_is_sloppy; mnt_context_is_verbose; + mnt_context_prepare_mount; mnt_context_set_cache; mnt_context_set_fs; mnt_context_set_fstab; @@ -125,6 +127,7 @@ global: mnt_mangle; mnt_match_fstype; mnt_match_options; + mnt_mount_context; mnt_new_cache; mnt_new_context; mnt_new_fs; diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h index ac46599da..cb7b68cd3 100644 --- a/shlibs/mount/src/mountP.h +++ b/shlibs/mount/src/mountP.h @@ -286,6 +286,7 @@ struct _mnt_context #define MNT_FL_TAB_APPLIED (1 << 21) /* mtab/fstab merged to cxt->fs */ #define MNT_FL_MOUNTFLAGS_MERGED (1 << 22) /* MS_* flags was read from optstr */ #define MNT_FL_SAVED_USER (1 << 23) +#define MNT_FL_PREPARED (1 << 24) /* default flags */ #define MNT_FL_DEFAULT 0