diff options
Diffstat (limited to 'libmount/src/context_umount.c')
| -rw-r--r-- | libmount/src/context_umount.c | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c index 4a8659c9c..dc16852c0 100644 --- a/libmount/src/context_umount.c +++ b/libmount/src/context_umount.c @@ -23,7 +23,7 @@ * umount2 flags */ #ifndef MNT_FORCE -# define MNT_FORCE 0x00000001 /* Attempt to forcibily umount */ +# define MNT_FORCE 0x00000001 /* Attempt to forcibly umount */ #endif #ifndef MNT_DETACH @@ -39,8 +39,8 @@ #endif /* - * Called by mtab parser to filter out entries, nonzero means that - * entry has to be filter out. + * 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) { @@ -71,19 +71,25 @@ int mnt_context_find_umount_fs(struct libmnt_context *cxt, struct libmnt_cache *cache = NULL; char *cn_tgt = NULL, *loopdev = NULL; + if (pfs) + *pfs = NULL; + if (!cxt || !tgt || !pfs) return -EINVAL; DBG(CXT, mnt_debug_h(cxt, "umount: lookup FS for '%s'", tgt)); + if (!*tgt) + return 1; /* empty string is not an error */ + /* - * The mtab file maybe huge and on systems with utab we have to merge + * The mtab file may be huge and on systems with utab we have to merge * userspace mount options into /proc/self/mountinfo. This all is * expensive. The mtab filter allows to filter out entries, then * mtab and utab are very tiny files. * * *but*... the filter uses mnt_fs_streq_{target,srcpath} functions - * where LABEL, UUID or symlinks are to canonicalized. It means that + * where LABEL, UUID or symlinks are canonicalized. It means that * it's usable only for canonicalized stuff (e.g. kernel mountinfo). */ if (!cxt->mtab_writable && *tgt == '/' && @@ -92,7 +98,7 @@ int mnt_context_find_umount_fs(struct libmnt_context *cxt, struct stat st; if (stat(tgt, &st) == 0 && S_ISDIR(st.st_mode)) { - /* we'll canonicalized /proc/self/mountinfo */ + /* we'll canonicalize /proc/self/mountinfo */ cache = mnt_context_get_cache(cxt); cn_tgt = mnt_resolve_path(tgt, cache); if (cn_tgt) @@ -155,7 +161,10 @@ try_loopdev: struct stat st; if (stat(tgt, &st) == 0 && S_ISREG(st.st_mode)) { - int count = loopdev_count_by_backing_file(tgt, &loopdev); + int count; + const char *bf = cache ? mnt_resolve_path(tgt, cache) : tgt; + + count = loopdev_count_by_backing_file(bf, &loopdev); if (count == 1) { DBG(CXT, mnt_debug_h(cxt, "umount: %s --> %s (retry)", tgt, loopdev)); @@ -169,15 +178,21 @@ try_loopdev: } } - *pfs = fs; + if (pfs) + *pfs = fs; free(loopdev); + DBG(CXT, mnt_debug_h(cxt, "umount fs: %s", fs ? mnt_fs_get_target(fs) : + "<not found>")); return fs ? 0 : 1; err: free(loopdev); return rc; } +/* this is umount replacement to mnt_context_apply_fstab(), use + * mnt_context_tab_applied() to check result. + */ static int lookup_umount_fs(struct libmnt_context *cxt) { const char *tgt; @@ -197,8 +212,8 @@ static int lookup_umount_fs(struct libmnt_context *cxt) if (rc < 0) return rc; if (rc == 1 || !fs) { - DBG(CXT, mnt_debug_h(cxt, "umount: cannot find %s in mtab", tgt)); - return 0; + DBG(CXT, mnt_debug_h(cxt, "umount: cannot find '%s' in mtab", tgt)); + return 0; /* this is correct! */ } if (fs != cxt->fs) { @@ -237,7 +252,7 @@ static int is_associated_fs(const char *devname, struct libmnt_fs *fs) if (!src) return 0; - /* check for offset option in @fs */ + /* check for the offset option in @fs */ optstr = (char *) mnt_fs_get_user_options(fs); if (optstr && @@ -300,7 +315,7 @@ static int evaluate_permissions(struct libmnt_context *cxt) DBG(CXT, mnt_debug_h(cxt, "umount: evaluating permissions")); - if (!(cxt->flags & MNT_FL_TAB_APPLIED)) { + if (!mnt_context_tab_applied(cxt)) { DBG(CXT, mnt_debug_h(cxt, "cannot find %s in mtab and you are not root", mnt_fs_get_target(cxt->fs))); @@ -317,7 +332,7 @@ static int evaluate_permissions(struct libmnt_context *cxt) } /* - * User mounts has to be in /etc/fstab + * User mounts have to be in /etc/fstab */ rc = mnt_context_get_fstab(cxt, &fstab); if (rc) @@ -336,18 +351,20 @@ static int evaluate_permissions(struct libmnt_context *cxt) * /dev/sda1 /mnt/zip auto user,noauto 0 0 * /dev/sda4 /mnt/zip auto user,noauto 0 0 * then "mount /dev/sda4" followed by "umount /mnt/zip" used to fail. - * So, we must not look for file, but for the pair (dev,file) in fstab. + * So, we must not look for the file, but for the pair (dev,file) in fstab. */ fs = mnt_table_find_pair(fstab, src, tgt, MNT_ITER_FORWARD); if (!fs) { /* * It's possible that there is /path/file.img in fstab and - * /dev/loop0 in mtab -- then we have to check releation + * /dev/loop0 in mtab -- then we have to check the relation * between loopdev and the file. */ fs = mnt_table_find_target(fstab, tgt, MNT_ITER_FORWARD); if (fs) { - const char *dev = mnt_fs_get_srcpath(cxt->fs); /* devname from mtab */ + struct libmnt_cache *cache = mnt_context_get_cache(cxt); + const char *sp = mnt_fs_get_srcpath(cxt->fs); /* devname from mtab */ + const char *dev = sp && cache ? mnt_resolve_path(sp, cache) : sp; if (!dev || !is_associated_fs(dev, fs)) fs = NULL; @@ -384,7 +401,7 @@ static int evaluate_permissions(struct libmnt_context *cxt) return 0; } /* - * Check user=<username> setting from mtab if there is user, owner or + * Check user=<username> setting from mtab if there is a user, owner or * group option in /etc/fstab */ if (u_flags & (MNT_MS_USER | MNT_MS_OWNER | MNT_MS_GROUP)) { @@ -409,6 +426,8 @@ static int evaluate_permissions(struct libmnt_context *cxt) if (optstr && !mnt_optstr_get_option(optstr, "user", &mtab_user, &sz) && sz) ok = !strncmp(curr_user, mtab_user, sz); + + free(curr_user); } if (ok) { @@ -539,7 +558,7 @@ int mnt_context_umount_setopt(struct libmnt_context *cxt, int c, char *arg) return rc; } -/* Check whether the kernel supports UMOUNT_NOFOLLOW flag */ +/* Check whether the kernel supports the UMOUNT_NOFOLLOW flag */ static int umount_nofollow_support(void) { int res = umount2("", UMOUNT_UNUSED); @@ -860,7 +879,7 @@ int mnt_context_umount(struct libmnt_context *cxt) * mnt_context_set_options_pattern() to simulate umount -a -O pattern * mnt_context_set_fstype_pattern() to simulate umount -a -t pattern * - * If the filesystem is not mounted or does not match defined criteria, + * If the filesystem is not mounted or does not match the defined criteria, * then the function mnt_context_next_umount() returns zero, but the @ignored is * non-zero. Note that the root filesystem is always ignored. * @@ -909,11 +928,11 @@ int mnt_context_next_umount(struct libmnt_context *cxt, DBG(CXT, mnt_debug_h(cxt, "next-umount: trying %s", tgt)); - /* ignore filesystems not match with options patterns */ + /* ignore filesystems which don't match options patterns */ if ((cxt->fstype_pattern && !mnt_fs_match_fstype(*fs, cxt->fstype_pattern)) || - /* ignore filesystems not match with type patterns */ + /* ignore filesystems which don't match type patterns */ (cxt->optstr_pattern && !mnt_fs_match_options(*fs, cxt->optstr_pattern))) { if (ignored) |
