fix the problem of one iso can't mount directly twice by default

This commit is contained in:
openeuler-basic 2020-03-05 16:56:40 +08:00
parent 61ec7ce103
commit 0e7c96fe76
3 changed files with 206 additions and 6 deletions

View File

@ -0,0 +1,95 @@
From acd229fc2afe0c402cca3b21e0490be71dec2725 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 3 Mar 2020 10:55:28 +0100
Subject: [PATCH] libmount: move "already mounted" code to separate function
Signed-off-by: Karel Zak <kzak@redhat.com>
---
libmount/src/context_mount.c | 54 +++++++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index 088d132..0c4b765 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -1119,6 +1119,36 @@ int mnt_context_do_mount(struct libmnt_context *cxt)
return res;
}
+/*
+ * Returns mountinfo FS entry of context source patch if the source is already
+ * mounted. This function is used for "already mounted" message or to get FS of
+ * re-used loop device.
+ */
+static struct libmnt_fs *get_already_mounted_source(struct libmnt_context *cxt)
+{
+ const char *src;
+ struct libmnt_table *tb;
+
+ assert(cxt);
+
+ src = mnt_fs_get_srcpath(cxt->fs);
+
+ if (src && mnt_context_get_mtab(cxt, &tb) == 0) {
+ struct libmnt_iter itr;
+ struct libmnt_fs *fs;
+
+ mnt_reset_iter(&itr, MNT_ITER_FORWARD);
+ while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
+ const char *s = mnt_fs_get_srcpath(fs),
+ *t = mnt_fs_get_target(fs);
+
+ if (t && s && mnt_fs_streq_srcpath(fs, src))
+ return fs;
+ }
+ }
+ return NULL;
+}
+
/**
* mnt_context_finalize_mount:
* @cxt: context
@@ -1721,34 +1751,22 @@ int mnt_context_get_mount_excode(
break;
case EBUSY:
- {
- struct libmnt_table *tb;
-
if (!buf)
break;
if (mflags & MS_REMOUNT) {
snprintf(buf, bufsz, _("mount point is busy"));
break;
}
- if (src && mnt_context_get_mtab(cxt, &tb) == 0) {
- struct libmnt_iter itr;
- struct libmnt_fs *fs;
-
- mnt_reset_iter(&itr, MNT_ITER_FORWARD);
- while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
- const char *s = mnt_fs_get_srcpath(fs),
- *t = mnt_fs_get_target(fs);
-
- if (t && s && mnt_fs_streq_srcpath(fs, src)) {
- snprintf(buf, bufsz, _("%s already mounted on %s"), s, t);
- break;
- }
- }
+ if (src) {
+ struct libmnt_fs *fs = get_already_mounted_source(cxt);
+
+ if (fs && mnt_fs_get_target(fs))
+ snprintf(buf, bufsz, _("%s already mounted on %s"),
+ src, mnt_fs_get_target(fs));
}
if (!*buf)
snprintf(buf, bufsz, _("%s already mounted or mount point busy"), src);
break;
- }
case ENOENT:
if (tgt && lstat(tgt, &st)) {
if (buf)
--
1.8.3.1

View File

@ -0,0 +1,99 @@
From 11b916cdabd9f57a4cddf10fd743af2165930dcd Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 3 Mar 2020 11:39:10 +0100
Subject: [PATCH] libmount: try read-only mount on write-protected superblock
too
The classic mount(8) behavior is to try read-only on write-protected devices
if the first mount syscall attempt ends with EACCES.
It seems we can implement this feature also for EBUSY if the same mount source
is already mounted with "ro" superblock option.
The typical use-case is iso image (always read-only) mounted on two places.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1809124
Signed-off-by: Karel Zak <kzak@redhat.com>
---
libmount/src/context_mount.c | 21 ++++++++++++++++++---
sys-utils/mount.8 | 13 +++++++++----
2 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index 0c4b765..efd7050 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -1149,6 +1149,18 @@ static struct libmnt_fs *get_already_mounted_source(struct libmnt_context *cxt)
return NULL;
}
+/*
+ * Checks if source filesystem superblock is already ro-mounted. Note that we
+ * care about FS superblock as VFS node is irrelevant here.
+ */
+static int is_source_already_rdonly(struct libmnt_context *cxt)
+{
+ struct libmnt_fs *fs = get_already_mounted_source(cxt);
+ const char *opts = fs ? mnt_fs_get_fs_options(fs) : NULL;
+
+ return opts && mnt_optstr_get_option(opts, "ro", NULL, NULL) == 0;
+}
+
/**
* mnt_context_finalize_mount:
* @cxt: context
@@ -1250,11 +1262,14 @@ again:
rc = mnt_context_update_tabs(cxt);
/*
- * Read-only device; try mount filesystem read-only
+ * Read-only device or already read-only mounted FS.
+ * Try mount the 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 */
+ || mnt_context_get_syscall_errno(cxt) == EACCES /* syscall failed with EACCES */
+ || (mnt_context_get_syscall_errno(cxt) == EBUSY /* already ro-mounted FS */
+ && is_source_already_rdonly(cxt)))
{
unsigned long mflags = 0;
@@ -1630,7 +1645,7 @@ int mnt_context_get_mount_excode(
* Libmount success && syscall success.
*/
if (buf && mnt_context_forced_rdonly(cxt))
- snprintf(buf, bufsz, _("WARNING: device write-protected, mounted read-only"));
+ snprintf(buf, bufsz, _("WARNING: source write-protected, mounted read-only"));
return MNT_EX_SUCCESS;
}
diff --git a/sys-utils/mount.8 b/sys-utils/mount.8
index 698b0f0..eddf05a 100644
--- a/sys-utils/mount.8
+++ b/sys-utils/mount.8
@@ -931,12 +931,17 @@ Mount the partition that has the specified
Verbose mode.
.TP
.BR \-w , " \-\-rw" , " \-\-read\-write"
-Mount the filesystem read/write. The read-write is kernel default. A synonym is
+Mount the filesystem read/write. The read-write is kernel default and
+.BR mount (8)
+default is to try read-only if the previous mount syscall with read-write flags
+on write-protected devices of filesystems failed.
+.sp
+A synonym is
.BR "\-o rw" .
-Note that specify \fB\-w\fR on command line forces \fBmount\fR command
-to never try read-only mount on write-protected devices. The default is
-try read-only if the previous mount syscall with read-write flags failed.
+Note that specify \fB\-w\fR on command line forces \fBmount\fR command to never
+try read-only mount on write-protected devices or already mounted read-only
+filesystems.
.TP
.BR \-V , " \-\-version"
Display version information and exit.
--
1.8.3.1

View File

@ -1,13 +1,12 @@
%define compldir %{_datadir}/bash-completion/completions/
%define _pre_version__ 2.34
Name: util-linux
Version: %{_pre_version__}
Release: 3
Version: 2.34
Release: 4
Summary: A random collection of Linux utilities
License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain
URL: https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
Source0: https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v%{_pre_version__}/%{name}-%{version}.tar.xz
Source0: https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v%{version}/%{name}-%{version}.tar.xz
Source1: util-linux-login.pamd
Source2: util-linux-remote.pamd
Source3: util-linux-chsh-chfn.pamd
@ -36,8 +35,9 @@ Provides: /sbin/blockdev /sbin/findfs /sbin/fsck /sbin/nologin
Obsoletes: eject <= 2.1.5 rfkill <= 0.5 util-linux-ng < 2.19
Patch0000: 2.28-login-lastlog-create.patch
Patch6000: fdisk-fix-quit-dialog-for-non-libreadline-version.patch
Patch0001: fdisk-fix-quit-dialog-for-non-libreadline-version.patch
Patch0002: libmount-move-already-mounted-code-to-separate-funct.patch
Patch0003: libmount-try-read-only-mount-on-write-protected-supe.patch
%description
The util-linux package contains a random collection of files that
@ -380,6 +380,12 @@ fi
%{_mandir}/man8/{swapoff.8*,swapon.8*,switch_root.8*,umount.8*,wdctl.8.gz,wipefs.8*,zramctl.8*}
%changelog
* Thu Mar 5 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.34-4
- Type:enhancement
- ID:NA
- SUG:NA
- DESC:fix the problem of one iso can't mount directly twice by default
* Fri Feb 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.34-3
- Type:enhancement
- ID:NA