Blame SOURCES/autofs-5.0.9-amd-lookup-fix-host-mount-naming.patch

6bbd11
autofs-5.0.9 - amd lookup fix host mount naming
6bbd11
6bbd11
From: Ian Kent <raven@themaw.net>
6bbd11
6bbd11
Currently the amd host mount type assumes the lookup name is
6bbd11
the host name for the host mount but amd uses ${rhost} for
6bbd11
this.
6bbd11
6bbd11
This introduces the possibility of multiple concurrent mount
6bbd11
requests since constructing a mount tree that isn't under the
6bbd11
lookup name can't take advantage of the kernel queuing other
6bbd11
concurrent lookups while the mount tree is constructed.
6bbd11
---
6bbd11
 daemon/lookup.c     |   20 +++++++++++++----
6bbd11
 modules/parse_amd.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++--
6bbd11
 modules/parse_sun.c |   22 +++++++++++-------
6bbd11
 3 files changed, 89 insertions(+), 14 deletions(-)
6bbd11
6bbd11
--- autofs-5.0.7.orig/daemon/lookup.c
6bbd11
+++ autofs-5.0.7/daemon/lookup.c
6bbd11
@@ -815,7 +815,8 @@ static int lookup_amd_instance(struct au
6bbd11
 
6bbd11
 	m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 1);
6bbd11
 	if (!m_key) {
6bbd11
-		error(ap->logopt, "failed to allocate storage for search key");
6bbd11
+		error(ap->logopt,
6bbd11
+		     "failed to allocate storage for search key");
6bbd11
 		return NSS_STATUS_UNKNOWN;
6bbd11
 	}
6bbd11
 
