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.
int rc = -1;
struct libmnt_table *tab = NULL;
const char *src = NULL, *tgt = NULL;
+ unsigned long mflags = 0;
assert(cxt);
assert(cxt->fs);
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);
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);
/* 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);
}
# 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
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;
* 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"));
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);