diff --git a/autofs-5.0.3-allow-dir-create-on-nfs-root.patch b/autofs-5.0.3-allow-dir-create-on-nfs-root.patch new file mode 100644 index 0000000..b21f02c --- /dev/null +++ b/autofs-5.0.3-allow-dir-create-on-nfs-root.patch @@ -0,0 +1,48 @@ +autofs-5.0.3 - allow directory create on NFS root + +From: Matthias Koenig + +autofs will not create the autofs mountpoint path if the filesystem is +not a locally mounted filesystem (e.g. a NFS mounted filesystem). + +contained_in_local_fs() returns false in this case. This is intentional +but breaks clients that have an NFS root filesystem. In this case we +shouldn't impose this restriction. +--- + + CHANGELOG | 1 + + lib/mounts.c | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index f7aa839..2553f26 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -19,6 +19,7 @@ + - check for map key in (possible) alternate map sources when doing lookup. + - eliminate redundant DNS name lookups. + - additional fix incorrect pthreads condition handling for mount requests. ++- allow mount point directory creation for clients with an NFS root. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/lib/mounts.c b/lib/mounts.c +index 425a65a..b987fbb 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -363,7 +363,13 @@ int contained_in_local_fs(const char *path) + if (!strncmp(path, this->path, len)) { + if (len > 1 && pathlen > len && path[len] != '/') + continue; +- else if (this->fs_name[0] == '/') { ++ else if (len == 1 && this->path[0] == '/') { ++ /* ++ * always return true on rootfs, we don't ++ * want to break diskless clients. ++ */ ++ ret = 1; ++ } else if (this->fs_name[0] == '/') { + if (strlen(this->fs_name) > 1) { + if (this->fs_name[1] != '/') + ret = 1; diff --git a/autofs-5.0.3-check-direct-path-len.patch b/autofs-5.0.3-check-direct-path-len.patch new file mode 100644 index 0000000..447d2b7 --- /dev/null +++ b/autofs-5.0.3-check-direct-path-len.patch @@ -0,0 +1,89 @@ +autofs-5.0.3 - check direct mount path length + +From: Ian Kent + +The length of the path corresponding to a direct mount can't be +checked in the kernel so we need to check it will fit into the +request structire before going ahead with the mount. The name +field of the request structure is also to short and so is increased +to PATH_MAX. +--- + + CHANGELOG | 1 + + daemon/direct.c | 15 +++++++++++++-- + include/automount.h | 2 +- + 3 files changed, 15 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 2553f26..82b080c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -20,6 +20,7 @@ + - eliminate redundant DNS name lookups. + - additional fix incorrect pthreads condition handling for mount requests. + - allow mount point directory creation for clients with an NFS root. ++- fix direct mount path length not being checked. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/daemon/direct.c b/daemon/direct.c +index 768fbf9..98590ec 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1411,7 +1411,7 @@ static void *do_mount_direct(void *arg) + } + + cont: +- status = lookup_nss_mount(ap, NULL, mt.name, strlen(mt.name)); ++ status = lookup_nss_mount(ap, NULL, mt.name, mt.len); + /* + * Direct mounts are always a single mount. If it fails there's + * nothing to undo so just complain +@@ -1454,7 +1454,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + struct pending_args *mt; + char buf[MAX_ERR_BUF]; + int status = 0; +- int ioctlfd, cl_flags, state; ++ int ioctlfd, len, cl_flags, state; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +@@ -1525,6 +1525,16 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + return 1; + } + ++ len = strlen(me->key); ++ if (len >= PATH_MAX) { ++ error(ap->logopt, "direct mount path too long %s", me->key); ++ send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token); ++ close(ioctlfd); ++ cache_unlock(mc); ++ pthread_setcancelstate(state, NULL); ++ return 1; ++ } ++ + mt = malloc(sizeof(struct pending_args)); + if (!mt) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -1553,6 +1563,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + mt->ioctlfd = ioctlfd; + mt->mc = mc; + strcpy(mt->name, me->key); ++ mt->len = len; + mt->dev = me->dev; + mt->type = NFY_MOUNT; + mt->uid = pkt->uid; +diff --git a/include/automount.h b/include/automount.h +index d59be77..72e2457 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -409,7 +409,7 @@ struct pending_args { + int type; /* Type of packet */ + int ioctlfd; /* Mount ioctl fd */ + struct mapent_cache *mc; /* Cache Containing entry */ +- char name[KEY_MAX_LEN]; /* Name field of the request */ ++ char name[PATH_MAX]; /* Name field of the request */ + dev_t dev; /* device number of mount */ + unsigned int len; /* Name field len */ + uid_t uid; /* uid of requestor */ diff --git a/autofs-5.0.3-dont-abuse-ap-ghost-field.patch b/autofs-5.0.3-dont-abuse-ap-ghost-field.patch new file mode 100644 index 0000000..1624ec3 --- /dev/null +++ b/autofs-5.0.3-dont-abuse-ap-ghost-field.patch @@ -0,0 +1,81 @@ +autofs-5.0.3 - don't abuse the ap->ghost field on NFS mount + +From: Ian Kent + +Using the ap->ghost field in the autofs mount point struct, to prevent +the mount point directory from being removed, when attempting a bind +mount when an NFS mount is local may lead to incorrectly reading and +ghosting the map. This can happen if a mount request comes in during +a map re-read when the autofs map doesn't have the browse option set. +This patch corrects that by using the existence check in the bind mount +module instead of the hack of changing the struct field. +--- + + modules/mount_bind.c | 2 +- + modules/mount_nfs.c | 11 ----------- + 2 files changed, 1 insertions(+), 12 deletions(-) + + +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index ef973e1..e4a04d0 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -144,7 +144,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + if (ap->type != LKP_INDIRECT) + return 1; + +- if ((!ap->ghost && name_len) || !existed) ++ if ((!ap->ghost && name_len) && !existed) + rmdir_path(ap, fullpath, ap->dev); + + return err; +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 1855ea9..d7f42a7 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -62,7 +62,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + { + char *fullpath, buf[MAX_ERR_BUF]; + struct host *this, *hosts = NULL; +- unsigned int save_ghost = ap->ghost; + unsigned int vers; + char *nfsoptions = NULL; + int len, rlen, status, err, existed = 1; +@@ -186,13 +185,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + if (!status) + existed = 0; + +- /* +- * We need to stop the bind mount module from removing the +- * mount point directory if a bind attempt fails so abuse +- * the ap->ghost field for this. +- */ +- ap->ghost = 1; +- + this = hosts; + while (this) { + char *loc, *port_opt = NULL; +@@ -229,7 +221,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + /* Success - we're done */ + if (!err) { + free_host_list(&hosts); +- ap->ghost = save_ghost; + return 0; + } + +@@ -271,7 +262,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + info(ap->logopt, MODPREFIX "mounted %s on %s", loc, fullpath); + free(loc); + free_host_list(&hosts); +- ap->ghost = save_ghost; + return 0; + } + +@@ -281,7 +271,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + + forced_fail: + free_host_list(&hosts); +- ap->ghost = save_ghost; + + /* If we get here we've failed to complete the mount */ + diff --git a/autofs-5.0.3-fix-couple-of-memory-leaks.patch b/autofs-5.0.3-fix-couple-of-memory-leaks.patch new file mode 100644 index 0000000..6545973 --- /dev/null +++ b/autofs-5.0.3-fix-couple-of-memory-leaks.patch @@ -0,0 +1,69 @@ +autofs-5.0.3 - fix a couple of memory leaks + +From: Ian Kent + + +--- + + CHANGELOG | 2 ++ + daemon/lookup.c | 5 ++++- + modules/parse_sun.c | 14 ++++++++++---- + 3 files changed, 16 insertions(+), 5 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 82b080c..5901c75 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -21,6 +21,8 @@ + - additional fix incorrect pthreads condition handling for mount requests. + - allow mount point directory creation for clients with an NFS root. + - fix direct mount path length not being checked. ++- fix incorrect if check in get user info. ++- fix couple of memory leaks. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/daemon/lookup.c b/daemon/lookup.c +index eac6053..29a1491 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -996,8 +996,11 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age) + + key = strdup(me->key); + me = cache_enumerate(mc, me); +- if (!key || *key == '*') ++ if (!key || *key == '*') { ++ if (key) ++ free(key); + continue; ++ } + + path = make_fullpath(ap->path, key); + if (!path) { +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 4241f16..d839694 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -462,11 +462,17 @@ static char *concat_options(char *left, char *right) + char buf[MAX_ERR_BUF]; + char *ret; + +- if (left == NULL || *left == '\0') +- return strdup(right); ++ if (left == NULL || *left == '\0') { ++ ret = strdup(right); ++ free(right); ++ return ret; ++ } + +- if (right == NULL || *right == '\0') +- return strdup(left); ++ if (right == NULL || *right == '\0') { ++ ret = strdup(left); ++ free(left); ++ return ret; ++ } + + ret = malloc(strlen(left) + strlen(right) + 2); + diff --git a/autofs-5.0.3-fix-get-user-info-check.patch b/autofs-5.0.3-fix-get-user-info-check.patch new file mode 100644 index 0000000..f11ab22 --- /dev/null +++ b/autofs-5.0.3-fix-get-user-info-check.patch @@ -0,0 +1,38 @@ +autofs-5.0.3 - fix incorrect if check in get user info + +From: Ian Kent + +Fix an if statement checking the wrong value in the get user info code. +--- + + daemon/direct.c | 2 +- + daemon/indirect.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + + +diff --git a/daemon/direct.c b/daemon/direct.c +index 98590ec..072ef97 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1337,7 +1337,7 @@ static void *do_mount_direct(void *arg) + } + + tsv->home = strdup(pw.pw_dir); +- if (!tsv->user) { ++ if (!tsv->home) { + error(ap->logopt, "failed to malloc buffer for home"); + free(pw_tmp); + free(tsv->user); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 9f22ec9..ccdd8bf 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -768,7 +768,7 @@ static void *do_mount_indirect(void *arg) + } + + tsv->home = strdup(pw.pw_dir); +- if (!tsv->user) { ++ if (!tsv->home) { + error(ap->logopt, "failed to malloc buffer for home"); + free(pw_tmp); + free(tsv->user); diff --git a/autofs-5.0.3-lookup-next-soucre-stale-entry.patch b/autofs-5.0.3-lookup-next-soucre-stale-entry.patch new file mode 100644 index 0000000..f63ebf9 --- /dev/null +++ b/autofs-5.0.3-lookup-next-soucre-stale-entry.patch @@ -0,0 +1,131 @@ +autofs-5.0.3 - multi-map doesn't pickup NIS updates automatically + +From: Ian Kent + +In a multi-map configuration, autofs doesn't pick up NIS updates +automatically. This is caused by the lookup not checking alternate +sources for the given key (or wildcard) when doing a key lookup. +--- + + CHANGELOG | 1 + + lib/cache.c | 2 ++ + modules/lookup_file.c | 11 ++++++++--- + modules/lookup_ldap.c | 11 ++++++++--- + modules/lookup_nisplus.c | 11 ++++++++--- + modules/lookup_yp.c | 11 ++++++++--- + 6 files changed, 35 insertions(+), 12 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 268fca6..3ed84d3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -16,6 +16,7 @@ + - fix incorrect pthreads condition handling for mount requests. + - add check for exports automatically mounted by NFS kernel client. + - update nsswitch parser to ignore nsswitch sources that aren't supported. ++- check for map key in (possible) alternate map sources when doing lookup. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/lib/cache.c b/lib/cache.c +index 55586a3..d5abab0 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -700,6 +700,8 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key + int ret = CHE_OK; + + me = cache_lookup(mc, key); ++ while (me && me->source != ms) ++ me = cache_lookup_key_next(me); + if (!me || (*me->key == '*' && *key != '*')) { + ret = cache_add(mc, ms, key, mapent, age); + if (!ret) { +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 466690a..894f6fd 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -1116,9 +1116,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + cache_readlock(mc); + me = cache_lookup(mc, key); +- /* Stale mapent => check for wildcard */ +- if (me && !me->mapent) +- me = cache_lookup_distinct(mc, "*"); ++ /* Stale mapent => check for entry in alternate source or wildcard */ ++ if (me && !me->mapent) { ++ while ((me = cache_lookup_key_next(me))) ++ if (me->source == source) ++ break; ++ if (!me) ++ me = cache_lookup_distinct(mc, "*"); ++ } + if (me && (me->source == source || *me->key == '/')) { + pthread_cleanup_push(cache_lock_cleanup, mc); + mapent_len = strlen(me->mapent); +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index ded26f7..5cc2148 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -2596,9 +2596,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + cache_readlock(mc); + me = cache_lookup(mc, key); +- /* Stale mapent => check for wildcard */ +- if (me && !me->mapent) +- me = cache_lookup_distinct(mc, "*"); ++ /* Stale mapent => check for entry in alternate source or wildcard */ ++ if (me && !me->mapent) { ++ while ((me = cache_lookup_key_next(me))) ++ if (me->source == source) ++ break; ++ if (!me) ++ me = cache_lookup_distinct(mc, "*"); ++ } + if (me && (me->source == source || *me->key == '/')) { + mapent_len = strlen(me->mapent); + mapent = alloca(mapent_len + 1); +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 628ffcf..3c19fd3 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -530,9 +530,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + cache_readlock(mc); + me = cache_lookup(mc, key); +- /* Stale mapent => check for wildcard */ +- if (me && !me->mapent) +- me = cache_lookup_distinct(mc, "*"); ++ /* Stale mapent => check for entry in alternate source or wildcard */ ++ if (me && !me->mapent) { ++ while ((me = cache_lookup_key_next(me))) ++ if (me->source == source) ++ break; ++ if (!me) ++ me = cache_lookup_distinct(mc, "*"); ++ } + if (me && (me->source == source || *me->key == '/')) { + mapent_len = strlen(me->mapent); + mapent = alloca(mapent_len + 1); +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 0fc84f8..14f981c 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -636,9 +636,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + cache_readlock(mc); + me = cache_lookup(mc, key); +- /* Stale mapent => check for wildcard */ +- if (me && !me->mapent) +- me = cache_lookup_distinct(mc, "*"); ++ /* Stale mapent => check for entry in alternate source or wildcard */ ++ if (me && !me->mapent) { ++ while ((me = cache_lookup_key_next(me))) ++ if (me->source == source) ++ break; ++ if (!me) ++ me = cache_lookup_distinct(mc, "*"); ++ } + if (me && (me->source == source || *me->key == '/')) { + mapent_len = strlen(me->mapent); + mapent = alloca(mapent_len + 1); diff --git a/autofs-5.0.3-mount-thread-create-cond-handling-fix.patch b/autofs-5.0.3-mount-thread-create-cond-handling-fix.patch new file mode 100644 index 0000000..016ec50 --- /dev/null +++ b/autofs-5.0.3-mount-thread-create-cond-handling-fix.patch @@ -0,0 +1,223 @@ +autofs-5.0.3 - mount thread create condition handling fix + +From: Ian Kent + +Make the mount thread creation condition mutex specific to the +thread being created. +--- + + CHANGELOG | 1 + + daemon/direct.c | 31 +++++++++++++++++++++++-------- + daemon/indirect.c | 31 +++++++++++++++++++++++-------- + 3 files changed, 47 insertions(+), 16 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 995daea..f7aa839 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -18,6 +18,7 @@ + - update nsswitch parser to ignore nsswitch sources that aren't supported. + - check for map key in (possible) alternate map sources when doing lookup. + - eliminate redundant DNS name lookups. ++- additional fix incorrect pthreads condition handling for mount requests. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/daemon/direct.c b/daemon/direct.c +index 86c817c..768fbf9 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -50,7 +50,6 @@ pthread_key_t key_mnt_direct_params; + pthread_key_t key_mnt_offset_params; + pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT; + +-static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER; + + static void key_mnt_params_destroy(void *arg) +@@ -1218,9 +1217,18 @@ static void mount_send_fail(void *arg) + close(mt->ioctlfd); + } + ++static void pending_mutex_destroy(void *arg) ++{ ++ struct pending_args *mt = (struct pending_args *) arg; ++ int status = pthread_mutex_destroy(&mt->mutex); ++ if (status) ++ fatal(status); ++} ++ + static void mount_mutex_unlock(void *arg) + { +- int status = pthread_mutex_unlock(&ma_mutex); ++ struct pending_args *mt = (struct pending_args *) arg; ++ int status = pthread_mutex_unlock(&mt->mutex); + if (status) + fatal(status); + } +@@ -1243,7 +1251,7 @@ static void *do_mount_direct(void *arg) + + args = (struct pending_args *) arg; + +- status = pthread_mutex_lock(&ma_mutex); ++ status = pthread_mutex_lock(&args->mutex); + if (status) + fatal(status); + +@@ -1256,7 +1264,7 @@ static void *do_mount_direct(void *arg) + if (status) + fatal(status); + +- mount_mutex_unlock(NULL); ++ mount_mutex_unlock(args); + + pthread_cleanup_push(mount_send_fail, &mt); + +@@ -1533,7 +1541,11 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + if (status) + fatal(status); + +- status = pthread_mutex_lock(&ma_mutex); ++ status = pthread_mutex_init(&mt->mutex, NULL); ++ if (status) ++ fatal(status); ++ ++ status = pthread_mutex_lock(&mt->mutex); + if (status) + fatal(status); + +@@ -1553,8 +1565,9 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token); + close(ioctlfd); + cache_unlock(mc); +- mount_mutex_unlock(NULL); ++ mount_mutex_unlock(mt); + pending_cond_destroy(mt); ++ pending_mutex_destroy(mt); + free_pending_args(mt); + pthread_setcancelstate(state, NULL); + return 1; +@@ -1562,13 +1575,14 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + + cache_unlock(mc); + pthread_cleanup_push(free_pending_args, mt); ++ pthread_cleanup_push(pending_mutex_destroy, mt); + pthread_cleanup_push(pending_cond_destroy, mt); +- pthread_cleanup_push(mount_mutex_unlock, NULL); ++ pthread_cleanup_push(mount_mutex_unlock, mt); + pthread_setcancelstate(state, NULL); + + mt->signaled = 0; + while (!mt->signaled) { +- status = pthread_cond_wait(&mt->cond, &ma_mutex); ++ status = pthread_cond_wait(&mt->cond, &mt->mutex); + if (status) + fatal(status); + } +@@ -1576,6 +1590,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); + + return 0; + } +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 11865b3..9f22ec9 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -40,7 +40,6 @@ + + extern pthread_attr_t thread_attr; + +-static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER; + + static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) +@@ -651,9 +650,18 @@ static void mount_send_fail(void *arg) + send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token); + } + ++static void pending_mutex_destroy(void *arg) ++{ ++ struct pending_args *mt = (struct pending_args *) arg; ++ int status = pthread_mutex_destroy(&mt->mutex); ++ if (status) ++ fatal(status); ++} ++ + static void mount_mutex_unlock(void *arg) + { +- int status = pthread_mutex_unlock(&ma_mutex); ++ struct pending_args *mt = (struct pending_args *) arg; ++ int status = pthread_mutex_unlock(&mt->mutex); + if (status) + fatal(status); + } +@@ -676,7 +684,7 @@ static void *do_mount_indirect(void *arg) + + args = (struct pending_args *) arg; + +- status = pthread_mutex_lock(&ma_mutex); ++ status = pthread_mutex_lock(&args->mutex); + if (status) + fatal(status); + +@@ -689,7 +697,7 @@ static void *do_mount_indirect(void *arg) + if (status) + fatal(status); + +- mount_mutex_unlock(NULL); ++ mount_mutex_unlock(args); + + pthread_cleanup_push(mount_send_fail, &mt); + +@@ -884,7 +892,11 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + if (status) + fatal(status); + +- status = pthread_mutex_lock(&ma_mutex); ++ status = pthread_mutex_init(&mt->mutex, NULL); ++ if (status) ++ fatal(status); ++ ++ status = pthread_mutex_lock(&mt->mutex); + if (status) + fatal(status); + +@@ -901,21 +913,23 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + if (status) { + error(ap->logopt, "expire thread create failed"); + send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token); +- mount_mutex_unlock(NULL); ++ mount_mutex_unlock(mt); + pending_cond_destroy(mt); ++ pending_mutex_destroy(mt); + free_pending_args(mt); + pthread_setcancelstate(state, NULL); + return 1; + } + + pthread_cleanup_push(free_pending_args, mt); ++ pthread_cleanup_push(pending_mutex_destroy, mt); + pthread_cleanup_push(pending_cond_destroy, mt); +- pthread_cleanup_push(mount_mutex_unlock, NULL); ++ pthread_cleanup_push(mount_mutex_unlock, mt); + pthread_setcancelstate(state, NULL); + + mt->signaled = 0; + while (!mt->signaled) { +- status = pthread_cond_wait(&mt->cond, &ma_mutex); ++ status = pthread_cond_wait(&mt->cond, &mt->mutex); + if (status) + fatal(status); + } +@@ -923,6 +937,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); + + return 0; + } diff --git a/autofs-5.0.3-remove-redundant-dns-name-lookups.patch b/autofs-5.0.3-remove-redundant-dns-name-lookups.patch new file mode 100644 index 0000000..a2c2771 --- /dev/null +++ b/autofs-5.0.3-remove-redundant-dns-name-lookups.patch @@ -0,0 +1,239 @@ +autofs-5.0.3 - eliminate redundant DNS name lookups + +From: Ian Kent + +When autofs tries to lookup a DNS host name where one or more DNS +servers aren't available the mount can take a long time. This is +caused by autofs doing the name lookups more often than it needs +to. This patch removes a number of these redundant name lookups. +--- + + CHANGELOG | 1 + + include/replicated.h | 1 + + include/rpc_subs.h | 4 +++- + lib/rpc_subs.c | 22 ++++++++++++++++++++-- + modules/replicated.c | 25 +++++++++++++++++++------ + 5 files changed, 44 insertions(+), 9 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 3ed84d3..995daea 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -17,6 +17,7 @@ + - add check for exports automatically mounted by NFS kernel client. + - update nsswitch parser to ignore nsswitch sources that aren't supported. + - check for map key in (possible) alternate map sources when doing lookup. ++- eliminate redundant DNS name lookups. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/include/replicated.h b/include/replicated.h +index 672f853..88cd08a 100644 +--- a/include/replicated.h ++++ b/include/replicated.h +@@ -52,6 +52,7 @@ + struct host { + char *name; + char *addr; ++ size_t addr_len; + char *path; + unsigned int version; + unsigned int proximity; +diff --git a/include/rpc_subs.h b/include/rpc_subs.h +index 3292e01..e20a89d 100644 +--- a/include/rpc_subs.h ++++ b/include/rpc_subs.h +@@ -46,6 +46,8 @@ + + struct conn_info { + const char *host; ++ const char *addr; ++ size_t addr_len; + unsigned short port; + unsigned long program; + unsigned long version; +@@ -61,7 +63,7 @@ int rpc_udp_getclient(struct conn_info *, unsigned int, unsigned int); + void rpc_destroy_udp_client(struct conn_info *); + int rpc_tcp_getclient(struct conn_info *, unsigned int, unsigned int); + void rpc_destroy_tcp_client(struct conn_info *); +-int rpc_portmap_getclient(struct conn_info *, const char *, const char *, unsigned int); ++int rpc_portmap_getclient(struct conn_info *, const char *, const char *, size_t, const char *, unsigned int); + unsigned short rpc_portmap_getport(struct conn_info *, struct pmap *); + int rpc_ping_proto(struct conn_info *); + int rpc_ping(const char *, long, long, unsigned int); +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 5797639..6be86c6 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -86,6 +86,11 @@ static CLIENT *create_udp_client(struct conn_info *info) + memset(&raddr, 0, sizeof(raddr)); + + raddr.sin_family = AF_INET; ++ if (info->addr) { ++ memcpy(&raddr.sin_addr.s_addr, info->addr, info->addr_len); ++ goto got_addr; ++ } ++ + if (inet_aton(info->host, &raddr.sin_addr)) + goto got_addr; + +@@ -295,6 +300,11 @@ static CLIENT *create_tcp_client(struct conn_info *info) + memset(&addr, 0, sizeof(addr)); + + addr.sin_family = AF_INET; ++ if (info->addr) { ++ memcpy(&addr.sin_addr.s_addr, info->addr, info->addr_len); ++ goto got_addr; ++ } ++ + if (inet_aton(info->host, &addr.sin_addr)) + goto got_addr; + +@@ -407,8 +417,8 @@ void rpc_destroy_tcp_client(struct conn_info *info) + } + + int rpc_portmap_getclient(struct conn_info *info, +- const char *host, const char *proto, +- unsigned int option) ++ const char *host, const char *addr, size_t addr_len, ++ const char *proto, unsigned int option) + { + struct protoent *pe_proto; + CLIENT *client; +@@ -418,6 +428,8 @@ int rpc_portmap_getclient(struct conn_info *info, + return 0; + + info->host = host; ++ info->addr = addr; ++ info->addr_len = addr_len; + info->program = PMAPPROG; + info->port = PMAPPORT; + info->version = PMAPVERS; +@@ -462,6 +474,8 @@ unsigned short rpc_portmap_getport(struct conn_info *info, struct pmap *parms) + client = info->client; + else { + pmap_info.host = info->host; ++ pmap_info.addr = info->addr; ++ pmap_info.addr_len = info->addr_len; + pmap_info.port = PMAPPORT; + pmap_info.program = PMAPPROG; + pmap_info.version = PMAPVERS; +@@ -589,6 +603,8 @@ static unsigned int __rpc_ping(const char *host, + struct pmap parms; + + info.host = host; ++ info.addr = NULL; ++ info.addr_len = 0; + info.program = NFS_PROGRAM; + info.version = version; + info.send_sz = 0; +@@ -769,6 +785,8 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in + int status; + + info.host = host; ++ info.addr = NULL; ++ info.addr_len = 0; + info.program = MOUNTPROG; + info.version = MOUNTVERS; + info.send_sz = 0; +diff --git a/modules/replicated.c b/modules/replicated.c +index 90b2925..efbe6b4 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -225,7 +225,9 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + return PROXIMITY_OTHER; + } + +-static struct host *new_host(const char *name, const char *addr, unsigned int proximity, unsigned int weight) ++static struct host *new_host(const char *name, ++ const char *addr, size_t addr_len, ++ unsigned int proximity, unsigned int weight) + { + struct host *new; + char *tmp1, *tmp2; +@@ -237,11 +239,12 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr + if (!tmp1) + return NULL; + +- tmp2 = strdup(addr); ++ tmp2 = malloc(addr_len); + if (!tmp2) { + free(tmp1); + return NULL; + } ++ memcpy(tmp2, addr, addr_len); + + new = malloc(sizeof(struct host)); + if (!new) { +@@ -253,6 +256,7 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr + memset(new, 0, sizeof(struct host)); + + new->name = tmp1; ++ new->addr_len = addr_len; + new->addr = tmp2; + new->proximity = proximity; + new->weight = weight; +@@ -437,7 +441,8 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, + v3_ver: + if (!have_port_opt) { + status = rpc_portmap_getclient(pm_info, +- host->name, proto, RPC_CLOSE_DEFAULT); ++ host->name, host->addr, host->addr_len, ++ proto, RPC_CLOSE_DEFAULT); + if (!status) + goto done_ver; + } +@@ -551,6 +556,8 @@ static int get_vers_and_cost(unsigned logopt, struct host *host, + timeout = RPC_TIMEOUT * 8; + + rpc_info.host = host->name; ++ rpc_info.addr = host->addr; ++ rpc_info.addr_len = host->addr_len; + rpc_info.program = NFS_PROGRAM; + rpc_info.timeout.tv_sec = timeout; + rpc_info.close_option = RPC_CLOSE_DEFAULT; +@@ -606,6 +613,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + timeout = RPC_TIMEOUT * 8; + + rpc_info.host = host->name; ++ rpc_info.addr = host->addr; ++ rpc_info.addr_len = host->addr_len; + rpc_info.program = NFS_PROGRAM; + rpc_info.timeout.tv_sec = timeout; + rpc_info.close_option = RPC_CLOSE_DEFAULT; +@@ -652,7 +661,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + return 0; + } else { + int ret = rpc_portmap_getclient(&pm_info, +- host->name, proto, RPC_CLOSE_DEFAULT); ++ host->name, host->addr, host->addr_len, ++ proto, RPC_CLOSE_DEFAULT); + if (!ret) + return 0; + +@@ -868,7 +878,7 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei + if (prx == PROXIMITY_ERROR) + return 0; + +- if (!(new = new_host(host, thost, prx, weight))) ++ if (!(new = new_host(host, thost, sizeof(saddr.sin_addr), prx, weight))) + return 0; + + if (!add_host(list, new)) +@@ -891,11 +901,14 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei + } + + for (haddr = phe->h_addr_list; *haddr; haddr++) { ++ struct in_addr tt; ++ + prx = get_proximity(*haddr, phe->h_length); + if (prx == PROXIMITY_ERROR) + return 0; + +- if (!(new = new_host(host, *haddr, prx, weight))) ++ memcpy(&tt, *haddr, sizeof(struct in_addr)); ++ if (!(new = new_host(host, *haddr, phe->h_length, prx, weight))) + return 0; + + if (!add_host(list, new)) { diff --git a/autofs.spec b/autofs.spec index baafabf..af00431 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.3 -Release: 16 +Release: 18 Epoch: 1 License: GPL Group: System Environment/Daemons @@ -24,6 +24,14 @@ Patch11: autofs-5.0.3-map-type-in-map-name.patch Patch12: autofs-5.0.3-mount-thread-create-cond-handling.patch Patch13: autofs-5.0.3-check-for-kernel-automount.patch Patch14: autofs-5.0.3-nss-source-any.patch +Patch15: autofs-5.0.3-dont-abuse-ap-ghost-field.patch +Patch16: autofs-5.0.3-lookup-next-soucre-stale-entry.patch +Patch17: autofs-5.0.3-remove-redundant-dns-name-lookups.patch +Patch18: autofs-5.0.3-mount-thread-create-cond-handling-fix.patch +Patch19: autofs-5.0.3-allow-dir-create-on-nfs-root.patch +Patch20: autofs-5.0.3-check-direct-path-len.patch +Patch21: autofs-5.0.3-fix-get-user-info-check.patch +Patch22: autofs-5.0.3-fix-couple-of-memory-leaks.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs Conflicts: kernel < 2.6.17 @@ -79,6 +87,14 @@ echo %{version}-%{release} > .version %patch12 -p1 %patch13 -p1 %patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -131,6 +147,16 @@ fi %{_libdir}/autofs/ %changelog +* Mon Jun 30 2008 Ian Kent - 5.0.3-18 +- don't abuse the ap->ghost field on NFS mount. +- multi-map doesn't pickup NIS updates automatically. +- eliminate redundant DNS name lookups. +- mount thread create condition handling fix. +- allow directory create on NFS root. +- check direct mount path length. +- fix incorrect in check in get user info. +- fix a couple of memory leaks. + * Wed May 14 2008 Ian Kent - 5.0.3-16 - update patches, documentation and comments only change. - rename patch and add to CVS.