Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37884987
en ru br
ALT Linux repos
S:5.1.8-alt6
D:5.0.3-alt1.1
5.0: 5.0.4-alt2
4.1: 5.0.1-alt1
4.0: 5.0.1-alt1
3.0: 4.1.4-alt0.3

Other repositories
Upstream:4.1.4

Group :: System/Kernel and hardware
RPM: autofs

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: autofs-5.0.3-check-for-kernel-automount.patch
Download


autofs 5.0.3 - check for exported mounts automatically mounted by kernel
From: Ian Kent <raven@themaw.net>
If a server exports file systems that are automatically mounted by
the kernel client autofs will mistakenly over mount them when it
constructs and mounts its multi-mount triggers.
This patch makes autofs check for this case and ignores them if the
kernel mounts them while it mounts multi-mount triggers.
We don't want to fight with NFS over mounting these because it
confuses autofs and they magically go away when the owner mount is
umounted. This isn't ideal because autofs will mount these mounts
while constructing its multi-mount triggers but it is unavoidable
at the moment.
---
 CHANGELOG           |    1 +
 daemon/direct.c     |   26 ++++++++++++++++++--------
 include/automount.h |    4 ++++
 lib/parse_subs.c    |   26 ++++++++++++++++++--------
 4 files changed, 41 insertions(+), 16 deletions(-)
--- autofs-5.0.3.orig/CHANGELOG
+++ autofs-5.0.3/CHANGELOG
@@ -12,6 +12,7 @@
 - init SASL callbacks on every ldap lookup library load.
 - fix incorrect match of map type name when included in map name.
 - fix incorrect pthreads condition handling for mount requests.
+- add check for exports automatically mounted by NFS kernel client.
  
 14/01/2008 autofs-5.0.3
 -----------------------
--- autofs-5.0.3.orig/daemon/direct.c
+++ autofs-5.0.3/daemon/direct.c
@@ -664,12 +664,12 @@ int mount_autofs_offset(struct autofs_po
 		if (ap->state != ST_READMAP)
 			warn(ap->logopt,
 			      "trigger %s already mounted", me->key);
-		return 0;
+		return MOUNT_OFFSET_OK;
 	}
 
 	if (me->ioctlfd != -1) {
 		error(ap->logopt, "active offset mount %s", me->key);
-		return -1;
+		return MOUNT_OFFSET_FAIL;
 	}
 
 	status = pthread_once(&key_mnt_params_once, key_mnt_params_init);
@@ -683,7 +683,7 @@ int mount_autofs_offset(struct autofs_po
 			crit(ap->logopt,
 			  "mnt_params value create failed for offset mount %s",
 			  me->key);
-			return 0;
+			return MOUNT_OFFSET_OK;
 		}
 		mp->options = NULL;
 
