- fix fix-umount-to-mount-race patch (bug 1399213).

This commit is contained in:
Ian Kent 2016-12-19 11:14:54 +08:00
parent cc01065e15
commit 38fe2a08cf
2 changed files with 87 additions and 16 deletions

View File

@ -1,6 +1,6 @@
am-utils-6.2 - fix umount to mount race am-utils-6.2 - fix umount to mount race
From: Richard P <richardp345@gmail.com> From: Ian Kent <raven@themaw.net>
If a mount request arrives while its mount fs is being umounted the If a mount request arrives while its mount fs is being umounted the
the reference count of the mount fs never reaches 1 so the location the reference count of the mount fs never reaches 1 so the location
@ -10,18 +10,39 @@ This leads to amd thinking the mount fs is still mounted and the
mount request succeeds without its corresponding target being mount request succeeds without its corresponding target being
mounted. mounted.
This patch from Richard P (with an added fix to a log message)
fixes the problem.
Signed-off-by: Richard P <richardp345@gmail.com>
Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Ian Kent <raven@themaw.net>
--- ---
amd/amfs_generic.c | 8 ++++++-- amd/amd.h | 1 +
amd/autil.c | 6 ++++++ amd/amfs_generic.c | 10 +++++++---
2 files changed, 12 insertions(+), 2 deletions(-) amd/autil.c | 9 +++++++++
amd/map.c | 13 ++++++++++++-
4 files changed, 29 insertions(+), 4 deletions(-)
--- am-utils-6.2.orig/amd/amfs_generic.c diff --git a/amd/amd.h b/amd/amd.h
+++ am-utils-6.2/amd/amfs_generic.c index f66f5b7..504bcf7 100644
--- a/amd/amd.h
+++ b/amd/amd.h
@@ -112,6 +112,7 @@
#define AMF_AUTOFS 0x0004 /* This node is part of an autofs filesystem */
#define AMF_REMOUNT 0x0008 /* This node needs to be remounted */
#define AMF_SOFTLOOKUP 0x0010 /* This node returns EIO if server is down */
+#define AMF_SOFTUNMOUNT 0x0020 /* unmount_node() returned EAGAIN, mount still referenced */
/*
* macros for struct mntfs (list of mounted filesystems)
diff --git a/amd/amfs_generic.c b/amd/amfs_generic.c
index 86d0ab7..7ab2829 100644
--- a/amd/amfs_generic.c
+++ b/amd/amfs_generic.c
@@ -178,7 +178,7 @@ amfs_lookup_node(am_node *mp, char *fname, int *error_return)
error = mf->mf_error;
continue;
}
- if (!(mf->mf_flags & MFF_MOUNTED) || (mf->mf_flags & MFF_UNMOUNTING)) {
+ if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) {
in_progrss:
/*
* If the fs is not mounted or it is unmounting then there
@@ -743,9 +743,13 @@ amfs_bgmount(struct continuation *cp) @@ -743,9 +743,13 @@ amfs_bgmount(struct continuation *cp)
if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) { if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) {
@ -38,18 +59,65 @@ Signed-off-by: Ian Kent <raven@themaw.net>
goto retry; goto retry;
} }
--- am-utils-6.2.orig/amd/autil.c diff --git a/amd/autil.c b/amd/autil.c
+++ am-utils-6.2/amd/autil.c index f44a0e2..1962c71 100644
@@ -703,6 +703,12 @@ am_unmounted(am_node *mp) --- a/amd/autil.c
+++ b/amd/autil.c
@@ -703,6 +703,15 @@ am_unmounted(am_node *mp)
} }
/* /*
+ * Clear the mounted flag in case there is a pending mount with + * Clear the mounted flag in case there is a pending mount with
+ * the same target fs. + * the same target fs and this is the last reference to it.
+ */ + */
+ mf->mf_flags &= ~MFF_MOUNTED; + if (mp->am_flags & AMF_SOFTUNMOUNT)
+ mp->am_flags &= ~AMF_SOFTUNMOUNT;
+ else
+ mf->mf_flags &= ~MFF_MOUNTED;
+ +
+ /* + /*
* If this is a pseudo-directory then adjust the link count * If this is a pseudo-directory then adjust the link count
* in the parent * in the parent
*/ */
diff --git a/amd/map.c b/amd/map.c
index a6df44b..cf5263e 100644
--- a/amd/map.c
+++ b/amd/map.c
@@ -819,11 +819,17 @@ unmount_node(opaque_t arg)
#endif /* HAVE_FS_AUTOFS */
if (mf->mf_refc == 1)
error = mf->mf_ops->umount_fs(mp, mf);
+
+ /* Mount was not actually unmounted, soft umount.
+ * Tell the caller about it.
+ */
+ if (!error && mf->mf_refc > 1)
+ error = EAGAIN;
}
/* do this again, it might have changed */
mf = mp->am_al->al_mnt;
- if (error) {
+ if (error && error != EAGAIN) {
errno = error; /* XXX */
dlog("%s: unmount: %m", mf->mf_mount);
}
@@ -870,6 +876,10 @@ free_map_if_success(int rc, int term, opaque_t arg)
#endif /* HAVE_FS_AUTOFS */
amd_stats.d_uerr++;
} else if (rc) {
+ if (rc == EAGAIN) {
+ mp->am_flags |= AMF_SOFTUNMOUNT;
+ goto done;
+ }
notify_child(mp, AMQ_UMNT_FAILED, rc, 0);
if (mf->mf_ops == &amfs_program_ops || rc == EBUSY)
plog(XLOG_STATS, "\"%s\" on %s still active", mp->am_path, mf->mf_mount);
@@ -885,6 +895,7 @@ free_map_if_success(int rc, int term, opaque_t arg)
#endif /* HAVE_FS_AUTOFS */
amd_stats.d_uerr++;
} else {
+done:
/*
* am_unmounted() will call notify_child() appropriately.
*/

View File

@ -2,7 +2,7 @@ Summary: Automount utilities including an updated version of Amd
Name: am-utils Name: am-utils
Version: 6.2.0 Version: 6.2.0
%define upstream_version 6.2 %define upstream_version 6.2
Release: 22%{?dist} Release: 23%{?dist}
License: BSD License: BSD
Epoch: 5 Epoch: 5
Group: System Environment/Daemons Group: System Environment/Daemons
@ -251,6 +251,9 @@ fi
%{_libdir}/libamu.so* %{_libdir}/libamu.so*
%changelog %changelog
* Thu Dec 1 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-23
- fix fix-umount-to-mount-race patch (bug 1399213).
* Mon Oct 3 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-22 * Mon Oct 3 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-22
- fix ambiguous else due to dlog() macro usage. - fix ambiguous else due to dlog() macro usage.