From 36bda5cbd0a18b2ae6aadd36fd54813f29566602 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 17 Dec 2010 17:46:24 +0100 Subject: [PATCH] libmount: cleanup MS_RDONLY usageand mnt_update_* symbols Signed-off-by: Karel Zak --- shlibs/mount/src/context.c | 15 +++++ shlibs/mount/src/context_mount.c | 5 ++ shlibs/mount/src/context_umount.c | 4 +- shlibs/mount/src/mount.h.in | 6 +- shlibs/mount/src/mount.sym | 19 +++---- shlibs/mount/src/tab_update.c | 93 +++++++++++++++++++++++++++---- 6 files changed, 115 insertions(+), 27 deletions(-) diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c index 67915205..abe0dc9d 100644 --- a/shlibs/mount/src/context.c +++ b/shlibs/mount/src/context.c @@ -1069,6 +1069,11 @@ int mnt_context_prepare_update(mnt_context *cxt) assert(cxt->action); assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); + if (cxt->mountflags & MS_PROPAGATION) { + DBG(CXT, mnt_debug_h(cxt, "skip update: MS_PROPAGATION")); + return 0; + } + target = mnt_fs_get_target(cxt->fs); if (cxt->action == MNT_ACT_UMOUNT && target && !strcmp(target, "/")) @@ -1106,6 +1111,8 @@ int mnt_context_prepare_update(mnt_context *cxt) int mnt_context_update_tabs(mnt_context *cxt) { + unsigned long fl; + assert(cxt); if (cxt->flags & MNT_FL_NOMTAB) { @@ -1125,6 +1132,14 @@ int mnt_context_update_tabs(mnt_context *cxt) return 0; } + fl = mnt_update_get_mountflags(cxt->update); + if ((cxt->mountflags & MS_RDONLY) != (fl & MS_RDONLY)) + /* + * fix MS_RDONLY in options + */ + mnt_update_force_rdonly(cxt->update, + cxt->mountflags & MS_RDONLY); + return mnt_update_tab(cxt->update, mnt_context_get_lock(cxt)); } diff --git a/shlibs/mount/src/context_mount.c b/shlibs/mount/src/context_mount.c index b66b060e..41673bc0 100644 --- a/shlibs/mount/src/context_mount.c +++ b/shlibs/mount/src/context_mount.c @@ -353,6 +353,11 @@ static int do_mount(mnt_context *cxt, const char *try_type) if (fs) rc = mnt_fs_set_fstype(fs, try_type); } + + /* TODO: check if the result is really read-only/read-write + * and if necessary update cxt->mountflags + */ + return rc; } diff --git a/shlibs/mount/src/context_umount.c b/shlibs/mount/src/context_umount.c index b4da7373..eeb7f266 100644 --- a/shlibs/mount/src/context_umount.c +++ b/shlibs/mount/src/context_umount.c @@ -496,7 +496,7 @@ int mnt_context_do_umount(mnt_context *cxt) if ((cxt->flags & MNT_FL_RDONLY_UMOUNT) && (cxt->mountflags & (MS_RDONLY | MS_REMOUNT))) { /* - * update options to handle remount to read-only + * remount --> read-only mount */ const char *o = mnt_fs_get_vfs_options(cxt->fs); char *n = o ? strdup(o) : NULL; @@ -509,7 +509,7 @@ int mnt_context_do_umount(mnt_context *cxt) if (!rc) rc = mnt_fs_set_vfs_options(cxt->fs, n); - /* refresh options in /etc/mtab as well */ + /* use "remount" instead of "umount" in /etc/mtab */ if (!rc && cxt->update && cxt->mtab_writable) rc = mnt_update_set_fs(cxt->update, cxt->mountflags, NULL, cxt->fs); diff --git a/shlibs/mount/src/mount.h.in b/shlibs/mount/src/mount.h.in index 02acddd1..0a671fb2 100644 --- a/shlibs/mount/src/mount.h.in +++ b/shlibs/mount/src/mount.h.in @@ -307,10 +307,12 @@ extern int mnt_tab_find_next_fs(mnt_tab *tb, mnt_iter *itr, extern mnt_update *mnt_new_update(void); extern void mnt_free_update(mnt_update *upd); extern int mnt_update_is_ready(mnt_update *upd); -extern int mnt_update_set_fs(mnt_update *upd, int mountflags, +extern int mnt_update_set_fs(mnt_update *upd, unsigned long mountflags, const char *target, mnt_fs *fs); extern int mnt_update_tab(mnt_update *upd, mnt_lock *lc); - +extern unsigned long mnt_update_get_mountflags(mnt_update *upd); +extern int mnt_update_force_rdonly(mnt_update *upd, int rdonly); +extern const char *mnt_update_get_filename(mnt_update *upd); /* context.c */ diff --git a/shlibs/mount/src/mount.sym b/shlibs/mount/src/mount.sym index 5d51cded..7890a140 100644 --- a/shlibs/mount/src/mount.sym +++ b/shlibs/mount/src/mount.sym @@ -128,18 +128,15 @@ global: mnt_tab_update_file; mnt_unlock_file; mnt_unmangle; - mnt_update_disable_lock; - mnt_update_file; - mnt_update_get_filename; - mnt_update_get_format; - mnt_update_get_lock; - mnt_update_prepare_update; - mnt_update_set_action; - mnt_update_set_filename; - mnt_update_set_format; + mnt_new_update; + mnt_free_update; + mnt_update_is_ready; mnt_update_set_fs; - mnt_update_set_mountflags; - mnt_update_set_old_target; + mnt_update_tab; + mnt_update_get_mountflags; + mnt_update_force_rdonly; + mnt_update_get_filename; + local: *; }; diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c index e474e514..cc0335fb 100644 --- a/shlibs/mount/src/tab_update.c +++ b/shlibs/mount/src/tab_update.c @@ -116,6 +116,20 @@ int mnt_update_set_filename(mnt_update *upd, const char *filename, int userspace return 0; } +/** + * mnt_update_get_filename: + * @upd: update + * + * This function returns file name (e.g. /etc/mtab) if the update + * should be covered by mnt_lock, otherwise returne NULL. + * + * Returns: pointer to filename that will be updated or NULL in case of error. + */ +const char *mnt_update_get_filename(mnt_update *upd) +{ + return upd && !upd->userspace_only ? upd->filename : NULL; +} + /** * mnt_update_is_ready: * @upd: update handler @@ -137,7 +151,7 @@ int mnt_update_is_ready(mnt_update *upd) * * Returns: -1 in case on error, 0 on success, 1 if update is unnecessary. */ -int mnt_update_set_fs(mnt_update *upd, int mountflags, +int mnt_update_set_fs(mnt_update *upd, unsigned long mountflags, const char *target, mnt_fs *fs) { int rc; @@ -149,7 +163,7 @@ int mnt_update_set_fs(mnt_update *upd, int mountflags, return -EINVAL; DBG(UPDATE, mnt_debug_h(upd, - "reseting FS [fs=0x%p, target=%s, flags=0x%08x]", + "reseting FS [fs=0x%p, target=%s, flags=0x%08lx]", fs, target, mountflags)); if (fs) { DBG(UPDATE, mnt_debug_h(upd, "FS template:")); @@ -161,6 +175,11 @@ int mnt_update_set_fs(mnt_update *upd, int mountflags, upd->ready = FALSE; upd->fs = NULL; upd->target = NULL; + upd->mountflags = 0; + + if (mountflags & MS_PROPAGATION) + return 1; + upd->mountflags = mountflags; rc = mnt_update_set_filename(upd, NULL, 0); @@ -190,7 +209,7 @@ int mnt_update_set_fs(mnt_update *upd, int mountflags, return 0; } -/* +/** * Returns update filesystem or NULL */ mnt_fs *mnt_update_get_fs(mnt_update *upd) @@ -198,6 +217,57 @@ mnt_fs *mnt_update_get_fs(mnt_update *upd) return upd ? upd->fs : NULL; } +/** + * mnt_update_get_mountflags: + * @upd: update + * + * Returns: mount flags as was set by mnt_update_set_fs() + */ +unsigned long mnt_update_get_mountflags(mnt_update *upd) +{ + return upd ? upd->mountflags : 0; +} + +/** + * mnt_update_force_rdonly: + * @upd: update + * @rdonly: is read-only? + * + * Returns: 0 on success and negative number in case of error. + */ +int mnt_update_force_rdonly(mnt_update *upd, int rdonly) +{ + int rc = 0; + + if (!upd || !upd->fs) + return -EINVAL; + + if (rdonly && (upd->mountflags & MS_RDONLY)) + return 0; + if (!rdonly && !(upd->mountflags & MS_RDONLY)) + return 0; + + if (!upd->userspace_only) { + /* /etc/mtab -- we care about VFS options there */ + const char *o = mnt_fs_get_vfs_options(upd->fs); + char *n = o ? strdup(o) : NULL; + + if (n) + mnt_optstr_remove_option(&n, rdonly ? "rw" : "ro"); + if (!mnt_optstr_prepend_option(&n, rdonly ? "ro" : "rw", NULL)) + rc = mnt_fs_set_vfs_options(upd->fs, n); + + free(n); + } + + if (rdonly) + upd->mountflags &= ~MS_RDONLY; + else + upd->mountflags |= MS_RDONLY; + + return rc; +} + /* * Allocates (but does not write) utab entry for mount/remount. This function * should be called *before* mount(2) syscall. @@ -718,19 +788,12 @@ static void lock_fallback(void) static int update(const char *target, mnt_fs *fs, unsigned long mountflags) { - int rc, writable = 0; - const char *filename = NULL; + int rc; mnt_update *upd; + const char *filename; DBG(UPDATE, mnt_debug("update test")); - rc = mnt_has_regular_mtab(&filename, &writable); - if (rc && writable) { - /* normal mtab, lock required */ - lock = mnt_new_lock(filename, 0); - if (lock) - atexit(lock_fallback); - } upd = mnt_new_update(); if (!upd) return -ENOMEM; @@ -748,6 +811,12 @@ static int update(const char *target, mnt_fs *fs, unsigned long mountflags) /* [... here should be mount(2) call ...] */ + filename = mnt_update_get_filename(upd); + if (filename) { + lock = mnt_new_lock(filename, 0); + if (lock) + atexit(lock_fallback); + } rc = mnt_update_tab(upd, lock); done: return rc; -- 2.39.5