]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add private mnt_context_get_mtab_for_target()
authorKarel Zak <kzak@redhat.com>
Wed, 19 Nov 2014 10:07:40 +0000 (11:07 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 19 Nov 2014 10:07:40 +0000 (11:07 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context.c
libmount/src/context_umount.c
libmount/src/mountP.h

index 48ee985fab975df128977dea23a1d49cb8d5b728..1620e9c8e954c8e10dd8bd97185e20f1a948aee2 100644 (file)
@@ -1059,6 +1059,52 @@ int mnt_context_get_mtab(struct libmnt_context *cxt, struct libmnt_table **tb)
        return 0;
 }
 
+/*
+ * Called by mtab parser to filter out entries, non-zero means that
+ * an entry has to be filtered out.
+ */
+static int mtab_filter(struct libmnt_fs *fs, void *data)
+{
+       if (!fs || !data)
+               return 0;
+       if (mnt_fs_streq_target(fs, data))
+               return 0;
+       if (mnt_fs_streq_srcpath(fs, data))
+               return 0;
+       return 1;
+}
+
+/*
+ * The same like mnt_context_get_mtab(), but does not read all mountinfo/mtab
+ * file, but only entries relevant for @tgt.
+ */
+int mnt_context_get_mtab_for_target(struct libmnt_context *cxt,
+                                   struct libmnt_table **mtab,
+                                   const char *tgt)
+{
+       struct stat st;
+       struct libmnt_cache *cache = NULL;
+       char *cn_tgt = NULL;
+       int rc;
+
+       if (stat(tgt, &st) == 0 && S_ISDIR(st.st_mode)) {
+               cache = mnt_context_get_cache(cxt);
+               cn_tgt = mnt_resolve_path(tgt, cache);
+               if (cn_tgt)
+                       mnt_context_set_tabfilter(cxt, mtab_filter, cn_tgt);
+       }
+
+       rc = mnt_context_get_mtab(cxt, mtab);
+
+       if (cn_tgt) {
+               mnt_context_set_tabfilter(cxt, NULL, NULL);
+               if (!cache)
+                       free(cn_tgt);
+       }
+
+       return rc;
+}
+
 /*
  * Allows to specify a filter for tab file entries. The filter is called by
  * the table parser. Currently used for mtab and utab only.
@@ -1979,6 +2025,7 @@ int mnt_context_apply_fstab(struct libmnt_context *cxt)
        int rc = -1;
        struct libmnt_table *tab = NULL;
        const char *src = NULL, *tgt = NULL;
+       unsigned long mflags = 0;
 
        assert(cxt);
        assert(cxt->fs);
@@ -2001,6 +2048,13 @@ int mnt_context_apply_fstab(struct libmnt_context *cxt)
                cxt->optsmode &= ~MNT_OMODE_FORCE;
        }
 
+       if (mnt_context_get_mflags(cxt, &mflags) == 0 && mflags & MS_REMOUNT) {
+               /* preffer mtab on remount */
+               DBG(CXT, ul_debugobj(cxt, "force mtab parsing on remount"));
+               cxt->optsmode |= MNT_OMODE_MTAB;
+               cxt->optsmode &= ~MNT_OMODE_FSTAB;
+       }
+
        if (cxt->fs) {
                src = mnt_fs_get_source(cxt->fs);
                tgt = mnt_fs_get_target(cxt->fs);
@@ -2030,14 +2084,12 @@ int mnt_context_apply_fstab(struct libmnt_context *cxt)
                return 0;
        }
 
