summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shlibs/mount/src/context.c15
-rw-r--r--shlibs/mount/src/context_mount.c5
-rw-r--r--shlibs/mount/src/context_umount.c4
-rw-r--r--shlibs/mount/src/mount.h.in6
-rw-r--r--shlibs/mount/src/mount.sym19
-rw-r--r--shlibs/mount/src/tab_update.c93
6 files changed, 115 insertions, 27 deletions
diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c
index 679152052..abe0dc9d0 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 b66b060e2..41673bc0f 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 b4da7373a..eeb7f2666 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 02acddd12..0a671fb2f 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 5d51cded1..7890a1403 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 e474e514d..cc0335fb8 100644
--- a/shlibs/mount/src/tab_update.c
+++ b/shlibs/mount/src/tab_update.c
@@ -117,6 +117,20 @@ int mnt_update_set_filename(mnt_update *upd, const char *filename, int userspace
}
/**
+ * 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;