From 7342f18e41c8e80f24aa707e77099de8f2b41995 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Mon, 14 Apr 2008 05:53:44 +0000 Subject: [PATCH] - fix incorrect pthreads condifion handling for mount requests. --- ....3-mount-thread-create-cond-handling.patch | 300 ++++++++++++++++++ autofs.spec | 7 +- 2 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 autofs-5.0.3-mount-thread-create-cond-handling.patch diff --git a/autofs-5.0.3-mount-thread-create-cond-handling.patch b/autofs-5.0.3-mount-thread-create-cond-handling.patch new file mode 100644 index 0000000..ef3a80c --- /dev/null +++ b/autofs-5.0.3-mount-thread-create-cond-handling.patch @@ -0,0 +1,300 @@ +diff -up autofs-5.0.3/daemon/indirect.c.mount-thread-create-cond-handling autofs-5.0.3/daemon/indirect.c +--- autofs-5.0.3/daemon/indirect.c.mount-thread-create-cond-handling 2008-04-14 10:52:47.000000000 +0800 ++++ autofs-5.0.3/daemon/indirect.c 2008-04-14 10:53:04.000000000 +0800 +@@ -660,7 +660,7 @@ static void mount_mutex_unlock(void *arg + + static void *do_mount_indirect(void *arg) + { +- struct pending_args *mt; ++ struct pending_args *args, mt; + struct autofs_point *ap; + char buf[PATH_MAX + 1]; + struct stat st; +@@ -674,29 +674,28 @@ static void *do_mount_indirect(void *arg + struct thread_stdenv_vars *tsv; + int len, tmplen, grplen, status, state; + +- mt = (struct pending_args *) arg; ++ args = (struct pending_args *) arg; + + status = pthread_mutex_lock(&ma_mutex); + if (status) + fatal(status); + +- ap = mt->ap; +- mt->status = 0; ++ memcpy(&mt, args, sizeof(struct pending_args)); ++ ++ ap = mt.ap; + +- mt->signaled = 1; +- status = pthread_cond_signal(&mt->cond); ++ args->signaled = 1; ++ status = pthread_cond_signal(&args->cond); + if (status) + fatal(status); + + mount_mutex_unlock(NULL); + +- pthread_cleanup_push(free_pending_args, mt); +- pthread_cleanup_push(pending_cond_destroy, mt); +- pthread_cleanup_push(mount_send_fail, mt); ++ pthread_cleanup_push(mount_send_fail, &mt); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +- len = ncat_path(buf, sizeof(buf), ap->path, mt->name, mt->len); ++ len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len); + if (!len) { + crit(ap->logopt, "path to be mounted is to long"); + pthread_setcancelstate(state, NULL); +@@ -704,7 +703,7 @@ static void *do_mount_indirect(void *arg + } + + status = lstat(buf, &st); +- if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt->dev)) { ++ if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt.dev)) { + error(ap->logopt, + "indirect trigger not valid or already mounted %s", buf); + pthread_setcancelstate(state, NULL); +@@ -725,8 +724,8 @@ static void *do_mount_indirect(void *arg + if (!tsv) + goto cont; + +- tsv->uid = mt->uid; +- tsv->gid = mt->gid; ++ tsv->uid = mt.uid; ++ tsv->gid = mt.gid; + + /* Try to get passwd info */ + +@@ -744,7 +743,7 @@ static void *do_mount_indirect(void *arg + goto cont; + } + +- status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw); ++ status = getpwuid_r(tsv->uid, ppw, pw_tmp, tmplen, pppw); + if (status || !ppw) { + error(ap->logopt, "failed to get passwd info from getpwuid_r"); + free(tsv); +@@ -798,7 +797,7 @@ static void *do_mount_indirect(void *arg + gr_tmp = tmp; + pgr = &gr; + ppgr = &pgr; +- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); ++ status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr); + if (status != ERANGE) + break; + tmplen += grplen; +@@ -834,20 +833,18 @@ static void *do_mount_indirect(void *arg + free(tsv); + } + cont: +- status = lookup_nss_mount(ap, NULL, mt->name, mt->len); ++ status = lookup_nss_mount(ap, NULL, mt.name, mt.len); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + if (status) { +- send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token); ++ send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token); + info(ap->logopt, "mounted %s", buf); + } else { +- send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token); ++ send_fail(ap->logopt, ap->ioctlfd, mt.wait_queue_token); + info(ap->logopt, "failed to mount %s", buf); + } + pthread_setcancelstate(state, NULL); + + pthread_cleanup_pop(0); +- pthread_cleanup_pop(1); +- pthread_cleanup_pop(1); + + return NULL; + } +@@ -911,6 +908,8 @@ int handle_packet_missing_indirect(struc + return 1; + } + ++ pthread_cleanup_push(free_pending_args, mt); ++ pthread_cleanup_push(pending_cond_destroy, mt); + pthread_cleanup_push(mount_mutex_unlock, NULL); + pthread_setcancelstate(state, NULL); + +@@ -922,6 +921,8 @@ int handle_packet_missing_indirect(struc + } + + pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); + + return 0; + } +diff -up autofs-5.0.3/daemon/direct.c.mount-thread-create-cond-handling autofs-5.0.3/daemon/direct.c +--- autofs-5.0.3/daemon/direct.c.mount-thread-create-cond-handling 2008-04-14 10:52:47.000000000 +0800 ++++ autofs-5.0.3/daemon/direct.c 2008-04-14 10:53:04.000000000 +0800 +@@ -1217,7 +1217,7 @@ static void mount_mutex_unlock(void *arg + + static void *do_mount_direct(void *arg) + { +- struct pending_args *mt; ++ struct pending_args *args, mt; + struct autofs_point *ap; + struct passwd pw; + struct passwd *ppw = &pw; +@@ -1231,47 +1231,47 @@ static void *do_mount_direct(void *arg) + struct stat st; + int status, state; + +- mt = (struct pending_args *) arg; ++ args = (struct pending_args *) arg; + + status = pthread_mutex_lock(&ma_mutex); + if (status) + fatal(status); + +- ap = mt->ap; ++ memcpy(&mt, args, sizeof(struct pending_args)); ++ ++ ap = mt.ap; + +- mt->signaled = 1; +- status = pthread_cond_signal(&mt->cond); ++ args->signaled = 1; ++ status = pthread_cond_signal(&args->cond); + if (status) + fatal(status); + + mount_mutex_unlock(NULL); + +- pthread_cleanup_push(free_pending_args, mt); +- pthread_cleanup_push(pending_cond_destroy, mt); +- pthread_cleanup_push(mount_send_fail, mt); ++ pthread_cleanup_push(mount_send_fail, &mt); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +- status = fstat(mt->ioctlfd, &st); ++ status = fstat(mt.ioctlfd, &st); + if (status == -1) { + error(ap->logopt, +- "can't stat direct mount trigger %s", mt->name); ++ "can't stat direct mount trigger %s", mt.name); + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } + +- status = stat(mt->name, &st); +- if (!S_ISDIR(st.st_mode) || st.st_dev != mt->dev) { ++ status = stat(mt.name, &st); ++ if (!S_ISDIR(st.st_mode) || st.st_dev != mt.dev) { + error(ap->logopt, + "direct trigger not valid or already mounted %s", +- mt->name); ++ mt.name); + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } + + pthread_setcancelstate(state, NULL); + +- info(ap->logopt, "attempting to mount entry %s", mt->name); ++ info(ap->logopt, "attempting to mount entry %s", mt.name); + + /* + * Setup thread specific data values for macro +@@ -1283,8 +1283,8 @@ static void *do_mount_direct(void *arg) + if (!tsv) + goto cont; + +- tsv->uid = mt->uid; +- tsv->gid = mt->gid; ++ tsv->uid = mt.uid; ++ tsv->gid = mt.gid; + + /* Try to get passwd info */ + +@@ -1302,7 +1302,7 @@ static void *do_mount_direct(void *arg) + goto cont; + } + +- status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw); ++ status = getpwuid_r(tsv->uid, ppw, pw_tmp, tmplen, pppw); + if (status || !ppw) { + error(ap->logopt, "failed to get passwd info from getpwuid_r"); + free(tsv); +@@ -1356,7 +1356,7 @@ static void *do_mount_direct(void *arg) + gr_tmp = tmp; + pgr = &gr; + ppgr = &pgr; +- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); ++ status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr); + if (status != ERANGE) + break; + tmplen += grplen; +@@ -1393,7 +1393,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 +@@ -1402,29 +1402,27 @@ cont: + if (status) { + struct mapent *me; + int real_mount, set_fd; +- cache_readlock(mt->mc); +- me = cache_lookup_distinct(mt->mc, mt->name); ++ cache_readlock(mt.mc); ++ me = cache_lookup_distinct(mt.mc, mt.name); + real_mount = is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL); + set_fd = (real_mount || me->multi == me); +- cache_unlock(mt->mc); ++ cache_unlock(mt.mc); + if (set_fd) { +- me->ioctlfd = mt->ioctlfd; +- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token); ++ me->ioctlfd = mt.ioctlfd; ++ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); + } else { +- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token); +- close(mt->ioctlfd); ++ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); ++ close(mt.ioctlfd); + } +- info(ap->logopt, "mounted %s", mt->name); ++ info(ap->logopt, "mounted %s", mt.name); + } else { +- send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token); +- close(mt->ioctlfd); +- info(ap->logopt, "failed to mount %s", mt->name); ++ send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token); ++ close(mt.ioctlfd); ++ info(ap->logopt, "failed to mount %s", mt.name); + } + pthread_setcancelstate(state, NULL); + + pthread_cleanup_pop(0); +- pthread_cleanup_pop(1); +- pthread_cleanup_pop(1); + + return NULL; + } +@@ -1553,6 +1551,8 @@ int handle_packet_missing_direct(struct + } + + cache_unlock(mc); ++ pthread_cleanup_push(free_pending_args, mt); ++ pthread_cleanup_push(pending_cond_destroy, mt); + pthread_cleanup_push(mount_mutex_unlock, NULL); + pthread_setcancelstate(state, NULL); + +@@ -1564,6 +1564,8 @@ int handle_packet_missing_direct(struct + } + + pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); + + return 0; + } diff --git a/autofs.spec b/autofs.spec index 28f9c0c..eb38aff 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: 11 +Release: 12 Epoch: 1 License: GPL Group: System Environment/Daemons @@ -21,6 +21,7 @@ Patch8: autofs-5.0.3-unlink-mount-return-fix.patch Patch9: autofs-5.0.3-handle-zero-length-nis-key.patch Patch10: autofs-5.0.2-init-cb-on-load.patch Patch11: autofs-5.0.3-map-type-in-map-name.patch +Patch12: autofs-5.0.3-mount-thread-create-cond-handling.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 @@ -73,6 +74,7 @@ echo %{version}-%{release} > .version %patch9 -p1 %patch10 -p1 %patch11 -p1 +%patch12 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -125,6 +127,9 @@ fi %{_libdir}/autofs/ %changelog +* Mon Apr 14 2008 Ian Kent - 5.0.3-12 +- fix incorrect pthreads condifion handling for mount requests. + * Sun Apr 1 2008 Ian Kent - 5.0.3-11 - and another try at fixing lexer matching map type in map name.