summaryrefslogtreecommitdiffstats
path: root/libmount/src
diff options
context:
space:
mode:
authorKarel Zak2019-01-16 15:00:07 +0100
committerKarel Zak2019-01-16 15:00:07 +0100
commit189a1bf3b314a8fc48c29ea1e0287d5cc71021a0 (patch)
tree684d7415e61e2769f2053cc35801f0c8256d8396 /libmount/src
parentfsck.cramfs: fix utimes() usage (diff)
downloadkernel-qcow2-util-linux-189a1bf3b314a8fc48c29ea1e0287d5cc71021a0.tar.gz
kernel-qcow2-util-linux-189a1bf3b314a8fc48c29ea1e0287d5cc71021a0.tar.xz
kernel-qcow2-util-linux-189a1bf3b314a8fc48c29ea1e0287d5cc71021a0.zip
libmount: add support for MS_REMOUNT on --all
This patch add to support for remount-all operation to libmount and mount(8). For example: mount --all -o remount,ro -t vfat to remount read-only all VFAT filesystems. Addresses: https://github.com/karelzak/util-linux/issues/589 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src')
-rw-r--r--libmount/src/context.c43
-rw-r--r--libmount/src/context_mount.c106
-rw-r--r--libmount/src/libmount.h.in6
-rw-r--r--libmount/src/libmount.sym1
-rw-r--r--libmount/src/mountP.h1
5 files changed, 157 insertions, 0 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c
index b9c18d94f..af9b9ca50 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -193,6 +193,49 @@ int mnt_reset_context(struct libmnt_context *cxt)
return 0;
}
+struct libmnt_context *mnt_copy_context(struct libmnt_context *o)
+{
+ struct libmnt_context *n;
+
+ n = mnt_new_context();
+ if (!n)
+ return NULL;
+
+ DBG(CXT, ul_debugobj(n, "<---- clone ---->"));
+
+ n->flags = o->flags;
+
+ if (o->fs) {
+ n->fs = mnt_copy_fs(NULL, o->fs);
+ if (!n->fs)
+ goto failed;
+ }
+
+ n->mtab = o->mtab;
+ mnt_ref_table(n->mtab);
+
+ n->mtab = o->utab;
+ mnt_ref_table(n->utab);
+
+ if (o->helper)
+ n->helper = strdup(o->helper);
+ if (o->orig_user)
+ n->orig_user = strdup(o->orig_user);
+
+ n->mountflags = o->mountflags;
+ n->mountdata = o->mountdata;
+
+ mnt_context_reset_status(n);
+
+ n->table_fltrcb = o->table_fltrcb;
+ n->table_fltrcb_data = o->table_fltrcb_data;
+
+ return n;
+failed:
+ mnt_free_context(n);
+ return NULL;
+}
+
/**
* mnt_context_reset_status:
* @cxt: context
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index f914c9b1b..307da3c5c 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -1382,6 +1382,112 @@ int mnt_context_next_mount(struct libmnt_context *cxt,
return 0;
}
+
+/**
+ * mnt_context_next_remount:
+ * @cxt: context
+ * @itr: iterator
+ * @fs: returns the current filesystem
+ * @mntrc: returns the return code from mnt_context_mount()
+ * @ignored: returns 1 for non-matching
+ *
+ * This function tries to remount the next mounted filesystem (as returned by
+ * mnt_context_get_mtab()).
+ *
+ * You can filter out filesystems by:
+ * mnt_context_set_options_pattern() to simulate mount -a -O pattern
+ * mnt_context_set_fstype_pattern() to simulate mount -a -t pattern
+ *
+ * If the filesystem does not match defined criteria, then the
+ * mnt_context_next_remount() function returns zero, but the @ignored is
+ * non-zero.
+ *
+ * If mount(2) syscall or mount.type helper failed, then the
+ * mnt_context_renext_mount() function returns zero, but the @mntrc is non-zero.
+ * Use also mnt_context_get_status() to check if the filesystem was
+ * successfully mounted.
+ *
+ * See mnt_context_mount() for more details about errors and warnings.
+ *
+ * Returns: 0 on success,
+ * <0 in case of error (!= mount(2) errors)
+ * 1 at the end of the list.
+ */
+int mnt_context_next_remount(struct libmnt_context *cxt,
+ struct libmnt_iter *itr,
+ struct libmnt_fs **fs,
+ int *mntrc,
+ int *ignored)
+{
+ struct libmnt_context *remount_cxt = NULL;
+ struct libmnt_table *mtab;
+ const char *tgt;
+ int rc;
+
+ if (ignored)
+ *ignored = 0;
+ if (mntrc)
+ *mntrc = 0;
+
+ if (!cxt || !fs || !itr)
+ return -EINVAL;
+
+ rc = mnt_context_get_mtab(cxt, &mtab);
+ if (rc)
+ return rc;
+
+ rc = mnt_table_next_fs(mtab, itr, fs);
+ if (rc != 0)
+ return rc; /* more filesystems (or error) */
+
+ tgt = mnt_fs_get_target(*fs);
+
+ DBG(CXT, ul_debugobj(cxt, "next-remount: trying %s", tgt));
+
+ /* ignore filesystems which don't match options patterns */
+ if ((cxt->fstype_pattern && !mnt_fs_match_fstype(*fs,
+ cxt->fstype_pattern)) ||
+
+ /* ignore filesystems which don't match type patterns */
+ (cxt->optstr_pattern && !mnt_fs_match_options(*fs,
+ cxt->optstr_pattern))) {
+ if (ignored)
+ *ignored = 1;
+ DBG(CXT, ul_debugobj(cxt, "next-remount: not-match "
+ "[fstype: %s, t-pattern: %s, options: %s, O-pattern: %s]",
+ mnt_fs_get_fstype(*fs),
+ cxt->fstype_pattern,
+ mnt_fs_get_options(*fs),
+ cxt->optstr_pattern));
+ return 0;
+ }
+
+ /* make sure fstab is already read to avoid fstab parsing in cloned context */
+ mnt_context_get_fstab(cxt, NULL);
+
+ /* clone context */
+ remount_cxt = mnt_copy_context(cxt);
+ if (!remount_cxt)
+ return -ENOMEM;
+
+ rc = mnt_context_set_target(remount_cxt, tgt);
+ if (!rc) {
+ /*
+ * "-t <pattern>" is used to filter out fstab entries, but for ordinary
+ * mount operation -t means "-t <type>". We have to zeroize the pattern
+ * to avoid misinterpretation.
+ */
+ remount_cxt->fstype_pattern = NULL;
+ rc = mnt_context_mount(remount_cxt);
+
+ if (mntrc)
+ *mntrc = rc;
+ }
+
+ mnt_free_context(remount_cxt);
+ return 0;
+}
+
/*
* Returns 1 if @dir parent is shared
*/
diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in
index 1ce9995ec..a14bb6f3d 100644
--- a/libmount/src/libmount.h.in
+++ b/libmount/src/libmount.h.in
@@ -849,6 +849,12 @@ extern int mnt_context_next_mount(struct libmnt_context *cxt,
struct libmnt_fs **fs,
int *mntrc, int *ignored);
+extern int mnt_context_next_remount(struct libmnt_context *cxt,
+ struct libmnt_iter *itr,
+ struct libmnt_fs **fs,
+ int *mntrc,
+ int *ignored);
+
extern int mnt_context_prepare_mount(struct libmnt_context *cxt)
__ul_attribute__((warn_unused_result));
extern int mnt_context_do_mount(struct libmnt_context *cxt);
diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym
index 5145c876d..0087a3d23 100644
--- a/libmount/src/libmount.sym
+++ b/libmount/src/libmount.sym
@@ -344,4 +344,5 @@ MOUNT_2.33 {
MOUNT_2.34 {
mnt_guess_system_root;
+ mnt_context_next_remount;
} MOUNT_2.33;
diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
index 795ea69dc..7887c0a55 100644
--- a/libmount/src/mountP.h
+++ b/libmount/src/mountP.h
@@ -403,6 +403,7 @@ extern int __mnt_fs_set_fstype_ptr(struct libmnt_fs *fs, char *fstype)
__attribute__((nonnull(1)));
/* context.c */
+extern struct libmnt_context *mnt_copy_context(struct libmnt_context *o);
extern int mnt_context_mtab_writable(struct libmnt_context *cxt);
extern int mnt_context_utab_writable(struct libmnt_context *cxt);
extern const char *mnt_context_get_writable_tabpath(struct libmnt_context *cxt);