]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: export umount mountpoint look up code
authorKarel Zak <kzak@redhat.com>
Tue, 26 Feb 2013 13:19:05 +0000 (14:19 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 26 Feb 2013 13:19:05 +0000 (14:19 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context_umount.c
libmount/src/libmount.h.in
libmount/src/libmount.sym

index a31402cd9704c26f3d672f76f5425322b79fda16..113c53e07c886542d8de2f412678e611ffd8f1d3 100644 (file)
@@ -53,25 +53,28 @@ static int mtab_filter(struct libmnt_fs *fs, void *data)
        return 1;
 }
 
-static int lookup_umount_fs(struct libmnt_context *cxt)
+/**
+ * mnt_context_find_umount_fs:
+ * @cxt: mount context
+ * @tgt: mountpoint, device, ...
+ * @pfs: returns point to filesystem
+ *
+ * Returns: 0 on success, <0 on error, 1 if target filesystem not found
+ */
+int mnt_context_find_umount_fs(struct libmnt_context *cxt,
+                              const char *tgt,
+                              struct libmnt_fs **pfs)
 {
-       int rc, loopdev = 0;
-       const char *tgt;
+       int rc;
        struct libmnt_table *mtab = NULL;
        struct libmnt_fs *fs;
        struct libmnt_cache *cache = NULL;
-       char *cn_tgt = NULL;
-
-       assert(cxt);
-       assert(cxt->fs);
-
-       DBG(CXT, mnt_debug_h(cxt, "umount: lookup FS"));
+       char *cn_tgt = NULL, *loopdev = NULL;
 
-       tgt = mnt_fs_get_target(cxt->fs);
-       if (!tgt) {
-               DBG(CXT, mnt_debug_h(cxt, "umount: undefined target"));
+       if (!cxt || !tgt || !pfs)
                return -EINVAL;
-       }
+
+       DBG(CXT, mnt_debug_h(cxt, "umount: lookup FS for '%s'", tgt));
 
        /*
         * The mtab file maybe huge and on systems with utab we have to merge
@@ -109,6 +112,11 @@ static int lookup_umount_fs(struct libmnt_context *cxt)
                return rc;
        }
 
+       if (mnt_table_get_nents(mtab) == 0) {
+               DBG(CXT, mnt_debug_h(cxt, "umount: mtab empty"));
+               return 1;
+       }
+
 try_loopdev:
        fs = mnt_table_find_target(mtab, tgt, MNT_ITER_BACKWARD);
        if (!fs && mnt_context_is_swapmatch(cxt)) {
@@ -124,7 +132,8 @@ try_loopdev:
                                                        MNT_ITER_BACKWARD);
                        if (!fs1) {
                                DBG(CXT, mnt_debug_h(cxt, "mtab is broken?!?!"));
-                               return -EINVAL;
+                               rc = -EINVAL;
+                               goto err;
                        }
                        if (fs != fs1) {
                                /* Something was stacked over `file' on the
@@ -133,7 +142,8 @@ try_loopdev:
                                                "umount: %s: %s is mounted "
                                                "over it on the same point",
                                                tgt, mnt_fs_get_source(fs1)));
-                               return -EINVAL;
+                               rc = -EINVAL;
+                               goto err;
                        }
                }
        }
@@ -145,18 +155,11 @@ try_loopdev:
                struct stat st;
 
                if (stat(tgt, &st) == 0 && S_ISREG(st.st_mode)) {
-                       char *dev = NULL;
-                       int count = loopdev_count_by_backing_file(tgt, &dev);
-
+                       int count = loopdev_count_by_backing_file(tgt, &loopdev);
                        if (count == 1) {
                                DBG(CXT, mnt_debug_h(cxt,
-                                       "umount: %s --> %s (retry)", tgt, dev));
-                               mnt_fs_set_source(cxt->fs, tgt);
-                               mnt_fs_set_target(cxt->fs, dev);
-                               free(dev);
-                               tgt = mnt_fs_get_target(cxt->fs);
-
-                               loopdev = 1;            /* to avoid endless loop */
+                                       "umount: %s --> %s (retry)", tgt, loopdev));
+                               tgt = loopdev;
                                goto try_loopdev;
 
                        } else if (count > 1)
@@ -166,6 +169,35 @@ try_loopdev:
                }
        }
 
+       *pfs = fs;
+       if (loopdev)
+               free(loopdev);
+
+       return fs ? 0 : 1;
+err:
+       if (loopdev)
+               free(loopdev);
+       return rc;
+}
+
+static int lookup_umount_fs(struct libmnt_context *cxt)
+{
+       const char *tgt;
+       struct libmnt_fs *fs;
+       int rc;
+
+       assert(cxt);
+       assert(cxt->fs);
+
+       tgt = mnt_fs_get_target(cxt->fs);
+       if (!tgt) {
+               DBG(CXT, mnt_debug_h(cxt, "umount: undefined target"));
+               return -EINVAL;
+       }
+
+       rc = mnt_context_find_umount_fs(cxt, tgt, &fs);
+       if (rc < 0)
+               return rc;
        if (!fs) {
                DBG(CXT, mnt_debug_h(cxt, "umount: cannot find %s in mtab", tgt));
                return 0;
index 5d62a5566814cbc0dfd0b91185299aead64f8ca0..9ba8e909a2db90bbbaccfefb1e4fbcb6382c2641 100644 (file)
@@ -765,6 +765,9 @@ extern int mnt_context_do_mount(struct libmnt_context *cxt);
 extern int mnt_context_finalize_mount(struct libmnt_context *cxt);
 
 /* context_umount.c */
+extern int mnt_context_find_umount_fs(struct libmnt_context *cxt,
+                              const char *tgt,
+                              struct libmnt_fs **pfs);
 extern int mnt_context_next_umount(struct libmnt_context *cxt,
                                struct libmnt_iter *itr,
                                struct libmnt_fs **fs,
index 68b272a8d01e3207517ee2b750222a44904b2a2b..9fc0ee6b0e462099662ddb675d56f4113dddfa1d 100644 (file)
@@ -253,4 +253,5 @@ MOUNT_2.23 {
 global:
        mnt_fs_get_optional_fields;
        mnt_fs_get_propagation;
+       mnt_context_find_umount_fs;
 } MOUNT_2.22;