Blob Blame History Raw
autofs-5.1.8 - fix handling of incorrect return from umount_ent()

From: Ian Kent <raven@themaw.net>

Commit 0210535df4b ("autofs-5.1.0 - gaurd against incorrect umount
return") guards against umount_ent() returning a fail when the mount
has actually been umounted.

But we also see umount_ent() return success when in fact the mount has
not been umounted leading to incorrect handling of automounts.

So checking the return of umount_ent() isn't always giving the correct
result in more than just one case, consequently we should ignore the
result from the spawned umount(8) and check if the mount has in fact
been umounted.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG          |    1 +
 daemon/automount.c |    3 +--
 lib/mounts.c       |   19 ++++++++++---------
 3 files changed, 12 insertions(+), 11 deletions(-)

--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -93,6 +93,7 @@
 - avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
 - fix sysconf(3) return handling.
 - remove nonstrict parameter from tree_mapent_umount_offsets().
+- fix handling of incorrect return from umount_ent().
 
 xx/xx/2018 autofs-5.1.5
 - fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -606,8 +606,7 @@ static int umount_subtree_mounts(struct
 		struct mnt_list *mnt;
 
 		debug(ap->logopt, "unmounting dir = %s", path);
-		if (umount_ent(ap, path) &&
-		    is_mounted(path, MNTS_REAL)) {
+		if (umount_ent(ap, path)) {
 			warn(ap->logopt, "could not umount dir %s", path);
 			left++;
 			goto done;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1869,8 +1869,7 @@ static int tree_mapent_umount_offset(str
 	 */
 	if (oe->ioctlfd != -1 ||
 	    is_mounted(oe->key, MNTS_REAL)) {
-		if (umount_ent(ap, oe->key) &&
-		    is_mounted(oe->key, MNTS_REAL)) {
+		if (umount_ent(ap, oe->key)) {
 			debug(ap->logopt,
 			      "offset %s has active mount, invalidate",
 			      oe->key);
@@ -2010,8 +2009,7 @@ int tree_mapent_umount_offsets(struct ma
 		 */
 		if (is_mounted(mp, MNTS_REAL)) {
 			info(ap->logopt, "unmounting dir = %s", mp);
-			if (umount_ent(ap, mp) &&
-			    is_mounted(mp, MNTS_REAL)) {
+			if (umount_ent(ap, mp)) {
 				if (!tree_mapent_mount_offsets(oe, 1))
 					warn(ap->logopt,
 					     "failed to remount offset triggers");
@@ -2982,6 +2980,7 @@ void set_direct_mount_tree_catatonic(str
 
 int umount_ent(struct autofs_point *ap, const char *path)
 {
+	unsigned int mounted;
 	int rv;
 
 	if (ap->state != ST_SHUTDOWN_FORCE)
@@ -2993,6 +2992,8 @@ int umount_ent(struct autofs_point *ap,
 		rv = spawn_umount(ap->logopt, "-l", path, NULL);
 	}
 
+	mounted = is_mounted(path, MNTS_REAL);
+
 	if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
 		/*
 		 * Verify that we actually unmounted the thing.  This is a
@@ -3004,20 +3005,20 @@ int umount_ent(struct autofs_point *ap,
 		 * so that we do not try to call rmdir_path on the
 		 * directory.
 		 */
-		if (is_mounted(path, MNTS_REAL)) {
+		if (mounted) {
 			crit(ap->logopt,
 			     "the umount binary reported that %s was "
 			     "unmounted, but there is still something "
 			     "mounted on this path.", path);
-			rv = -1;
+			mounted = -1;
 		}
 	}
 
-	/* On success, check for mounted mount and remove it if found */
-	if (!rv)
+	/* If mount is gone remove it from mounted mounts list. */
+	if (!mounted)
 		mnts_remove_mount(path, MNTS_MOUNTED);
 
-	return rv;
+	return mounted;
 }
 
 int umount_amd_ext_mount(struct autofs_point *ap, const char *path)