@@ -697,12 +697,22 @@ int mount_autofs_offset(struct autofs_po
 	if (!mp->options) {
 		mp->options = make_options_string(ap->path, ap->kpipefd, "offset");
 		if (!mp->options)
-			return 0;
+			return MOUNT_OFFSET_OK;
 	}
 
 	/* In case the directory doesn't exist, try to mkdir it */
 	if (mkdir_path(me->key, 0555) < 0) {
 		if (errno == EEXIST) {
+			/*
+			 * If the mount point directory is a real mount
+			 * and it isn't the root offset then it must be
+			 * a mount that has been automatically mounted by
+			 * the kernel NFS client.
+			 */
+			if (me->multi != me &&
+			    is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL))
+				return MOUNT_OFFSET_IGNORE;
+
 			/* 
 			 * If we recieve an error, and it's EEXIST
 			 * we know the directory was not created.
@@ -721,13 +731,13 @@ int mount_autofs_offset(struct autofs_po
 			debug(ap->logopt,
 			     "can't create mount directory: %s, %s",
 			     me->key, estr);
-			return -1;
+			return MOUNT_OFFSET_FAIL;
 		} else {
 			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 			crit(ap->logopt,
 			     "failed to create mount directory: %s, %s",
 			     me->key, estr);
-			return -1;
+			return MOUNT_OFFSET_FAIL;
 		}
 	} else {
 		/* No errors so the directory was successfully created */
@@ -787,7 +797,7 @@ int mount_autofs_offset(struct autofs_po
 
 	debug(ap->logopt, "mounted trigger %s", me->key);
 
-	return 0;
+	return MOUNT_OFFSET_OK;
 
 out_close:
 	close(ioctlfd);
@@ -797,7 +807,7 @@ out_err:
 	if (stat(me->key, &st) == 0 && me->dir_created)
 		 rmdir_path(ap, me->key, st.st_dev);
 
-	return -1;
+	return MOUNT_OFFSET_FAIL;
 }
 
 static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt)
--- autofs-5.0.3.orig/include/automount.h
+++ autofs-5.0.3/include/automount.h
@@ -468,6 +468,10 @@ struct autofs_point {
 
 /* Standard functions used by daemon or modules */
 
+#define	MOUNT_OFFSET_OK		0
+#define	MOUNT_OFFSET_FAIL	-1
+#define MOUNT_OFFSET_IGNORE	-2
+
 void *handle_mounts(void *arg);
 int umount_multi(struct autofs_point *ap, const char *path, int incl);
 int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token);
--- autofs-5.0.3.orig/lib/parse_subs.c
+++ autofs-5.0.3/lib/parse_subs.c
@@ -390,7 +390,7 @@ int mount_multi_triggers(struct autofs_p
 	struct list_head *pos = NULL;
 	unsigned int fs_path_len;
 	unsigned int mounted;
-	int start;
+	int ret, start;
 
 	fs_path_len = strlen(root) + strlen(base);
 	if (fs_path_len > PATH_MAX)
@@ -411,15 +411,25 @@ int mount_multi_triggers(struct autofs_p
 		}
 
 		oe = cache_lookup_offset(base, offset, start, &me->multi_list);
-		if (!oe)
+		if (!oe || !oe->mapent)
 			goto cont;
 
 		debug(ap->logopt, "mount offset %s", oe->key);
 
-		if (mount_autofs_offset(ap, oe) < 0)
-			warn(ap->logopt, "failed to mount offset");
-		else
+		ret = mount_autofs_offset(ap, oe);
+		if (ret >= MOUNT_OFFSET_OK)
 			mounted++;
+		else {
+			if (ret != MOUNT_OFFSET_IGNORE)
+				warn(ap->logopt, "failed to mount offset");
+			else {
+				debug(ap->logopt,
+				      "ignoring \"nohide\" trigger %s",
+				      oe->key);
+				free(oe->mapent);
+				oe->mapent = NULL;
+			}
+		}
 cont:
 		offset = cache_get_offset(base,
 				offset, start, &me->multi_list, &pos);
@@ -457,7 +467,7 @@ int umount_multi_triggers(struct autofs_
 
 		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
 		/* root offset is a special case */
-		if (!oe || (strlen(oe->key) - start) == 1)
+		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
 			continue;
 
 		/*
@@ -481,7 +491,7 @@ int umount_multi_triggers(struct autofs_
 	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
 		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
 		/* root offset is a special case */
-		if (!oe || (strlen(oe->key) - start) == 1)
+		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
 			continue;
 
 		debug(ap->logopt, "umount offset %s", oe->key);
@@ -505,7 +515,7 @@ int umount_multi_triggers(struct autofs_
 		if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) {
 			info(ap->logopt, "unmounting dir = %s", root);
 			if (umount_ent(ap, root)) {
-				if (!mount_multi_triggers(ap, root, me, "/"))
+				if (mount_multi_triggers(ap, root, me, "/") < 0)
 					warn(ap->logopt,
 					     "failed to remount offset triggers");
 				return left++;
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin