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