From: Karel Zak Date: Mon, 4 Oct 2010 12:09:55 +0000 (+0200) Subject: libmount: allows to swap source and target X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f63173b2202c9ce3c7a973a14e6b0dfb26c0c564;p=util-linux libmount: allows to swap source and target Signed-off-by: Karel Zak --- diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c index 07a72c2d..1d3c76a7 100644 --- a/shlibs/mount/src/context.c +++ b/shlibs/mount/src/context.c @@ -57,7 +57,6 @@ void mnt_free_context(mnt_context *cxt) free(cxt->fstype_pattern); free(cxt->optstr_pattern); - free(cxt->spec); free(cxt->helper); free(cxt->orig_user); @@ -113,11 +112,9 @@ int mnt_reset_context(mnt_context *cxt) cxt->fs = NULL; cxt->mtab = NULL; - free(cxt->spec); free(cxt->helper); free(cxt->orig_user); - cxt->spec = NULL; cxt->helper = NULL; cxt->mountflags = 0; @@ -332,27 +329,6 @@ int mnt_context_enable_loopdel(mnt_context *cxt, int enable) return set_flag(cxt, MNT_FL_LOOPDEL, enable); } -/** - * mnt_context_set_spec: - * @cxt: mount context - * @spec: unresolved source (device, label, uuid, ...) or target (mountpoint) - * - * Returns: 0 on success, negative number in case of error. - */ -int mnt_context_set_spec(mnt_context *cxt, const char *spec) -{ - char *p; - - if (!cxt) - return -EINVAL; - p = strdup(spec); - if (!p) - return -ENOMEM; - free(cxt->spec); - cxt->spec = p; - return 0; -} - /** * mnt_context_set_fs: * @cxt: mount context @@ -960,3 +936,147 @@ int mnt_context_prepare_update(mnt_context *cxt, int act) return rc; } +static int is_remount(mnt_context *cxt) +{ + unsigned long fl = 0; + + if (cxt->mountflags & MS_REMOUNT) + return 1; + if (!mnt_context_get_mountflags(cxt, &fl) && (fl & MS_REMOUNT)) + return 1; + return 0; +} + +static int apply_tab(mnt_context *cxt, mnt_tab *tb) +{ + mnt_fs *fs = NULL; + const char *src = NULL, *tgt = NULL; + int rc; + + if (!cxt->fs) + return -EINVAL; + + src = mnt_fs_get_source(cxt->fs); + tgt = mnt_fs_get_target(cxt->fs); + + if (tgt && src) + ; /* TODO: search pair for MNT_OPTSMODE_FORCE */ + else { + if (src) + fs = mnt_tab_find_source(tb, src, MNT_ITER_FORWARD); + else if (tgt) + fs = mnt_tab_find_target(tb, tgt, MNT_ITER_FORWARD); + + if (!fs) { + /* swap source and target (if @src is not LABEL/UUID), + * for example in + * + * mount /foo/bar + * + * the path could be a mountpoint as well as source (for + * example bind mount, symlink to device, ...). + */ + if (src && !mnt_fs_get_tag(cxt->fs, NULL, NULL)) + fs = mnt_tab_find_target(tb, src, + MNT_ITER_FORWARD); + if (!fs && tgt) + fs = mnt_tab_find_source(tb, tgt, + MNT_ITER_FORWARD); + } + } + + if (!fs) + return -EINVAL; + + DBG(CXT, mnt_debug_h(cxt, "apply entry:")); + DBG(CXT, mnt_fs_print_debug(fs, stderr)); + + /* copy from fstab to our FS description + */ + rc = mnt_fs_set_source(cxt->fs, mnt_fs_get_source(fs)); + if (!rc) + rc = mnt_fs_set_target(cxt->fs, mnt_fs_get_target(fs)); + + if (!rc && !mnt_fs_get_fstype(cxt->fs)) + rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs)); + + if (!rc && cxt->optsmode != MNT_OPTSMODE_IGNORE) + rc = mnt_fs_prepend_optstr(cxt->fs, mnt_fs_get_optstr(fs)); + + if (!rc) + cxt->flags |= MNT_FL_FSTAB_APPLIED; + + return rc; +} + +int mnt_context_apply_fstab(mnt_context *cxt) +{ + int rc; + mnt_cache *cache; + const char *src = NULL, *tgt = NULL; + + if (!cxt || !cxt->fs) + return -EINVAL; + + if (cxt->flags & MNT_FL_FSTAB_APPLIED) + return 0; + + if (cxt->fs) { + src = mnt_fs_get_source(cxt->fs); + tgt = mnt_fs_get_target(cxt->fs); + } + + /* fstab is not required if source and target are specified */ + if (src && tgt && !(cxt->optsmode == MNT_OPTSMODE_FORCE || + cxt->optsmode == MNT_OPTSMODE_MTABFORCE)) + return 0; + + DBG(CXT, mnt_debug_h(cxt, + "trying to apply fstab (src=%s, target=%s)", src, tgt)); + + /* initialize fstab */ + if (!cxt->fstab) { + cxt->fstab = mnt_new_tab(); + if (!cxt->fstab) + goto errnomem; + cxt->flags &= ~MNT_FL_EXTERN_FSTAB; + rc = mnt_tab_parse_fstab(cxt->fstab); + if (rc) + goto err; + } + + cache = mnt_context_get_cache(cxt); /* NULL if MNT_FL_NOCANONICALIZE is enabled */ + + /* never touch an external fstab */ + if (!(cxt->flags & MNT_FL_EXTERN_FSTAB)) + mnt_tab_set_cache(cxt->fstab, cache); + + /* let's initialize cxt->fs */ + mnt_context_get_fs(cxt); + + /* try fstab */ + rc = apply_tab(cxt, cxt->fstab); + + /* try mtab */ + if (rc || (cxt->optsmode == MNT_OPTSMODE_MTABFORCE && is_remount(cxt))) { + + cxt->mtab = mnt_new_tab(); + if (!cxt->mtab) + goto errnomem; + rc = mnt_tab_parse_mtab(cxt->mtab); + if (rc) + goto err; + + mnt_tab_set_cache(cxt->mtab, cache); + rc = apply_tab(cxt, cxt->mtab); + if (rc) + goto err; + } + return 0; + +errnomem: + rc = ENOMEM; +err: + DBG(CXT, mnt_debug_h(cxt, "failed to found entry in fstab/mtab")); + return rc; +} diff --git a/shlibs/mount/src/context_mount.c b/shlibs/mount/src/context_mount.c index d5f361a8..77f9497d 100644 --- a/shlibs/mount/src/context_mount.c +++ b/shlibs/mount/src/context_mount.c @@ -24,140 +24,6 @@ #include "c.h" #include "mountP.h" -static int is_remount(mnt_context *cxt) -{ - unsigned long fl = 0; - - if (cxt->mountflags & MS_REMOUNT) - return 1; - if (!mnt_context_get_mountflags(cxt, &fl) && (fl & MS_REMOUNT)) - return 1; - return 0; -} - -static int apply_tab(mnt_context *cxt, mnt_tab *tb) -{ - mnt_fs *fs = NULL; - const char *src = NULL, *tgt = NULL; - int rc; - - if (!cxt->fs) - return -EINVAL; - - src = mnt_fs_get_source(cxt->fs); - tgt = mnt_fs_get_target(cxt->fs); - - if (tgt && src) - ; /* TODO: search pair for MNT_OPTSMODE_FORCE */ - else if (src) - fs = mnt_tab_find_source(tb, src, MNT_ITER_FORWARD); - else if (tgt) - fs = mnt_tab_find_target(tb, tgt, MNT_ITER_FORWARD); - else if (cxt->spec) { - fs = mnt_tab_find_source(tb, cxt->spec, MNT_ITER_FORWARD); - - if (!fs && (strncmp(cxt->spec, "LABEL=", 6) || - strncmp(cxt->spec, "UUID=", 5))) - fs = mnt_tab_find_target(tb, cxt->spec, MNT_ITER_FORWARD); - } - - if (!fs) - return -EINVAL; - - DBG(CXT, mnt_debug_h(cxt, "apply entry:")); - DBG(CXT, mnt_fs_print_debug(fs, stderr)); - - /* copy from fstab to our FS description - */ - rc = mnt_fs_set_source(cxt->fs, mnt_fs_get_source(fs)); - if (!rc) - rc = mnt_fs_set_target(cxt->fs, mnt_fs_get_target(fs)); - - if (!rc && !mnt_fs_get_fstype(cxt->fs)) - rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs)); - - if (!rc && cxt->optsmode != MNT_OPTSMODE_IGNORE) - rc = mnt_fs_prepend_optstr(cxt->fs, mnt_fs_get_optstr(fs)); - - if (!rc) - cxt->flags |= MNT_FL_FSTAB_APPLIED; - - return rc; -} - -static int apply_fstab(mnt_context *cxt) -{ - int rc; - mnt_cache *cache; - const char *src = NULL, *tgt = NULL; - - if (!cxt || (!cxt->spec && !cxt->fs)) - return -EINVAL; - - if (cxt->flags & MNT_FL_FSTAB_APPLIED) - return 0; - - if (cxt->fs) { - src = mnt_fs_get_source(cxt->fs); - tgt = mnt_fs_get_target(cxt->fs); - } - - /* fstab is not required if source and target are specified */ - if (src && tgt && !(cxt->optsmode == MNT_OPTSMODE_FORCE || - cxt->optsmode == MNT_OPTSMODE_MTABFORCE)) - return 0; - - DBG(CXT, mnt_debug_h(cxt, - "trying to apply fstab (src=%s, target=%s, spec=%s)", - src, tgt, cxt->spec)); - - /* initialize fstab */ - if (!cxt->fstab) { - cxt->fstab = mnt_new_tab(); - if (!cxt->fstab) - goto errnomem; - cxt->flags &= ~MNT_FL_EXTERN_FSTAB; - rc = mnt_tab_parse_fstab(cxt->fstab); - if (rc) - goto err; - } - - cache = mnt_context_get_cache(cxt); /* NULL if MNT_FL_NOCANONICALIZE is enabled */ - - /* never touch an external fstab */ - if (!(cxt->flags & MNT_FL_EXTERN_FSTAB)) - mnt_tab_set_cache(cxt->fstab, cache); - - /* let's initialize cxt->fs */ - mnt_context_get_fs(cxt); - - /* try fstab */ - rc = apply_tab(cxt, cxt->fstab); - - /* try mtab */ - if (rc || (cxt->optsmode == MNT_OPTSMODE_MTABFORCE && is_remount(cxt))) { - - cxt->mtab = mnt_new_tab(); - if (!cxt->mtab) - goto errnomem; - rc = mnt_tab_parse_mtab(cxt->mtab); - if (rc) - goto err; - - mnt_tab_set_cache(cxt->mtab, cache); - rc = apply_tab(cxt, cxt->mtab); - if (rc) - goto err; - } - return 0; - -errnomem: - rc = ENOMEM; -err: - DBG(CXT, mnt_debug_h(cxt, "failed to found entry in fstab/mtab")); - return rc; -} - /* * this has to be called after mnt_context_evaluate_permissions() */ @@ -526,11 +392,11 @@ int mnt_context_prepare_mount(mnt_context *cxt) if (!cxt) return -EINVAL; - if (!cxt->spec && !(cxt->fs && (mnt_fs_get_source(cxt->fs) || - mnt_fs_get_target(cxt->fs)))) + if (!cxt->fs || (!mnt_fs_get_source(cxt->fs) && + !mnt_fs_get_target(cxt->fs))) return -EINVAL; - rc = apply_fstab(cxt); + rc = mnt_context_apply_fstab(cxt); if (!rc) rc = merge_mountflags(cxt); if (!rc) @@ -671,8 +537,8 @@ int test_mount(struct mtest *ts, int argc, char *argv[]) } if (argc == idx + 1) - /* mount */ - mnt_context_set_spec(cxt, argv[idx++]); + /* mount | */ + mnt_context_set_target(cxt, argv[idx++]); else if (argc == idx + 2) { /* mount */ diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h index 51230c67..fba072e3 100644 --- a/shlibs/mount/src/mountP.h +++ b/shlibs/mount/src/mountP.h @@ -214,7 +214,6 @@ struct _mnt_context char *fstype_pattern; /* for mnt_match_fstype() */ char *optstr_pattern; /* for mnt_match_options() */ - char *spec; /* unresolved source OR target */ mnt_fs *fs; /* filesystem description (type, mountpopint, device, ...) */ mnt_tab *fstab; /* fstab (or mtab for some remounts) entires */