summaryrefslogtreecommitdiffstats
path: root/libmount/src/context_mount.c
diff options
context:
space:
mode:
authorKarel Zak2017-04-26 17:27:02 +0200
committerKarel Zak2017-04-26 17:27:02 +0200
commit6dede2f2f7c5271b95c0361abd647af2a731b1dc (patch)
tree0fb5635e0154879a0d06d97eb7be594f7cce296f /libmount/src/context_mount.c
parentumount: fix typo (diff)
downloadkernel-qcow2-util-linux-6dede2f2f7c5271b95c0361abd647af2a731b1dc.tar.gz
kernel-qcow2-util-linux-6dede2f2f7c5271b95c0361abd647af2a731b1dc.tar.xz
kernel-qcow2-util-linux-6dede2f2f7c5271b95c0361abd647af2a731b1dc.zip
libmount: support MS_RDONLY on write-protected devices
This feature is supported by mount(8) only. It seems better move this code to libmount. The results is more simple mount(8) and the feature is accessible for all libmount users. Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src/context_mount.c')
-rw-r--r--libmount/src/context_mount.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index 6368e9ba8..1c8a62924 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -1083,6 +1083,7 @@ int mnt_context_mount(struct libmnt_context *cxt)
assert(cxt->helper_exec_status == 1);
assert(cxt->syscall_status == 1);
+again:
rc = mnt_context_prepare_mount(cxt);
if (!rc)
rc = mnt_context_prepare_update(cxt);
@@ -1090,6 +1091,32 @@ int mnt_context_mount(struct libmnt_context *cxt)
rc = mnt_context_do_mount(cxt);
if (!rc)
rc = mnt_context_update_tabs(cxt);
+
+ /*
+ * Read-only device; try mount filesystem read-only
+ */
+ if ((rc == -EROFS && !mnt_context_syscall_called(cxt)) /* before syscall; rdonly loopdev */
+ || mnt_context_get_syscall_errno(cxt) == EROFS /* syscall failed with EROFS */
+ || mnt_context_get_syscall_errno(cxt) == EACCES) /* syscall failed with EACCES */
+ {
+ unsigned long mflags = 0;
+
+ mnt_context_get_mflags(cxt, &mflags);
+
+ if (!(mflags & MS_RDONLY) /* not yet RDONLY */
+ && !(mflags & MS_REMOUNT) /* not remount */
+ && !(mflags & MS_BIND) /* not bin mount */
+ && !mnt_context_is_rwonly_mount(cxt)) { /* no explicit read-write */
+
+ assert(!(cxt->flags & MNT_FL_FORCED_RDONLY));
+ DBG(CXT, ul_debugobj(cxt, "write-protected source, trying RDONLY."));
+
+ mnt_context_reset_status(cxt);
+ mnt_context_set_mflags(cxt, mflags | MS_RDONLY);
+ cxt->flags |= MNT_FL_FORCED_RDONLY;
+ goto again;
+ }
+ }
return rc;
}