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; }