-       DBG(CXT, ul_debugobj(cxt,
-               "trying to apply fstab (src=%s, target=%s)", src, tgt));
-
        /* let's initialize cxt->fs */
        ignore_result( mnt_context_get_fs(cxt) );
 
        /* try fstab */
        if (cxt->optsmode & MNT_OMODE_FSTAB) {
+               DBG(CXT, ul_debugobj(cxt, "trying to apply fstab (src=%s, target=%s)", src, tgt));
                rc = mnt_context_get_fstab(cxt, &tab);
                if (!rc)
                        rc = apply_table(cxt, tab, MNT_ITER_FORWARD);
@@ -2045,8 +2097,11 @@ int mnt_context_apply_fstab(struct libmnt_context *cxt)
 
        /* try mtab */
        if (rc < 0 && (cxt->optsmode & MNT_OMODE_MTAB)) {
-               DBG(CXT, ul_debugobj(cxt, "trying to apply from mtab"));
-               rc = mnt_context_get_mtab(cxt, &tab);
+               DBG(CXT, ul_debugobj(cxt, "trying to apply mtab (src=%s, target=%s)", src, tgt));
+               if (tgt)
+                       rc = mnt_context_get_mtab_for_target(cxt, &tab, tgt);
+               else
+                       rc = mnt_context_get_mtab(cxt, &tab);
                if (!rc)
                        rc = apply_table(cxt, tab, MNT_ITER_BACKWARD);
        }
index 6c1d9a2f4aa5b3f4bbd4e35cfbb9516bc01f5ca5..c50b97bfbb8be8f76cd9b1d9684a9b6fac57837d 100644 (file)
 # define UMOUNT_UNUSED    0x80000000   /* Flag guaranteed to be unused */
 #endif
 
-/*
- * Called by mtab parser to filter out entries, non-zero means that
- * an entry has to be filtered out.
- */
-static int mtab_filter(struct libmnt_fs *fs, void *data)
-{
-       if (!fs || !data)
-               return 0;
-       if (mnt_fs_streq_target(fs, data))
-               return 0;
-       if (mnt_fs_streq_srcpath(fs, data))
-               return 0;
-       return 1;
-}
-
 /**
  * mnt_context_find_umount_fs:
  * @cxt: mount context
@@ -68,8 +53,7 @@ int mnt_context_find_umount_fs(struct libmnt_context *cxt,
        int rc;
        struct libmnt_table *mtab = NULL;
        struct libmnt_fs *fs;
-       struct libmnt_cache *cache = NULL;
-       char *cn_tgt = NULL, *loopdev = NULL;
+       char *loopdev = NULL;
 
        if (pfs)
                *pfs = NULL;
@@ -93,24 +77,10 @@ int mnt_context_find_umount_fs(struct libmnt_context *cxt,
         * it's usable only for canonicalized stuff (e.g. kernel mountinfo).
         */
        if (!mnt_context_mtab_writable(cxt) && *tgt == '/' &&
-           !mnt_context_is_force(cxt) && !mnt_context_is_lazy(cxt)) {
-
-               struct stat st;
-
-               if (stat(tgt, &st) == 0 && S_ISDIR(st.st_mode)) {
-                       cache = mnt_context_get_cache(cxt);
-                       cn_tgt = mnt_resolve_path(tgt, cache);
-                       if (cn_tgt)
-                               mnt_context_set_tabfilter(cxt, mtab_filter, cn_tgt);
-               }
-       }
-       rc = mnt_context_get_mtab(cxt, &mtab);
-
-       if (cn_tgt) {
-               mnt_context_set_tabfilter(cxt, NULL, NULL);
-               if (!cache)
-                       free(cn_tgt);
-       }
+           !mnt_context_is_force(cxt) && !mnt_context_is_lazy(cxt))
+               rc = mnt_context_get_mtab_for_target(cxt, &mtab, tgt);
+       else
+               rc = mnt_context_get_mtab(cxt, &mtab);
 
        if (rc) {
                DBG(CXT, ul_debugobj(cxt, "umount: failed to read mtab"));
@@ -161,6 +131,7 @@ try_loopdev:
 
                if (stat(tgt, &st) == 0 && S_ISREG(st.st_mode)) {
                        int count;
+                       struct libmnt_cache *cache = mnt_context_get_cache(cxt);
                        const char *bf = cache ? mnt_resolve_path(tgt, cache) : tgt;
 
                        count = loopdev_count_by_backing_file(bf, &loopdev);
index 2dd9fae4658a7f3bf7666773051ef3237531c67f..d530d6419f9354a45657a4c3c495af34aa063478 100644 (file)
@@ -376,6 +376,9 @@ extern int mnt_context_mtab_writable(struct libmnt_context *cxt);
 extern int mnt_context_utab_writable(struct libmnt_context *cxt);
 extern const char *mnt_context_get_writable_tabpath(struct libmnt_context *cxt);
 
+extern int mnt_context_get_mtab_for_target(struct libmnt_context *cxt,
+                                   struct libmnt_table **mtab, const char *tgt);
+
 extern int mnt_context_prepare_srcpath(struct libmnt_context *cxt);
 extern int mnt_context_prepare_target(struct libmnt_context *cxt);
 extern int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type);