summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2011-02-02 21:30:17 +0100
committerKarel Zak2011-02-02 21:30:17 +0100
commit9376009202a6371a28abb335b92a0063569b0fd1 (patch)
tree8b86fd1567e3fd40c914bfc85468c4a48db69049
parentlibmount: cleanup high-level mount API (diff)
downloadkernel-qcow2-util-linux-9376009202a6371a28abb335b92a0063569b0fd1.tar.gz
kernel-qcow2-util-linux-9376009202a6371a28abb335b92a0063569b0fd1.tar.xz
kernel-qcow2-util-linux-9376009202a6371a28abb335b92a0063569b0fd1.zip
libmount: add low-level API for umount
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--shlibs/mount/docs/libmount-sections.txt10
-rw-r--r--shlibs/mount/src/context_umount.c115
-rw-r--r--shlibs/mount/src/libmount.h.in6
-rw-r--r--shlibs/mount/src/libmount.sym5
4 files changed, 117 insertions, 19 deletions
diff --git a/shlibs/mount/docs/libmount-sections.txt b/shlibs/mount/docs/libmount-sections.txt
index d351aab53..ce744f3a2 100644
--- a/shlibs/mount/docs/libmount-sections.txt
+++ b/shlibs/mount/docs/libmount-sections.txt
@@ -185,6 +185,8 @@ mnt_context_enable_loopdel
mnt_context_enable_rdonly_umount
mnt_context_enable_sloppy
mnt_context_enable_verbose
+mnt_context_finalize_mount
+mnt_context_finalize_umount
mnt_context_get_cache
mnt_context_get_fs
mnt_context_get_fstab
@@ -197,6 +199,9 @@ mnt_context_get_status
mnt_context_get_target
mnt_context_get_user_mflags
mnt_context_is_restricted
+mnt_context_mount
+mnt_context_prepare_mount
+mnt_context_prepare_umount
mnt_context_set_cache
mnt_context_set_fs
mnt_context_set_fstab
@@ -211,12 +216,9 @@ mnt_context_set_source
mnt_context_set_target
mnt_context_set_user_mflags
mnt_context_strerror
-mnt_context_mount
+mnt_context_umount
mnt_free_context
mnt_new_context
mnt_reset_context
-mnt_context_prepare_mount
-mnt_context_do_mount
-mnt_context_finalize_mount
</SECTION>
diff --git a/shlibs/mount/src/context_umount.c b/shlibs/mount/src/context_umount.c
index 7f71ef2be..d38e5de6e 100644
--- a/shlibs/mount/src/context_umount.c
+++ b/shlibs/mount/src/context_umount.c
@@ -443,27 +443,31 @@ static int do_umount(struct libmnt_context *cxt)
}
/**
- * mnt_context_do_umount:
+ * mnt_context_prepare_umount:
* @cxt: mount context
*
- * Umount filesystem by umount(2) or fork()+exec(/sbin/umount.type).
- *
- * See also mnt_context_disable_helpers().
+ * Prepare context for umounting, unnecessary for mnt_context_umount().
*
* Returns: 0 on success, and negative number in case of error.
*/
-int mnt_context_do_umount(struct libmnt_context *cxt)
+int mnt_context_prepare_umount(struct libmnt_context *cxt)
{
int rc;
+ assert(cxt);
+ assert(cxt->fs);
+ assert(cxt->helper_exec_status == 1);
+ assert(cxt->syscall_status == 1);
+
if (!cxt || !cxt->fs || (cxt->fs->flags & MNT_FS_SWAP))
return -EINVAL;
if (!mnt_fs_get_source(cxt->fs) && !mnt_fs_get_target(cxt->fs))
return -EINVAL;
+ if (cxt->flags & MNT_FL_PREPARED)
+ return 0;
free(cxt->helper); /* be paranoid */
cxt->helper = NULL;
-
cxt->action = MNT_ACT_UMOUNT;
rc = lookup_umount_fs(cxt);
@@ -475,20 +479,41 @@ int mnt_context_do_umount(struct libmnt_context *cxt)
rc = mnt_context_prepare_target(cxt);
if (!rc && !cxt->helper)
rc = mnt_context_prepare_helper(cxt, "umount", NULL);
-
- /* TODO : evaluate fstype pattern */
-
/* TODO
if ((cxt->flags & MNT_FL_LOOPDEL) &&
(!mnt_is_loopdev(src) || mnt_loopdev_is_autoclear(src)))
cxt->flags &= ~MNT_FL_LOOPDEL;
*/
- if (!rc)
- rc = mnt_context_prepare_update(cxt);
if (rc) {
- DBG(CXT, mnt_debug_h(cxt, "prepared umount failed"));
+ DBG(CXT, mnt_debug_h(cxt, "umount: preparing failed"));
return rc;
}
+ cxt->flags |= MNT_FL_PREPARED;
+ return rc;
+}
+
+/**
+ * mnt_context_do_umount:
+ * @cxt: mount context
+ *
+ * Umount filesystem by umount(2) or fork()+exec(/sbin/umount.type).
+ * Unnecessary for mnt_context_umount().
+ *
+ * See also mnt_context_disable_helpers().
+ *
+ * Returns: 0 on success, and negative number in case of error.
+ */
+int mnt_context_do_umount(struct libmnt_context *cxt)
+{
+ int rc;
+
+ assert(cxt);
+ assert(cxt->fs);
+ assert(cxt->helper_exec_status == 1);
+ assert(cxt->syscall_status == 1);
+ assert((cxt->flags & MNT_FL_PREPARED));
+ assert((cxt->action == MNT_ACT_UMOUNT));
+ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
rc = do_umount(cxt);
if (rc)
@@ -503,7 +528,7 @@ int mnt_context_do_umount(struct libmnt_context *cxt)
if ((cxt->flags & MNT_FL_RDONLY_UMOUNT) &&
(cxt->mountflags & (MS_RDONLY | MS_REMOUNT))) {
/*
- * remount --> read-only mount
+ * fix options, remount --> read-only mount
*/
const char *o = mnt_fs_get_vfs_options(cxt->fs);
char *n = o ? strdup(o) : NULL;
@@ -522,5 +547,67 @@ int mnt_context_do_umount(struct libmnt_context *cxt)
cxt->mountflags, NULL, cxt->fs);
}
- return rc ? : mnt_context_update_tabs(cxt);
+ return rc;
+}
+
+/**
+ * mnt_context_finalize_umount:
+ * @cxt: context
+ *
+ * Mtab update, etc. Unnecessary for mnt_context_umount(), but should be called
+ * after mnt_context_do_umount(). See also mnt_context_set_syscall_status().
+ *
+ * Returns: negative number on error, 0 on success.
+ */
+int mnt_context_finalize_umount(struct libmnt_context *cxt)
+{
+ int rc;
+
+ assert(cxt);
+ assert(cxt->fs);
+ assert((cxt->flags & MNT_FL_PREPARED));
+ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
+
+ rc = mnt_context_prepare_update(cxt);
+ if (!rc)
+ rc = mnt_context_update_tabs(cxt);;
+ return rc;
+}
+
+
+/**
+ * mnt_context_umount:
+ * @cxt: umount context
+ *
+ * High-level, umounts filesystem by umount(2) or fork()+exec(/sbin/umount.type).
+ *
+ * This is similar to:
+ *
+ * mnt_context_prepare_umount(cxt);
+ * mnt_context_do_umount(cxt);
+ * mnt_context_finalize_umount(cxt);
+ *
+ * See also mnt_context_disable_helpers().
+ *
+ * Returns: 0 on success, and negative number in case of error. WARNING: error
+ * does not mean that umount(2) syscall or mount.type helper wasn't
+ * sucessfully called. Check mnt_context_get_status() after error!
+ */
+int mnt_context_umount(struct libmnt_context *cxt)
+{
+ int rc;
+
+ assert(cxt);
+ assert(cxt->fs);
+ assert(cxt->helper_exec_status == 1);
+ assert(cxt->syscall_status == 1);
+
+ rc = mnt_context_prepare_umount(cxt);
+ if (!rc)
+ rc = mnt_context_prepare_update(cxt);
+ if (!rc)
+ rc = mnt_context_do_umount(cxt);
+ if (!rc)
+ rc = mnt_context_update_tabs(cxt);
+ return rc;
}
diff --git a/shlibs/mount/src/libmount.h.in b/shlibs/mount/src/libmount.h.in
index 9870ba792..81fa1df33 100644
--- a/shlibs/mount/src/libmount.h.in
+++ b/shlibs/mount/src/libmount.h.in
@@ -417,10 +417,16 @@ extern int mnt_context_strerror(struct libmnt_context *cxt, char *buf,
size_t bufsiz);
extern int mnt_context_mount(struct libmnt_context *cxt);
+extern int mnt_context_umount(struct libmnt_context *cxt);
extern int mnt_context_prepare_mount(struct libmnt_context *cxt);
extern int mnt_context_do_mount(struct libmnt_context *cxt);
extern int mnt_context_finalize_mount(struct libmnt_context *cxt);
+
+extern int mnt_context_prepare_umount(struct libmnt_context *cxt);
+extern int mnt_context_do_umount(struct libmnt_context *cxt);
+extern int mnt_context_finalize_umount(struct libmnt_context *cxt);
+
extern int mnt_context_set_syscall_status(struct libmnt_context *cxt, int status);
extern int mnt_context_do_umount(struct libmnt_context *cxt);
diff --git a/shlibs/mount/src/libmount.sym b/shlibs/mount/src/libmount.sym
index 47488b512..78f4f7e2f 100644
--- a/shlibs/mount/src/libmount.sym
+++ b/shlibs/mount/src/libmount.sym
@@ -23,6 +23,7 @@ global:
mnt_context_enable_sloppy;
mnt_context_enable_verbose;
mnt_context_finalize_mount;
+ mnt_context_finalize_umount;
mnt_context_get_cache;
mnt_context_get_fs;
mnt_context_get_fstab;
@@ -44,8 +45,10 @@ global:
mnt_context_is_restricted;
mnt_context_is_sloppy;
mnt_context_is_verbose;
+ mnt_context_mount;
mnt_context_mounthelper_setopt;
mnt_context_prepare_mount;
+ mnt_context_prepare_umount;
mnt_context_set_cache;
mnt_context_set_fs;
mnt_context_set_fstab;
@@ -61,6 +64,7 @@ global:
mnt_context_set_target;
mnt_context_set_user_mflags;
mnt_context_strerror;
+ mnt_context_umount;
mnt_copy_fs;
mnt_free_cache;
mnt_free_context;
@@ -133,7 +137,6 @@ global:
mnt_mangle;
mnt_match_fstype;
mnt_match_options;
- mnt_context_mount;
mnt_new_cache;
mnt_new_context;
mnt_new_fs;