6bbd11
@@ -823,12 +824,12 @@ static int lookup_amd_instance(struct au
6bbd11
 	strcat(m_key, "/");
6bbd11
 	strcat(m_key, me->multi->key);
6bbd11
 	entry = master_find_amdmount(ap, m_key);
6bbd11
+	free(m_key);
6bbd11
+
6bbd11
 	if (!entry) {
6bbd11
 		error(ap->logopt, "expected amd mount entry not found");
6bbd11
-		free(m_key);
6bbd11
 		return NSS_STATUS_UNKNOWN;
6bbd11
 	}
6bbd11
-	free(m_key);
6bbd11
 
6bbd11
 	if (strcmp(entry->type, "host")) {
6bbd11
 		error(ap->logopt, "unexpected map type %s", entry->type);
6bbd11
@@ -843,6 +844,17 @@ static int lookup_amd_instance(struct au
6bbd11
 	}
6bbd11
 
6bbd11
 	instance = master_find_source_instance(map, "hosts", "sun", argc, pargv);
6bbd11
+	/* If this is an nss map instance it may have an amd host map sub instance */
6bbd11
+	if (!instance && map->instance) {
6bbd11
+		struct map_source *next = map->instance;
6bbd11
+		while (next) {
6bbd11
+			instance = master_find_source_instance(next,
6bbd11
+						"hosts", "sun", argc, pargv);
6bbd11
+			if (instance)
6bbd11
+				break;
6bbd11
+			next = next->next;
6bbd11
+		}
6bbd11
+	}
6bbd11
 	if (!instance) {
6bbd11
 		error(ap->logopt, "expected hosts map instance not found");
6bbd11
 		return NSS_STATUS_UNKNOWN;
6bbd11
@@ -1174,7 +1186,6 @@ int lookup_nss_mount(struct autofs_point
6bbd11
 	}
6bbd11
 	if (ap->state != ST_INIT)
6bbd11
 		send_map_update_request(ap);
6bbd11
-	pthread_cleanup_pop(1);
6bbd11
 
6bbd11
 	/*
6bbd11
 	 * The last source lookup will return NSS_STATUS_NOTFOUND if the
6bbd11
@@ -1183,6 +1194,7 @@ int lookup_nss_mount(struct autofs_point
6bbd11
 	 */
6bbd11
 	if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL)
6bbd11
 		update_negative_cache(ap, source, name);
6bbd11
+	pthread_cleanup_pop(1);
6bbd11
 
6bbd11
 	return !result;
6bbd11
 }
6bbd11
--- autofs-5.0.7.orig/modules/parse_amd.c
6bbd11
+++ autofs-5.0.7/modules/parse_amd.c
6bbd11
@@ -1068,6 +1068,23 @@ static int do_nfsl_mount(struct autofs_p
6bbd11
 	return do_link_mount(ap, name, entry, flags);
6bbd11
 }
6bbd11
 
6bbd11
+static int wait_for_expire(struct autofs_point *ap)
6bbd11
+{
6bbd11
+	int ret = 1;
6bbd11
+
6bbd11
+	st_wait_task(ap, ST_EXPIRE, 0);
6bbd11
+
6bbd11
+	st_mutex_lock();
6bbd11
+	if (ap->state != ST_SHUTDOWN &&
6bbd11
+	    ap->state != ST_SHUTDOWN_PENDING &&
6bbd11
+	    ap->state != ST_SHUTDOWN_FORCE) {
6bbd11
+		ret = 0;
6bbd11
+	}
6bbd11
+	st_mutex_unlock();
6bbd11
+
6bbd11
+	return ret;
6bbd11
+}
6bbd11
+
6bbd11
 static int do_host_mount(struct autofs_point *ap, const char *name,
6bbd11
 			 struct amd_entry *entry, struct map_source *source,
6bbd11
 			 unsigned int flags)
6bbd11
@@ -1080,6 +1097,36 @@ static int do_host_mount(struct autofs_p
6bbd11
 	int argc = 0;
6bbd11
 	int ret = 1;
6bbd11
 
6bbd11
+	/*
6bbd11
+	 * If the mount point name isn't the same as the host name
6bbd11
+	 * then we need to symlink to it after the mount. Attempt
6bbd11
+	 * the allocation and set entry->path to the base location
6bbd11
+	 * of the hosts mount tree so we can find it in
6bbd11
+	 * lookup_nss_mount() later.
6bbd11
+	 */
6bbd11
+	if (strcmp(name, entry->rhost)) {
6bbd11
+		char *target;
6bbd11
+		size_t len = strlen(ap->path) + strlen(entry->rhost) + 2;
6bbd11
+		target = malloc(len);
6bbd11
+		if (!target) {
6bbd11
+			warn(ap->logopt, MODPREFIX
6bbd11
+			     "failed to alloc target to hosts mount base");
6bbd11
+			goto out;
6bbd11
+		}
6bbd11
+		strcpy(target, ap->path);
6bbd11
+		strcat(target, "/");
6bbd11
+		strcat(target, entry->rhost);
6bbd11
+		if (entry->path)
6bbd11
+			free(entry->path);
6bbd11
+		entry->path = target;
6bbd11
+		/*
6bbd11
+		 * Wait for any expire before racing to mount the
6bbd11
+		 * export tree or bail out if we're shutting down.
6bbd11
+		*/
6bbd11
+		if (!wait_for_expire(ap))
6bbd11
+			goto out;
6bbd11
+	}
6bbd11
+
6bbd11
 	if (entry->opts) {
6bbd11
 		argv[0] = entry->opts;
6bbd11
 		argv[1] = NULL;
6bbd11
@@ -1095,7 +1142,8 @@ static int do_host_mount(struct autofs_p
6bbd11
 		goto out;
6bbd11
 	}
6bbd11
 
6bbd11
-	instance = master_find_source_instance(source, "hosts", "sun", argc, pargv);
6bbd11
+	instance = master_find_source_instance(source,
6bbd11
+					 "hosts", "sun", argc, pargv);
6bbd11
 	if (!instance) {
6bbd11
 		instance = master_add_source_instance(source,
6bbd11
 				 "hosts", "sun", time(NULL), argc, pargv);
6bbd11
@@ -1119,7 +1167,16 @@ static int do_host_mount(struct autofs_p
6bbd11
 	master_source_current_wait(ap->entry);
6bbd11
 	ap->entry->current = source;
6bbd11
 
6bbd11
-	ret = lookup->lookup_mount(ap, name, strlen(name), lookup->context);
6bbd11
+	ret = lookup->lookup_mount(ap, entry->rhost,
6bbd11
+				   strlen(entry->rhost), lookup->context);
6bbd11
+
6bbd11
+	if (!strcmp(name, entry->rhost))
6bbd11
+		goto out;
6bbd11
+
6bbd11
+	if (do_mount(ap, ap->path,
6bbd11
+		     name, strlen(name), entry->path, "bind", "symlink"))
6bbd11
+		warn(ap->logopt, MODPREFIX
6bbd11
+		     "failed to create symlink to hosts mount base");
6bbd11
 out:
6bbd11
 	return ret;
6bbd11
 }
6bbd11
--- autofs-5.0.7.orig/modules/parse_sun.c
6bbd11
+++ autofs-5.0.7/modules/parse_sun.c
6bbd11
@@ -1343,26 +1343,32 @@ int parse_mount(struct autofs_point *ap,
6bbd11
 			strcat(m_root, name);
6bbd11
 		}
6bbd11
 
6bbd11
+		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
6bbd11
 		cache_readlock(mc);
6bbd11
 		me = cache_lookup_distinct(mc, name);
6bbd11
-		if (me) {
6bbd11
-			/* So we know we're the multi-mount root */
6bbd11
-			if (!me->multi)
6bbd11
-				me->multi = me;
6bbd11
-		}
6bbd11
-
6bbd11
 		if (!me) {
6bbd11
 			free(options);
6bbd11
 			cache_unlock(mc);
6bbd11
+			pthread_setcancelstate(cur_state, NULL);
6bbd11
 			error(ap->logopt,
6bbd11
 			      MODPREFIX "can't find multi root %s", name);
6bbd11
 			return 1;
6bbd11
 		}
6bbd11
 
6bbd11
+		cache_multi_writelock(me);
6bbd11
+		/* Someone beat us to it, return success */
6bbd11
+		if (me->multi) {
6bbd11
+			free(options);
6bbd11
+			cache_multi_unlock(me);
6bbd11
+			cache_unlock(mc);
6bbd11
+			pthread_setcancelstate(cur_state, NULL);
6bbd11
+			return 0;
6bbd11
+		}
6bbd11
+		/* So we know we're the multi-mount root */
6bbd11
+		me->multi = me;
6bbd11
+
6bbd11
 		age = me->age;
6bbd11
 
6bbd11
-		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
6bbd11
-		cache_multi_writelock(me);
6bbd11
 		/* It's a multi-mount; deal with it */
6bbd11
 		do {
6bbd11
 			char *path, *myoptions, *loc;