]> err.no Git - util-linux/commitdiff
libmount: allows to swap source and target
authorKarel Zak <kzak@redhat.com>
Mon, 4 Oct 2010 12:09:55 +0000 (14:09 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 3 Jan 2011 11:28:45 +0000 (12:28 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/mount/src/context.c
shlibs/mount/src/context_mount.c
shlibs/mount/src/mountP.h

index 07a72c2d35ff2a3351b4a9048917baa0cec70e47..1d3c76a75f95645b69b6e01ae310f112b04260e2 100644 (file)
@@ -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;
+}
index d5f361a83ce13bfea925bf7578de873abe5ec0df..77f9497da141db764d96bb4c49a840616e963f1b 100644 (file)
 #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 <spec> */
-               mnt_context_set_spec(cxt, argv[idx++]);
+               /* mount <mountpont>|<device> */
+               mnt_context_set_target(cxt, argv[idx++]);
 
        else if (argc == idx + 2) {
                /* mount <device> <mountpoint> */
index 51230c67b170762b7ea0264cd545dc23292ea763..fba072e3164d571e518783c44b226f20bd571f58 100644 (file)
@@ -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 */