From 226cfba24777875615b5010bd72fb23e4c73f447 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 11 Nov 2008 08:04:36 +0000 Subject: [PATCH] Remove patches included in the 5.0.4 release. --- autofs-5.0.2-init-cb-on-load.patch | 137 - autofs-5.0.3-active-restart.patch | 2254 ----------------- ...-5.0.3-add-missing-uris-list-locking.patch | 129 - ...s-5.0.3-add-replicated-debug-logging.patch | 189 -- autofs-5.0.3-add-umount_wait-parameter.patch | 138 - ...s-5.0.3-allow-dir-create-on-nfs-root.patch | 48 - autofs-5.0.3-basedn-with-spaces-fix-3.patch | 25 - autofs-5.0.3-check-direct-path-len.patch | 89 - ...5.0.3-check-for-kernel-automount-fix.patch | 25 - autofs-5.0.3-check-for-kernel-automount.patch | 200 -- ....3-check-replicated-list-after-probe.patch | 33 - autofs-5.0.3-clear-stale-on-map-read.patch | 29 - autofs-5.0.3-correct-ldap-lib.patch | 78 - autofs-5.0.3-dont-abuse-ap-ghost-field.patch | 81 - autofs-5.0.3-dont-block-on-expire.patch | 495 ---- ....0.3-dont-fail-on-empty-master-fix-2.patch | 52 - ....3-dont-readmap-on-hup-for-new-mount.patch | 39 - ...3-dont-use-proc-for-is-running-check.patch | 619 ----- ...3-expire-thread-create-cond-handling.patch | 179 -- autofs-5.0.3-expire-works-too-hard.patch | 74 - autofs-5.0.3-fix-bad-alloca-usage.patch | 48 - autofs-5.0.3-fix-couple-of-memory-leaks.patch | 69 - ....0.3-fix-fd-leak-at-multi-mount-fail.patch | 39 - autofs-5.0.3-fix-get-user-info-check.patch | 38 - autofs-5.0.3-fix-ifc-buff-size-fix-2.patch | 59 - autofs-5.0.3-fix-ifc-buff-size.patch | 144 -- ....3-fix-included-browse-map-not-found.patch | 26 - ...fix-incorrect-multi-mount-mountpoint.patch | 32 - ....0.3-fix-master-map-lexer-eval-order.patch | 33 - autofs-5.0.3-fix-multi-mount-race.patch | 1637 ------------ autofs-5.0.3-fix-multi-source-messages.patch | 182 -- autofs-5.0.3-fix-nfs4-colon-escape.patch | 28 - autofs-5.0.3-fix-percent-hack.patch | 369 --- ...fs-5.0.3-fix-proximity-other-timeout.patch | 36 - ...x-rootless-direct-multi-mount-expire.patch | 36 - ....3-handle-zero-length-nis-key-update.patch | 57 - autofs-5.0.3-handle-zero-length-nis-key.patch | 36 - ....0.3-ldap-page-control-configure-fix.patch | 406 --- autofs-5.0.3-library-reload-fix.patch | 164 -- ...5.0.3-lookup-next-soucre-stale-entry.patch | 131 - ...-handle_mounts-startup-cond-distinct.patch | 309 --- autofs-5.0.3-map-type-in-map-name-fix.patch | 27 - autofs-5.0.3-map-type-in-map-name.patch | 65 - ...ount-thread-create-cond-handling-fix.patch | 223 -- ....3-mount-thread-create-cond-handling.patch | 308 --- autofs-5.0.3-mtab-as-proc-mounts-fix.patch | 25 - autofs-5.0.3-mtab-as-proc-mounts.patch | 170 -- autofs-5.0.3-nfs4-tcp-only.patch | 25 - autofs-5.0.3-nisplus-partial-and-free.patch | 54 - autofs-5.0.3-nss-source-any.patch | 158 -- autofs-5.0.3-override-is-running-check.patch | 121 - ...fs-5.0.3-refactor-mount-request-vars.patch | 1217 --------- ....3-remove-redundant-dns-name-lookups.patch | 239 -- ....3-submount-shutdown-recovery-12-fix.patch | 32 - ...-5.0.3-submount-shutdown-recovery-12.patch | 1924 -------------- autofs-5.0.3-unlink-mount-return-fix.patch | 52 - autofs-5.0.3-update-replicated-doco.patch | 103 - autofs-5.0.3-use-dev-urandom.patch | 39 - ...-5.0.3-wait-submount-expire-complete.patch | 48 - autofs-5.0.3-xfn-not-supported.patch | 75 - 60 files changed, 13697 deletions(-) delete mode 100644 autofs-5.0.2-init-cb-on-load.patch delete mode 100644 autofs-5.0.3-active-restart.patch delete mode 100644 autofs-5.0.3-add-missing-uris-list-locking.patch delete mode 100644 autofs-5.0.3-add-replicated-debug-logging.patch delete mode 100644 autofs-5.0.3-add-umount_wait-parameter.patch delete mode 100644 autofs-5.0.3-allow-dir-create-on-nfs-root.patch delete mode 100644 autofs-5.0.3-basedn-with-spaces-fix-3.patch delete mode 100644 autofs-5.0.3-check-direct-path-len.patch delete mode 100644 autofs-5.0.3-check-for-kernel-automount-fix.patch delete mode 100644 autofs-5.0.3-check-for-kernel-automount.patch delete mode 100644 autofs-5.0.3-check-replicated-list-after-probe.patch delete mode 100644 autofs-5.0.3-clear-stale-on-map-read.patch delete mode 100644 autofs-5.0.3-correct-ldap-lib.patch delete mode 100644 autofs-5.0.3-dont-abuse-ap-ghost-field.patch delete mode 100644 autofs-5.0.3-dont-block-on-expire.patch delete mode 100644 autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch delete mode 100644 autofs-5.0.3-dont-readmap-on-hup-for-new-mount.patch delete mode 100644 autofs-5.0.3-dont-use-proc-for-is-running-check.patch delete mode 100644 autofs-5.0.3-expire-thread-create-cond-handling.patch delete mode 100644 autofs-5.0.3-expire-works-too-hard.patch delete mode 100644 autofs-5.0.3-fix-bad-alloca-usage.patch delete mode 100644 autofs-5.0.3-fix-couple-of-memory-leaks.patch delete mode 100644 autofs-5.0.3-fix-fd-leak-at-multi-mount-fail.patch delete mode 100644 autofs-5.0.3-fix-get-user-info-check.patch delete mode 100644 autofs-5.0.3-fix-ifc-buff-size-fix-2.patch delete mode 100644 autofs-5.0.3-fix-ifc-buff-size.patch delete mode 100644 autofs-5.0.3-fix-included-browse-map-not-found.patch delete mode 100644 autofs-5.0.3-fix-incorrect-multi-mount-mountpoint.patch delete mode 100644 autofs-5.0.3-fix-master-map-lexer-eval-order.patch delete mode 100644 autofs-5.0.3-fix-multi-mount-race.patch delete mode 100644 autofs-5.0.3-fix-multi-source-messages.patch delete mode 100644 autofs-5.0.3-fix-nfs4-colon-escape.patch delete mode 100644 autofs-5.0.3-fix-percent-hack.patch delete mode 100644 autofs-5.0.3-fix-proximity-other-timeout.patch delete mode 100644 autofs-5.0.3-fix-rootless-direct-multi-mount-expire.patch delete mode 100644 autofs-5.0.3-handle-zero-length-nis-key-update.patch delete mode 100644 autofs-5.0.3-handle-zero-length-nis-key.patch delete mode 100644 autofs-5.0.3-ldap-page-control-configure-fix.patch delete mode 100644 autofs-5.0.3-library-reload-fix.patch delete mode 100644 autofs-5.0.3-lookup-next-soucre-stale-entry.patch delete mode 100644 autofs-5.0.3-make-handle_mounts-startup-cond-distinct.patch delete mode 100644 autofs-5.0.3-map-type-in-map-name-fix.patch delete mode 100644 autofs-5.0.3-map-type-in-map-name.patch delete mode 100644 autofs-5.0.3-mount-thread-create-cond-handling-fix.patch delete mode 100644 autofs-5.0.3-mount-thread-create-cond-handling.patch delete mode 100644 autofs-5.0.3-mtab-as-proc-mounts-fix.patch delete mode 100644 autofs-5.0.3-mtab-as-proc-mounts.patch delete mode 100644 autofs-5.0.3-nfs4-tcp-only.patch delete mode 100644 autofs-5.0.3-nisplus-partial-and-free.patch delete mode 100644 autofs-5.0.3-nss-source-any.patch delete mode 100644 autofs-5.0.3-override-is-running-check.patch delete mode 100644 autofs-5.0.3-refactor-mount-request-vars.patch delete mode 100644 autofs-5.0.3-remove-redundant-dns-name-lookups.patch delete mode 100644 autofs-5.0.3-submount-shutdown-recovery-12-fix.patch delete mode 100644 autofs-5.0.3-submount-shutdown-recovery-12.patch delete mode 100644 autofs-5.0.3-unlink-mount-return-fix.patch delete mode 100644 autofs-5.0.3-update-replicated-doco.patch delete mode 100644 autofs-5.0.3-use-dev-urandom.patch delete mode 100644 autofs-5.0.3-wait-submount-expire-complete.patch delete mode 100644 autofs-5.0.3-xfn-not-supported.patch diff --git a/autofs-5.0.2-init-cb-on-load.patch b/autofs-5.0.2-init-cb-on-load.patch deleted file mode 100644 index 8eea563..0000000 --- a/autofs-5.0.2-init-cb-on-load.patch +++ /dev/null @@ -1,137 +0,0 @@ -diff -up autofs-5.0.3/include/lookup_ldap.h.init-cb-on-load autofs-5.0.3/include/lookup_ldap.h ---- autofs-5.0.3/include/lookup_ldap.h.init-cb-on-load 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/include/lookup_ldap.h 2008-03-24 14:10:09.000000000 +0900 -@@ -99,10 +99,12 @@ int unbind_ldap_connection(unsigned logo - int authtype_requires_creds(const char *authtype); - - /* cyrus-sasl.c */ -+int autofs_sasl_client_init(unsigned logopt); - int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt); - int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt); - void autofs_sasl_unbind(struct lookup_context *ctxt); --void autofs_sasl_done(struct lookup_context *ctxt); -+void autofs_sasl_dispose(struct lookup_context *ctxt); -+void autofs_sasl_done(void); - #endif - - #endif -diff -up autofs-5.0.3/modules/lookup_ldap.c.init-cb-on-load autofs-5.0.3/modules/lookup_ldap.c ---- autofs-5.0.3/modules/lookup_ldap.c.init-cb-on-load 2008-03-24 14:09:18.000000000 +0900 -+++ autofs-5.0.3/modules/lookup_ldap.c 2008-03-24 14:10:09.000000000 +0900 -@@ -599,7 +599,7 @@ static LDAP *connect_to_server(unsigned - - if (!do_bind(logopt, ldap, ctxt)) { - unbind_ldap_connection(logopt, ldap, ctxt); -- autofs_sasl_done(ctxt); -+ autofs_sasl_dispose(ctxt); - error(logopt, MODPREFIX "cannot bind to server"); - return NULL; - } -@@ -672,7 +672,7 @@ static LDAP *do_reconnect(unsigned logop - list_add_tail(&this->list, ctxt->uri); - - #ifdef WITH_SASL -- autofs_sasl_done(ctxt); -+ autofs_sasl_dispose(ctxt); - #endif - - /* Current server failed connect, try the rest */ -@@ -1330,6 +1330,13 @@ int lookup_init(const char *mapfmt, int - free_context(ctxt); - return 1; - } -+ -+ /* Init the sasl callbacks */ -+ if (!autofs_sasl_client_init(LOGOPT_NONE)) { -+ error(LOGOPT_ANY, "failed to init sasl client"); -+ free_context(ctxt); -+ return 1; -+ } - #endif - - if (ctxt->server || !ctxt->uri) { -@@ -2640,7 +2647,8 @@ int lookup_done(void *context) - struct lookup_context *ctxt = (struct lookup_context *) context; - int rv = close_parse(ctxt->parse); - #ifdef WITH_SASL -- autofs_sasl_done(ctxt); -+ autofs_sasl_dispose(ctxt); -+ autofs_sasl_done(); - #endif - free_context(ctxt); - return rv; -diff -up autofs-5.0.3/modules/cyrus-sasl.c.init-cb-on-load autofs-5.0.3/modules/cyrus-sasl.c ---- autofs-5.0.3/modules/cyrus-sasl.c.init-cb-on-load 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/modules/cyrus-sasl.c 2008-03-24 14:10:09.000000000 +0900 -@@ -76,7 +76,6 @@ static const char *default_client = "aut - static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER; - static unsigned int krb5cc_in_use = 0; - --static unsigned int init_callbacks = 1; - static int sasl_log_func(void *, int, const char *); - static int getpass_func(sasl_conn_t *, void *, int, sasl_secret_t **); - static int getuser_func(void *, int, const char **, unsigned *); -@@ -878,13 +877,6 @@ autofs_sasl_init(unsigned logopt, LDAP * - { - sasl_conn_t *conn; - -- /* Start up Cyrus SASL--only needs to be done once. */ -- if (init_callbacks && sasl_client_init(callbacks) != SASL_OK) { -- error(logopt, "sasl_client_init failed"); -- return -1; -- } -- init_callbacks = 0; -- - sasl_auth_id = ctxt->user; - sasl_auth_secret = ctxt->secret; - -@@ -916,8 +908,7 @@ autofs_sasl_init(unsigned logopt, LDAP * - * Destructor routine. This should be called when finished with an ldap - * session. - */ --void --autofs_sasl_done(struct lookup_context *ctxt) -+void autofs_sasl_dispose(struct lookup_context *ctxt) - { - int status, ret; - -@@ -953,3 +944,28 @@ autofs_sasl_done(struct lookup_context * - ctxt->kinit_successful = 0; - } - } -+ -+/* -+ * Initialize the sasl callbacks, which increments the global -+ * use counter. -+ */ -+int autofs_sasl_client_init(unsigned logopt) -+{ -+ /* Start up Cyrus SASL--only needs to be done at library load. */ -+ if (sasl_client_init(callbacks) != SASL_OK) { -+ error(logopt, "sasl_client_init failed"); -+ return 0; -+ } -+ return 1; -+} -+ -+/* -+ * Decrement the library reference count and free resources if -+ * we are the last to close the library. -+ */ -+void autofs_sasl_done(void) -+{ -+ sasl_done(); -+ return; -+} -+ -diff -up autofs-5.0.3/CHANGELOG.init-cb-on-load autofs-5.0.3/CHANGELOG ---- autofs-5.0.3/CHANGELOG.init-cb-on-load 2008-03-24 14:09:18.000000000 +0900 -+++ autofs-5.0.3/CHANGELOG 2008-03-24 14:10:09.000000000 +0900 -@@ -9,6 +9,7 @@ - - fix expire working harder than needed. - - fix unlink of mount tree incorrectly causing autofs mount fail. - - add missing check for zero length NIS key (Wengang Wang). -+- init SASL callbacks on every ldap lookup library load. - - 14/01/2008 autofs-5.0.3 - ----------------------- diff --git a/autofs-5.0.3-active-restart.patch b/autofs-5.0.3-active-restart.patch deleted file mode 100644 index 6bdb36c..0000000 --- a/autofs-5.0.3-active-restart.patch +++ /dev/null @@ -1,2254 +0,0 @@ -diff -up autofs-5.0.3/daemon/indirect.c.active-restart autofs-5.0.3/daemon/indirect.c ---- autofs-5.0.3/daemon/indirect.c.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 09:16:46.000000000 +0900 -@@ -20,6 +20,7 @@ - * ----------------------------------------------------------------------- */ - - #include -+#include - #include - #include - #include -@@ -32,9 +33,8 @@ - #include - #include - #include -+#include - #include --#include --#include - - #include "automount.h" - -@@ -43,8 +43,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 const unsigned int indirect = AUTOFS_TYPE_INDIRECT; -- - static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) - { - struct mnt_list *this; -@@ -90,6 +88,7 @@ static int unlink_mount_tree(struct auto - - static int do_mount_autofs_indirect(struct autofs_point *ap) - { -+ const char *str_indirect = mount_type_str(indirect); - struct ioctl_ops *ops = get_ioctl_ops(); - time_t timeout = ap->exp_timeout; - char *options = NULL; -@@ -98,8 +97,58 @@ static int do_mount_autofs_indirect(stru - struct mnt_list *mnts; - int ret; - -- mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1); -- if (mnts) { -+ ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; -+ -+ if (ops->version) { -+ char device[AUTOFS_DEVID_LEN]; -+ struct statfs fst; -+ int ioctlfd; -+ dev_t devid; -+ char *tmp; -+ -+ if (!find_mnt_devid(_PROC_MOUNTS, ap->path, device, indirect)) -+ goto cont; -+ -+ devid = strtoul(device, NULL, 0); -+ -+ ret = remount_active_mount(ap, NULL, ap->path, devid, indirect, &ioctlfd); -+ -+ /* -+ * The directory must exist since we found a device -+ * number for the mount above but we can't know if we -+ * created it or not. However, if we're mounted on an -+ * autofs fs then we need to cleanup the path anyway. -+ */ -+ ap->dir_created = 0; -+ tmp = strdup(ap->path); -+ if (tmp) { -+ if (statfs(dirname(tmp), &fst) != -1) -+ if (fst.f_type == AUTOFS_SUPER_MAGIC) -+ ap->dir_created = 1; -+ free(tmp); -+ } -+ -+ /* -+ * Either we opened the mount or we're re-reading the map. -+ * If we opened the mount and ioctlfd is not -1 we have -+ * a descriptor for the indirect mount so we need to -+ * record that in the mount point struct. Otherwise we're -+ * re-reading the map. -+ */ -+ if (ret == REMOUNT_SUCCESS || ret == REMOUNT_READ_MAP) { -+ if (ioctlfd != -1) -+ ap->ioctlfd = ioctlfd; -+ return 0; -+ } -+ /* -+ * Since we got the device number above a mount exists so -+ * any other failure warrants a failure return here. -+ */ -+ return -1; -+ } else { -+ mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1); -+ if (!mnts) -+ goto cont; - ret = unlink_mount_tree(ap, mnts); - free_mnt_list(mnts); - if (!ret) { -@@ -109,7 +158,7 @@ static int do_mount_autofs_indirect(stru - goto out_err; - } - } -- -+cont: - options = make_options_string(ap->path, ap->kpipefd, NULL); - if (!options) { - error(ap->logopt, "options string error"); -@@ -152,29 +201,21 @@ static int do_mount_autofs_indirect(stru - - options = NULL; - -- if (ops->open(ap->logopt, &ap->ioctlfd, -1, ap->path, indirect)) { -+ if (stat(ap->path, &st) == -1) { -+ error(ap->logopt, -+ "failed to stat mount %s", ap->path); -+ goto out_umount; -+ } -+ ap->dev = st.st_dev; -+ -+ if (ops->open(ap->logopt, &ap->ioctlfd, ap->dev, ap->path, indirect)) { - crit(ap->logopt, - "failed to create ioctl fd for autofs path %s", ap->path); - goto out_umount; - } - -- ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; -- - ops->timeout(ap->logopt, ap->ioctlfd, &timeout); -- -- if (ap->exp_timeout) -- info(ap->logopt, -- "mounted indirect mount on %s " -- "with timeout %u, freq %u seconds", ap->path, -- (unsigned int) ap->exp_timeout, -- (unsigned int) ap->exp_runfreq); -- else -- info(ap->logopt, -- "mounted indirect mount on %s with timeouts disabled", -- ap->path); -- -- fstat(ap->ioctlfd, &st); -- ap->dev = st.st_dev; /* Device number for mount point checks */ -+ notify_mount_result(ap, ap->path, str_indirect); - - return 0; - -@@ -636,15 +677,7 @@ static void *do_mount_indirect(void *arg - struct autofs_point *ap; - char buf[PATH_MAX + 1]; - struct stat st; -- struct passwd pw; -- struct passwd *ppw = &pw; -- struct passwd **pppw = &ppw; -- struct group gr; -- struct group *pgr; -- struct group **ppgr; -- char *pw_tmp, *gr_tmp; -- struct thread_stdenv_vars *tsv; -- int len, tmplen, grplen, status, state; -+ int len, status, state; - - mt = (struct pending_args *) arg; - -@@ -687,125 +720,8 @@ static void *do_mount_indirect(void *arg - - info(ap->logopt, "attempting to mount entry %s", buf); - -- /* -- * Setup thread specific data values for macro -- * substution in map entries during the mount. -- * Best effort only as it must go ahead. -- */ -+ set_tsd_user_vars(ap->logopt, mt->uid, mt->gid); - -- tsv = malloc(sizeof(struct thread_stdenv_vars)); -- if (!tsv) -- goto cont; -- -- tsv->uid = mt->uid; -- tsv->gid = mt->gid; -- -- /* Try to get passwd info */ -- -- tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- pw_tmp = malloc(tmplen + 1); -- if (!pw_tmp) { -- error(ap->logopt, "failed to malloc buffer for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw); -- if (status || !ppw) { -- error(ap->logopt, "failed to get passwd info from getpwuid_r"); -- free(tsv); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->user = strdup(pw.pw_name); -- if (!tsv->user) { -- error(ap->logopt, "failed to malloc buffer for user"); -- free(tsv); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->home = strdup(pw.pw_dir); -- if (!tsv->user) { -- error(ap->logopt, "failed to malloc buffer for home"); -- free(pw_tmp); -- free(tsv->user); -- free(tsv); -- goto cont; -- } -- -- free(pw_tmp); -- -- /* Try to get group info */ -- -- grplen = sysconf(_SC_GETGR_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- -- gr_tmp = NULL; -- tmplen = grplen; -- while (1) { -- char *tmp = realloc(gr_tmp, tmplen + 1); -- if (!tmp) { -- error(ap->logopt, "failed to malloc buffer for getgrgid_r"); -- if (gr_tmp) -- free(gr_tmp); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- gr_tmp = tmp; -- pgr = &gr; -- ppgr = &pgr; -- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); -- if (status != ERANGE) -- break; -- tmplen += grplen; -- } -- -- if (status || !pgr) { -- error(ap->logopt, "failed to get group info from getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- tsv->group = strdup(gr.gr_name); -- if (!tsv->group) { -- error(ap->logopt, "failed to malloc buffer for group"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- free(gr_tmp); -- -- status = pthread_setspecific(key_thread_stdenv_vars, tsv); -- if (status) { -- error(ap->logopt, "failed to set stdenv thread var"); -- free(tsv->group); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- } --cont: - status = lookup_nss_mount(ap, NULL, mt->name, mt->len); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); - if (status) { -diff -up autofs-5.0.3/daemon/automount.c.active-restart autofs-5.0.3/daemon/automount.c ---- autofs-5.0.3/daemon/automount.c.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/daemon/automount.c 2008-02-25 09:16:46.000000000 +0900 -@@ -466,7 +466,7 @@ static int umount_subtree_mounts(struct - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); - /* Lock the closest parent nesting point for umount */ -- cache_multi_lock(me->parent); -+ cache_multi_writelock(me->parent); - if (umount_multi_triggers(ap, root, me, base)) { - warn(ap->logopt, - "some offset mounts still present under %s", path); -@@ -1412,6 +1412,55 @@ static void mutex_operation_wait(pthread - return; - } - -+int handle_mounts_startup_cond_init(struct startup_cond *suc) -+{ -+ int status; -+ -+ status = pthread_mutex_init(&suc->mutex, NULL); -+ if (status) -+ return status; -+ -+ status = pthread_cond_init(&suc->cond, NULL); -+ if (status) { -+ status = pthread_mutex_destroy(&suc->mutex); -+ if (status) -+ fatal(status); -+ return status; -+ } -+ -+ status = pthread_mutex_lock(&suc->mutex); -+ if (status) { -+ status = pthread_mutex_destroy(&suc->mutex); -+ if (status) -+ fatal(status); -+ status = pthread_cond_destroy(&suc->cond); -+ if (status) -+ fatal(status); -+ } -+ -+ return 0; -+} -+ -+void handle_mounts_startup_cond_destroy(void *arg) -+{ -+ struct startup_cond *suc = (struct startup_cond *) arg; -+ int status; -+ -+ status = pthread_mutex_unlock(&suc->mutex); -+ if (status) -+ fatal(status); -+ -+ status = pthread_mutex_destroy(&suc->mutex); -+ if (status) -+ fatal(status); -+ -+ status = pthread_cond_destroy(&suc->cond); -+ if (status) -+ fatal(status); -+ -+ return; -+} -+ - static void handle_mounts_cleanup(void *arg) - { - struct autofs_point *ap; -@@ -1463,17 +1512,20 @@ static void handle_mounts_cleanup(void * - - void *handle_mounts(void *arg) - { -+ struct startup_cond *suc; - struct autofs_point *ap; - int cancel_state, status = 0; - -- ap = (struct autofs_point *) arg; -+ suc = (struct startup_cond *) arg; -+ -+ ap = suc->ap; - -- pthread_cleanup_push(return_start_status, &suc); -+ pthread_cleanup_push(return_start_status, suc); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); - - state_mutex_lock(ap); - -- status = pthread_mutex_lock(&suc.mutex); -+ status = pthread_mutex_lock(&suc->mutex); - if (status) { - logerr("failed to lock startup condition mutex!"); - fatal(status); -@@ -1481,7 +1533,7 @@ void *handle_mounts(void *arg) - - if (mount_autofs(ap) < 0) { - crit(ap->logopt, "mount of %s failed!", ap->path); -- suc.status = 1; -+ suc->status = 1; - state_mutex_unlock(ap); - umount_autofs(ap, 1); - pthread_setcancelstate(cancel_state, NULL); -@@ -1491,7 +1543,7 @@ void *handle_mounts(void *arg) - if (ap->ghost && ap->type != LKP_DIRECT) - info(ap->logopt, "ghosting enabled"); - -- suc.status = 0; -+ suc->status = 0; - pthread_cleanup_pop(1); - - /* We often start several automounters at the same time. Add some -@@ -1948,7 +2000,9 @@ int main(int argc, char *argv[]) - - if (!query_kproto_ver() || get_kver_major() < 5) { - fprintf(stderr, -- "%s: kernel protocol version 5.00 or above required.\n", -+ "%s: test mount forbidden or " -+ "incorrect kernel protocol version, " -+ "kernel protocol version 5.00 or above required.\n", - program); - exit(1); - } -diff -up autofs-5.0.3/daemon/direct.c.active-restart autofs-5.0.3/daemon/direct.c ---- autofs-5.0.3/daemon/direct.c.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/daemon/direct.c 2008-02-25 09:16:46.000000000 +0900 -@@ -20,6 +20,7 @@ - * ----------------------------------------------------------------------- */ - - #include -+#include - #include - #include - #include -@@ -35,16 +36,11 @@ - #include - #include - #include --#include --#include - - #include "automount.h" - - extern pthread_attr_t thread_attr; - --static const unsigned int direct = AUTOFS_TYPE_DIRECT; --static const unsigned int offset = AUTOFS_TYPE_OFFSET; -- - struct mnt_params { - char *options; - }; -@@ -287,15 +283,11 @@ static int unlink_mount_tree(struct auto - return ret; - } - --int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) -+static int unlink_active_mounts(struct autofs_point *ap, -+ struct mnt_list *mnts, struct mapent *me) - { - struct ioctl_ops *ops = get_ioctl_ops(); -- struct mnt_params *mp; -- time_t timeout = ap->exp_timeout; -- struct stat st; -- int status, ret, ioctlfd; - struct list_head list; -- const char *map_name; - - INIT_LIST_HEAD(&list); - -@@ -313,7 +305,7 @@ int do_mount_autofs_direct(struct autofs - error(ap->logopt, - "failed to create ioctl fd for %s", - me->key); -- return 0; -+ return 1; - } - - ops->timeout(ap->logopt, ioctlfd, &tout); -@@ -321,22 +313,99 @@ int do_mount_autofs_direct(struct autofs - if (save_ioctlfd == -1) - ops->close(ap->logopt, ioctlfd); - -- return 0; -+ return 1; - } - - if (!unlink_mount_tree(ap, &list)) { - debug(ap->logopt, - "already mounted as other than autofs " - "or failed to unlink entry in tree"); -- return -1; -+ return 0; - } - } -+ return 1; -+} - -- if (me->ioctlfd != -1) { -- error(ap->logopt, "active direct mount %s", me->key); -- return -1; -- } -+int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) -+{ -+ const char *str_direct = mount_type_str(direct); -+ struct ioctl_ops *ops = get_ioctl_ops(); -+ struct mnt_params *mp; -+ time_t timeout = ap->exp_timeout; -+ struct stat st; -+ int status, ret, ioctlfd; -+ const char *map_name; -+ -+ /* Calculate the timeouts */ -+ ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; -+ -+ if (ops->version) { -+ char device[AUTOFS_DEVID_LEN]; -+ struct statfs fst; -+ dev_t devid; -+ char *tmp; -+ -+ /* Mount in mount table */ -+ if (!tree_find_mnt_devid(mnts, me->key, device, direct)) -+ goto cont; -+ -+ devid = strtoul(device, NULL, 0); -+ -+ ret = remount_active_mount(ap, me->mc, -+ me->key, devid, direct, -+ &ioctlfd); -+ -+ /* -+ * The directory must exist since we found a device -+ * number for the mount above but we can't know if we -+ * created it or not. However, if we're mounted on an -+ * autofs fs then we need to cleanup the path anyway. -+ */ -+ me->dir_created = 0; -+ tmp = strdup(me->key); -+ if (tmp) { -+ if (statfs(dirname(tmp), &fst) != -1) -+ if (fst.f_type == AUTOFS_SUPER_MAGIC) -+ me->dir_created = 1; -+ free(tmp); -+ } -+ -+ /* -+ * Either we opened the mount or we're re-reading the map. -+ * If we opened the mount and ioctlfd is not -1 we have an -+ * active mount so we need to record the descriptor in the -+ * cache entry. Otherwise there is no active mount or we're -+ * re-reading the map. -+ */ -+ if (ret == REMOUNT_SUCCESS || ret == REMOUNT_READ_MAP) { -+ if (ioctlfd != -1) -+ me->ioctlfd = ioctlfd; -+ return 0; -+ } -+ -+ /* -+ * Since we got the device number above a mount exists so -+ * any other failure warrants a failure return here. -+ */ -+ goto out_err; -+ } else { -+ /* -+ * A return of 1 indicates we're re-reading the map -+ * or we successfully unlinked the mount tree if it -+ * there was one. A return of zero inducates we -+ * failed to unlink the mount tree so we have to -+ * return a failure. -+ */ -+ ret = unlink_active_mounts(ap, mnts, me); -+ if (ret == 0) -+ return -1; - -+ if (me->ioctlfd != -1) { -+ error(ap->logopt, "active direct mount %s", me->key); -+ return -1; -+ } -+ } -+cont: - status = pthread_once(&key_mnt_params_once, key_mnt_params_init); - if (status) - fatal(status); -@@ -388,44 +457,27 @@ int do_mount_autofs_direct(struct autofs - goto out_err; - } - -- ops->open(ap->logopt, &ioctlfd, -1, me->key, direct); -+ if (stat(me->key, &st) == -1) { -+ error(ap->logopt, -+ "failed to stat direct mount trigger %s", me->key); -+ goto out_umount; -+ } -+ -+ ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key, direct); - if (ioctlfd < 0) { - crit(ap->logopt, "failed to create ioctl fd for %s", me->key); - goto out_umount; - } - -- /* Calculate the timeouts */ -- ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; -- - ops->timeout(ap->logopt, ioctlfd, &timeout); -- -- if (ap->exp_timeout) -- info(ap->logopt, -- "mounted direct mount on %s " -- "with timeout %u, freq %u seconds", me->key, -- (unsigned int) ap->exp_timeout, -- (unsigned int) ap->exp_runfreq); -- else -- info(ap->logopt, -- "mounted direct mount on %s with timeouts disabled", -- me->key); -- -- ret = fstat(ioctlfd, &st); -- if (ret == -1) { -- error(ap->logopt, -- "failed to stat direct mount trigger %s", me->key); -- goto out_close; -- } -+ notify_mount_result(ap, me->key, str_direct); - cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); -- - ops->close(ap->logopt, ioctlfd); - - debug(ap->logopt, "mounted trigger %s", me->key); - - return 0; - --out_close: -- ops->close(ap->logopt, ioctlfd); - out_umount: - /* TODO: maybe force umount (-l) */ - umount(me->key); -@@ -462,8 +514,6 @@ int mount_autofs_direct(struct autofs_po - pthread_cleanup_push(master_source_lock_cleanup, ap->entry); - master_source_readlock(ap->entry); - nc = ap->entry->master->nc; -- cache_readlock(nc); -- pthread_cleanup_push(cache_lock_cleanup, nc); - map = ap->entry->maps; - while (map) { - /* -@@ -476,8 +526,6 @@ int mount_autofs_direct(struct autofs_po - } - - mc = map->mc; -- pthread_cleanup_push(cache_lock_cleanup, mc); -- cache_readlock(mc); - me = cache_enumerate(mc, NULL); - while (me) { - ne = cache_lookup_distinct(nc, me->key); -@@ -505,12 +553,10 @@ int mount_autofs_direct(struct autofs_po - - me = cache_enumerate(mc, me); - } -- pthread_cleanup_pop(1); - map = map->next; - } - pthread_cleanup_pop(1); - pthread_cleanup_pop(1); -- pthread_cleanup_pop(1); - - return 0; - } -@@ -627,6 +673,7 @@ force_umount: - - int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - { -+ const char *str_offset = mount_type_str(offset); - struct ioctl_ops *ops = get_ioctl_ops(); - char buf[MAX_ERR_BUF]; - struct mnt_params *mp; -@@ -635,18 +682,68 @@ int mount_autofs_offset(struct autofs_po - int ioctlfd, status, ret; - const char *type, *map_name = NULL; - -- if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { -- if (ap->state != ST_READMAP) -- warn(ap->logopt, -- "trigger %s already mounted", me->key); -- return 0; -- } -+ if (ops->version) { -+ char device[AUTOFS_DEVID_LEN]; -+ struct statfs fst; -+ dev_t devid; -+ char *tmp; - -- if (me->ioctlfd != -1) { -- error(ap->logopt, "active offset mount %s", me->key); -- return -1; -- } -+ /* If we can find it it's mounted */ -+ if (!find_mnt_devid(_PROC_MOUNTS, me->key, device, offset)) -+ goto cont; -+ -+ devid = strtoul(device, NULL, 0); -+ -+ ret = remount_active_mount(ap, me->mc, -+ me->key, devid, offset, -+ &ioctlfd); -+ -+ /* -+ * The directory must exist since we found a device -+ * number for the mount above but we can't know if we -+ * created it or not. However, if we're mounted on an -+ * autofs fs then we need to cleanup the path anyway. -+ */ -+ me->dir_created = 0; -+ tmp = strdup(me->key); -+ if (tmp) { -+ if (statfs(dirname(tmp), &fst) != -1) -+ if (fst.f_type == AUTOFS_SUPER_MAGIC) -+ me->dir_created = 1; -+ free(tmp); -+ } -+ -+ /* -+ * Either we opened the mount or we're re-reading the map. -+ * If we opened the mount and ioctlfd is not -1 we have an -+ * active mount so we need to record the descriptor in the -+ * cache entry. Otherwise there is no active mount or we're -+ * re-reading the map. -+ */ -+ if (ret == REMOUNT_SUCCESS || ret == REMOUNT_READ_MAP) { -+ if (ioctlfd != -1) -+ me->ioctlfd = ioctlfd; -+ return 0; -+ } -+ /* -+ * Since we got the device number above a mount exists so -+ * any other failure warrants a failure return here. -+ */ -+ goto out_err; -+ } else { -+ if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { -+ if (ap->state != ST_READMAP) -+ warn(ap->logopt, -+ "trigger %s already mounted", me->key); -+ return 0; -+ } - -+ if (me->ioctlfd != -1) { -+ error(ap->logopt, "active offset mount %s", me->key); -+ return -1; -+ } -+ } -+cont: - status = pthread_once(&key_mnt_params_once, key_mnt_params_init); - if (status) - fatal(status); -@@ -670,7 +767,7 @@ int mount_autofs_offset(struct autofs_po - } - - if (!mp->options) { -- mp->options = make_options_string(ap->path, ap->kpipefd, "offset"); -+ mp->options = make_options_string(ap->path, ap->kpipefd, str_offset); - if (!mp->options) - return 0; - } -@@ -724,34 +821,28 @@ int mount_autofs_offset(struct autofs_po - map_name = me->mc->map->argv[0]; - - ret = mount(map_name, me->key, "autofs", MS_MGC_VAL, mp->options); -- if (ret) { -- crit(ap->logopt, "failed to mount autofs path %s", me->key); -- goto out_err; -- } -- - if (ret != 0) { - crit(ap->logopt, - "failed to mount autofs offset trigger %s", me->key); - goto out_err; - } - -- ops->open(ap->logopt, &ioctlfd, -1, me->key, offset); -- if (ioctlfd < 0) { -- crit(ap->logopt, "failed to create ioctl fd for %s", me->key); -- goto out_umount; -- } -- -- ops->timeout(ap->logopt, ioctlfd, &timeout); -- -- ret = fstat(ioctlfd, &st); -+ ret = stat(me->key, &st); - if (ret == -1) { - error(ap->logopt, - "failed to stat direct mount trigger %s", me->key); - goto out_close; - } - -- cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); -+ ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key, offset); -+ if (ioctlfd < 0) { -+ crit(ap->logopt, "failed to create ioctl fd for %s", me->key); -+ goto out_umount; -+ } - -+ ops->timeout(ap->logopt, ioctlfd, &timeout); -+ notify_mount_result(ap, me->key, str_offset); -+ cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); - ops->close(ap->logopt, ioctlfd); - - debug(ap->logopt, "mounted trigger %s", me->key); -@@ -1072,7 +1163,6 @@ int handle_packet_expire_direct(struct a - return 1; - } - -- - mt = malloc(sizeof(struct pending_args)); - if (!mt) { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -@@ -1155,15 +1245,6 @@ static void *do_mount_direct(void *arg) - struct ioctl_ops *ops = get_ioctl_ops(); - struct pending_args *mt; - struct autofs_point *ap; -- struct passwd pw; -- struct passwd *ppw = &pw; -- struct passwd **pppw = &ppw; -- struct group gr; -- struct group *pgr; -- struct group **ppgr; -- char *pw_tmp, *gr_tmp; -- struct thread_stdenv_vars *tsv; -- int tmplen, grplen; - struct stat st; - int status, state; - -@@ -1209,126 +1290,8 @@ static void *do_mount_direct(void *arg) - - info(ap->logopt, "attempting to mount entry %s", mt->name); - -- /* -- * Setup thread specific data values for macro -- * substution in map entries during the mount. -- * Best effort only as it must go ahead. -- */ -+ set_tsd_user_vars(ap->logopt, mt->uid, mt->gid); - -- tsv = malloc(sizeof(struct thread_stdenv_vars)); -- if (!tsv) -- goto cont; -- -- tsv->uid = mt->uid; -- tsv->gid = mt->gid; -- -- /* Try to get passwd info */ -- -- tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- pw_tmp = malloc(tmplen + 1); -- if (!pw_tmp) { -- error(ap->logopt, "failed to malloc buffer for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw); -- if (status || !ppw) { -- error(ap->logopt, "failed to get passwd info from getpwuid_r"); -- free(tsv); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->user = strdup(pw.pw_name); -- if (!tsv->user) { -- error(ap->logopt, "failed to malloc buffer for user"); -- free(tsv); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->home = strdup(pw.pw_dir); -- if (!tsv->user) { -- error(ap->logopt, "failed to malloc buffer for home"); -- free(pw_tmp); -- free(tsv->user); -- free(tsv); -- goto cont; -- } -- -- free(pw_tmp); -- -- /* Try to get group info */ -- -- grplen = sysconf(_SC_GETGR_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- -- gr_tmp = NULL; -- tmplen = grplen; -- while (1) { -- char *tmp = realloc(gr_tmp, tmplen + 1); -- if (!tmp) { -- error(ap->logopt, "failed to malloc buffer for getgrgid_r"); -- if (gr_tmp) -- free(gr_tmp); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- gr_tmp = tmp; -- pgr = &gr; -- ppgr = &pgr; -- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr); -- if (status != ERANGE) -- break; -- tmplen += grplen; -- } -- -- if (status || !pgr) { -- error(ap->logopt, "failed to get group info from getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- tsv->group = strdup(gr.gr_name); -- if (!tsv->group) { -- error(ap->logopt, "failed to malloc buffer for group"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- free(gr_tmp); -- -- status = pthread_setspecific(key_thread_stdenv_vars, tsv); -- if (status) { -- error(ap->logopt, "failed to set stdenv thread var"); -- free(tsv->group); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- } -- --cont: - status = lookup_nss_mount(ap, NULL, mt->name, strlen(mt->name)); - /* - * Direct mounts are always a single mount. If it fails there's -diff -up autofs-5.0.3/daemon/lookup.c.active-restart autofs-5.0.3/daemon/lookup.c ---- autofs-5.0.3/daemon/lookup.c.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/daemon/lookup.c 2008-02-25 09:16:46.000000000 +0900 -@@ -898,7 +898,8 @@ int lookup_nss_mount(struct autofs_point - - map = map->next; - } -- send_map_update_request(ap); -+ if (ap->state != ST_INIT) -+ send_map_update_request(ap); - pthread_cleanup_pop(1); - - return !result; -diff -up autofs-5.0.3/include/parse_subs.h.active-restart autofs-5.0.3/include/parse_subs.h ---- autofs-5.0.3/include/parse_subs.h.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/include/parse_subs.h 2008-02-25 09:16:46.000000000 +0900 -@@ -27,8 +27,5 @@ int strmcmp(const char *, const char *, - char *dequote(const char *, int, unsigned int); - int span_space(const char *, unsigned int); - char *sanitize_path(const char *, int, unsigned int, unsigned int); --int umount_ent(struct autofs_point *, const char *); --int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); --int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); - - #endif -diff -up autofs-5.0.3/include/automount.h.active-restart autofs-5.0.3/include/automount.h ---- autofs-5.0.3/include/automount.h.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/include/automount.h 2008-02-25 09:16:46.000000000 +0900 -@@ -29,6 +29,7 @@ - #include "log.h" - #include "rpc_subs.h" - #include "parse_subs.h" -+#include "mounts.h" - #include "dev-ioctl-lib.h" - - #ifdef WITH_DMALLOC -@@ -71,10 +72,6 @@ int load_autofs4_module(void); - #define SMB_SUPER_MAGIC 0x0000517BL - #define CIFS_MAGIC_NUMBER 0xFF534D42L - --#define AUTOFS_TYPE_INDIRECT 0x0001 --#define AUTOFS_TYPE_DIRECT 0x0002 --#define AUTOFS_TYPE_OFFSET 0x0004 -- - /* This sould be enough for at least 20 host aliases */ - #define HOST_ENT_BUF_SIZE 2048 - -@@ -146,7 +143,7 @@ struct mapent_cache { - struct mapent { - struct mapent *next; - struct list_head ino_index; -- pthread_mutex_t multi_mutex; -+ pthread_rwlock_t multi_rwlock; - struct list_head multi_list; - struct mapent_cache *mc; - struct map_source *source; -@@ -189,7 +186,8 @@ int cache_add_offset(struct mapent_cache - int cache_set_parents(struct mapent *mm); - int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); - int cache_delete(struct mapent_cache *mc, const char *key); --void cache_multi_lock(struct mapent *me); -+void cache_multi_readlock(struct mapent *me); -+void cache_multi_writelock(struct mapent *me); - void cache_multi_unlock(struct mapent *me); - int cache_delete_offset_list(struct mapent_cache *mc, const char *key); - void cache_release(struct map_source *map); -@@ -328,62 +326,6 @@ int cat_path(char *buf, size_t len, cons - int ncat_path(char *buf, size_t len, - const char *dir, const char *base, size_t blen); - --/* mount table utilities */ -- --#define MNTS_ALL 0x0001 --#define MNTS_REAL 0x0002 --#define MNTS_AUTOFS 0x0004 -- --struct mnt_list { -- char *path; -- char *fs_name; -- char *fs_type; -- char *opts; -- pid_t owner; -- /* -- * List operations ie. get_mnt_list. -- */ -- struct mnt_list *next; -- /* -- * Tree operations ie. tree_make_tree, -- * tree_get_mnt_list etc. -- */ -- struct mnt_list *left; -- struct mnt_list *right; -- struct list_head self; -- struct list_head list; -- struct list_head entries; -- struct list_head sublist; -- /* -- * Offset mount handling ie. add_ordered_list -- * and get_offset. -- */ -- struct list_head ordered; --}; -- --unsigned int query_kproto_ver(void); --unsigned int get_kver_major(void); --unsigned int get_kver_minor(void); --char *make_options_string(char *path, int kernel_pipefd, char *extra); --char *make_mnt_name_string(char *path); --struct mnt_list *get_mnt_list(const char *table, const char *path, int include); --struct mnt_list *reverse_mnt_list(struct mnt_list *list); --void free_mnt_list(struct mnt_list *list); --int contained_in_local_fs(const char *path); --int is_mounted(const char *table, const char *path, unsigned int type); --int has_fstab_option(const char *opt); --int find_mnt_devid(const char *table, const char *path, char *devid, unsigned int type); --char *get_offset(const char *prefix, char *offset, -- struct list_head *head, struct list_head **pos); --void add_ordered_list(struct mnt_list *ent, struct list_head *head); --void tree_free_mnt_tree(struct mnt_list *tree); --struct mnt_list *tree_make_mnt_tree(const char *table, const char *path); --int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include); --int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include); --int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path); --int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type); --int tree_find_mnt_devid(struct mnt_list *mnts, const char *path, char *devid, unsigned int type); -- - /* Core automount definitions */ - - #define MNT_DETACH 0x00000002 /* Just detach from the tree */ -@@ -391,10 +333,14 @@ int tree_find_mnt_devid(struct mnt_list - struct startup_cond { - pthread_mutex_t mutex; - pthread_cond_t cond; -+ struct autofs_point *ap; - unsigned int done; - unsigned int status; - }; - -+int handle_mounts_startup_cond_init(struct startup_cond *suc); -+void handle_mounts_startup_cond_destroy(void *arg); -+ - struct master_readmap_cond { - pthread_mutex_t mutex; - pthread_cond_t cond; -diff -up autofs-5.0.3/modules/mount_ext2.c.active-restart autofs-5.0.3/modules/mount_ext2.c ---- autofs-5.0.3/modules/mount_ext2.c.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/modules/mount_ext2.c 2008-02-25 09:16:46.000000000 +0900 -@@ -84,8 +84,9 @@ int mount_mount(struct autofs_point *ap, - existed = 0; - - if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX "warning: %s is already mounted", fullpath); -+ info(ap->logopt, MODPREFIX -+ "%s is already mounted or is bieng re-mounted", -+ fullpath); - return 0; - } - -diff -up autofs-5.0.3/modules/mount_generic.c.active-restart autofs-5.0.3/modules/mount_generic.c ---- autofs-5.0.3/modules/mount_generic.c.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/modules/mount_generic.c 2008-02-25 09:16:46.000000000 +0900 -@@ -83,8 +83,9 @@ int mount_mount(struct autofs_point *ap, - existed = 0; - - if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX "warning: %s is already mounted", fullpath); -+ info(ap->logopt, MODPREFIX -+ "%s is already mounted or is being re-mounted", -+ fullpath); - return 0; - } - -diff -up autofs-5.0.3/modules/mount_autofs.c.active-restart autofs-5.0.3/modules/mount_autofs.c ---- autofs-5.0.3/modules/mount_autofs.c.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/modules/mount_autofs.c 2008-02-25 09:16:46.000000000 +0900 -@@ -46,6 +46,7 @@ int mount_mount(struct autofs_point *ap, - int name_len, const char *what, const char *fstype, - const char *c_options, void *context) - { -+ struct startup_cond suc; - pthread_t thid; - char *fullpath; - const char **argv; -@@ -216,27 +217,26 @@ int mount_mount(struct autofs_point *ap, - - mounts_mutex_lock(ap); - -- status = pthread_mutex_lock(&suc.mutex); -- if (status) { -- crit(ap->logopt, -- MODPREFIX "failed to lock startup condition mutex!"); -+ if (handle_mounts_startup_cond_init(&suc)) { -+ crit(ap->logopt, MODPREFIX -+ "failed to init startup cond for mount %s", entry->path); -+ mounts_mutex_unlock(ap); - cache_release(source); - master_free_mapent(entry); - return 1; - } - -+ suc.ap = nap; - suc.done = 0; - suc.status = 0; - -- if (pthread_create(&thid, NULL, handle_mounts, nap)) { -+ if (pthread_create(&thid, NULL, handle_mounts, &suc)) { - crit(ap->logopt, - MODPREFIX - "failed to create mount handler thread for %s", - fullpath); - mounts_mutex_unlock(ap); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - cache_release(source); - master_free_mapent(entry); - return 1; -@@ -247,7 +247,7 @@ int mount_mount(struct autofs_point *ap, - status = pthread_cond_wait(&suc.cond, &suc.mutex); - if (status) { - mounts_mutex_unlock(ap); -- pthread_mutex_unlock(&suc.mutex); -+ handle_mounts_startup_cond_destroy(&suc); - fatal(status); - } - } -@@ -256,9 +256,7 @@ int mount_mount(struct autofs_point *ap, - crit(ap->logopt, - MODPREFIX "failed to create submount for %s", fullpath); - mounts_mutex_unlock(ap); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - master_free_mapent(entry); - return 1; - } -@@ -266,12 +264,9 @@ int mount_mount(struct autofs_point *ap, - ap->submnt_count++; - list_add(&nap->mounts, &ap->submounts); - -+ handle_mounts_startup_cond_destroy(&suc); - mounts_mutex_unlock(ap); - -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -- - return 0; - } - -diff -up autofs-5.0.3/modules/mount_nfs.c.active-restart autofs-5.0.3/modules/mount_nfs.c ---- autofs-5.0.3/modules/mount_nfs.c.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/modules/mount_nfs.c 2008-02-25 09:16:46.000000000 +0900 -@@ -198,10 +198,10 @@ int mount_mount(struct autofs_point *ap, - char *loc, *port_opt = NULL; - - if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX -- "warning: %s is already mounted", fullpath); -- break; -+ info(ap->logopt, MODPREFIX -+ "%s is already mounted or is being re-mounted", fullpath); -+ free_host_list(&hosts); -+ return 0; - } - - /* -diff -up autofs-5.0.3/modules/parse_sun.c.active-restart autofs-5.0.3/modules/parse_sun.c ---- autofs-5.0.3/modules/parse_sun.c.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/modules/parse_sun.c 2008-02-25 09:16:46.000000000 +0900 -@@ -968,8 +968,6 @@ static int mount_subtree_offsets(struct - if (!mm) - return 0; - -- cache_multi_lock(me->parent); -- - m_key = mm->key; - - if (*m_key == '/') { -@@ -999,8 +997,6 @@ static int mount_subtree_offsets(struct - return -1; - } - -- cache_multi_unlock(me->parent); -- - return ret; - } - -@@ -1197,7 +1193,7 @@ int parse_mount(struct autofs_point *ap, - * us to fail on the check for duplicate offsets in - * we don't know when submounts go away. - */ -- cache_multi_lock(me); -+ cache_multi_writelock(me); - cache_delete_offset_list(mc, name); - cache_multi_unlock(me); - } -@@ -1220,7 +1216,7 @@ int parse_mount(struct autofs_point *ap, - } - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); -- cache_multi_lock(me); -+ cache_multi_writelock(me); - /* It's a multi-mount; deal with it */ - do { - char *path, *myoptions, *loc; -@@ -1296,6 +1292,10 @@ int parse_mount(struct autofs_point *ap, - */ - cache_set_parents(me); - -+ /* Added multi-mount cache entries, down grade lock */ -+ cache_multi_unlock(me); -+ cache_multi_readlock(me); -+ - /* Mount root offset if it exists */ - ro = cache_lookup_offset("/", "/", strlen(m_root), &me->multi_list); - if (ro) { -@@ -1468,10 +1468,14 @@ mount_it: - cache_readlock(mc); - me = cache_lookup_distinct(mc, name); - if (me) { -- int ret = mount_subtree_offsets(ap, mc, me); -+ int ret; -+ -+ cache_multi_readlock(me->parent); -+ ret = mount_subtree_offsets(ap, mc, me); - /* Convert fail on nonstrict, non-empty multi-mount to success */ - if (rv < 0 && ret > 0) - rv = 0; -+ cache_multi_unlock(me->parent); - } - cache_unlock(mc); - pthread_setcancelstate(cur_state, NULL); -diff -up autofs-5.0.3/modules/mount_bind.c.active-restart autofs-5.0.3/modules/mount_bind.c ---- autofs-5.0.3/modules/mount_bind.c.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/modules/mount_bind.c 2008-02-25 09:16:46.000000000 +0900 -@@ -126,8 +126,8 @@ int mount_mount(struct autofs_point *ap, - existed = 0; - - if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX "warning: %s is already mounted", -+ info(ap->logopt, MODPREFIX -+ "%s is already mounted or is being re-mounted", - fullpath); - return 0; - } -diff -up autofs-5.0.3/lib/parse_subs.c.active-restart autofs-5.0.3/lib/parse_subs.c ---- autofs-5.0.3/lib/parse_subs.c.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/lib/parse_subs.c 2008-02-25 09:16:46.000000000 +0900 -@@ -18,10 +18,7 @@ - #include - #include - #include --#include --#include - #include --#include - #include "automount.h" - - /* -@@ -304,220 +301,3 @@ char *sanitize_path(const char *path, in - return s_path; - } - --int umount_ent(struct autofs_point *ap, const char *path) --{ -- struct stat st; -- struct statfs fs; -- int sav_errno; -- int status, is_smbfs = 0; -- int ret, rv = 1; -- -- ret = statfs(path, &fs); -- if (ret == -1) { -- warn(ap->logopt, "could not stat fs of %s", path); -- is_smbfs = 0; -- } else { -- int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER; -- int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC; -- is_smbfs = (cifsfs | smbfs) ? 1 : 0; -- } -- -- status = lstat(path, &st); -- sav_errno = errno; -- -- if (status < 0) -- warn(ap->logopt, "lstat of %s failed with %d", path, status); -- -- /* -- * lstat failed and we're an smbfs fs returning an error that is not -- * EIO or EBADSLT or the lstat failed so it's a bad path. Return -- * a fail. -- * -- * EIO appears to correspond to an smb mount that has gone away -- * and EBADSLT relates to CD changer not responding. -- */ -- if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) { -- rv = spawn_umount(ap->logopt, path, NULL); -- } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) { -- rv = spawn_umount(ap->logopt, path, NULL); -- } -- -- /* We are doing a forced shutcwdown down so unlink busy mounts */ -- if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { -- ret = stat(path, &st); -- if (ret == -1 && errno == ENOENT) { -- warn(ap->logopt, "mount point does not exist"); -- return 0; -- } -- -- if (ret == 0 && !S_ISDIR(st.st_mode)) { -- warn(ap->logopt, "mount point is not a directory"); -- return 0; -- } -- -- if (ap->state == ST_SHUTDOWN_FORCE) { -- info(ap->logopt, "forcing umount of %s", path); -- rv = spawn_umount(ap->logopt, "-l", path, NULL); -- } -- -- /* -- * Verify that we actually unmounted the thing. This is a -- * belt and suspenders approach to not eating user data. -- * We have seen cases where umount succeeds, but there is -- * still a file system mounted on the mount point. How -- * this happens has not yet been determined, but we want to -- * make sure to return failure here, if that is the case, -- * so that we do not try to call rmdir_path on the -- * directory. -- */ -- if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { -- crit(ap->logopt, -- "the umount binary reported that %s was " -- "unmounted, but there is still something " -- "mounted on this path.", path); -- rv = -1; -- } -- } -- -- return rv; --} -- --int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) --{ -- char path[PATH_MAX + 1]; -- char *offset = path; -- struct mapent *oe; -- struct list_head *pos = NULL; -- unsigned int fs_path_len; -- unsigned int mounted; -- int start; -- -- fs_path_len = strlen(root) + strlen(base); -- if (fs_path_len > PATH_MAX) -- return -1; -- -- strcpy(path, root); -- strcat(path, base); -- -- mounted = 0; -- start = strlen(root); -- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); -- while (offset) { -- int plen = fs_path_len + strlen(offset); -- -- if (plen > PATH_MAX) { -- warn(ap->logopt, "path loo long"); -- goto cont; -- } -- -- oe = cache_lookup_offset(base, offset, start, &me->multi_list); -- if (!oe) -- goto cont; -- -- debug(ap->logopt, "mount offset %s", oe->key); -- -- if (mount_autofs_offset(ap, oe) < 0) -- warn(ap->logopt, "failed to mount offset"); -- else -- mounted++; --cont: -- offset = cache_get_offset(base, -- offset, start, &me->multi_list, &pos); -- } -- -- return mounted; --} -- --int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) --{ -- char path[PATH_MAX + 1]; -- char *offset; -- struct mapent *oe; -- struct list_head *mm_root, *pos; -- const char o_root[] = "/"; -- const char *mm_base; -- int left, start; -- -- left = 0; -- start = strlen(root); -- -- mm_root = &me->multi->multi_list; -- -- if (!base) -- mm_base = o_root; -- else -- mm_base = base; -- -- pos = NULL; -- offset = path; -- -- /* Make sure "none" of the offsets have an active mount. */ -- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -- char *oe_base; -- -- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -- /* root offset is a special case */ -- if (!oe || (strlen(oe->key) - start) == 1) -- continue; -- -- /* -- * Check for and umount subtree offsets resulting from -- * nonstrict mount fail. -- */ -- oe_base = oe->key + strlen(root); -- left += umount_multi_triggers(ap, root, oe, oe_base); -- -- if (oe->ioctlfd != -1) -- left++; -- } -- -- if (left) -- return left; -- -- pos = NULL; -- offset = path; -- -- /* Make sure "none" of the offsets have an active mount. */ -- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -- /* root offset is a special case */ -- if (!oe || (strlen(oe->key) - start) == 1) -- continue; -- -- debug(ap->logopt, "umount offset %s", oe->key); -- -- if (umount_autofs_offset(ap, oe)) { -- warn(ap->logopt, "failed to umount offset"); -- left++; -- } -- } -- -- if (!left && me->multi == me) { -- struct mapent_cache *mc = me->mc; -- int status; -- -- /* -- * Special case. -- * If we can't umount the root container then we can't -- * delete the offsets from the cache and we need to put -- * the offset triggers back. -- */ -- if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { -- info(ap->logopt, "unmounting dir = %s", root); -- if (umount_ent(ap, root)) { -- if (!mount_multi_triggers(ap, root, me, "/")) -- warn(ap->logopt, -- "failed to remount offset triggers"); -- return left++; -- } -- } -- -- /* We're done - clean out the offsets */ -- status = cache_delete_offset_list(mc, me->key); -- if (status != CHE_OK) -- warn(ap->logopt, "couldn't delete offset list"); -- } -- -- return left; --} -- -diff -up autofs-5.0.3/lib/mounts.c.active-restart autofs-5.0.3/lib/mounts.c ---- autofs-5.0.3/lib/mounts.c.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/lib/mounts.c 2008-02-25 09:16:46.000000000 +0900 -@@ -1,6 +1,6 @@ - /* ----------------------------------------------------------------------- * - * -- * mounts.c - module for Linux automount mount table lookup functions -+ * mounts.c - module for mount utilities. - * - * Copyright 2002-2005 Ian Kent - All Rights Reserved - * -@@ -23,12 +23,21 @@ - #include - #include - #include -+#include -+#include -+#include -+#include - - #include "automount.h" - - #define MAX_OPTIONS_LEN 80 - #define MAX_MNT_NAME_LEN 30 - -+const unsigned int indirect = AUTOFS_TYPE_INDIRECT; -+const unsigned int direct = AUTOFS_TYPE_DIRECT; -+const unsigned int offset = AUTOFS_TYPE_OFFSET; -+const unsigned int type_count = 3; -+ - static const char options_template[] = "fd=%d,pgrp=%u,minproto=5,maxproto=%d"; - static const char options_template_extra[] = "fd=%d,pgrp=%u,minproto=5,maxproto=%d,%s"; - static const char mnt_name_template[] = "automount(pid%u)"; -@@ -466,7 +475,7 @@ int has_fstab_option(const char *opt) - * super block when searching for the mount. - */ - int find_mnt_devid(const char *table, -- const char *path, char *devid, unsigned int type) -+ const char *path, char *devid, const unsigned int type) - { - struct mntent *mnt; - struct mntent mnt_wrk; -@@ -1070,3 +1079,528 @@ int tree_find_mnt_devid(struct mnt_list - return 1; - } - -+void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid) -+{ -+ struct thread_stdenv_vars *tsv; -+ struct passwd pw; -+ struct passwd *ppw = &pw; -+ struct passwd **pppw = &ppw; -+ struct group gr; -+ struct group *pgr; -+ struct group **ppgr; -+ char *pw_tmp, *gr_tmp; -+ int status, tmplen, grplen; -+ -+ /* -+ * Setup thread specific data values for macro -+ * substution in map entries during the mount. -+ * Best effort only as it must go ahead. -+ */ -+ -+ tsv = malloc(sizeof(struct thread_stdenv_vars)); -+ if (!tsv) { -+ error(logopt, "failed alloc tsv storage"); -+ return; -+ } -+ -+ tsv->uid = uid; -+ tsv->gid = gid; -+ -+ /* Try to get passwd info */ -+ -+ tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); -+ if (tmplen < 0) { -+ error(logopt, "failed to get buffer size for getpwuid_r"); -+ goto free_tsv; -+ } -+ -+ pw_tmp = malloc(tmplen + 1); -+ if (!pw_tmp) { -+ error(logopt, "failed to malloc buffer for getpwuid_r"); -+ goto free_tsv; -+ } -+ -+ status = getpwuid_r(uid, ppw, pw_tmp, tmplen, pppw); -+ if (status || !ppw) { -+ error(logopt, "failed to get passwd info from getpwuid_r"); -+ free(pw_tmp); -+ goto free_tsv; -+ } -+ -+ tsv->user = strdup(pw.pw_name); -+ if (!tsv->user) { -+ error(logopt, "failed to malloc buffer for user"); -+ free(pw_tmp); -+ goto free_tsv; -+ } -+ -+ tsv->home = strdup(pw.pw_dir); -+ if (!tsv->user) { -+ error(logopt, "failed to malloc buffer for home"); -+ free(pw_tmp); -+ goto free_tsv_user; -+ } -+ -+ free(pw_tmp); -+ -+ /* Try to get group info */ -+ -+ grplen = sysconf(_SC_GETGR_R_SIZE_MAX); -+ if (tmplen < 0) { -+ error(logopt, "failed to get buffer size for getgrgid_r"); -+ goto free_tsv_home; -+ } -+ -+ gr_tmp = NULL; -+ tmplen = grplen; -+ while (1) { -+ char *tmp = realloc(gr_tmp, tmplen + 1); -+ if (!tmp) { -+ error(logopt, "failed to malloc buffer for getgrgid_r"); -+ if (gr_tmp) -+ free(gr_tmp); -+ goto free_tsv_home; -+ } -+ gr_tmp = tmp; -+ pgr = &gr; -+ ppgr = &pgr; -+ status = getgrgid_r(gid, pgr, gr_tmp, tmplen, ppgr); -+ if (status != ERANGE) -+ break; -+ tmplen += grplen; -+ } -+ -+ if (status || !pgr) { -+ error(logopt, "failed to get group info from getgrgid_r"); -+ free(gr_tmp); -+ goto free_tsv_home; -+ } -+ -+ tsv->group = strdup(gr.gr_name); -+ if (!tsv->group) { -+ error(logopt, "failed to malloc buffer for group"); -+ free(gr_tmp); -+ goto free_tsv_home; -+ } -+ -+ free(gr_tmp); -+ -+ status = pthread_setspecific(key_thread_stdenv_vars, tsv); -+ if (status) { -+ error(logopt, "failed to set stdenv thread var"); -+ goto free_tsv_group; -+ } -+ -+ return; -+ -+free_tsv_group: -+ free(tsv->group); -+free_tsv_home: -+ free(tsv->home); -+free_tsv_user: -+ free(tsv->user); -+free_tsv: -+ free(tsv); -+ return; -+} -+ -+const char *mount_type_str(const unsigned int type) -+{ -+ static const char *str_type[] = { -+ "direct", -+ "indirect", -+ "offset" -+ }; -+ unsigned int pos, i; -+ -+ for (pos = 0, i = type; pos < type_count; i >>= 1, pos++) -+ if (i & 0x1) -+ break; -+ -+ return (pos == type_count ? NULL : str_type[pos]); -+} -+ -+void notify_mount_result(struct autofs_point *ap, -+ const char *path, const char *type) -+{ -+ if (ap->exp_timeout) -+ info(ap->logopt, -+ "mounted %s on %s with timeout %u, freq %u seconds", -+ type, path, -+ (unsigned int) ap->exp_timeout, -+ (unsigned int) ap->exp_runfreq); -+ else -+ info(ap->logopt, -+ "mounted %s on %s with timeouts disabled", -+ type, path); -+ -+ return; -+} -+ -+static int do_remount_direct(struct autofs_point *ap, int fd, const char *path) -+{ -+ struct ioctl_ops *ops = get_ioctl_ops(); -+ uid_t uid; -+ gid_t gid; -+ int ret; -+ -+ ops->requestor(ap->logopt, fd, path, &uid, &gid); -+ if (uid != -1 && gid != -1) -+ set_tsd_user_vars(ap->logopt, uid, gid); -+ -+ ret = lookup_nss_mount(ap, NULL, path, strlen(path)); -+ if (ret) -+ info(ap->logopt, "re-mounted %s", path); -+ else -+ info(ap->logopt, "failed to re-mount %s", path); -+ -+ return ret; -+} -+ -+static int do_remount_indirect(struct autofs_point *ap, int fd, const char *path) -+{ -+ struct ioctl_ops *ops = get_ioctl_ops(); -+ struct dirent **de; -+ char buf[PATH_MAX + 1]; -+ uid_t uid; -+ gid_t gid; -+ unsigned int mounted; -+ int n, size; -+ -+ n = scandir(path, &de, 0, alphasort); -+ if (n < 0) -+ return -1; -+ -+ size = sizeof(buf); -+ -+ while (n--) { -+ int ret, len; -+ -+ if (strcmp(de[n]->d_name, ".") == 0 || -+ strcmp(de[n]->d_name, "..") == 0) { -+ free(de[n]); -+ continue; -+ } -+ -+ ret = cat_path(buf, size, path, de[n]->d_name); -+ if (!ret) { -+ do { -+ free(de[n]); -+ } while (n--); -+ free(de); -+ return -1; -+ } -+ -+ ops->ismountpoint(ap->logopt, fd, buf, &mounted); -+ if (!mounted) { -+ free(de[n]); -+ continue; -+ } -+ -+ ops->requestor(ap->logopt, fd, buf, &uid, &gid); -+ if (uid != -1 && gid != -1) -+ set_tsd_user_vars(ap->logopt, uid, gid); -+ -+ len = strlen(de[n]->d_name); -+ -+ ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len); -+ if (ret) -+ info(ap->logopt, "re-mounted %s", buf); -+ else -+ info(ap->logopt, "failed to re-mount %s", buf); -+ -+ free(de[n]); -+ } -+ free(de); -+ -+ return 0; -+} -+ -+int remount_active_mount(struct autofs_point *ap, struct mapent_cache *mc, -+ const char *path, dev_t devid, const unsigned int type, -+ int *ioctlfd) -+{ -+ struct ioctl_ops *ops = get_ioctl_ops(); -+ time_t timeout = ap->exp_timeout; -+ const char *str_type = mount_type_str(type); -+ unsigned int mounted; -+ struct stat st; -+ int fd; -+ -+ *ioctlfd = -1; -+ -+ /* Open failed, no mount present */ -+ ops->open(ap->logopt, &fd, devid, path, type); -+ if (fd == -1) -+ return REMOUNT_OPEN_FAIL; -+ -+ /* Re-reading the map, set timeout and return */ -+ if (ap->state == ST_READMAP) { -+ ops->timeout(ap->logopt, fd, &timeout); -+ ops->close(ap->logopt, fd); -+ return REMOUNT_READ_MAP; -+ } -+ -+ /* Mounted so set pipefd and timeout etc. */ -+ ops->catatonic(ap->logopt, fd); -+ ops->setpipefd(ap->logopt, fd, ap->kpipefd); -+ ops->timeout(ap->logopt, fd, &timeout); -+ if (fstat(fd, &st) == -1) { -+ error(ap->logopt, -+ "failed to stat %s mount %s", str_type, path); -+ ops->close(ap->logopt, fd); -+ return REMOUNT_STAT_FAIL; -+ } -+ ap->dev = st.st_dev; -+ if (mc) -+ cache_set_ino_index(mc, path, st.st_dev, st.st_ino); -+ notify_mount_result(ap, path, str_type); -+ -+ debug(ap->logopt, "re-connected to mount %s", path); -+ -+ *ioctlfd = fd; -+ -+ /* Any mounts on or below? */ -+ ops->ismountpoint(ap->logopt, fd, path, &mounted); -+ if (!mounted) { -+ /* -+ * If we're an indirect mount we pass back the fd. -+ * But if were a direct or offset mount with no active -+ * mount we don't retain an open file descriptor. -+ */ -+ if (type == direct) { -+ ops->close(ap->logopt, fd); -+ *ioctlfd = -1; -+ } -+ } else { -+ /* -+ * What can I do if we can't remount the existing -+ * mount(s) (possibly a partial failure), everything -+ * following will be broken? -+ */ -+ if (type == indirect) -+ do_remount_indirect(ap, fd, path); -+ else -+ do_remount_direct(ap, fd, path); -+ } -+ -+ return REMOUNT_SUCCESS; -+} -+ -+int umount_ent(struct autofs_point *ap, const char *path) -+{ -+ struct stat st; -+ struct statfs fs; -+ int sav_errno; -+ int status, is_smbfs = 0; -+ int ret, rv = 1; -+ -+ ret = statfs(path, &fs); -+ if (ret == -1) { -+ warn(ap->logopt, "could not stat fs of %s", path); -+ is_smbfs = 0; -+ } else { -+ int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER; -+ int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC; -+ is_smbfs = (cifsfs | smbfs) ? 1 : 0; -+ } -+ -+ status = lstat(path, &st); -+ sav_errno = errno; -+ -+ if (status < 0) -+ warn(ap->logopt, "lstat of %s failed with %d", path, status); -+ -+ /* -+ * lstat failed and we're an smbfs fs returning an error that is not -+ * EIO or EBADSLT or the lstat failed so it's a bad path. Return -+ * a fail. -+ * -+ * EIO appears to correspond to an smb mount that has gone away -+ * and EBADSLT relates to CD changer not responding. -+ */ -+ if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) { -+ rv = spawn_umount(ap->logopt, path, NULL); -+ } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) { -+ rv = spawn_umount(ap->logopt, path, NULL); -+ } -+ -+ /* We are doing a forced shutcwdown down so unlink busy mounts */ -+ if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { -+ ret = stat(path, &st); -+ if (ret == -1 && errno == ENOENT) { -+ warn(ap->logopt, "mount point does not exist"); -+ return 0; -+ } -+ -+ if (ret == 0 && !S_ISDIR(st.st_mode)) { -+ warn(ap->logopt, "mount point is not a directory"); -+ return 0; -+ } -+ -+ if (ap->state == ST_SHUTDOWN_FORCE) { -+ info(ap->logopt, "forcing umount of %s", path); -+ rv = spawn_umount(ap->logopt, "-l", path, NULL); -+ } -+ -+ /* -+ * Verify that we actually unmounted the thing. This is a -+ * belt and suspenders approach to not eating user data. -+ * We have seen cases where umount succeeds, but there is -+ * still a file system mounted on the mount point. How -+ * this happens has not yet been determined, but we want to -+ * make sure to return failure here, if that is the case, -+ * so that we do not try to call rmdir_path on the -+ * directory. -+ */ -+ if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { -+ crit(ap->logopt, -+ "the umount binary reported that %s was " -+ "unmounted, but there is still something " -+ "mounted on this path.", path); -+ rv = -1; -+ } -+ } -+ -+ return rv; -+} -+ -+int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) -+{ -+ char path[PATH_MAX + 1]; -+ char *offset = path; -+ struct mapent *oe; -+ struct list_head *pos = NULL; -+ unsigned int fs_path_len; -+ unsigned int mounted; -+ int start; -+ -+ fs_path_len = strlen(root) + strlen(base); -+ if (fs_path_len > PATH_MAX) -+ return -1; -+ -+ strcpy(path, root); -+ strcat(path, base); -+ -+ mounted = 0; -+ start = strlen(root); -+ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); -+ while (offset) { -+ int plen = fs_path_len + strlen(offset); -+ -+ if (plen > PATH_MAX) { -+ warn(ap->logopt, "path loo long"); -+ goto cont; -+ } -+ -+ oe = cache_lookup_offset(base, offset, start, &me->multi_list); -+ if (!oe) -+ goto cont; -+ -+ debug(ap->logopt, "mount offset %s", oe->key); -+ -+ if (mount_autofs_offset(ap, oe) < 0) -+ warn(ap->logopt, "failed to mount offset"); -+ else -+ mounted++; -+cont: -+ offset = cache_get_offset(base, -+ offset, start, &me->multi_list, &pos); -+ } -+ -+ return mounted; -+} -+ -+int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) -+{ -+ char path[PATH_MAX + 1]; -+ char *offset; -+ struct mapent *oe; -+ struct list_head *mm_root, *pos; -+ const char o_root[] = "/"; -+ const char *mm_base; -+ int left, start; -+ -+ left = 0; -+ start = strlen(root); -+ -+ mm_root = &me->multi->multi_list; -+ -+ if (!base) -+ mm_base = o_root; -+ else -+ mm_base = base; -+ -+ pos = NULL; -+ offset = path; -+ -+ /* Make sure "none" of the offsets have an active mount. */ -+ while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -+ char *oe_base; -+ -+ oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -+ /* root offset is a special case */ -+ if (!oe || (strlen(oe->key) - start) == 1) -+ continue; -+ -+ /* -+ * Check for and umount subtree offsets resulting from -+ * nonstrict mount fail. -+ */ -+ oe_base = oe->key + strlen(root); -+ left += umount_multi_triggers(ap, root, oe, oe_base); -+ -+ if (oe->ioctlfd != -1) -+ left++; -+ } -+ -+ if (left) -+ return left; -+ -+ pos = NULL; -+ offset = path; -+ -+ /* Make sure "none" of the offsets have an active mount. */ -+ while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -+ oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -+ /* root offset is a special case */ -+ if (!oe || (strlen(oe->key) - start) == 1) -+ continue; -+ -+ debug(ap->logopt, "umount offset %s", oe->key); -+ -+ if (umount_autofs_offset(ap, oe)) { -+ warn(ap->logopt, "failed to umount offset"); -+ left++; -+ } -+ } -+ -+ if (!left && me->multi == me) { -+ struct mapent_cache *mc = me->mc; -+ int status; -+ -+ /* -+ * Special case. -+ * If we can't umount the root container then we can't -+ * delete the offsets from the cache and we need to put -+ * the offset triggers back. -+ */ -+ if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { -+ info(ap->logopt, "unmounting dir = %s", root); -+ if (umount_ent(ap, root)) { -+ if (!mount_multi_triggers(ap, root, me, "/")) -+ warn(ap->logopt, -+ "failed to remount offset triggers"); -+ return left++; -+ } -+ } -+ -+ /* We're done - clean out the offsets */ -+ status = cache_delete_offset_list(mc, me->key); -+ if (status != CHE_OK) -+ warn(ap->logopt, "couldn't delete offset list"); -+ } -+ -+ return left; -+} -+ -diff -up autofs-5.0.3/lib/cache.c.active-restart autofs-5.0.3/lib/cache.c ---- autofs-5.0.3/lib/cache.c.active-restart 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/lib/cache.c 2008-02-25 09:16:46.000000000 +0900 -@@ -111,14 +111,29 @@ void cache_lock_cleanup(void *arg) - return; - } - --void cache_multi_lock(struct mapent *me) -+void cache_multi_readlock(struct mapent *me) - { - int status; - - if (!me) - return; - -- status = pthread_mutex_lock(&me->multi_mutex); -+ status = pthread_rwlock_rdlock(&me->multi_rwlock); -+ if (status) { -+ logmsg("mapent cache multi mutex lock failed"); -+ fatal(status); -+ } -+ return; -+} -+ -+void cache_multi_writelock(struct mapent *me) -+{ -+ int status; -+ -+ if (!me) -+ return; -+ -+ status = pthread_rwlock_wrlock(&me->multi_rwlock); - if (status) { - logmsg("mapent cache multi mutex lock failed"); - fatal(status); -@@ -133,7 +148,7 @@ void cache_multi_unlock(struct mapent *m - if (!me) - return; - -- status = pthread_mutex_unlock(&me->multi_mutex); -+ status = pthread_rwlock_unlock(&me->multi_rwlock); - if (status) { - logmsg("mapent cache multi mutex unlock failed"); - fatal(status); -@@ -553,8 +568,9 @@ int cache_add(struct mapent_cache *mc, s - me->ioctlfd = -1; - me->dev = (dev_t) -1; - me->ino = (ino_t) -1; -+ me->dir_created = 0; - -- status = pthread_mutex_init(&me->multi_mutex, NULL); -+ status = pthread_rwlock_init(&me->multi_rwlock, NULL); - if (status) - fatal(status); - -@@ -760,7 +776,7 @@ int cache_delete(struct mapent_cache *mc - goto done; - } - pred->next = me->next; -- status = pthread_mutex_destroy(&me->multi_mutex); -+ status = pthread_rwlock_destroy(&me->multi_rwlock); - if (status) - fatal(status); - ino_index_lock(mc); -@@ -784,7 +800,7 @@ int cache_delete(struct mapent_cache *mc - goto done; - } - mc->hash[hashval] = me->next; -- status = pthread_mutex_destroy(&me->multi_mutex); -+ status = pthread_rwlock_destroy(&me->multi_rwlock); - if (status) - fatal(status); - ino_index_lock(mc); -diff -up autofs-5.0.3/lib/master.c.active-restart autofs-5.0.3/lib/master.c ---- autofs-5.0.3/lib/master.c.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/lib/master.c 2008-02-25 09:16:46.000000000 +0900 -@@ -997,28 +997,31 @@ next: - - static int master_do_mount(struct master_mapent *entry) - { -+ struct startup_cond suc; - struct autofs_point *ap; - pthread_t thid; - int status; - -- status = pthread_mutex_lock(&suc.mutex); -- if (status) -- fatal(status); -+ ap = entry->ap; -+ -+ if (handle_mounts_startup_cond_init(&suc)) { -+ crit(ap->logopt, -+ "failed to init startup cond for mount %s", entry->path); -+ return 0; -+ } - -+ suc.ap = ap; - suc.done = 0; - suc.status = 0; - -- ap = entry->ap; -- - debug(ap->logopt, "mounting %s", entry->path); - -- if (pthread_create(&thid, &thread_attr, handle_mounts, ap)) { -+ status = pthread_create(&thid, &thread_attr, handle_mounts, &suc); -+ if (status) { - crit(ap->logopt, - "failed to create mount handler thread for %s", - entry->path); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - return 0; - } - entry->thid = thid; -@@ -1031,15 +1034,11 @@ static int master_do_mount(struct master - - if (suc.status) { - error(ap->logopt, "failed to startup mount"); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - return 0; - } - -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - - return 1; - } -diff -up autofs-5.0.3/CHANGELOG.active-restart autofs-5.0.3/CHANGELOG ---- autofs-5.0.3/CHANGELOG.active-restart 2008-02-25 09:16:05.000000000 +0900 -+++ autofs-5.0.3/CHANGELOG 2008-02-25 09:16:46.000000000 +0900 -@@ -9,6 +9,7 @@ - - fix expire working harder than needed. - - fix unlink of mount tree incorrectly causing autofs mount fail. - - add miscellaneous device node interface library. -+- use miscellaneous device node, if available, for active restart. - - 14/01/2008 autofs-5.0.3 - ----------------------- diff --git a/autofs-5.0.3-add-missing-uris-list-locking.patch b/autofs-5.0.3-add-missing-uris-list-locking.patch deleted file mode 100644 index d89f0d7..0000000 --- a/autofs-5.0.3-add-missing-uris-list-locking.patch +++ /dev/null @@ -1,129 +0,0 @@ -autofs-5.0.3 - add missing uris list locking - -From: Ian Kent - -Add inadvertantly ommitted server list locking in LDAP module. ---- - - include/lookup_ldap.h | 1 + - modules/lookup_ldap.c | 39 ++++++++++++++++++++++++++++++++++++++- - 2 files changed, 39 insertions(+), 1 deletion(-) - - ---- autofs-5.0.3.orig/include/lookup_ldap.h -+++ autofs-5.0.3/include/lookup_ldap.h -@@ -54,6 +54,7 @@ struct lookup_context { - * sdns is the list of basdns to check, done in the order - * given in configuration. - */ -+ pthread_mutex_t uris_mutex; - struct list_head *uri; - char *cur_host; - struct ldap_searchdn *sdns; ---- autofs-5.0.3.orig/modules/lookup_ldap.c -+++ autofs-5.0.3/modules/lookup_ldap.c -@@ -122,6 +122,22 @@ int ldap_parse_page_control(LDAP *ldap, - } - #endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */ - -+static void uris_mutex_lock(struct lookup_context *ctxt) -+{ -+ int status = pthread_mutex_lock(&ctxt->uris_mutex); -+ if (status) -+ fatal(status); -+ return; -+} -+ -+static void uris_mutex_unlock(struct lookup_context *ctxt) -+{ -+ int status = pthread_mutex_unlock(&ctxt->uris_mutex); -+ if (status) -+ fatal(status); -+ return; -+} -+ - int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) - { - int rv; -@@ -627,16 +643,20 @@ static LDAP *find_server(unsigned logopt - LIST_HEAD(tmp); - - /* Try each uri in list, add connect fails to tmp list */ -+ uris_mutex_lock(ctxt); - p = ctxt->uri->next; - while(p != ctxt->uri) { - this = list_entry(p, struct ldap_uri, list); -- p = p->next; -+ uris_mutex_unlock(ctxt); - debug(logopt, "trying server %s", this->uri); - ldap = connect_to_server(logopt, this->uri, ctxt); - if (ldap) { - info(logopt, "connected to uri %s", this->uri); -+ uris_mutex_lock(ctxt); - break; - } -+ uris_mutex_lock(ctxt); -+ p = p->next; - list_del_init(&this->list); - list_add_tail(&this->list, &tmp); - } -@@ -648,6 +668,7 @@ static LDAP *find_server(unsigned logopt - list_splice(ctxt->uri, &tmp); - INIT_LIST_HEAD(ctxt->uri); - list_splice(&tmp, ctxt->uri); -+ uris_mutex_unlock(ctxt); - - return ldap; - } -@@ -662,14 +683,18 @@ static LDAP *do_reconnect(unsigned logop - return ldap; - } - -+ uris_mutex_lock(ctxt); - this = list_entry(ctxt->uri->next, struct ldap_uri, list); -+ uris_mutex_unlock(ctxt); - ldap = do_connect(logopt, this->uri, ctxt); - if (ldap) - return ldap; - - /* Failed to connect, put at end of list */ -+ uris_mutex_lock(ctxt); - list_del_init(&this->list); - list_add_tail(&this->list, ctxt->uri); -+ uris_mutex_unlock(ctxt); - - #ifdef WITH_SASL - autofs_sasl_dispose(ctxt); -@@ -1203,6 +1228,8 @@ done: - - static void free_context(struct lookup_context *ctxt) - { -+ int ret; -+ - if (ctxt->schema) { - free(ctxt->schema->map_class); - free(ctxt->schema->map_attr); -@@ -1235,6 +1262,9 @@ static void free_context(struct lookup_c - free(ctxt->base); - if (ctxt->uri) - defaults_free_uris(ctxt->uri); -+ ret = pthread_mutex_destroy(&ctxt->uris_mutex); -+ if (ret) -+ fatal(ret); - if (ctxt->sdns) - defaults_free_searchdns(ctxt->sdns); - free(ctxt); -@@ -1286,6 +1316,13 @@ int lookup_init(const char *mapfmt, int - } - memset(ctxt, 0, sizeof(struct lookup_context)); - -+ ret = pthread_mutex_init(&ctxt->uris_mutex, NULL); -+ if (ret) { -+ error(LOGOPT_ANY, MODPREFIX "failed to init uris mutex"); -+ free(ctxt); -+ return 1; -+ } -+ - /* If a map type isn't explicitly given, parse it like sun entries. */ - if (mapfmt == NULL) - mapfmt = MAPFMT_DEFAULT; diff --git a/autofs-5.0.3-add-replicated-debug-logging.patch b/autofs-5.0.3-add-replicated-debug-logging.patch deleted file mode 100644 index dfbb99c..0000000 --- a/autofs-5.0.3-add-replicated-debug-logging.patch +++ /dev/null @@ -1,189 +0,0 @@ -autofs-5.0.3 - add replicated server selection debug logging - -From: Ian Kent - -Add some debug logging to the replicated server selection code. ---- - - CHANGELOG | 1 + - modules/replicated.c | 86 ++++++++++++++++++++++++++++++++++++++------------ - 2 files changed, 67 insertions(+), 20 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index a7b41ec..af3318a 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -30,6 +30,7 @@ - - avoid stat of possibly dead mount points and limit time to wait for - umount during expire. - - make mount of multi-mounts wuth a root offset atomic. -+- add replicated server selection debug logging. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/modules/replicated.c b/modules/replicated.c -index 271907c..e41713e 100644 ---- a/modules/replicated.c -+++ b/modules/replicated.c -@@ -404,6 +404,10 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, - double taken = 0; - int status, count = 0; - -+ debug(logopt, -+ "called for host %s proto %s version 0x%x", -+ host->name, proto, version); -+ - memset(&parms, 0, sizeof(struct pmap)); - - parms.pm_prog = NFS_PROGRAM; -@@ -428,11 +432,17 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, - status = rpc_ping_proto(rpc_info); - gettimeofday(&end, &tz); - if (status) { -- if (random_selection) -+ double reply; -+ if (random_selection) { - /* Random value between 0 and 1 */ -- taken += ((float) random())/((float) RAND_MAX+1); -- else -- taken += elapsed(start, end);; -+ reply = ((float) random())/((float) RAND_MAX+1); -+ debug(logopt, -+ "nfs v4 random selection time: %f", reply); -+ } else { -+ reply = elapsed(start, end); -+ debug(logopt, "nfs v4 rpc ping time: %f", reply); -+ } -+ taken += reply; - count++; - supported = NFS4_SUPPORTED; - } -@@ -470,11 +480,17 @@ v3_ver: - status = rpc_ping_proto(rpc_info); - gettimeofday(&end, &tz); - if (status) { -- if (random_selection) -+ double reply; -+ if (random_selection) { - /* Random value between 0 and 1 */ -- taken += ((float) random())/((float) RAND_MAX+1); -- else -- taken += elapsed(start, end);; -+ reply = ((float) random())/((float) RAND_MAX+1); -+ debug(logopt, -+ "nfs v3 random selection time: %f", reply); -+ } else { -+ reply = elapsed(start, end); -+ debug(logopt, "nfs v3 rpc ping time: %f", reply); -+ } -+ taken += reply; - count++; - supported |= NFS3_SUPPORTED; - } -@@ -504,11 +520,17 @@ v2_ver: - status = rpc_ping_proto(rpc_info); - gettimeofday(&end, &tz); - if (status) { -- if (random_selection) -+ double reply; -+ if (random_selection) { - /* Random value between 0 and 1 */ -- taken += ((float) random())/((float) RAND_MAX+1); -- else -- taken += elapsed(start, end);; -+ reply = ((float) random())/((float) RAND_MAX+1); -+ debug(logopt, -+ "nfs v2 random selection time: %f", reply); -+ } else { -+ reply = elapsed(start, end);; -+ debug(logopt, "nfs v2 rpc ping time: %f", reply); -+ } -+ taken += reply; - count++; - supported |= NFS2_SUPPORTED; - } -@@ -533,6 +555,9 @@ done_ver: - /* Allow for user bias */ - if (host->weight) - host->cost *= (host->weight + 1); -+ -+ debug(logopt, "host %s cost %ld weight %d", -+ host->name, host->cost, host->weight); - } - - return supported; -@@ -603,6 +628,9 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, - time_t timeout = RPC_TIMEOUT; - int status; - -+ debug(logopt, -+ "called with host %s version 0x%x", host->name, version); -+ - memset(&pm_info, 0, sizeof(struct conn_info)); - memset(&rpc_info, 0, sizeof(struct conn_info)); - memset(&parms, 0, sizeof(struct pmap)); -@@ -681,11 +709,14 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, - status = rpc_ping_proto(&rpc_info); - gettimeofday(&end, &tz); - if (status) { -- if (random_selection) -+ if (random_selection) { - /* Random value between 0 and 1 */ - taken = ((float) random())/((float) RAND_MAX+1); -- else -+ debug(logopt, "random selection time %f", taken); -+ } else { - taken = elapsed(start, end); -+ debug(logopt, "rpc ping time %f", taken); -+ } - } - } - done: -@@ -705,6 +736,8 @@ done: - if (host->weight) - host->cost *= (host->weight + 1); - -+ debug(logopt, "cost %ld weight %d", host->cost, host->weight); -+ - return 1; - } - -@@ -811,18 +844,31 @@ int prune_host_list(unsigned logopt, struct host **list, - max_udp_count = mmax(v4_udp_count, v3_udp_count, v2_udp_count); - max_count = max(max_tcp_count, max_udp_count); - -- if (max_count == v4_tcp_count) -+ if (max_count == v4_tcp_count) { - selected_version = NFS4_TCP_SUPPORTED; -- else if (max_count == v3_tcp_count) -+ debug(logopt, -+ "selected subset of hosts that support NFS4 over TCP"); -+ } else if (max_count == v3_tcp_count) { - selected_version = NFS3_TCP_SUPPORTED; -- else if (max_count == v2_tcp_count) -+ debug(logopt, -+ "selected subset of hosts that support NFS3 over TCP"); -+ } else if (max_count == v2_tcp_count) { - selected_version = NFS2_TCP_SUPPORTED; -- else if (max_count == v4_udp_count) -+ debug(logopt, -+ "selected subset of hosts that support NFS2 over TCP"); -+ } else if (max_count == v4_udp_count) { - selected_version = NFS4_UDP_SUPPORTED; -- else if (max_count == v3_udp_count) -+ debug(logopt, -+ "selected subset of hosts that support NFS4 over UDP"); -+ } else if (max_count == v3_udp_count) { - selected_version = NFS3_UDP_SUPPORTED; -- else if (max_count == v2_udp_count) -+ debug(logopt, -+ "selected subset of hosts that support NFS3 over UDP"); -+ } else if (max_count == v2_udp_count) { - selected_version = NFS2_UDP_SUPPORTED; -+ debug(logopt, -+ "selected subset of hosts that support NFS2 over UDP"); -+ } - - /* Add local and hosts with selected version to new list */ - this = *list; diff --git a/autofs-5.0.3-add-umount_wait-parameter.patch b/autofs-5.0.3-add-umount_wait-parameter.patch deleted file mode 100644 index ed2d527..0000000 --- a/autofs-5.0.3-add-umount_wait-parameter.patch +++ /dev/null @@ -1,138 +0,0 @@ -autofs-5.0.3 - add configuration paramter UMOUNT_WAIT - -From: Ian Kent - -To try and prevent expire delays when trying to umount from a server -that is not available we limit the time that we wait for a response -from the spawned umount process before sending it a SIGTERM signal. -This patch adds a configuration parameter to allow this wait to be -changed if needed. ---- - - daemon/spawn.c | 2 +- - include/defaults.h | 2 ++ - lib/defaults.c | 13 +++++++++++++ - man/auto.master.5.in | 6 ++++++ - redhat/autofs.sysconfig.in | 4 ++++ - samples/autofs.conf.default.in | 4 ++++ - 6 files changed, 30 insertions(+), 1 deletions(-) - - -diff --git a/daemon/spawn.c b/daemon/spawn.c -index e3c355e..6b26c41 100644 ---- a/daemon/spawn.c -+++ b/daemon/spawn.c -@@ -502,7 +502,7 @@ int spawn_umount(unsigned logopt, ...) - unsigned int options; - unsigned int retries = MTAB_LOCK_RETRIES; - int ret, printed = 0; -- unsigned int wait = 12; -+ unsigned int wait = defaults_get_umount_wait(); - - #ifdef ENABLE_MOUNT_LOCKING - options = SPAWN_OPT_LOCK; -diff --git a/include/defaults.h b/include/defaults.h -index 6e4f52a..12534ec 100644 ---- a/include/defaults.h -+++ b/include/defaults.h -@@ -24,6 +24,7 @@ - - #define DEFAULT_TIMEOUT 600 - #define DEFAULT_NEGATIVE_TIMEOUT 60 -+#define DEFAULT_UMOUNT_WAIT 12 - #define DEFAULT_BROWSE_MODE 1 - #define DEFAULT_LOGGING 0 - -@@ -59,6 +60,7 @@ struct ldap_schema *defaults_get_schema(void); - struct ldap_searchdn *defaults_get_searchdns(void); - void defaults_free_searchdns(struct ldap_searchdn *); - unsigned int defaults_get_append_options(void); -+unsigned int defaults_get_umount_wait(void); - const char *defaults_get_auth_conf_file(void); - - #endif -diff --git a/lib/defaults.c b/lib/defaults.c -index 8149549..21d76d2 100644 ---- a/lib/defaults.c -+++ b/lib/defaults.c -@@ -45,6 +45,7 @@ - #define ENV_NAME_VALUE_ATTR "VALUE_ATTRIBUTE" - - #define ENV_APPEND_OPTIONS "APPEND_OPTIONS" -+#define ENV_UMOUNT_WAIT "UMOUNT_WAIT" - #define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE" - - static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME; -@@ -320,6 +321,7 @@ unsigned int defaults_read_config(unsigned int to_syslog) - check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value, to_syslog) || - check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) || - check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) || -+ check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) || - check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog)) - ; - } -@@ -647,6 +649,17 @@ unsigned int defaults_get_append_options(void) - return res; - } - -+unsigned int defaults_get_umount_wait(void) -+{ -+ long wait; -+ -+ wait = get_env_number(ENV_UMOUNT_WAIT); -+ if (wait < 0) -+ wait = DEFAULT_UMOUNT_WAIT; -+ -+ return (unsigned int) wait; -+} -+ - const char *defaults_get_auth_conf_file(void) - { - char *cf; -diff --git a/man/auto.master.5.in b/man/auto.master.5.in -index 49a711c..9cc5f02 100644 ---- a/man/auto.master.5.in -+++ b/man/auto.master.5.in -@@ -174,6 +174,12 @@ Set the default timeout for caching failed key lookups (program default - 60). If the equivalent command line option is given it will override this - setting. - .TP -+.B UMOUNT_WAIT -+Set the default time to wait for a response from a spawned umount(8) -+before sending it a SIGTERM. Note that we still need to wait for the -+RPC layer to timeout before the sub-process exits so this isn't ideal -+but it is the best we can do. -+.TP - .B BROWSE_MODE - Maps are browsable by default (program default "yes"). - .TP -diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in -index 636763a..ce64feb 100644 ---- a/redhat/autofs.sysconfig.in -+++ b/redhat/autofs.sysconfig.in -@@ -14,6 +14,10 @@ TIMEOUT=300 - # - #NEGATIVE_TIMEOUT=60 - # -+# UMOUNT_WAIT - time to wait for a response from umount(8). -+# -+#UMOUNT_WAIT=12 -+# - # BROWSE_MODE - maps are browsable by default. - # - BROWSE_MODE="no" -diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in -index 086ba4f..0231e1d 100644 ---- a/samples/autofs.conf.default.in -+++ b/samples/autofs.conf.default.in -@@ -14,6 +14,10 @@ TIMEOUT=300 - # - #NEGATIVE_TIMEOUT=60 - # -+# UMOUNT_WAIT - time to wait for a response from umount(8). -+# -+#UMOUNT_WAIT=12 -+# - # BROWSE_MODE - maps are browsable by default. - # - BROWSE_MODE="no" 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 deleted file mode 100644 index b21f02c..0000000 --- a/autofs-5.0.3-allow-dir-create-on-nfs-root.patch +++ /dev/null @@ -1,48 +0,0 @@ -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-basedn-with-spaces-fix-3.patch b/autofs-5.0.3-basedn-with-spaces-fix-3.patch deleted file mode 100644 index 74dd070..0000000 --- a/autofs-5.0.3-basedn-with-spaces-fix-3.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/CHANGELOG b/CHANGELOG -index 8d09e93..b172579 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -2,6 +2,7 @@ - ----------------------- - - correct configure test for ldapr page control functions. - - catch "-xfn" map type and issue "no supported" message. -+- correction for handling of LDAP base dns with spaces. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/lib/master_tok.l b/lib/master_tok.l -index 2a6fdf9..7f1de90 100644 ---- a/lib/master_tok.l -+++ b/lib/master_tok.l -@@ -289,7 +289,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo - return EQUAL; - } - -- {DNNAMESTR1}/"," { -+ {DNNAMESTR1}/","{DNATTRSTR}"=" { - strcpy(master_lval.strtype, master_text); - return DNNAME; - } diff --git a/autofs-5.0.3-check-direct-path-len.patch b/autofs-5.0.3-check-direct-path-len.patch deleted file mode 100644 index 447d2b7..0000000 --- a/autofs-5.0.3-check-direct-path-len.patch +++ /dev/null @@ -1,89 +0,0 @@ -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-check-for-kernel-automount-fix.patch b/autofs-5.0.3-check-for-kernel-automount-fix.patch deleted file mode 100644 index 225f51b..0000000 --- a/autofs-5.0.3-check-for-kernel-automount-fix.patch +++ /dev/null @@ -1,25 +0,0 @@ -autofs-5.0.3 - check for kernel automount fix - -From: Ian Kent - -Look in the correct mount table for kernel automounted "nohide" -mounts. ---- - - daemon/direct.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - - -diff --git a/daemon/direct.c b/daemon/direct.c -index afb354e..13f572c 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -709,7 +709,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * - * the kernel NFS client. - */ - if (me->multi != me && -- is_mounted(_PATH_MOUNTED, mountpoint, MNTS_REAL)) -+ is_mounted(_PROC_MOUNTS, mountpoint, MNTS_REAL)) - return MOUNT_OFFSET_IGNORE; - - /* diff --git a/autofs-5.0.3-check-for-kernel-automount.patch b/autofs-5.0.3-check-for-kernel-automount.patch deleted file mode 100644 index df6e2c3..0000000 --- a/autofs-5.0.3-check-for-kernel-automount.patch +++ /dev/null @@ -1,200 +0,0 @@ -autofs 5.0.3 - check for exported mounts automatically mounted by kernel - -From: Ian Kent - -If a server exports file systems that are automatically mounted by -the kernel client autofs will mistakenly over mount them when it -constructs and mounts its multi-mount triggers. - -This patch makes autofs check for this case and ignores them if the -kernel mounts them while it mounts multi-mount triggers. - -We don't want to fight with NFS over mounting these because it -confuses autofs and they magically go away when the owner mount is -umounted. This isn't ideal because autofs will mount these mounts -while constructing its multi-mount triggers but it is unavoidable -at the moment. ---- - - CHANGELOG | 1 + - daemon/direct.c | 26 ++++++++++++++++++-------- - include/automount.h | 4 ++++ - lib/parse_subs.c | 26 ++++++++++++++++++-------- - 4 files changed, 41 insertions(+), 16 deletions(-) - - ---- autofs-5.0.3.orig/CHANGELOG -+++ autofs-5.0.3/CHANGELOG -@@ -12,6 +12,7 @@ - - init SASL callbacks on every ldap lookup library load. - - fix incorrect match of map type name when included in map name. - - fix incorrect pthreads condition handling for mount requests. -+- add check for exports automatically mounted by NFS kernel client. - - 14/01/2008 autofs-5.0.3 - ----------------------- ---- autofs-5.0.3.orig/daemon/direct.c -+++ autofs-5.0.3/daemon/direct.c -@@ -664,12 +664,12 @@ int mount_autofs_offset(struct autofs_po - if (ap->state != ST_READMAP) - warn(ap->logopt, - "trigger %s already mounted", me->key); -- return 0; -+ return MOUNT_OFFSET_OK; - } - - if (me->ioctlfd != -1) { - error(ap->logopt, "active offset mount %s", me->key); -- return -1; -+ return MOUNT_OFFSET_FAIL; - } - - status = pthread_once(&key_mnt_params_once, key_mnt_params_init); -@@ -683,7 +683,7 @@ int mount_autofs_offset(struct autofs_po - crit(ap->logopt, - "mnt_params value create failed for offset mount %s", - me->key); -- return 0; -+ return MOUNT_OFFSET_OK; - } - mp->options = NULL; - -@@ -697,12 +697,22 @@ int mount_autofs_offset(struct autofs_po - if (!mp->options) { - mp->options = make_options_string(ap->path, ap->kpipefd, "offset"); - if (!mp->options) -- return 0; -+ return MOUNT_OFFSET_OK; - } - - /* In case the directory doesn't exist, try to mkdir it */ - if (mkdir_path(me->key, 0555) < 0) { - if (errno == EEXIST) { -+ /* -+ * If the mount point directory is a real mount -+ * and it isn't the root offset then it must be -+ * a mount that has been automatically mounted by -+ * the kernel NFS client. -+ */ -+ if (me->multi != me && -+ is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) -+ return MOUNT_OFFSET_IGNORE; -+ - /* - * If we recieve an error, and it's EEXIST - * we know the directory was not created. -@@ -721,13 +731,13 @@ int mount_autofs_offset(struct autofs_po - debug(ap->logopt, - "can't create mount directory: %s, %s", - me->key, estr); -- return -1; -+ return MOUNT_OFFSET_FAIL; - } else { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - crit(ap->logopt, - "failed to create mount directory: %s, %s", - me->key, estr); -- return -1; -+ return MOUNT_OFFSET_FAIL; - } - } else { - /* No errors so the directory was successfully created */ -@@ -787,7 +797,7 @@ int mount_autofs_offset(struct autofs_po - - debug(ap->logopt, "mounted trigger %s", me->key); - -- return 0; -+ return MOUNT_OFFSET_OK; - - out_close: - close(ioctlfd); -@@ -797,7 +807,7 @@ out_err: - if (stat(me->key, &st) == 0 && me->dir_created) - rmdir_path(ap, me->key, st.st_dev); - -- return -1; -+ return MOUNT_OFFSET_FAIL; - } - - static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt) ---- autofs-5.0.3.orig/include/automount.h -+++ autofs-5.0.3/include/automount.h -@@ -468,6 +468,10 @@ struct autofs_point { - - /* Standard functions used by daemon or modules */ - -+#define MOUNT_OFFSET_OK 0 -+#define MOUNT_OFFSET_FAIL -1 -+#define MOUNT_OFFSET_IGNORE -2 -+ - void *handle_mounts(void *arg); - int umount_multi(struct autofs_point *ap, const char *path, int incl); - int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token); ---- autofs-5.0.3.orig/lib/parse_subs.c -+++ autofs-5.0.3/lib/parse_subs.c -@@ -390,7 +390,7 @@ int mount_multi_triggers(struct autofs_p - struct list_head *pos = NULL; - unsigned int fs_path_len; - unsigned int mounted; -- int start; -+ int ret, start; - - fs_path_len = strlen(root) + strlen(base); - if (fs_path_len > PATH_MAX) -@@ -411,15 +411,25 @@ int mount_multi_triggers(struct autofs_p - } - - oe = cache_lookup_offset(base, offset, start, &me->multi_list); -- if (!oe) -+ if (!oe || !oe->mapent) - goto cont; - - debug(ap->logopt, "mount offset %s", oe->key); - -- if (mount_autofs_offset(ap, oe) < 0) -- warn(ap->logopt, "failed to mount offset"); -- else -+ ret = mount_autofs_offset(ap, oe); -+ if (ret >= MOUNT_OFFSET_OK) - mounted++; -+ else { -+ if (ret != MOUNT_OFFSET_IGNORE) -+ warn(ap->logopt, "failed to mount offset"); -+ else { -+ debug(ap->logopt, -+ "ignoring \"nohide\" trigger %s", -+ oe->key); -+ free(oe->mapent); -+ oe->mapent = NULL; -+ } -+ } - cont: - offset = cache_get_offset(base, - offset, start, &me->multi_list, &pos); -@@ -457,7 +467,7 @@ int umount_multi_triggers(struct autofs_ - - oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); - /* root offset is a special case */ -- if (!oe || (strlen(oe->key) - start) == 1) -+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) - continue; - - /* -@@ -481,7 +491,7 @@ int umount_multi_triggers(struct autofs_ - while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { - oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); - /* root offset is a special case */ -- if (!oe || (strlen(oe->key) - start) == 1) -+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) - continue; - - debug(ap->logopt, "umount offset %s", oe->key); -@@ -505,7 +515,7 @@ int umount_multi_triggers(struct autofs_ - if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { - info(ap->logopt, "unmounting dir = %s", root); - if (umount_ent(ap, root)) { -- if (!mount_multi_triggers(ap, root, me, "/")) -+ if (mount_multi_triggers(ap, root, me, "/") < 0) - warn(ap->logopt, - "failed to remount offset triggers"); - return left++; diff --git a/autofs-5.0.3-check-replicated-list-after-probe.patch b/autofs-5.0.3-check-replicated-list-after-probe.patch deleted file mode 100644 index 55a1715..0000000 --- a/autofs-5.0.3-check-replicated-list-after-probe.patch +++ /dev/null @@ -1,33 +0,0 @@ -autofs-5.0.3 - check replicated list after probe - -From: Ian Kent - -When checking a list of servers for proximity and NFS version -the list may become empty after after the initial probe. This -case isn't handled and this patch adds it. ---- - - modules/replicated.c | 9 +++++++++ - 1 files changed, 9 insertions(+), 0 deletions(-) - - -diff --git a/modules/replicated.c b/modules/replicated.c -index 925f641..271907c 100644 ---- a/modules/replicated.c -+++ b/modules/replicated.c -@@ -768,6 +768,15 @@ int prune_host_list(unsigned logopt, struct host **list, - this = next; - } - -+ /* -+ * The list of hosts that aren't proximity local may now -+ * be empty if we haven't been able probe any so we need -+ * to check again for a list containing only proximity -+ * local hosts. -+ */ -+ if (!first) -+ return 1; -+ - last = this; - - /* Select NFS version of highest number of closest servers */ diff --git a/autofs-5.0.3-clear-stale-on-map-read.patch b/autofs-5.0.3-clear-stale-on-map-read.patch deleted file mode 100644 index c4f2730..0000000 --- a/autofs-5.0.3-clear-stale-on-map-read.patch +++ /dev/null @@ -1,29 +0,0 @@ -autofs-5.0.3 - clear stale flag on map read - -From: Ian Kent - -We're not properly clearing the map stale flag after a map re-read -which causes a re-read after every lookup for master map entries -that have the "browse" option set. I removed the line that did -this at some point in the past and I must have had a reason to -do so. We'll have to wait and see what shows up after fixing -it. ---- - - daemon/lookup.c | 2 ++ - 1 files changed, 2 insertions(+), 0 deletions(-) - - -diff --git a/daemon/lookup.c b/daemon/lookup.c -index d33aadc..2277623 100644 ---- a/daemon/lookup.c -+++ b/daemon/lookup.c -@@ -298,6 +298,8 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a - - status = lookup->lookup_read_map(ap, age, lookup->context); - -+ map->stale = 0; -+ - /* - * For maps that don't support enumeration return success - * and do whatever we must to have autofs function with an diff --git a/autofs-5.0.3-correct-ldap-lib.patch b/autofs-5.0.3-correct-ldap-lib.patch deleted file mode 100644 index 8b03d87..0000000 --- a/autofs-5.0.3-correct-ldap-lib.patch +++ /dev/null @@ -1,78 +0,0 @@ -diff --git a/CHANGELOG b/CHANGELOG -index 5a85a8e..e393f33 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -4,6 +4,7 @@ - - catch "-xfn" map type and issue "no supported" message. - - correction for handling of LDAP base dns with spaces. - - avoid using UDP for probing NFSv4 mount requests. -+- use libldap instead of libldap_r (Guillaume Rousse). - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/aclocal.m4 b/aclocal.m4 -index f24e076..a1105ae 100644 ---- a/aclocal.m4 -+++ b/aclocal.m4 -@@ -232,7 +232,7 @@ AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL], - - # save current ldflags - af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" --LDFLAGS="$LDFLAGS -lldap_r" -+LDFLAGS="$LDFLAGS -lldap" - - AC_TRY_LINK( - [ #include ], -@@ -265,7 +265,7 @@ AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL], - - # save current ldflags - af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" --LDFLAGS="$LDFLAGS -lldap_r" -+LDFLAGS="$LDFLAGS -lldap" - - AC_TRY_LINK( - [ #include ], -diff --git a/configure b/configure -index e872392..0d3268c 100755 ---- a/configure -+++ b/configure -@@ -4563,7 +4563,7 @@ fi - { echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5 - echo "${ECHO_T}$ac_cv_lib_ldap_ldap_initialize" >&6; } - if test $ac_cv_lib_ldap_ldap_initialize = yes; then -- HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv" -+ HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap -llber -lresolv" - fi - - if test "$HAVE_LDAP" = "1"; then -@@ -4578,7 +4578,7 @@ echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; } - - # save current ldflags - af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" --LDFLAGS="$LDFLAGS -lldap_r" -+LDFLAGS="$LDFLAGS -lldap" - - cat >conftest.$ac_ext <<_ACEOF - /* confdefs.h. */ -@@ -4648,7 +4648,7 @@ echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; } - - # save current ldflags - af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" --LDFLAGS="$LDFLAGS -lldap_r" -+LDFLAGS="$LDFLAGS -lldap" - - cat >conftest.$ac_ext <<_ACEOF - /* confdefs.h. */ -diff --git a/configure.in b/configure.in -index a9c86dd..27b9bec 100644 ---- a/configure.in -+++ b/configure.in -@@ -197,7 +197,7 @@ AC_ARG_WITH(openldap, - if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then - HAVE_LDAP=0 - LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1" -- AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv", , -+ AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap -llber -lresolv", , - -llber -lresolv $LIBS) - if test "$HAVE_LDAP" = "1"; then - AC_DEFINE(WITH_LDAP,1, diff --git a/autofs-5.0.3-dont-abuse-ap-ghost-field.patch b/autofs-5.0.3-dont-abuse-ap-ghost-field.patch deleted file mode 100644 index 1624ec3..0000000 --- a/autofs-5.0.3-dont-abuse-ap-ghost-field.patch +++ /dev/null @@ -1,81 +0,0 @@ -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-dont-block-on-expire.patch b/autofs-5.0.3-dont-block-on-expire.patch deleted file mode 100644 index 1b4b394..0000000 --- a/autofs-5.0.3-dont-block-on-expire.patch +++ /dev/null @@ -1,495 +0,0 @@ -autofs-5.0.3 - try not to block on expire - -From: Ian Kent - -When a server is not available umount and any stat statfs and related -function calls may block for a significant amount of time. This effects -expire timeouts a lot due to their synchronous nature. This patch limits -the time we wait on spawned umounts and elininates calls to functions -that would block. This allows us to retry the umount on the next expire -event and continue the expire of remaining mounts. ---- - - CHANGELOG | 2 ++ - daemon/automount.c | 34 ++++++++++++++++++------------ - daemon/direct.c | 29 +++++--------------------- - daemon/indirect.c | 26 +++++++++-------------- - daemon/spawn.c | 59 ++++++++++++++++++++++++++++++++++++++++++---------- - include/master.h | 1 + - lib/master.c | 23 ++++++++++++++++++++ - lib/mounts.c | 48 ++---------------------------------------- - 8 files changed, 112 insertions(+), 110 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index ff04985..ff44cc7 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -27,6 +27,8 @@ - - don't use proc file system when checking if the daemon is running. - - make handle_mounts startup condition distinct. - - fix submount shutdown recovery handling. -+- avoid stat of possibly dead mount points and limit time to wait for -+ umount during expire. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/daemon/automount.c b/daemon/automount.c -index 68bf1d3..5bd5f6d 100644 ---- a/daemon/automount.c -+++ b/daemon/automount.c -@@ -247,9 +247,17 @@ static int walk_tree(const char *base, int (*fn) (unsigned logopt, - int, void *), int incl, unsigned logopt, void *arg) - { - char buf[PATH_MAX + 1]; -- struct stat st; -+ struct stat st, *pst = &st; -+ int ret; -+ -+ if (!is_mounted(_PATH_MOUNTED, base, MNTS_REAL)) -+ ret = lstat(base, pst); -+ else { -+ pst = NULL; -+ ret = 0; -+ } - -- if (lstat(base, &st) != -1 && (fn) (logopt, base, &st, 0, arg)) { -+ if (ret != -1 && (fn) (logopt, base, pst, 0, arg)) { - if (S_ISDIR(st.st_mode)) { - struct dirent **de; - int n; -@@ -283,7 +291,7 @@ static int walk_tree(const char *base, int (*fn) (unsigned logopt, - free(de); - } - if (incl) -- (fn) (logopt, base, &st, 1, arg); -+ (fn) (logopt, base, pst, 1, arg); - } - return 0; - } -@@ -294,6 +302,9 @@ static int rm_unwanted_fn(unsigned logopt, const char *file, const struct stat * - char buf[MAX_ERR_BUF]; - struct stat newst; - -+ if (!st) -+ return 0; -+ - if (when == 0) { - if (st->st_dev != dev) - return 0; -@@ -344,8 +355,8 @@ static int counter_fn(unsigned logopt, const char *file, const struct stat *st, - { - struct counter_args *counter = (struct counter_args *) arg; - -- if (S_ISLNK(st->st_mode) || (S_ISDIR(st->st_mode) -- && st->st_dev != counter->dev)) { -+ if (!st || (S_ISLNK(st->st_mode) || (S_ISDIR(st->st_mode) -+ && st->st_dev != counter->dev))) { - counter->count++; - return 0; - } -@@ -512,9 +523,8 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi - int umount_multi(struct autofs_point *ap, const char *path, int incl) - { - struct mapent_cache *nc; -- struct statfs fs; - int is_autofs_fs; -- int ret, left; -+ int left; - - debug(ap->logopt, "path %s incl %d", path, incl); - -@@ -526,13 +536,9 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl) - } - cache_unlock(nc); - -- ret = statfs(path, &fs); -- if (ret == -1) { -- error(ap->logopt, "could not stat fs of %s", path); -- return 1; -- } -- -- is_autofs_fs = fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC ? 1 : 0; -+ is_autofs_fs = 0; -+ if (master_find_submount(ap, path)) -+ is_autofs_fs = 1; - - left = 0; - -diff --git a/daemon/direct.c b/daemon/direct.c -index 334a4b6..7fb78a3 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -152,7 +152,7 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru - - retries = UMOUNT_RETRIES; - while ((rv = umount(me->key)) == -1 && retries--) { -- struct timespec tm = {0, 100000000}; -+ struct timespec tm = {0, 200000000}; - if (errno != EBUSY) - break; - nanosleep(&tm, NULL); -@@ -604,7 +604,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) - - retries = UMOUNT_RETRIES; - while ((rv = umount(me->key)) == -1 && retries--) { -- struct timespec tm = {0, 100000000}; -+ struct timespec tm = {0, 200000000}; - if (errno != EBUSY) - break; - nanosleep(&tm, NULL); -@@ -705,7 +705,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - * the kernel NFS client. - */ - if (me->multi != me && -- is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) -+ is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) - return MOUNT_OFFSET_IGNORE; - - /* -@@ -807,17 +807,7 @@ out_err: - - static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt) - { -- char buf[MAX_ERR_BUF]; -- int ret, retries; -- struct stat st; -- -- if (fstat(ioctlfd, &st) == -1) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- debug(logopt, "fstat failed: %s", estr); -- return 0; -- } -- -- retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES; -+ int ret, retries = EXPIRE_RETRIES; - - while (retries--) { - struct timespec tm = {0, 100000000}; -@@ -911,7 +901,6 @@ void *expire_proc_direct(void *arg) - - if (!strcmp(next->fs_type, "autofs")) { - struct stat st; -- struct statfs fs; - int ioctlfd; - - cache_unlock(me->mc); -@@ -932,14 +921,8 @@ void *expire_proc_direct(void *arg) - continue; - } - -- if (statfs(next->path, &fs) == -1) { -- pthread_setcancelstate(cur_state, NULL); -- warn(ap->logopt, -- "fstatfs failed for %s", next->path); -- continue; -- } -- -- if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) { -+ /* It's got a mount, deal with in the outer loop */ -+ if (tree_is_mounted(mnts, me->key, MNTS_REAL)) { - pthread_setcancelstate(cur_state, NULL); - continue; - } -diff --git a/daemon/indirect.c b/daemon/indirect.c -index 17bed3e..e832cd4 100644 ---- a/daemon/indirect.c -+++ b/daemon/indirect.c -@@ -285,7 +285,7 @@ int umount_autofs_indirect(struct autofs_point *ap) - - retries = UMOUNT_RETRIES; - while ((rv = umount(ap->path)) == -1 && retries--) { -- struct timespec tm = {0, 100000000}; -+ struct timespec tm = {0, 200000000}; - if (errno != EBUSY) - break; - nanosleep(&tm, NULL); -@@ -368,17 +368,7 @@ force_umount: - - static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *path, unsigned int when) - { -- char buf[MAX_ERR_BUF]; -- int ret, retries; -- struct stat st; -- -- if (fstat(ioctlfd, &st) == -1) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- debug(ap->logopt, "fstat failed: %s", estr); -- return 0; -- } -- -- retries = (count_mounts(ap->logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES; -+ int ret, retries = EXPIRE_RETRIES; - - while (retries--) { - struct timespec tm = {0, 100000000}; -@@ -512,7 +502,6 @@ void *expire_proc_indirect(void *arg) - left++; - pthread_setcancelstate(cur_state, NULL); - } -- pthread_cleanup_pop(1); - - /* - * If there are no more real mounts left we could still -@@ -520,12 +509,17 @@ void *expire_proc_indirect(void *arg) - * umount them here. - */ - if (mnts) { -+ int retries; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); -- ret = expire_indirect(ap, ap->ioctlfd, ap->path, now); -- if (!ret) -- left++; -+ retries = (count_mounts(ap->logopt, ap->path, ap->dev) + 1); -+ while (retries--) { -+ ret = expire_indirect(ap, ap->ioctlfd, ap->path, now); -+ if (!ret) -+ left++; -+ } - pthread_setcancelstate(cur_state, NULL); - } -+ pthread_cleanup_pop(1); - - count = offsets = submnts = 0; - mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0); -diff --git a/daemon/spawn.c b/daemon/spawn.c -index 78d69c6..e3c355e 100644 ---- a/daemon/spawn.c -+++ b/daemon/spawn.c -@@ -89,13 +89,43 @@ void reset_signals(void) - - #define ERRBUFSIZ 2047 /* Max length of error string excl \0 */ - --static int do_spawn(unsigned logopt, unsigned int options, const char *prog, const char *const *argv) -+static int timed_read(int pipe, char *buf, size_t len, int time) -+{ -+ struct timeval timeout = { 0, 0 }; -+ struct timeval *tout = NULL; -+ fd_set wset, rset; -+ int ret; -+ -+ FD_ZERO(&rset); -+ FD_SET(pipe, &rset); -+ wset = rset; -+ -+ if (time != -1) { -+ timeout.tv_sec = time; -+ tout = &timeout; -+ } -+ -+ ret = select(pipe + 1, &rset, &wset, NULL, tout); -+ if (ret <= 0) { -+ if (ret == 0) -+ ret = -ETIMEDOUT; -+ return ret; -+ } -+ -+ while ((ret = read(pipe, buf, len)) == -1 && errno == EINTR); -+ -+ return ret; -+} -+ -+static int do_spawn(unsigned logopt, unsigned int wait, -+ unsigned int options, const char *prog, -+ const char *const *argv) - { - pid_t f; - int ret, status, pipefd[2]; - char errbuf[ERRBUFSIZ + 1], *p, *sp; - int errp, errn; -- int cancel_state; -+ int flags, cancel_state; - unsigned int use_lock = options & SPAWN_OPT_LOCK; - unsigned int use_access = options & SPAWN_OPT_ACCESS; - sigset_t allsigs, tmpsig, oldsig; -@@ -183,12 +213,15 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con - return -1; - } - -+ if ((flags = fcntl(pipefd[0], F_GETFD, 0)) != -1) { -+ flags |= FD_CLOEXEC; -+ fcntl(pipefd[0], F_SETFD, flags); -+ } -+ - errp = 0; - do { -- while ((errn = -- read(pipefd[0], errbuf + errp, ERRBUFSIZ - errp)) == -1 -- && errno == EINTR); -- -+ errn = timed_read(pipefd[0], -+ errbuf + errp, ERRBUFSIZ - errp, wait); - if (errn > 0) { - errp += errn; - -@@ -213,6 +246,9 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con - } - } while (errn > 0); - -+ if (errn == -ETIMEDOUT) -+ kill(f, SIGTERM); -+ - close(pipefd[0]); - - if (errp > 0) { -@@ -238,7 +274,7 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con - - int spawnv(unsigned logopt, const char *prog, const char *const *argv) - { -- return do_spawn(logopt, SPAWN_OPT_NONE, prog, argv); -+ return do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, argv); - } - - int spawnl(unsigned logopt, const char *prog, ...) -@@ -259,7 +295,7 @@ int spawnl(unsigned logopt, const char *prog, ...) - while ((*p++ = va_arg(arg, char *))); - va_end(arg); - -- return do_spawn(logopt, SPAWN_OPT_NONE, prog, (const char **) argv); -+ return do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, (const char **) argv); - } - - int spawn_mount(unsigned logopt, ...) -@@ -307,7 +343,7 @@ int spawn_mount(unsigned logopt, ...) - va_end(arg); - - while (retries--) { -- ret = do_spawn(logopt, options, prog, (const char **) argv); -+ ret = do_spawn(logopt, -1, options, prog, (const char **) argv); - if (ret & MTAB_NOTUPDATED) { - struct timespec tm = {3, 0}; - -@@ -406,7 +442,7 @@ int spawn_bind_mount(unsigned logopt, ...) - va_end(arg); - - while (retries--) { -- ret = do_spawn(logopt, options, prog, (const char **) argv); -+ ret = do_spawn(logopt, -1, options, prog, (const char **) argv); - if (ret & MTAB_NOTUPDATED) { - struct timespec tm = {3, 0}; - -@@ -466,6 +502,7 @@ int spawn_umount(unsigned logopt, ...) - unsigned int options; - unsigned int retries = MTAB_LOCK_RETRIES; - int ret, printed = 0; -+ unsigned int wait = 12; - - #ifdef ENABLE_MOUNT_LOCKING - options = SPAWN_OPT_LOCK; -@@ -488,7 +525,7 @@ int spawn_umount(unsigned logopt, ...) - va_end(arg); - - while (retries--) { -- ret = do_spawn(logopt, options, prog, (const char **) argv); -+ ret = do_spawn(logopt, wait, options, prog, (const char **) argv); - if (ret & MTAB_NOTUPDATED) { - /* - * If the mount succeeded but the mtab was not -diff --git a/include/master.h b/include/master.h -index 86ae045..a397a75 100644 ---- a/include/master.h -+++ b/include/master.h -@@ -91,6 +91,7 @@ void master_source_lock_cleanup(void *); - void master_source_current_wait(struct master_mapent *); - void master_source_current_signal(struct master_mapent *); - struct master_mapent *master_find_mapent(struct master *, const char *); -+struct autofs_point *master_find_submount(struct autofs_point *, const char *); - struct master_mapent *master_new_mapent(struct master *, const char *, time_t); - void master_add_mapent(struct master *, struct master_mapent *); - void master_remove_mapent(struct master_mapent *); -diff --git a/lib/master.c b/lib/master.c -index 522b919..71ba04a 100644 ---- a/lib/master.c -+++ b/lib/master.c -@@ -602,6 +602,29 @@ struct master_mapent *master_find_mapent(struct master *master, const char *path - return NULL; - } - -+struct autofs_point *master_find_submount(struct autofs_point *ap, const char *path) -+{ -+ struct list_head *head, *p; -+ -+ mounts_mutex_lock(ap); -+ -+ head = &ap->submounts; -+ list_for_each(p, head) { -+ struct autofs_point *submount; -+ -+ submount = list_entry(p, struct autofs_point, mounts); -+ -+ if (!strcmp(submount->path, path)) { -+ mounts_mutex_unlock(ap); -+ return submount; -+ } -+ } -+ -+ mounts_mutex_unlock(ap); -+ -+ return NULL; -+} -+ - struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age) - { - struct master_mapent *entry; -diff --git a/lib/mounts.c b/lib/mounts.c -index a4bf86c..d77a6b0 100644 ---- a/lib/mounts.c -+++ b/lib/mounts.c -@@ -1073,55 +1073,11 @@ free_tsv: - - int umount_ent(struct autofs_point *ap, const char *path) - { -- struct stat st; -- struct statfs fs; -- int sav_errno; -- int status, is_smbfs = 0; -- int ret, rv = 1; -- -- ret = statfs(path, &fs); -- if (ret == -1) { -- warn(ap->logopt, "could not stat fs of %s", path); -- is_smbfs = 0; -- } else { -- int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER; -- int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC; -- is_smbfs = (cifsfs | smbfs) ? 1 : 0; -- } -- -- status = lstat(path, &st); -- sav_errno = errno; -- -- if (status < 0) -- warn(ap->logopt, "lstat of %s failed with %d", path, status); -- -- /* -- * lstat failed and we're an smbfs fs returning an error that is not -- * EIO or EBADSLT or the lstat failed so it's a bad path. Return -- * a fail. -- * -- * EIO appears to correspond to an smb mount that has gone away -- * and EBADSLT relates to CD changer not responding. -- */ -- if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) { -- rv = spawn_umount(ap->logopt, path, NULL); -- } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) { -- rv = spawn_umount(ap->logopt, path, NULL); -- } -+ int rv; - -+ rv = spawn_umount(ap->logopt, path, NULL); - /* We are doing a forced shutcwdown down so unlink busy mounts */ - if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { -- ret = stat(path, &st); -- if (ret == -1 && errno == ENOENT) { -- warn(ap->logopt, "mount point does not exist"); -- return 0; -- } -- -- if (ret == 0 && !S_ISDIR(st.st_mode)) { -- warn(ap->logopt, "mount point is not a directory"); -- return 0; -- } -- - if (ap->state == ST_SHUTDOWN_FORCE) { - info(ap->logopt, "forcing umount of %s", path); - rv = spawn_umount(ap->logopt, "-l", path, NULL); diff --git a/autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch b/autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch deleted file mode 100644 index 90a3273..0000000 --- a/autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch +++ /dev/null @@ -1,52 +0,0 @@ -diff --git a/CHANGELOG b/CHANGELOG -index e393f33..033923d 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -5,6 +5,7 @@ - - correction for handling of LDAP base dns with spaces. - - avoid using UDP for probing NFSv4 mount requests. - - use libldap instead of libldap_r (Guillaume Rousse). -+- another fix for don't fail on empty master map. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/lib/master.c b/lib/master.c -index ed82131..4a34dd4 100644 ---- a/lib/master.c -+++ b/lib/master.c -@@ -799,21 +799,13 @@ int master_read_master(struct master *master, time_t age, int readall) - - master_init_scan(); - -- if (!lookup_nss_read_master(master, age)) { -- error(logopt, -- "can't read master map %s", master->name); -- return 0; -- } -- -+ lookup_nss_read_master(master, age); - master_mount_mounts(master, age, readall); - - master_mutex_lock(); - -- if (list_empty(&master->mounts)) { -- master_mutex_unlock(); -+ if (list_empty(&master->mounts)) - warn(logopt, "no mounts in table"); -- return 1; -- } - - master_mutex_unlock(); - -diff --git a/modules/lookup_file.c b/modules/lookup_file.c -index b01eea6..466690a 100644 ---- a/modules/lookup_file.c -+++ b/modules/lookup_file.c -@@ -475,6 +475,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) - "failed to read included master map %s", - master->name); - if (!master->recurse) { -+ master->name = save_name; - master->depth--; - master->recurse = 0; - fclose(f); diff --git a/autofs-5.0.3-dont-readmap-on-hup-for-new-mount.patch b/autofs-5.0.3-dont-readmap-on-hup-for-new-mount.patch deleted file mode 100644 index 39823c2..0000000 --- a/autofs-5.0.3-dont-readmap-on-hup-for-new-mount.patch +++ /dev/null @@ -1,39 +0,0 @@ -autofs-5.0.3 - don't readmap on HUP for new mount - -From: Ian Kent - -If we're performing a new mount during a HUP signal then -we will read the map during the mount. ---- - - lib/master.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - - ---- autofs-5.0.3.orig/lib/master.c -+++ autofs-5.0.3/lib/master.c -@@ -1108,8 +1108,6 @@ int master_mount_mounts(struct master *m - } - cache_unlock(nc); - -- check_update_map_sources(this, readall); -- - st_mutex_lock(); - - state_pipe = this->ap->state_pipe[1]; -@@ -1120,11 +1118,14 @@ int master_mount_mounts(struct master *m - - st_mutex_unlock(); - -- if (ret == -1 && save_errno == EBADF) -+ if (!ret) -+ check_update_map_sources(this, readall); -+ else if (ret == -1 && save_errno == EBADF) { - if (!master_do_mount(this)) { - list_del_init(&this->list); - master_free_mapent_sources(ap->entry, 1); - master_free_mapent(ap->entry); -+ } - } - } - diff --git a/autofs-5.0.3-dont-use-proc-for-is-running-check.patch b/autofs-5.0.3-dont-use-proc-for-is-running-check.patch deleted file mode 100644 index dad67f9..0000000 --- a/autofs-5.0.3-dont-use-proc-for-is-running-check.patch +++ /dev/null @@ -1,619 +0,0 @@ -autofs-5.0.3 - don't use proc for is running check - -From: Ian Kent - -Using /proc//cmdline to check if the daemon is running allows -any user to create a trivial program called "automount" and prevent -the system automounter from running simply by executing it and -leaving it running. This patch makes autofs use a flag file for this -check instead. ---- - - CHANGELOG | 1 - Makefile.conf.in | 3 + - aclocal.m4 | 16 ++++ - configure | 35 +++++++++ - configure.in | 17 +++++ - daemon/Makefile | 5 + - daemon/automount.c | 95 ++++++++------------------ - daemon/flag.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 8 files changed, 294 insertions(+), 70 deletions(-) - create mode 100644 daemon/flag.c - - -diff --git a/CHANGELOG b/CHANGELOG -index f40a941..3921552 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -24,6 +24,7 @@ - - fix incorrect if check in get user info. - - fix couple of memory leaks. - - add command line option to override check for daemon already running. -+- don't use proc file system when checking if the daemon is running. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/Makefile.conf.in b/Makefile.conf.in -index 09c3129..d88f5ee 100644 ---- a/Makefile.conf.in -+++ b/Makefile.conf.in -@@ -74,6 +74,9 @@ autofsmapdir = @mapdir@ - # Location for autofs fifos - autofsfifodir = @fifodir@ - -+# Location for autofs flag file -+autofsflagdir = @flagdir@ -+ - # Where to install the automount program - sbindir = @sbindir@ - -diff --git a/aclocal.m4 b/aclocal.m4 -index a1105ae..9ef4050 100644 ---- a/aclocal.m4 -+++ b/aclocal.m4 -@@ -136,6 +136,22 @@ AC_DEFUN(AF_FIFO_D, - done - fi]) - -+dnl -------------------------------------------------------------------------- -+dnl AF_FLAG_D -+dnl -+dnl Check the location of the autofs flag file directory -+dnl -------------------------------------------------------------------------- -+AC_DEFUN(AF_FLAG_D, -+[if test -z "$flagdir"; then -+ for flag_d in /var/run /tmp; do -+ if test -z "$flagdir"; then -+ if test -d "$flag_d"; then -+ flagdir="$flag_d" -+ fi -+ fi -+ done -+fi]) -+ - dnl ----------------------------------- ## -*- Autoconf -*- - dnl Check if --with-dmalloc was given. ## - dnl From Franc,ois Pinard ## -diff --git a/configure b/configure -index 0d3268c..9278196 100755 ---- a/configure -+++ b/configure -@@ -655,6 +655,7 @@ initdir - confdir - mapdir - fifodir -+flagdir - DMALLOCLIB - MOUNT - HAVE_MOUNT -@@ -1295,6 +1296,7 @@ Optional Packages: - --with-confdir=DIR use DIR for autofs configuration files - --with-mapdir=PATH look in PATH for mount maps used by the automounter - --with-fifodir=PATH use PATH as the directory for fifos used by the automounter -+ --with-flagdir=PATH use PATH as the directory for the flag file used by the automounter - --with-dmalloc use dmalloc, as in - http://www.dmalloc.com/dmalloc.tar.gz - --with-hesiod=DIR enable Hesiod support (libs and includes in DIR) -@@ -1876,6 +1878,36 @@ echo "${ECHO_T}$fifodir" >&6; } - - - # -+# The user can specify --with-flagdir=PATH to specify where autofs flag file goes -+# -+if test -z "$flagdir"; then -+ for flag_d in /var/run /tmp; do -+ if test -z "$flagdir"; then -+ if test -d "$flag_d"; then -+ flagdir="$flag_d" -+ fi -+ fi -+ done -+fi -+ -+# Check whether --with-flagdir was given. -+if test "${with_flagdir+set}" = set; then -+ withval=$with_flagdir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" -+ then -+ : -+ else -+ filagdir="${withval}" -+ fi -+ -+fi -+ -+{ echo "$as_me:$LINENO: checking for autofs flag file directory" >&5 -+echo $ECHO_N "checking for autofs flag file directory... $ECHO_C" >&6; } -+{ echo "$as_me:$LINENO: result: $flagdir" >&5 -+echo "${ECHO_T}$flagdir" >&6; } -+ -+ -+# - # Optional include dmalloc - # - { echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5 -@@ -6247,6 +6279,7 @@ initdir!$initdir$ac_delim - confdir!$confdir$ac_delim - mapdir!$mapdir$ac_delim - fifodir!$fifodir$ac_delim -+flagdir!$flagdir$ac_delim - DMALLOCLIB!$DMALLOCLIB$ac_delim - MOUNT!$MOUNT$ac_delim - HAVE_MOUNT!$HAVE_MOUNT$ac_delim -@@ -6297,7 +6330,7 @@ LIBOBJS!$LIBOBJS$ac_delim - LTLIBOBJS!$LTLIBOBJS$ac_delim - _ACEOF - -- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then -+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then - break - elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -diff --git a/configure.in b/configure.in -index 27b9bec..5ba3a49 100644 ---- a/configure.in -+++ b/configure.in -@@ -96,6 +96,23 @@ AC_MSG_RESULT([$fifodir]) - AC_SUBST(fifodir) - - # -+# The user can specify --with-flagdir=PATH to specify where autofs flag file goes -+# -+AF_FLAG_D() -+AC_ARG_WITH(flagdir, -+[ --with-flagdir=PATH use PATH as the directory for the flag file used by the automounter], -+ if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" -+ then -+ : -+ else -+ filagdir="${withval}" -+ fi -+) -+AC_MSG_CHECKING([for autofs flag file directory]) -+AC_MSG_RESULT([$flagdir]) -+AC_SUBST(flagdir) -+ -+# - # Optional include dmalloc - # - AM_WITH_DMALLOC() -diff --git a/daemon/Makefile b/daemon/Makefile -index 528a684..9c2d858 100644 ---- a/daemon/Makefile -+++ b/daemon/Makefile -@@ -6,9 +6,9 @@ - include ../Makefile.rules - - SRCS = automount.c indirect.c direct.c spawn.c module.c mount.c \ -- lookup.c state.c -+ lookup.c state.c flag.c - OBJS = automount.o indirect.o direct.o spawn.o module.o mount.o \ -- lookup.o state.o -+ lookup.o state.o flag.o - - version := $(shell cat ../.version) - -@@ -17,6 +17,7 @@ CFLAGS += -DAUTOFS_LIB_DIR=\"$(autofslibdir)\" - CFLAGS += -DAUTOFS_MAP_DIR=\"$(autofsmapdir)\" - CFLAGS += -DAUTOFS_CONF_DIR=\"$(autofsconfdir)\" - CFLAGS += -DAUTOFS_FIFO_DIR=\"$(autofsfifodir)\" -+CFLAGS += -DAUTOFS_FLAG_DIR=\"$(autofsflagdir)\" - CFLAGS += -DVERSION_STRING=\"$(version)\" - LDFLAGS += -rdynamic - LIBS = -ldl -diff --git a/daemon/automount.c b/daemon/automount.c -index 48ac30a..dbf267c 100644 ---- a/daemon/automount.c -+++ b/daemon/automount.c -@@ -81,6 +81,8 @@ pthread_key_t key_thread_stdenv_vars; - - #define MAX_OPEN_FILES 10240 - -+int aquire_flag_file(void); -+void release_flag_file(void); - static int umount_all(struct autofs_point *ap, int force); - - extern pthread_mutex_t master_mutex; -@@ -1098,7 +1100,7 @@ static int handle_packet(struct autofs_point *ap) - return -1; - } - --static void become_daemon(unsigned foreground) -+static void become_daemon(unsigned foreground, unsigned daemon_check) - { - FILE *pidfp; - char buf[MAX_ERR_BUF]; -@@ -1118,9 +1120,14 @@ static void become_daemon(unsigned foreground) - } - - /* Detach from foreground process */ -- if (foreground) -+ if (foreground) { -+ if (daemon_check && !aquire_flag_file()) { -+ fprintf(stderr, "%s: program is already running.\n", -+ program); -+ exit(1); -+ } - log_to_stderr(); -- else { -+ } else { - pid = fork(); - if (pid > 0) { - int r; -@@ -1136,6 +1143,13 @@ static void become_daemon(unsigned foreground) - } - close(start_pipefd[0]); - -+ if (daemon_check && !aquire_flag_file()) { -+ fprintf(stderr, "%s: program is already running.\n", -+ program); -+ close(start_pipefd[1]); -+ exit(1); -+ } -+ - /* - * Make our own process group for "magic" reason: processes that share - * our pgrp see the raw filesystem behind the magic. -@@ -1143,6 +1157,7 @@ static void become_daemon(unsigned foreground) - if (setsid() == -1) { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - fprintf(stderr, "setsid: %s", estr); -+ close(start_pipefd[1]); - exit(1); - } - log_to_syslog(); -@@ -1617,64 +1632,6 @@ static void key_thread_stdenv_vars_destroy(void *arg) - return; - } - --static int is_automount_running(void) --{ -- FILE *fp; -- DIR *dir; -- struct dirent entry; -- struct dirent *result; -- char path[PATH_MAX + 1], buf[PATH_MAX]; -- -- if ((dir = opendir("/proc")) == NULL) { -- fprintf(stderr, "cannot opendir(/proc)\n"); -- exit(1); -- } -- -- while (readdir_r(dir, &entry, &result) == 0) { -- int path_len, pid = 0; -- -- if (!result) -- break; -- -- if (*entry.d_name == '.') -- continue; -- -- if (!strcmp(entry.d_name, "self")) -- continue; -- -- if (!isdigit(*entry.d_name)) -- continue; -- -- pid = atoi(entry.d_name); -- if (pid == getpid()) -- continue; -- -- path_len = sprintf(path, "/proc/%s/cmdline", entry.d_name); -- if (path_len >= PATH_MAX) { -- fprintf(stderr, -- "buffer to small for /proc path\n"); -- return -1; -- } -- path[path_len] = '\0'; -- -- fp = fopen(path, "r"); -- if (fp) { -- int c, len = 0; -- -- while (len < 127 && (c = fgetc(fp)) != EOF && c) -- buf[len++] = c; -- buf[len] = '\0'; -- -- if (strstr(buf, "automount")) -- return pid; -- fclose(fp); -- } -- } -- closedir(dir); -- -- return 0; --} -- - static void usage(void) - { - fprintf(stderr, -@@ -1973,11 +1930,6 @@ int main(int argc, char *argv[]) - exit(exit_code); - } - -- if (daemon_check && is_automount_running() > 0) { -- fprintf(stderr, "%s: program is already running.\n", -- program); -- exit(1); -- } - #if 0 - if (!load_autofs4_module()) { - fprintf(stderr, "%s: can't load %s filesystem module.\n", -@@ -2009,7 +1961,7 @@ int main(int argc, char *argv[]) - "can't increase core file limit - continuing"); - #endif - -- become_daemon(foreground); -+ become_daemon(foreground, daemon_check); - - if (argc == 0) - master_list = master_new(NULL, timeout, ghost); -@@ -2020,6 +1972,7 @@ int main(int argc, char *argv[]) - logerr("%s: can't create master map %s", - program, argv[0]); - close(start_pipefd[1]); -+ release_flag_file(); - exit(1); - } - -@@ -2027,6 +1980,7 @@ int main(int argc, char *argv[]) - logerr("%s: failed to init thread attribute struct!", - program); - close(start_pipefd[1]); -+ release_flag_file(); - exit(1); - } - -@@ -2035,6 +1989,7 @@ int main(int argc, char *argv[]) - logerr("%s: failed to set detached thread attribute!", - program); - close(start_pipefd[1]); -+ release_flag_file(); - exit(1); - } - -@@ -2044,6 +1999,7 @@ int main(int argc, char *argv[]) - logerr("%s: failed to set stack size thread attribute!", - program); - close(start_pipefd[1]); -+ release_flag_file(); - exit(1); - } - #endif -@@ -2060,6 +2016,7 @@ int main(int argc, char *argv[]) - program); - master_kill(master_list); - close(start_pipefd[1]); -+ release_flag_file(); - exit(1); - } - -@@ -2067,6 +2024,7 @@ int main(int argc, char *argv[]) - logerr("%s: failed to create alarm handler thread!", program); - master_kill(master_list); - close(start_pipefd[1]); -+ release_flag_file(); - exit(1); - } - -@@ -2074,6 +2032,7 @@ int main(int argc, char *argv[]) - logerr("%s: failed to create FSM handler thread!", program); - master_kill(master_list); - close(start_pipefd[1]); -+ release_flag_file(); - exit(1); - } - -@@ -2086,6 +2045,7 @@ int main(int argc, char *argv[]) - *pst_stat = 3; - res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); - close(start_pipefd[1]); -+ release_flag_file(); - exit(3); - } - -@@ -2102,6 +2062,7 @@ int main(int argc, char *argv[]) - pid_file = NULL; - } - closelog(); -+ release_flag_file(); - - #ifdef LIBXML2_WORKAROUND - if (dh) -diff --git a/daemon/flag.c b/daemon/flag.c -new file mode 100644 -index 0000000..d8ca61b ---- /dev/null -+++ b/daemon/flag.c -@@ -0,0 +1,192 @@ -+/* ----------------------------------------------------------------------- * -+ * -+ * flag.c - autofs flag file management -+ * -+ * Copyright 2008 Red Hat, Inc. All rights reserved. -+ * Copyright 2008 Ian Kent -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, -+ * USA; either version 2 of the License, or (at your option) any later -+ * version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * ----------------------------------------------------------------------- */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_PIDSIZE 20 -+#define FLAG_FILE AUTOFS_FLAG_DIR "/autofs-running" -+ -+/* Flag for already existing flag file. */ -+static int we_created_flagfile = 0; -+ -+/* file descriptor of flag file */ -+static int fd = -1; -+ -+static int flag_is_owned(int fd) -+{ -+ int pid = 0, tries = 3; -+ -+ while (tries--) { -+ char pidbuf[MAX_PIDSIZE + 1]; -+ int got; -+ -+ lseek(fd, 0, SEEK_SET); -+ got = read(fd, pidbuf, MAX_PIDSIZE); -+ /* -+ * We add a terminator to the pid to verify write complete. -+ * If the write isn't finished in 300 milliseconds then it's -+ * probably a stale lock file. -+ */ -+ if (got > 0 && pidbuf[got - 1] == '\n') { -+ sscanf(pidbuf, "%d", &pid); -+ break; -+ } else { -+ struct timespec t = { 0, 100000000 }; -+ struct timespec r; -+ -+ while (nanosleep(&t, &r) == -1 && errno == EINTR) -+ memcpy(&t, &r, sizeof(struct timespec)); -+ -+ continue; -+ } -+ -+ /* Stale flagfile */ -+ if (!tries) -+ return 0; -+ } -+ -+ -+ if (pid) { -+ int ret; -+ -+ ret = kill(pid, 0); -+ /* -+ * If lock file exists but is not owned by a process -+ * we return unowned status so we can get rid of it -+ * and continue. -+ */ -+ if (ret == -1 && errno == ESRCH) -+ return 0; -+ } else { -+ /* -+ * Odd, no pid in file - so what should we do? -+ * Assume something bad happened to owner and -+ * return unowned status. -+ */ -+ return 0; -+ } -+ -+ return 1; -+} -+ -+/* Remove flag file. */ -+void release_flag_file(void) -+{ -+ if (fd > 0) { -+ close(fd); -+ fd = -1; -+ } -+ -+ if (we_created_flagfile) { -+ unlink(FLAG_FILE); -+ we_created_flagfile = 0; -+ } -+} -+ -+/* * Try to create flag file */ -+int aquire_flag_file(void) -+{ -+ char *linkf; -+ int len; -+ -+ len = strlen(FLAG_FILE) + MAX_PIDSIZE; -+ linkf = alloca(len + 1); -+ snprintf(linkf, len, "%s.%d", FLAG_FILE, getpid()); -+ -+ /* -+ * Repeat until it was us who made the link or we find the -+ * flag file already exists. If an unexpected error occurs -+ * we return 0 claiming the flag file exists which may not -+ * really be the case. -+ */ -+ while (!we_created_flagfile) { -+ int errsv, i, j; -+ -+ i = open(linkf, O_WRONLY|O_CREAT, 0); -+ if (i < 0) { -+ release_flag_file(); -+ return 0; -+ } -+ close(i); -+ -+ j = link(linkf, FLAG_FILE); -+ errsv = errno; -+ -+ (void) unlink(linkf); -+ -+ if (j < 0 && errsv != EEXIST) { -+ release_flag_file(); -+ return 0; -+ } -+ -+ fd = open(FLAG_FILE, O_RDWR); -+ if (fd < 0) { -+ /* Maybe the file was just deleted? */ -+ if (errno == ENOENT) -+ continue; -+ release_flag_file(); -+ return 0; -+ } -+ -+ if (j == 0) { -+ char pidbuf[MAX_PIDSIZE + 1]; -+ int pidlen; -+ -+ pidlen = sprintf(pidbuf, "%d\n", getpid()); -+ if (write(fd, pidbuf, pidlen) != pidlen) { -+ release_flag_file(); -+ return 0; -+ } -+ -+ we_created_flagfile = 1; -+ } else { -+ /* -+ * Someone else made the link. -+ * If the flag file is not owned by anyone clean -+ * it up and try again, otherwise return fail. -+ */ -+ if (!flag_is_owned(fd)) { -+ close(fd); -+ fd = -1; -+ unlink(FLAG_FILE); -+ continue; -+ } -+ -+ release_flag_file(); -+ return 0; -+ } -+ -+ close(fd); -+ fd = -1; -+ } -+ -+ return 1; -+} -+ diff --git a/autofs-5.0.3-expire-thread-create-cond-handling.patch b/autofs-5.0.3-expire-thread-create-cond-handling.patch deleted file mode 100644 index 2f01d56..0000000 --- a/autofs-5.0.3-expire-thread-create-cond-handling.patch +++ /dev/null @@ -1,179 +0,0 @@ -autofs-5.0.3 - fix incorrect pthreads condition handling for expire requests. - -From: Ian Kent - -Occassionally, when starting an expire thread we can attempt to use the -structure for parameter communication after it has been freed. This patch -resolves this issue. ---- - - daemon/direct.c | 40 +++++++++++++++++++++------------------- - daemon/indirect.c | 28 +++++++++++++++------------- - 2 files changed, 36 insertions(+), 32 deletions(-) - - ---- autofs-5.0.3.orig/daemon/direct.c -+++ autofs-5.0.3/daemon/direct.c -@@ -1033,55 +1033,53 @@ static void expire_mutex_unlock(void *ar - - static void *do_expire_direct(void *arg) - { -- struct pending_args *mt; -+ struct pending_args *args, mt; - struct autofs_point *ap; - size_t len; - int status, state; - -- mt = (struct pending_args *) arg; -+ args = (struct pending_args *) arg; - - status = pthread_mutex_lock(&ea_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); - - expire_mutex_unlock(NULL); - -- pthread_cleanup_push(free_pending_args, mt); -- pthread_cleanup_push(pending_cond_destroy, mt); -- pthread_cleanup_push(expire_send_fail, mt); -+ pthread_cleanup_push(expire_send_fail, &mt); - -- len = _strlen(mt->name, KEY_MAX_LEN); -+ len = _strlen(mt.name, KEY_MAX_LEN); - if (!len) { -- warn(ap->logopt, "direct key path too long %s", mt->name); -+ warn(ap->logopt, "direct key path too long %s", mt.name); - /* TODO: force umount ?? */ - pthread_exit(NULL); - } - -- status = do_expire(ap, mt->name, len); -+ status = do_expire(ap, mt.name, len); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); - if (status) -- send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token); -+ send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token); - else { - struct mapent *me; -- cache_readlock(mt->mc); -- me = cache_lookup_distinct(mt->mc, mt->name); -+ cache_readlock(mt.mc); -+ me = cache_lookup_distinct(mt.mc, mt.name); - me->ioctlfd = -1; -- cache_unlock(mt->mc); -- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token); -- close(mt->ioctlfd); -+ cache_unlock(mt.mc); -+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); -+ close(mt.ioctlfd); - } - pthread_setcancelstate(state, NULL); - - pthread_cleanup_pop(0); -- pthread_cleanup_pop(1); -- pthread_cleanup_pop(1); - - return NULL; - } -@@ -1198,6 +1196,8 @@ int handle_packet_expire_direct(struct a - cache_unlock(mc); - master_source_unlock(ap->entry); - -+ pthread_cleanup_push(free_pending_args, mt); -+ pthread_cleanup_push(pending_cond_destroy, mt); - pthread_cleanup_push(expire_mutex_unlock, NULL); - pthread_setcancelstate(state, NULL); - -@@ -1212,6 +1212,8 @@ int handle_packet_expire_direct(struct a - } - - pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); - - return 0; - } ---- autofs-5.0.3.orig/daemon/indirect.c -+++ autofs-5.0.3/daemon/indirect.c -@@ -596,40 +596,38 @@ static void expire_mutex_unlock(void *ar - - static void *do_expire_indirect(void *arg) - { -- struct pending_args *mt; -+ struct pending_args *args, mt; - struct autofs_point *ap; - int status, state; - -- mt = (struct pending_args *) arg; -+ args = (struct pending_args *) arg; - - status = pthread_mutex_lock(&ea_mutex); - if (status) - fatal(status); - -- ap = mt->ap; -+ memcpy(&mt, args, sizeof(struct pending_args)); - -- mt->signaled = 1; -- status = pthread_cond_signal(&mt->cond); -+ ap = mt.ap; -+ -+ args->signaled = 1; -+ status = pthread_cond_signal(&args->cond); - if (status) - fatal(status); - - expire_mutex_unlock(NULL); - -- pthread_cleanup_push(free_pending_args, mt); -- pthread_cleanup_push(pending_cond_destroy, mt); -- pthread_cleanup_push(expire_send_fail, mt); -+ pthread_cleanup_push(expire_send_fail, &mt); - -- status = do_expire(mt->ap, mt->name, mt->len); -+ status = do_expire(mt.ap, mt.name, mt.len); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); - if (status) -- send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token); -+ send_fail(ap->logopt, ap->ioctlfd, mt.wait_queue_token); - else -- send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token); -+ send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token); - pthread_setcancelstate(state, NULL); - - pthread_cleanup_pop(0); -- pthread_cleanup_pop(1); -- pthread_cleanup_pop(1); - - return NULL; - } -@@ -682,6 +680,8 @@ int handle_packet_expire_indirect(struct - return 1; - } - -+ pthread_cleanup_push(free_pending_args, mt); -+ pthread_cleanup_push(pending_cond_destroy, mt); - pthread_cleanup_push(expire_mutex_unlock, NULL); - pthread_setcancelstate(state, NULL); - -@@ -696,6 +696,8 @@ int handle_packet_expire_indirect(struct - } - - pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); - - return 0; - } diff --git a/autofs-5.0.3-expire-works-too-hard.patch b/autofs-5.0.3-expire-works-too-hard.patch deleted file mode 100644 index cd9fb43..0000000 --- a/autofs-5.0.3-expire-works-too-hard.patch +++ /dev/null @@ -1,74 +0,0 @@ -diff -up autofs-5.0.3/daemon/direct.c.expire-works-too-hard autofs-5.0.3/daemon/direct.c ---- autofs-5.0.3/daemon/direct.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/daemon/direct.c 2008-02-25 08:48:08.000000000 +0900 -@@ -808,7 +808,7 @@ static int expire_direct(int ioctlfd, co - - if (fstat(ioctlfd, &st) == -1) { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- error(logopt, "fstat failed: %s", estr); -+ debug(logopt, "fstat failed: %s", estr); - return 0; - } - -@@ -824,11 +824,16 @@ static int expire_direct(int ioctlfd, co - if (errno == EBADF || errno == EINVAL) - return 1; - -- /* Other than need to wait for the kernel ? */ -- if (errno != EAGAIN) -- return 0; -+ /* -+ * Other than EAGAIN is an expire error so continue. -+ * Kernel try the same mount again, limited by -+ * retries (ie. number of mounts directly under -+ * mount point, should always be one for direct -+ * mounts). -+ */ -+ if (errno == EAGAIN) -+ break; - } -- - nanosleep(&tm, NULL); - } - -diff -up autofs-5.0.3/daemon/indirect.c.expire-works-too-hard autofs-5.0.3/daemon/indirect.c ---- autofs-5.0.3/daemon/indirect.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 08:48:53.000000000 +0900 -@@ -328,7 +328,7 @@ static int expire_indirect(struct autofs - - if (fstat(ioctlfd, &st) == -1) { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- error(ap->logopt, "fstat failed: %s", estr); -+ debug(ap->logopt, "fstat failed: %s", estr); - return 0; - } - -@@ -344,11 +344,13 @@ static int expire_indirect(struct autofs - if (errno == EBADF || errno == EINVAL) - return 1; - -- /* Other than need to wait for the kernel ? */ -- if (errno != EAGAIN) -- return 0; -+ /* -+ * Other than EAGAIN is an expire error so continue. -+ * Kernel will try the next mount. -+ */ -+ if (errno == EAGAIN) -+ break; - } -- - nanosleep(&tm, NULL); - } - -diff -up autofs-5.0.3/CHANGELOG.expire-works-too-hard autofs-5.0.3/CHANGELOG ---- autofs-5.0.3/CHANGELOG.expire-works-too-hard 2008-02-25 08:44:54.000000000 +0900 -+++ autofs-5.0.3/CHANGELOG 2008-02-25 08:48:08.000000000 +0900 -@@ -6,6 +6,7 @@ - - avoid using UDP for probing NFSv4 mount requests. - - use libldap instead of libldap_r (Guillaume Rousse). - - another fix for don't fail on empty master map. -+- fix expire working harder than needed. - - 14/01/2008 autofs-5.0.3 - ----------------------- diff --git a/autofs-5.0.3-fix-bad-alloca-usage.patch b/autofs-5.0.3-fix-bad-alloca-usage.patch deleted file mode 100644 index e6aee39..0000000 --- a/autofs-5.0.3-fix-bad-alloca-usage.patch +++ /dev/null @@ -1,48 +0,0 @@ -autofs-5.0.3 - fix bad alloca usage - -From: Ian Kent - -In the lookup_ghost() function alloca is used within a loop which can -lead to stack overflow. ---- - - daemon/lookup.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - - ---- autofs-5.0.3.orig/daemon/lookup.c -+++ autofs-5.0.3/daemon/lookup.c -@@ -608,7 +608,7 @@ int lookup_ghost(struct autofs_point *ap - goto next; - } - -- fullpath = alloca(strlen(me->key) + strlen(root) + 3); -+ fullpath = malloc(strlen(me->key) + strlen(root) + 3); - if (!fullpath) { - warn(ap->logopt, "failed to allocate full path"); - goto next; -@@ -619,6 +619,7 @@ int lookup_ghost(struct autofs_point *ap - if (ret == -1 && errno != ENOENT) { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - warn(ap->logopt, "stat error %s", estr); -+ free(fullpath); - goto next; - } - -@@ -627,6 +628,7 @@ int lookup_ghost(struct autofs_point *ap - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - warn(ap->logopt, - "mkdir_path %s failed: %s", fullpath, estr); -+ free(fullpath); - goto next; - } - -@@ -634,6 +636,8 @@ int lookup_ghost(struct autofs_point *ap - me->dev = st.st_dev; - me->ino = st.st_ino; - } -+ -+ free(fullpath); - next: - me = cache_enumerate(mc, me); - } diff --git a/autofs-5.0.3-fix-couple-of-memory-leaks.patch b/autofs-5.0.3-fix-couple-of-memory-leaks.patch deleted file mode 100644 index 6545973..0000000 --- a/autofs-5.0.3-fix-couple-of-memory-leaks.patch +++ /dev/null @@ -1,69 +0,0 @@ -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-fd-leak-at-multi-mount-fail.patch b/autofs-5.0.3-fix-fd-leak-at-multi-mount-fail.patch deleted file mode 100644 index 8e78948..0000000 --- a/autofs-5.0.3-fix-fd-leak-at-multi-mount-fail.patch +++ /dev/null @@ -1,39 +0,0 @@ -autofs-5.0.3 - fix fd leak at multi-mount fail - -From: Ian Kent - -Fix file handle being left open following a multi-mount non-fatal mount -fail. ---- - - daemon/direct.c | 12 ++++++++++-- - 1 files changed, 10 insertions(+), 2 deletions(-) - - -diff --git a/daemon/direct.c b/daemon/direct.c -index 13f572c..b94601a 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -1303,12 +1303,20 @@ static void *do_mount_direct(void *arg) - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); - if (status) { - struct mapent *me; -+ struct statfs fs; -+ unsigned int close_fd = 0; -+ -+ if (statfs(mt.name, &fs) == -1 || -+ (fs.f_type == AUTOFS_SUPER_MAGIC && -+ !master_find_submount(ap, mt.name))) -+ close_fd = 1; - cache_writelock(mt.mc); -- me = cache_lookup_distinct(mt.mc, mt.name); -- if (me) -+ if (!close_fd && (me = cache_lookup_distinct(mt.mc, mt.name))) - me->ioctlfd = mt.ioctlfd; - send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); - cache_unlock(mt.mc); -+ if (close_fd) -+ close(mt.ioctlfd); - info(ap->logopt, "mounted %s", mt.name); - } else { - send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token); diff --git a/autofs-5.0.3-fix-get-user-info-check.patch b/autofs-5.0.3-fix-get-user-info-check.patch deleted file mode 100644 index f11ab22..0000000 --- a/autofs-5.0.3-fix-get-user-info-check.patch +++ /dev/null @@ -1,38 +0,0 @@ -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-fix-ifc-buff-size-fix-2.patch b/autofs-5.0.3-fix-ifc-buff-size-fix-2.patch deleted file mode 100644 index 4010c2d..0000000 --- a/autofs-5.0.3-fix-ifc-buff-size-fix-2.patch +++ /dev/null @@ -1,59 +0,0 @@ -autofs-5.0.3 - fix ifc buff size fix 2 - -From: Ian Kent - -For the case of a large number of interfaces there can be -a lot of malloc(3)s for every mount which could slow things -down. So we remember the maximum allocation size and use it -in subsequent allocations. ---- - - modules/replicated.c | 12 ++++++++++-- - 1 files changed, 10 insertions(+), 2 deletions(-) - - -diff --git a/modules/replicated.c b/modules/replicated.c -index 35a6675..b435f4b 100644 ---- a/modules/replicated.c -+++ b/modules/replicated.c -@@ -62,7 +62,10 @@ - #ifndef MAX_ERR_BUF - #define MAX_ERR_BUF 512 - #endif -+ - #define MAX_IFC_BUF 2048 -+static int volatile ifc_buf_len = MAX_IFC_BUF; -+static int volatile ifc_last_len = 0; - - #define MASK_A 0x7F000000 - #define MASK_B 0xBFFF0000 -@@ -97,7 +100,7 @@ void seed_random(void) - - static int alloc_ifreq(struct ifconf *ifc, int sock) - { -- int ret, lastlen = 0, len = MAX_IFC_BUF; -+ int ret, lastlen = ifc_last_len, len = ifc_buf_len; - char err_buf[MAX_ERR_BUF], *buf; - - while (1) { -@@ -119,7 +122,7 @@ static int alloc_ifreq(struct ifconf *ifc, int sock) - return 0; - } - -- if (ifc->ifc_len == lastlen) -+ if (ifc->ifc_len <= lastlen) - break; - - lastlen = ifc->ifc_len; -@@ -127,6 +130,11 @@ static int alloc_ifreq(struct ifconf *ifc, int sock) - free(buf); - } - -+ if (lastlen != ifc_last_len) { -+ ifc_last_len = lastlen; -+ ifc_buf_len = len; -+ } -+ - return 1; - } - diff --git a/autofs-5.0.3-fix-ifc-buff-size.patch b/autofs-5.0.3-fix-ifc-buff-size.patch deleted file mode 100644 index c243ed7..0000000 --- a/autofs-5.0.3-fix-ifc-buff-size.patch +++ /dev/null @@ -1,144 +0,0 @@ -autofs-5.0.3 - fix interface config buffer size - -From: Ian Kent - -When getting the interface configuration information autofs uses a -fixed size buffer for the interface information. If there are many -interfaces this causes the check to fail. ---- - - CHANGELOG | 1 + - modules/replicated.c | 51 ++++++++++++++++++++++++++++++++++++++++++-------- - 2 files changed, 44 insertions(+), 8 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index d2fe0a6..5b0f265 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -34,6 +34,7 @@ - - update replicated server selection documentation. - - use /dev/urandom instead of /dev/random. - - check for mtab pointing to /proc/mounts. -+- dynamically allocate interface config buffer. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/modules/replicated.c b/modules/replicated.c -index 362ab1b..ad1ede2 100644 ---- a/modules/replicated.c -+++ b/modules/replicated.c -@@ -95,6 +95,41 @@ void seed_random(void) - return; - } - -+static int alloc_ifreq(struct ifconf *ifc, int sock) -+{ -+ int ret, lastlen = 0, len = MAX_IFC_BUF; -+ char err_buf[MAX_ERR_BUF], *buf; -+ -+ while (1) { -+ buf = malloc(len); -+ if (!buf) { -+ char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF); -+ logerr("malloc: %s", estr); -+ return 0; -+ } -+ -+ ifc->ifc_len = len; -+ ifc->ifc_req = (struct ifreq *) buf; -+ -+ ret = ioctl(sock, SIOCGIFCONF, ifc); -+ if (ret == -1) { -+ char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF); -+ logerr("ioctl: %s", estr); -+ free(buf); -+ return 0; -+ } -+ -+ if (ifc->ifc_len == lastlen) -+ break; -+ -+ lastlen = ifc->ifc_len; -+ len += MAX_IFC_BUF; -+ free(buf); -+ } -+ -+ return 1; -+} -+ - static unsigned int get_proximity(const char *host_addr, int addr_len) - { - struct sockaddr_in *msk_addr, *if_addr; -@@ -122,12 +157,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - fcntl(sock, F_SETFD, cl_flags); - } - -- ifc.ifc_len = sizeof(buf); -- ifc.ifc_req = (struct ifreq *) buf; -- ret = ioctl(sock, SIOCGIFCONF, &ifc); -- if (ret == -1) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- logerr("ioctl: %s", estr); -+ if (!alloc_ifreq(&ifc, sock)) { - close(sock); - return PROXIMITY_ERROR; - } -@@ -138,7 +168,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - i = 0; - ptr = (char *) &ifc.ifc_buf[0]; - -- while (ptr < buf + ifc.ifc_len) { -+ while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) { - ifr = (struct ifreq *) ptr; - - switch (ifr->ifr_addr.sa_family) { -@@ -147,6 +177,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len); - if (!ret) { - close(sock); -+ free(ifc.ifc_req); - return PROXIMITY_LOCAL; - } - break; -@@ -162,7 +193,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - i = 0; - ptr = (char *) &ifc.ifc_buf[0]; - -- while (ptr < buf + ifc.ifc_len) { -+ while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) { - ifr = (struct ifreq *) ptr; - - switch (ifr->ifr_addr.sa_family) { -@@ -178,6 +209,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - logerr("ioctl: %s", estr); - close(sock); -+ free(ifc.ifc_req); - return PROXIMITY_ERROR; - } - -@@ -186,6 +218,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - - if ((ia & mask) == (ha & mask)) { - close(sock); -+ free(ifc.ifc_req); - return PROXIMITY_SUBNET; - } - -@@ -208,6 +241,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - - if ((ia & mask) == (ha & mask)) { - close(sock); -+ free(ifc.ifc_req); - return PROXIMITY_NET; - } - break; -@@ -221,6 +255,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) - } - - close(sock); -+ free(ifc.ifc_req); - - return PROXIMITY_OTHER; - } diff --git a/autofs-5.0.3-fix-included-browse-map-not-found.patch b/autofs-5.0.3-fix-included-browse-map-not-found.patch deleted file mode 100644 index a854566..0000000 --- a/autofs-5.0.3-fix-included-browse-map-not-found.patch +++ /dev/null @@ -1,26 +0,0 @@ -autofs-5.0.3 - fix fail on included browse map not found - -From: Ian Kent - -When looking up nsswitch sources, if nsswitch action check tells us -to continue we need to set the returned result to success so we -don't return a false failure. ---- - - daemon/lookup.c | 2 ++ - 1 files changed, 2 insertions(+), 0 deletions(-) - - -diff --git a/daemon/lookup.c b/daemon/lookup.c -index 29a1491..3c22a35 100644 ---- a/daemon/lookup.c -+++ b/daemon/lookup.c -@@ -545,6 +545,8 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time - map = NULL; - break; - } -+ -+ result = NSS_STATUS_SUCCESS; - } - pthread_cleanup_pop(1); - diff --git a/autofs-5.0.3-fix-incorrect-multi-mount-mountpoint.patch b/autofs-5.0.3-fix-incorrect-multi-mount-mountpoint.patch deleted file mode 100644 index 89ae77b..0000000 --- a/autofs-5.0.3-fix-incorrect-multi-mount-mountpoint.patch +++ /dev/null @@ -1,32 +0,0 @@ -autofs-5.0.3 - fix incorrect multi-mount mountpoint - -From: Ian Kent - -Fix case where an incorrect mount point path was being used when -mounting a multi-mount component. ---- - - modules/parse_sun.c | 8 +++++++- - 1 files changed, 7 insertions(+), 1 deletions(-) - - -diff --git a/modules/parse_sun.c b/modules/parse_sun.c -index 333f8a5..5a39113 100644 ---- a/modules/parse_sun.c -+++ b/modules/parse_sun.c -@@ -1248,8 +1248,14 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, - return 1; - } - } else if (rv < 0) { -+ char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1); -+ - move = MOUNT_MOVE_NONE; -- ret = mount_multi_triggers(ap, me->multi, mm_root, start, mm_base); -+ -+ strcpy(mm_root_base, mm_root); -+ strcat(mm_root_base, mm_base); -+ -+ ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base); - if (ret == -1) { - error(ap->logopt, MODPREFIX - "failed to mount offset triggers"); diff --git a/autofs-5.0.3-fix-master-map-lexer-eval-order.patch b/autofs-5.0.3-fix-master-map-lexer-eval-order.patch deleted file mode 100644 index 750bcf8..0000000 --- a/autofs-5.0.3-fix-master-map-lexer-eval-order.patch +++ /dev/null @@ -1,33 +0,0 @@ -autofs-5.0.3 - fix master map lexer eval order - -From: Ian Kent - -Two compound regular expressions in the master map lexical -analyser lack brackets which leads to an evaluation order -error in some versions of flex. ---- - - lib/master_tok.l | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - - ---- autofs-5.0.3.orig/lib/master_tok.l -+++ autofs-5.0.3/lib/master_tok.l -@@ -99,7 +99,7 @@ DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(: - DNSERVSTR2 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/) - DNSERVSTR3 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:) - DNSERVSTR4 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/) --DNSERVERSTR {DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4} -+DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}) - - AT_CN ([cC][[nN]) - AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE]) -@@ -108,7 +108,7 @@ AT_OU ([oO][[uU]) - AT_DC ([dD][[cC]) - AT_O ([oO]) - AT_C ([cC]) --DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C} -+DNATTRSTR ({AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}) - DNNAMESTR1 ([[:alnum:]_.\- ]+) - DNNAMESTR2 ([[:alnum:]_.\-]+) - diff --git a/autofs-5.0.3-fix-multi-mount-race.patch b/autofs-5.0.3-fix-multi-mount-race.patch deleted file mode 100644 index 1bbe65b..0000000 --- a/autofs-5.0.3-fix-multi-mount-race.patch +++ /dev/null @@ -1,1637 +0,0 @@ -autofs-5.0.3 - fix multi mount race. - -From: Ian Kent - -When using multi-mounts it is possible for a path walk to walk into -a mount tree before it is completely setup which leads to autofs -incorrectly failing to perform mounts. - -For example, for the multi-mount - -mm1 - /om1 :/ - /om2 :/ - /om2/om21 :/ - /om2/om22 :/ - -when a path walk hits mm1/om2 :/ is mounted on top of -mm1/om2. If a path walk comes along before the multi-mount offsets for -mm1/om2 are setup it doesn't see that mm1/om2 is pending. This happens -because the lookup gets to mm1/om2, which is within the mm1 file system, -and is covered by a mount trigger mounted at mm1/om2, and the the trigger -itself is covered by the :/ mount. So the walk follows -the stack up to the mount at :/, never seeing that the -trigger mm1/om2 is currently pending. - -In the example above mm1/om2 could also be a submount. - -To resolve this the mount tree needs to be created under a temporary -directory and moved into place once setup in one operation. ---- - - CHANGELOG | 1 - daemon/automount.c | 32 +++- - daemon/direct.c | 40 ++--- - daemon/indirect.c | 55 ++++-- - daemon/lookup.c | 6 - - daemon/state.c | 2 - include/automount.h | 12 + - include/master.h | 1 - include/mounts.h | 4 - lib/master.c | 20 +- - lib/mounts.c | 21 +- - modules/mount_autofs.c | 61 ++++--- - modules/mount_bind.c | 43 +---- - modules/mount_changer.c | 34 +--- - modules/mount_ext2.c | 40 +---- - modules/mount_generic.c | 40 +---- - modules/mount_nfs.c | 41 +---- - modules/parse_sun.c | 408 ++++++++++++++++++++++++++++++++++++----------- - 18 files changed, 517 insertions(+), 344 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index ff44cc7..a7b41ec 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -29,6 +29,7 @@ - - fix submount shutdown recovery handling. - - avoid stat of possibly dead mount points and limit time to wait for - umount during expire. -+- make mount of multi-mounts wuth a root offset atomic. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/daemon/automount.c b/daemon/automount.c -index 5bd5f6d..5b6a561 100644 ---- a/daemon/automount.c -+++ b/daemon/automount.c -@@ -489,7 +489,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); - /* Lock the closest parent nesting point for umount */ - cache_multi_lock(me->parent); -- if (umount_multi_triggers(ap, root, me, base)) { -+ if (umount_multi_triggers(ap, me, root, base)) { - warn(ap->logopt, - "some offset mounts still present under %s", path); - left++; -@@ -572,7 +572,7 @@ static int umount_all(struct autofs_point *ap, int force) - return left; - } - --int umount_autofs(struct autofs_point *ap, int force) -+int umount_autofs(struct autofs_point *ap, const char *root, int force) - { - int ret = 0; - -@@ -589,7 +589,7 @@ int umount_autofs(struct autofs_point *ap, int force) - if (ap->type == LKP_INDIRECT) { - if (umount_all(ap, force) && !force) - return -1; -- ret = umount_autofs_indirect(ap); -+ ret = umount_autofs_indirect(ap, root); - } else - ret = umount_autofs_direct(ap); - -@@ -754,7 +754,7 @@ out_free: - return ret; - } - --static int destroy_logpri_fifo(struct autofs_point *ap) -+int destroy_logpri_fifo(struct autofs_point *ap) - { - int ret = -1; - int fd = ap->logpri_fifo; -@@ -1056,7 +1056,7 @@ static int autofs_init_ap(struct autofs_point *ap) - return 0; - } - --static int mount_autofs(struct autofs_point *ap) -+static int mount_autofs(struct autofs_point *ap, const char *root) - { - int status = 0; - -@@ -1066,7 +1066,7 @@ static int mount_autofs(struct autofs_point *ap) - if (ap->type == LKP_DIRECT) - status = mount_autofs_direct(ap); - else -- status = mount_autofs_indirect(ap); -+ status = mount_autofs_indirect(ap, root); - - if (status < 0) - return -1; -@@ -1531,10 +1531,12 @@ void *handle_mounts(void *arg) - struct startup_cond *suc; - struct autofs_point *ap; - int cancel_state, status = 0; -+ char *root; - - suc = (struct startup_cond *) arg; - - ap = suc->ap; -+ root = strdup(suc->root); - - pthread_cleanup_push(return_start_status, suc); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); -@@ -1545,14 +1547,24 @@ void *handle_mounts(void *arg) - fatal(status); - } - -- if (mount_autofs(ap) < 0) { -+ if (!root) { -+ crit(ap->logopt, "failed to alloc string root"); -+ suc->status = 1; -+ pthread_setcancelstate(cancel_state, NULL); -+ pthread_exit(NULL); -+ } -+ -+ if (mount_autofs(ap, root) < 0) { - crit(ap->logopt, "mount of %s failed!", ap->path); - suc->status = 1; -- umount_autofs(ap, 1); -+ umount_autofs(ap, root, 1); -+ free(root); - pthread_setcancelstate(cancel_state, NULL); - pthread_exit(NULL); - } - -+ free(root); -+ - if (ap->ghost && ap->type != LKP_DIRECT) - info(ap->logopt, "ghosting enabled"); - -@@ -1615,7 +1627,7 @@ void *handle_mounts(void *arg) - * to check for possible recovery. - */ - if (ap->type == LKP_DIRECT) { -- umount_autofs(ap, 1); -+ umount_autofs(ap, NULL, 1); - break; - } - -@@ -1625,7 +1637,7 @@ void *handle_mounts(void *arg) - * so we can continue. This can happen if a lookup - * occurs while we're trying to umount. - */ -- ret = umount_autofs(ap, 1); -+ ret = umount_autofs(ap, NULL, 1); - if (!ret) - break; - -diff --git a/daemon/direct.c b/daemon/direct.c -index 7fb78a3..34e882b 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -646,7 +646,7 @@ force_umount: - return rv; - } - --int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) -+int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset) - { - char buf[MAX_ERR_BUF]; - struct mnt_params *mp; -@@ -654,6 +654,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - struct stat st; - int ioctlfd, cl_flags, status, ret; - const char *type, *map_name = NULL; -+ char mountpoint[PATH_MAX]; - - if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { - if (ap->state != ST_READMAP) -@@ -695,8 +696,11 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - return MOUNT_OFFSET_OK; - } - -+ strcpy(mountpoint, root); -+ strcat(mountpoint, offset); -+ - /* In case the directory doesn't exist, try to mkdir it */ -- if (mkdir_path(me->key, 0555) < 0) { -+ if (mkdir_path(mountpoint, 0555) < 0) { - if (errno == EEXIST) { - /* - * If the mount point directory is a real mount -@@ -705,7 +709,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - * the kernel NFS client. - */ - if (me->multi != me && -- is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) -+ is_mounted(_PATH_MOUNTED, mountpoint, MNTS_REAL)) - return MOUNT_OFFSET_IGNORE; - - /* -@@ -725,13 +729,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - debug(ap->logopt, - "can't create mount directory: %s, %s", -- me->key, estr); -+ mountpoint, estr); - return MOUNT_OFFSET_FAIL; - } else { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - crit(ap->logopt, - "failed to create mount directory: %s, %s", -- me->key, estr); -+ mountpoint, estr); - return MOUNT_OFFSET_FAIL; - } - } else { -@@ -741,7 +745,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - - debug(ap->logopt, - "calling mount -t autofs " SLOPPY " -o %s automount %s", -- mp->options, me->key); -+ mp->options, mountpoint); - - type = ap->entry->maps->type; - if (type && !strcmp(ap->entry->maps->type, "hosts")) { -@@ -753,22 +757,18 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - } else - map_name = me->mc->map->argv[0]; - -- ret = mount(map_name, me->key, "autofs", MS_MGC_VAL, mp->options); -+ ret = mount(map_name, mountpoint, "autofs", MS_MGC_VAL, mp->options); - if (ret) { -- crit(ap->logopt, "failed to mount autofs path %s", me->key); -- goto out_err; -- } -- -- if (ret != 0) { - crit(ap->logopt, -- "failed to mount autofs offset trigger %s", me->key); -+ "failed to mount offset trigger %s at %s", -+ me->key, mountpoint); - goto out_err; - } - - /* Root directory for ioctl()'s */ -- ioctlfd = open(me->key, O_RDONLY); -+ ioctlfd = open(mountpoint, O_RDONLY); - if (ioctlfd < 0) { -- crit(ap->logopt, "failed to create ioctl fd for %s", me->key); -+ crit(ap->logopt, "failed to create ioctl fd for %s", mountpoint); - goto out_umount; - } - -@@ -782,7 +782,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - ret = fstat(ioctlfd, &st); - if (ret == -1) { - error(ap->logopt, -- "failed to stat direct mount trigger %s", me->key); -+ "failed to stat direct mount trigger %s", mountpoint); - goto out_close; - } - -@@ -790,17 +790,17 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - - close(ioctlfd); - -- debug(ap->logopt, "mounted trigger %s", me->key); -+ debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint); - - return MOUNT_OFFSET_OK; - - out_close: - close(ioctlfd); - out_umount: -- umount(me->key); -+ umount(mountpoint); - out_err: -- if (stat(me->key, &st) == 0 && me->dir_created) -- rmdir_path(ap, me->key, st.st_dev); -+ if (stat(mountpoint, &st) == 0 && me->dir_created) -+ rmdir_path(ap, mountpoint, st.st_dev); - - return MOUNT_OFFSET_FAIL; - } -diff --git a/daemon/indirect.c b/daemon/indirect.c -index e832cd4..168d915 100644 ---- a/daemon/indirect.c -+++ b/daemon/indirect.c -@@ -83,7 +83,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) - return ret; - } - --static int do_mount_autofs_indirect(struct autofs_point *ap) -+static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) - { - time_t timeout = ap->exp_timeout; - char *options = NULL; -@@ -109,11 +109,11 @@ static int do_mount_autofs_indirect(struct autofs_point *ap) - goto out_err; - - /* In case the directory doesn't exist, try to mkdir it */ -- if (mkdir_path(ap->path, 0555) < 0) { -+ if (mkdir_path(root, 0555) < 0) { - if (errno != EEXIST && errno != EROFS) { - crit(ap->logopt, - "failed to create autofs directory %s", -- ap->path); -+ root); - goto out_err; - } - /* If we recieve an error, and it's EEXIST or EROFS we know -@@ -134,9 +134,10 @@ static int do_mount_autofs_indirect(struct autofs_point *ap) - } else - map_name = ap->entry->maps->argv[0]; - -- ret = mount(map_name, ap->path, "autofs", MS_MGC_VAL, options); -+ ret = mount(map_name, root, "autofs", MS_MGC_VAL, options); - if (ret) { -- crit(ap->logopt, "failed to mount autofs path %s", ap->path); -+ crit(ap->logopt, -+ "failed to mount autofs path %s at %s", ap->path, root); - goto out_rmdir; - } - -@@ -145,7 +146,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap) - options = NULL; - - /* Root directory for ioctl()'s */ -- ap->ioctlfd = open(ap->path, O_RDONLY); -+ ap->ioctlfd = open(root, O_RDONLY); - if (ap->ioctlfd < 0) { - crit(ap->logopt, - "failed to create ioctl fd for autofs path %s", ap->path); -@@ -163,13 +164,13 @@ static int do_mount_autofs_indirect(struct autofs_point *ap) - - if (ap->exp_timeout) - info(ap->logopt, -- "mounted indirect mount on %s " -+ "mounted indirect mount for %s " - "with timeout %u, freq %u seconds", ap->path, - (unsigned int) ap->exp_timeout, - (unsigned int) ap->exp_runfreq); - else - info(ap->logopt, -- "mounted indirect mount on %s with timeouts disabled", -+ "mounted indirect mount for %s with timeouts disabled", - ap->path); - - fstat(ap->ioctlfd, &st); -@@ -178,10 +179,10 @@ static int do_mount_autofs_indirect(struct autofs_point *ap) - return 0; - - out_umount: -- umount(ap->path); -+ umount(root); - out_rmdir: - if (ap->dir_created) -- rmdir_path(ap, ap->path, ap->dev); -+ rmdir(root); - out_err: - if (options) - free(options); -@@ -193,7 +194,7 @@ out_err: - return -1; - } - --int mount_autofs_indirect(struct autofs_point *ap) -+int mount_autofs_indirect(struct autofs_point *ap, const char *root) - { - time_t now = time(NULL); - int status; -@@ -207,11 +208,11 @@ int mount_autofs_indirect(struct autofs_point *ap) - return -1; - } - -- status = do_mount_autofs_indirect(ap); -+ status = do_mount_autofs_indirect(ap, root); - if (status < 0) - return -1; - -- map = lookup_ghost(ap); -+ map = lookup_ghost(ap, root); - if (map & LKP_FAIL) { - if (map & LKP_DIRECT) { - error(ap->logopt, -@@ -230,7 +231,7 @@ int mount_autofs_indirect(struct autofs_point *ap) - return 0; - } - --static void close_mount_fds(struct autofs_point *ap) -+void close_mount_fds(struct autofs_point *ap) - { - /* - * Since submounts look after themselves the parent never knows -@@ -255,11 +256,17 @@ static void close_mount_fds(struct autofs_point *ap) - return; - } - --int umount_autofs_indirect(struct autofs_point *ap) -+int umount_autofs_indirect(struct autofs_point *ap, const char *root) - { - char buf[MAX_ERR_BUF]; -+ char mountpoint[PATH_MAX + 1]; - int ret, rv, retries; - -+ if (root) -+ strcpy(mountpoint, root); -+ else -+ strcpy(mountpoint, ap->path); -+ - /* If we are trying to shutdown make sure we can umount */ - rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret); - if (rv == -1) { -@@ -284,7 +291,7 @@ int umount_autofs_indirect(struct autofs_point *ap) - sched_yield(); - - retries = UMOUNT_RETRIES; -- while ((rv = umount(ap->path)) == -1 && retries--) { -+ while ((rv = umount(mountpoint)) == -1 && retries--) { - struct timespec tm = {0, 200000000}; - if (errno != EBUSY) - break; -@@ -296,13 +303,13 @@ int umount_autofs_indirect(struct autofs_point *ap) - case ENOENT: - case EINVAL: - error(ap->logopt, -- "mount point %s does not exist", ap->path); -+ "mount point %s does not exist", mountpoint); - close_mount_fds(ap); - return 0; - break; - case EBUSY: - debug(ap->logopt, -- "mount point %s is in use", ap->path); -+ "mount point %s is in use", mountpoint); - if (ap->state == ST_SHUTDOWN_FORCE) { - close_mount_fds(ap); - goto force_umount; -@@ -321,11 +328,11 @@ int umount_autofs_indirect(struct autofs_point *ap) - return 0; - } - #endif -- ap->ioctlfd = open(ap->path, O_RDONLY); -+ ap->ioctlfd = open(mountpoint, O_RDONLY); - if (ap->ioctlfd < 0) { - warn(ap->logopt, - "could not recover autofs path %s", -- ap->path); -+ mountpoint); - close_mount_fds(ap); - return 0; - } -@@ -355,12 +362,12 @@ int umount_autofs_indirect(struct autofs_point *ap) - force_umount: - if (rv != 0) { - warn(ap->logopt, -- "forcing umount of indirect mount %s", ap->path); -- rv = umount2(ap->path, MNT_DETACH); -+ "forcing umount of indirect mount %s", mountpoint); -+ rv = umount2(mountpoint, MNT_DETACH); - } else { -- info(ap->logopt, "umounted indirect mount %s", ap->path); -+ info(ap->logopt, "umounted indirect mount %s", mountpoint); - if (ap->submount) -- rm_unwanted(ap->logopt, ap->path, 1, ap->dev); -+ rm_unwanted(ap->logopt, mountpoint, 1, ap->dev); - } - - return rv; -diff --git a/daemon/lookup.c b/daemon/lookup.c -index 85ac519..db3b636 100644 ---- a/daemon/lookup.c -+++ b/daemon/lookup.c -@@ -565,7 +565,7 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time - return 0; - } - --int lookup_ghost(struct autofs_point *ap) -+int lookup_ghost(struct autofs_point *ap, const char *root) - { - struct master_mapent *entry = ap->entry; - struct map_source *map; -@@ -611,12 +611,12 @@ int lookup_ghost(struct autofs_point *ap) - goto next; - } - -- fullpath = alloca(strlen(me->key) + strlen(ap->path) + 3); -+ fullpath = alloca(strlen(me->key) + strlen(root) + 3); - if (!fullpath) { - warn(ap->logopt, "failed to allocate full path"); - goto next; - } -- sprintf(fullpath, "%s/%s", ap->path, me->key); -+ sprintf(fullpath, "%s/%s", root, me->key); - - ret = stat(fullpath, &st); - if (ret == -1 && errno != ENOENT) { -diff --git a/daemon/state.c b/daemon/state.c -index 122177c..0042a74 100644 ---- a/daemon/state.c -+++ b/daemon/state.c -@@ -393,7 +393,7 @@ static void *do_readmap(void *arg) - - if (ap->type == LKP_INDIRECT) { - lookup_prune_cache(ap, now); -- status = lookup_ghost(ap); -+ status = lookup_ghost(ap, ap->path); - } else { - struct mapent *me, *ne, *nested; - mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); -diff --git a/include/automount.h b/include/automount.h -index 8ff24a7..61cdac6 100644 ---- a/include/automount.h -+++ b/include/automount.h -@@ -230,7 +230,7 @@ int lookup_nss_read_master(struct master *master, time_t age); - int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age); - int lookup_enumerate(struct autofs_point *ap, - int (*fn)(struct autofs_point *,struct mapent *, int), time_t now); --int lookup_ghost(struct autofs_point *ap); -+int lookup_ghost(struct autofs_point *ap, const char *root); - int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len); - void lookup_close_lookup(struct autofs_point *ap); - int lookup_prune_cache(struct autofs_point *ap, time_t age); -@@ -332,6 +332,7 @@ struct startup_cond { - pthread_mutex_t mutex; - pthread_cond_t cond; - struct autofs_point *ap; -+ char *root; - unsigned int done; - unsigned int status; - }; -@@ -427,12 +428,13 @@ int do_expire(struct autofs_point *ap, const char *name, int namelen); - void *expire_proc_indirect(void *); - void *expire_proc_direct(void *); - int expire_offsets_direct(struct autofs_point *ap, struct mapent *me, int now); --int mount_autofs_indirect(struct autofs_point *ap); -+int mount_autofs_indirect(struct autofs_point *ap, const char *root); - int mount_autofs_direct(struct autofs_point *ap); --int mount_autofs_offset(struct autofs_point *ap, struct mapent *me); -+int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset); - void submount_signal_parent(struct autofs_point *ap, unsigned int success); --int umount_autofs(struct autofs_point *ap, int force); --int umount_autofs_indirect(struct autofs_point *ap); -+void close_mount_fds(struct autofs_point *ap); -+int umount_autofs(struct autofs_point *ap, const char *root, int force); -+int umount_autofs_indirect(struct autofs_point *ap, const char *root); - int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me); - int umount_autofs_direct(struct autofs_point *ap); - int umount_autofs_offset(struct autofs_point *ap, struct mapent *me); -diff --git a/include/master.h b/include/master.h -index a397a75..e62c67b 100644 ---- a/include/master.h -+++ b/include/master.h -@@ -91,6 +91,7 @@ void master_source_lock_cleanup(void *); - void master_source_current_wait(struct master_mapent *); - void master_source_current_signal(struct master_mapent *); - struct master_mapent *master_find_mapent(struct master *, const char *); -+struct autofs_point *__master_find_submount(struct autofs_point *, const char *); - struct autofs_point *master_find_submount(struct autofs_point *, const char *); - struct master_mapent *master_new_mapent(struct master *, const char *, time_t); - void master_add_mapent(struct master *, struct master_mapent *); -diff --git a/include/mounts.h b/include/mounts.h -index 7120351..ca4f9f3 100644 ---- a/include/mounts.h -+++ b/include/mounts.h -@@ -85,7 +85,7 @@ int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char - int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type); - void set_tsd_user_vars(unsigned int, uid_t, gid_t); - int umount_ent(struct autofs_point *, const char *); --int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); --int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); -+int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *); -+int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); - - #endif -diff --git a/lib/master.c b/lib/master.c -index 71ba04a..d971ad6 100644 ---- a/lib/master.c -+++ b/lib/master.c -@@ -602,27 +602,32 @@ struct master_mapent *master_find_mapent(struct master *master, const char *path - return NULL; - } - --struct autofs_point *master_find_submount(struct autofs_point *ap, const char *path) -+struct autofs_point *__master_find_submount(struct autofs_point *ap, const char *path) - { - struct list_head *head, *p; - -- mounts_mutex_lock(ap); -- - head = &ap->submounts; - list_for_each(p, head) { - struct autofs_point *submount; - - submount = list_entry(p, struct autofs_point, mounts); - -- if (!strcmp(submount->path, path)) { -- mounts_mutex_unlock(ap); -+ if (!strcmp(submount->path, path)) - return submount; -- } - } - -+ return NULL; -+} -+ -+struct autofs_point *master_find_submount(struct autofs_point *ap, const char *path) -+{ -+ struct autofs_point *submount; -+ -+ mounts_mutex_lock(ap); -+ submount = __master_find_submount(ap, path); - mounts_mutex_unlock(ap); - -- return NULL; -+ return submount; - } - - struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age) -@@ -955,6 +960,7 @@ static int master_do_mount(struct master_mapent *entry) - } - - suc.ap = ap; -+ suc.root = ap->path; - suc.done = 0; - suc.status = 0; - -diff --git a/lib/mounts.c b/lib/mounts.c -index d77a6b0..f6fc389 100644 ---- a/lib/mounts.c -+++ b/lib/mounts.c -@@ -1105,7 +1105,8 @@ int umount_ent(struct autofs_point *ap, const char *path) - return rv; - } - --int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) -+int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, -+ const char *root, unsigned int start, const char *base) - { - char path[PATH_MAX + 1]; - char *offset = path; -@@ -1113,17 +1114,13 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, - struct list_head *pos = NULL; - unsigned int fs_path_len; - unsigned int mounted; -- int ret, start; -+ int ret; - -- fs_path_len = strlen(root) + strlen(base); -+ fs_path_len = start + strlen(base); - if (fs_path_len > PATH_MAX) - return -1; - -- strcpy(path, root); -- strcat(path, base); -- - mounted = 0; -- start = strlen(root); - offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); - while (offset) { - int plen = fs_path_len + strlen(offset); -@@ -1137,9 +1134,9 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, - if (!oe || !oe->mapent) - goto cont; - -- debug(ap->logopt, "mount offset %s", oe->key); -+ debug(ap->logopt, "mount offset %s at %s", oe->key, root); - -- ret = mount_autofs_offset(ap, oe); -+ ret = mount_autofs_offset(ap, oe, root, offset); - if (ret >= MOUNT_OFFSET_OK) - mounted++; - else { -@@ -1161,7 +1158,7 @@ cont: - return mounted; - } - --int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) -+int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) - { - char path[PATH_MAX + 1]; - char *offset; -@@ -1198,7 +1195,7 @@ int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me - * nonstrict mount fail. - */ - oe_base = oe->key + strlen(root); -- left += umount_multi_triggers(ap, root, oe, oe_base); -+ left += umount_multi_triggers(ap, oe, root, oe_base); - - if (oe->ioctlfd != -1) - left++; -@@ -1238,7 +1235,7 @@ int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me - if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { - info(ap->logopt, "unmounting dir = %s", root); - if (umount_ent(ap, root)) { -- if (mount_multi_triggers(ap, root, me, "/") < 0) -+ if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0) - warn(ap->logopt, - "failed to remount offset triggers"); - return left++; -diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c -index d6cbda8..8a7dd78 100644 ---- a/modules/mount_autofs.c -+++ b/modules/mount_autofs.c -@@ -48,7 +48,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - { - struct startup_cond suc; - pthread_t thid; -- char *fullpath; -+ char *realpath, *mountpoint; - const char **argv; - int argc, status, ghost = ap->ghost; - time_t timeout = ap->exp_timeout; -@@ -60,32 +60,32 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - struct autofs_point *nap; - char buf[MAX_ERR_BUF]; - char *options, *p; -- int ret; -- -- fullpath = alloca(strlen(root) + name_len + 2); -- if (!fullpath) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- logerr(MODPREFIX "alloca: %s", estr); -- return 1; -- } -+ int len, ret; - - /* Root offset of multi-mount */ -- if (*name == '/' && name_len == 1) -- strcpy(fullpath, root); -- else if (*name == '/') -- strcpy(fullpath, name); -- else { -- strcpy(fullpath, root); -- strcat(fullpath, "/"); -- strcat(fullpath, name); -- } -- -- if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX -- "warning: about to mount over %s, continuing", -- fullpath); -- return 0; -+ len = strlen(root); -+ if (root[len - 1] == '/') { -+ realpath = alloca(strlen(ap->path) + name_len + 2); -+ mountpoint = alloca(len + 1); -+ strcpy(realpath, ap->path); -+ strcat(realpath, "/"); -+ strcat(realpath, name); -+ len--; -+ strncpy(mountpoint, root, len); -+ mountpoint[len] = '\0'; -+ } else if (*name == '/') { -+ realpath = alloca(name_len + 1); -+ mountpoint = alloca(len + 1); -+ strcpy(mountpoint, root); -+ strcpy(realpath, name); -+ } else { -+ realpath = alloca(len + name_len + 2); -+ mountpoint = alloca(len + name_len + 2); -+ strcpy(mountpoint, root); -+ strcat(mountpoint, "/"); -+ strcpy(realpath, mountpoint); -+ strcat(mountpoint, name); -+ strcat(realpath, name); - } - - options = NULL; -@@ -136,12 +136,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - } - - debug(ap->logopt, -- MODPREFIX "fullpath=%s what=%s options=%s", -- fullpath, what, options); -+ MODPREFIX "mountpoint=%s what=%s options=%s", -+ mountpoint, what, options); - - master = ap->entry->master; - -- entry = master_new_mapent(master, fullpath, ap->entry->age); -+ entry = master_new_mapent(master, realpath, ap->entry->age); - if (!entry) { - error(ap->logopt, - MODPREFIX "failed to malloc master_mapent struct"); -@@ -228,6 +228,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - } - - suc.ap = nap; -+ suc.root = mountpoint; - suc.done = 0; - suc.status = 0; - -@@ -235,7 +236,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - crit(ap->logopt, - MODPREFIX - "failed to create mount handler thread for %s", -- fullpath); -+ realpath); - handle_mounts_startup_cond_destroy(&suc); - mounts_mutex_unlock(ap); - master_free_map_source(source, 1); -@@ -256,7 +257,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - - if (suc.status) { - crit(ap->logopt, -- MODPREFIX "failed to create submount for %s", fullpath); -+ MODPREFIX "failed to create submount for %s", realpath); - handle_mounts_startup_cond_destroy(&suc); - mounts_mutex_unlock(ap); - master_free_map_source(source, 1); -diff --git a/modules/mount_bind.c b/modules/mount_bind.c -index e4a04d0..396a3ca 100644 ---- a/modules/mount_bind.c -+++ b/modules/mount_bind.c -@@ -74,34 +74,24 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - char *fullpath; - char buf[MAX_ERR_BUF]; - int err; -- int i, rlen; -+ int i, len; - - /* Root offset of multi-mount */ -- if (*name == '/' && name_len == 1) { -- rlen = strlen(root); -- name_len = 0; -+ len = strlen(root); -+ if (root[len - 1] == '/') { -+ fullpath = alloca(len); -+ len = snprintf(fullpath, len, "%s", root); - /* Direct mount name is absolute path so don't use root */ -- } else if (*name == '/') -- rlen = 0; -- else -- rlen = strlen(root); -- -- fullpath = alloca(rlen + name_len + 2); -- if (!fullpath) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- logerr(MODPREFIX "alloca: %s", estr); -- return 1; -+ } else if (*name == '/') { -+ fullpath = alloca(len + 1); -+ len = sprintf(fullpath, "%s", root); -+ } else { -+ fullpath = alloca(len + name_len + 2); -+ len = sprintf(fullpath, "%s/%s", root, name); - } -+ fullpath[len] = '\0'; - -- if (name_len) { -- if (rlen) -- sprintf(fullpath, "%s/%s", root, name); -- else -- sprintf(fullpath, "%s", name); -- } else -- sprintf(fullpath, "%s", root); -- -- i = strlen(fullpath); -+ i = len; - while (--i > 0 && fullpath[i] == '/') - fullpath[i] = '\0'; - -@@ -125,13 +115,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - if (!status) - existed = 0; - -- if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX "warning: %s is already mounted", -- fullpath); -- return 0; -- } -- - debug(ap->logopt, - MODPREFIX - "calling mount --bind " SLOPPY " -o %s %s %s", -diff --git a/modules/mount_changer.c b/modules/mount_changer.c -index 08d9147..e838fcf 100644 ---- a/modules/mount_changer.c -+++ b/modules/mount_changer.c -@@ -49,34 +49,24 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - char *fullpath; - char buf[MAX_ERR_BUF]; - int err; -- int rlen, status, existed = 1; -+ int len, status, existed = 1; - - fstype = "iso9660"; - - /* Root offset of multi-mount */ -- if (*name == '/' && name_len == 1) { -- rlen = strlen(root); -- name_len = 0; -+ len = strlen(root); -+ if (root[len - 1] == '/') { -+ fullpath = alloca(len); -+ len = snprintf(fullpath, len, "%s", root); - /* Direct mount name is absolute path so don't use root */ -- } else if (*name == '/') -- rlen = 0; -- else -- rlen = strlen(root); -- -- fullpath = alloca(rlen + name_len + 2); -- if (!fullpath) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- logerr(MODPREFIX "alloca: %s", estr); -- return 1; -+ } else if (*name == '/') { -+ fullpath = alloca(len + 1); -+ len = sprintf(fullpath, "%s", root); -+ } else { -+ fullpath = alloca(len + name_len + 2); -+ len = sprintf(fullpath, "%s/%s", root, name); - } -- -- if (name_len) { -- if (rlen) -- sprintf(fullpath, "%s/%s", root, name); -- else -- sprintf(fullpath, "%s", name); -- } else -- sprintf(fullpath, "%s", root); -+ fullpath[len] = '\0'; - - debug(ap->logopt, MODPREFIX "calling umount %s", what); - -diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c -index 8cf9937..7589991 100644 ---- a/modules/mount_ext2.c -+++ b/modules/mount_ext2.c -@@ -43,32 +43,22 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - const char *p, *p1; - int err, ro = 0; - const char *fsck_prog; -- int rlen, status, existed = 1; -+ int len, status, existed = 1; - - /* Root offset of multi-mount */ -- if (*name == '/' && name_len == 1) { -- rlen = strlen(root); -- name_len = 0; -+ len = strlen(root); -+ if (root[len - 1] == '/') { -+ fullpath = alloca(len); -+ len = snprintf(fullpath, len, "%s", root); - /* Direct mount name is absolute path so don't use root */ -- } else if (*name == '/') -- rlen = 0; -- else -- rlen = strlen(root); -- -- fullpath = alloca(rlen + name_len + 2); -- if (!fullpath) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- logerr(MODPREFIX "alloca: %s", estr); -- return 1; -+ } else if (*name == '/') { -+ fullpath = alloca(len + 1); -+ len = sprintf(fullpath, "%s", root); -+ } else { -+ fullpath = alloca(len + name_len + 2); -+ len = sprintf(fullpath, "%s/%s", root, name); - } -- -- if (name_len) { -- if (rlen) -- sprintf(fullpath, "%s/%s", root, name); -- else -- sprintf(fullpath, "%s", name); -- } else -- sprintf(fullpath, "%s", root); -+ fullpath[len] = '\0'; - - debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); - -@@ -83,12 +73,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - if (!status) - existed = 0; - -- if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX "warning: %s is already mounted", fullpath); -- return 0; -- } -- - if (options && options[0]) { - for (p = options; (p1 = strchr(p, ',')); p = p1) - if (!strncmp(p, "ro", p1 - p) && ++p1 - p == sizeof("ro")) -diff --git a/modules/mount_generic.c b/modules/mount_generic.c -index 85b4391..4b1213e 100644 ---- a/modules/mount_generic.c -+++ b/modules/mount_generic.c -@@ -42,32 +42,22 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - char *fullpath; - char buf[MAX_ERR_BUF]; - int err; -- int rlen, status, existed = 1; -+ int len, status, existed = 1; - - /* Root offset of multi-mount */ -- if (*name == '/' && name_len == 1) { -- rlen = strlen(root); -- name_len = 0; -+ len = strlen(root); -+ if (root[len - 1] == '/') { -+ fullpath = alloca(len); -+ len = snprintf(fullpath, len, "%s", root); - /* Direct mount name is absolute path so don't use root */ -- } else if (*name == '/') -- rlen = 0; -- else -- rlen = strlen(root); -- -- fullpath = alloca(rlen + name_len + 2); -- if (!fullpath) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- logerr(MODPREFIX "alloca: %s", estr); -- return 1; -+ } else if (*name == '/') { -+ fullpath = alloca(len + 1); -+ len = sprintf(fullpath, "%s", root); -+ } else { -+ fullpath = alloca(len + name_len + 2); -+ len = sprintf(fullpath, "%s/%s", root, name); - } -- -- if (name_len) { -- if (rlen) -- sprintf(fullpath, "%s/%s", root, name); -- else -- sprintf(fullpath, "%s", name); -- } else -- sprintf(fullpath, "%s", root); -+ fullpath[len] = '\0'; - - debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); - -@@ -82,12 +72,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - if (!status) - existed = 0; - -- if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX "warning: %s is already mounted", fullpath); -- return 0; -- } -- - if (options && options[0]) { - debug(ap->logopt, - MODPREFIX "calling mount -t %s " SLOPPY "-o %s %s %s", -diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c -index d7f42a7..0b253d8 100644 ---- a/modules/mount_nfs.c -+++ b/modules/mount_nfs.c -@@ -64,7 +64,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - struct host *this, *hosts = NULL; - unsigned int vers; - char *nfsoptions = NULL; -- int len, rlen, status, err, existed = 1; -+ int len, status, err, existed = 1; - int nosymlink = 0; - int ro = 0; /* Set if mount bind should be read-only */ - -@@ -146,30 +146,18 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - /* Construct and perhaps create mount point directory */ - - /* Root offset of multi-mount */ -- if (*name == '/' && name_len == 1) { -- rlen = strlen(root); -- name_len = 0; -+ len = strlen(root); -+ if (root[len - 1] == '/') { -+ fullpath = alloca(len); -+ len = snprintf(fullpath, len, "%s", root); - /* Direct mount name is absolute path so don't use root */ -- } else if (*name == '/') -- rlen = 0; -- else -- rlen = strlen(root); -- -- fullpath = alloca(rlen + name_len + 2); -- if (!fullpath) { -- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -- logerr(MODPREFIX "alloca: %s", estr); -- free_host_list(&hosts); -- return 1; -- } -- -- if (name_len) { -- if (rlen) -- len = sprintf(fullpath, "%s/%s", root, name); -- else -- len = sprintf(fullpath, "%s", name); -- } else -+ } else if (*name == '/') { -+ fullpath = alloca(len + 1); - len = sprintf(fullpath, "%s", root); -+ } else { -+ fullpath = alloca(len + name_len + 2); -+ len = sprintf(fullpath, "%s/%s", root, name); -+ } - fullpath[len] = '\0'; - - debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); -@@ -189,13 +177,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - while (this) { - char *loc, *port_opt = NULL; - -- if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) { -- error(ap->logopt, -- MODPREFIX -- "warning: %s is already mounted", fullpath); -- break; -- } -- - /* - * If the "port" option is specified, then we don't want - * a bind mount. Use the "port" option if you want to -diff --git a/modules/parse_sun.c b/modules/parse_sun.c -index d839694..b548520 100644 ---- a/modules/parse_sun.c -+++ b/modules/parse_sun.c -@@ -31,12 +31,18 @@ - #include - #include - #include -+#include -+#include - - #define MODULE_PARSE - #include "automount.h" - - #define MODPREFIX "parse(sun): " - -+#define MOUNT_MOVE_NONE 0x00 -+#define MOUNT_MOVE_AUTOFS 0x01 -+#define MOUNT_MOVE_OTHER 0x02 -+ - int parse_version = AUTOFS_PARSE_VERSION; /* Required by protocol */ - - static struct mount_mod *mount_nfs = NULL; -@@ -67,6 +73,7 @@ static struct parse_context default_context = { - 1 /* Do slashify_colons */ - }; - -+int destroy_logpri_fifo(struct autofs_point *ap); - static char *concat_options(char *left, char *right); - - /* Free all storage associated with this context */ -@@ -756,8 +763,10 @@ add_offset_entry(struct autofs_point *ap, const char *name, - - p_len = strlen(path); - /* Trailing '/' causes us pain */ -- if (p_len > 1 && path[p_len - 1] == '/') -- p_len--; -+ if (p_len > 1) { -+ while (p_len > 1 && path[p_len - 1] == '/') -+ p_len--; -+ } - m_key_len = m_root_len + p_len; - if (m_key_len > PATH_MAX) { - error(ap->logopt, MODPREFIX "multi mount key too long"); -@@ -961,53 +970,318 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char * - return (p - ent); - } - --static int mount_subtree_offsets(struct autofs_point *ap, struct mapent_cache *mc, struct mapent *me) -+static int move_mount(struct autofs_point *ap, -+ const char *mm_tmp_root, const char *mm_root, -+ unsigned int move) - { -- struct mapent *mm; -- char *m_key; -- int ret, start; -- char *base, *m_root; - char buf[MAX_ERR_BUF]; -+ int err; - -- mm = me->multi; -+ if (move == MOUNT_MOVE_NONE) -+ return 1; - -- if (!mm) -+ err = mkdir_path(mm_root, 0555); -+ if (err < 0 && errno != EEXIST) { -+ error(ap->logopt, -+ "failed to create move target mount point %s", mm_root); - return 0; -+ } - -- cache_multi_lock(me->parent); -+ if (move == MOUNT_MOVE_AUTOFS) -+ err = mount(mm_tmp_root, mm_root, NULL, MS_MOVE, NULL); -+ else -+ err = spawn_mount(ap->logopt, -+ "--move", mm_tmp_root, mm_root, NULL); -+ if (err) { -+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -+ error(ap->logopt, -+ "failed to move mount from %s to %s: %s", -+ mm_tmp_root, mm_root, estr); -+ return 0; -+ } - -- m_key = mm->key; -+ debug(ap->logopt, -+ "moved mount tree from %s to %s", mm_tmp_root, mm_root); - -- if (*m_key == '/') { -- m_root = m_key; -- start = strlen(m_key); -- } else { -- start = strlen(ap->path) + strlen(m_key) + 1; -- m_root = alloca(start + 1); -- if (!m_root) { -- char *estr; -- cache_multi_unlock(me->parent); -- estr = strerror_r(errno, buf, MAX_ERR_BUF); -- error(ap->logopt, MODPREFIX "alloca: %s", estr); -- return -1; -+ return 1; -+} -+ -+static void cleanup_multi_root(struct autofs_point *ap, const char *root, -+ const char *path, unsigned int move) -+{ -+ if (move == MOUNT_MOVE_NONE) -+ return; -+ -+ if (move == MOUNT_MOVE_OTHER) -+ spawn_umount(ap->logopt, root, NULL); -+ else { -+ struct autofs_point *submount; -+ -+ mounts_mutex_lock(ap); -+ submount = __master_find_submount(ap, path); -+ if (!submount) { -+ mounts_mutex_unlock(ap); -+ return; -+ } -+ -+ alarm_delete(submount); -+ st_remove_tasks(submount); -+ st_wait_state(submount, ST_READY); -+ -+ submount->parent->submnt_count--; -+ list_del_init(&submount->mounts); -+ -+ ioctl(submount->ioctlfd, AUTOFS_IOC_CATATONIC, 0); -+ -+ mounts_mutex_unlock(ap); -+ -+ if (submount->thid) { -+ pthread_cancel(submount->thid); -+ close_mount_fds(submount); -+ umount(root); -+ destroy_logpri_fifo(submount); -+ master_free_mapent_sources(submount->entry, 1); -+ master_free_mapent(ap->entry); - } -- strcpy(m_root, ap->path); -- strcat(m_root, "/"); -- strcat(m_root, m_key); - } -+ return; -+} - -- base = &me->key[start]; -+static void cleanup_multi_triggers(struct autofs_point *ap, -+ struct mapent *me, const char *root, int start, -+ const char *base) -+{ -+ char path[PATH_MAX + 1]; -+ char offset[PATH_MAX + 1]; -+ char *poffset = offset; -+ struct mapent *oe; -+ struct list_head *mm_root, *pos; -+ const char o_root[] = "/"; -+ const char *mm_base; -+ -+ mm_root = &me->multi->multi_list; -+ -+ if (!base) -+ mm_base = o_root; -+ else -+ mm_base = base; -+ -+ pos = NULL; -+ -+ /* Make sure "none" of the offsets have an active mount. */ -+ while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) { -+ oe = cache_lookup_offset(mm_base, poffset, start, &me->multi_list); -+ /* root offset is a special case */ -+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) -+ continue; -+ -+ strcpy(path, root); -+ strcat(path, poffset); -+ if (umount(path)) { -+ error(ap->logopt, "error recovering from mount fail"); -+ error(ap->logopt, "cannot umount offset %s", path); -+ } -+ } -+ -+ return; -+} - -- ret = mount_multi_triggers(ap, m_root, me->multi, base); -- if (ret == -1) { -- cache_multi_unlock(me->parent); -- error(ap->logopt, MODPREFIX "failed to mount offset triggers"); -- return -1; -+static int check_fstype_autofs_option(const char *options) -+{ -+ char *tok, *tokbuf; -+ int found; -+ -+ /* -+ * Look for fstype= in options and return true if -+ * the last occurrence is fstype=autofs. -+ */ -+ found = 0; -+ tokbuf = alloca(strlen(options) + 2); -+ strcpy(tokbuf, options); -+ tok = strtok_r(tokbuf, ",", &tokbuf); -+ if (tok) { -+ do { -+ if (strstr(tok, "fstype=")) { -+ if (strstr(tok, "autofs")) -+ found = 1; -+ else -+ found = 0; -+ } -+ } while ((tok = strtok_r(NULL, ",", &tokbuf))); - } - -- cache_multi_unlock(me->parent); -+ return found; -+} - -- return ret; -+static int mount_subtree(struct autofs_point *ap, struct mapent *me, -+ const char *name, char *loc, char *options, void *ctxt) -+{ -+ struct mapent *mm; -+ struct mapent *ro; -+ char t_dir[] = "/tmp/autoXXXXXX"; -+ char *mm_root, *mm_base, *mm_key; -+ const char *mm_tmp_root, *target; -+ unsigned int mm_tmp_root_len; -+ int start, ret = 0, rv; -+ unsigned int move; -+ -+ rv = 0; -+ -+ if (!me || !me->multi) { -+ int loclen = strlen(loc); -+ int namelen = strlen(name); -+ const char *root = ap->path; -+ -+ if (!strcmp(ap->path, "/-")) -+ root = name; -+ -+ rv = sun_mount(ap, root, name, namelen, loc, loclen, options, ctxt); -+ -+ goto done; -+ } -+ -+ mm = me->multi; -+ mm_key = mm->key; -+ move = MOUNT_MOVE_NONE; -+ -+ if (*mm_key == '/') { -+ mm_root = mm_key; -+ start = strlen(mm_key); -+ } else { -+ start = strlen(ap->path) + strlen(mm_key) + 1; -+ mm_root = alloca(start + 3); -+ strcpy(mm_root, ap->path); -+ strcat(mm_root, "/"); -+ strcat(mm_root, mm_key); -+ } -+ -+ mm_tmp_root = mkdtemp(t_dir); -+ if (!mm_tmp_root) -+ return 1; -+ mm_tmp_root_len = strlen(mm_tmp_root); -+ -+ if (me == me->multi) { -+ /* name = NULL */ -+ /* destination = mm_root */ -+ target = mm_root; -+ mm_base = "/"; -+ -+ /* Mount root offset if it exists */ -+ ro = cache_lookup_offset(mm_base, mm_base, strlen(mm_root), &me->multi_list); -+ if (ro) { -+ char *myoptions, *ro_loc, *tmp; -+ int namelen = name ? strlen(name) : 0; -+ const char *root; -+ int ro_len; -+ -+ rv = parse_mapent(ro->mapent, -+ options, &myoptions, &ro_loc, ap->logopt); -+ if (!rv) { -+ warn(ap->logopt, -+ MODPREFIX "failed to parse root offset"); -+ cache_delete_offset_list(me->mc, name); -+ rmdir(mm_tmp_root); -+ return 1; -+ } -+ ro_len = strlen(ro_loc); -+ -+ move = MOUNT_MOVE_OTHER; -+ if (check_fstype_autofs_option(myoptions)) -+ move = MOUNT_MOVE_AUTOFS; -+ -+ root = mm_tmp_root; -+ tmp = alloca(mm_tmp_root_len + 1); -+ strcpy(tmp, mm_tmp_root); -+ tmp[mm_tmp_root_len] = '/'; -+ tmp[mm_tmp_root_len + 1] = '\0'; -+ root = tmp; -+ -+ rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt); -+ -+ free(myoptions); -+ free(ro_loc); -+ } -+ -+ if (ro && rv == 0) { -+ ret = mount_multi_triggers(ap, me, mm_tmp_root, start, mm_base); -+ if (ret == -1) { -+ error(ap->logopt, MODPREFIX -+ "failed to mount offset triggers"); -+ cleanup_multi_triggers(ap, me, mm_tmp_root, start, mm_base); -+ cleanup_multi_root(ap, mm_tmp_root, mm_root, move); -+ rmdir(mm_tmp_root); -+ return 1; -+ } -+ } else if (rv <= 0) { -+ move = MOUNT_MOVE_NONE; -+ ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); -+ if (ret == -1) { -+ error(ap->logopt, MODPREFIX -+ "failed to mount offset triggers"); -+ cleanup_multi_triggers(ap, me, mm_tmp_root, start, mm_base); -+ rmdir(mm_tmp_root); -+ return 1; -+ } -+ } -+ } else { -+ int loclen = strlen(loc); -+ int namelen = strlen(name); -+ -+ move = MOUNT_MOVE_OTHER; -+ if (check_fstype_autofs_option(options)) -+ move = MOUNT_MOVE_AUTOFS; -+ -+ /* name = mm_root + mm_base */ -+ /* destination = mm_root + mm_base = name */ -+ target = name; -+ mm_base = &me->key[start]; -+ -+ rv = sun_mount(ap, mm_tmp_root, name, namelen, loc, loclen, options, ctxt); -+ if (rv == 0) { -+ ret = mount_multi_triggers(ap, me->multi, mm_tmp_root, start, mm_base); -+ if (ret == -1) { -+ error(ap->logopt, MODPREFIX -+ "failed to mount offset triggers"); -+ cleanup_multi_triggers(ap, me, mm_tmp_root, start, mm_base); -+ cleanup_multi_root(ap, mm_tmp_root, mm_root, move); -+ rmdir(mm_tmp_root); -+ return 1; -+ } -+ } else if (rv < 0) { -+ move = MOUNT_MOVE_NONE; -+ ret = mount_multi_triggers(ap, me->multi, mm_root, start, mm_base); -+ if (ret == -1) { -+ error(ap->logopt, MODPREFIX -+ "failed to mount offset triggers"); -+ cleanup_multi_triggers(ap, me, mm_tmp_root, start, mm_base); -+ rmdir(mm_tmp_root); -+ return 1; -+ } -+ } -+ } -+ -+ if (!move_mount(ap, mm_tmp_root, target, move)) { -+ cleanup_multi_triggers(ap, me, mm_tmp_root, start, mm_base); -+ cleanup_multi_root(ap, mm_tmp_root, mm_root, move); -+ rmdir(mm_tmp_root); -+ return 1; -+ } -+ -+ rmdir(mm_tmp_root); -+ -+ /* Mount for base of tree failed */ -+ if (rv > 0) -+ return rv; -+ -+done: -+ /* -+ * Convert fail on nonstrict, non-empty multi-mount -+ * to success -+ */ -+ if (rv < 0 && ret > 0) -+ rv = 0; -+ -+ return rv; - } - - /* -@@ -1029,7 +1303,7 @@ int parse_mount(struct autofs_point *ap, const char *name, - char buf[MAX_ERR_BUF]; - struct map_source *source; - struct mapent_cache *mc; -- struct mapent *me, *ro; -+ struct mapent *me = NULL; - char *pmapent, *options; - const char *p; - int mapent_len, rv = 0; -@@ -1154,7 +1428,7 @@ int parse_mount(struct autofs_point *ap, const char *name, - char *m_root = NULL; - int m_root_len; - time_t age = time(NULL); -- int l, ret; -+ int l; - - /* If name starts with "/" it's a direct mount */ - if (*name == '/') { -@@ -1302,48 +1576,7 @@ int parse_mount(struct autofs_point *ap, const char *name, - */ - cache_set_parents(me); - -- /* Mount root offset if it exists */ -- ro = cache_lookup_offset("/", "/", strlen(m_root), &me->multi_list); -- if (ro) { -- char *myoptions, *loc; -- -- rv = parse_mapent(ro->mapent, -- options, &myoptions, &loc, ap->logopt); -- if (!rv) { -- warn(ap->logopt, -- MODPREFIX "failed to mount root offset"); -- cache_delete_offset_list(mc, name); -- cache_multi_unlock(me); -- cache_unlock(mc); -- free(options); -- pthread_setcancelstate(cur_state, NULL); -- return 1; -- } -- -- rv = sun_mount(ap, m_root, -- "/", 1, loc, strlen(loc), myoptions, ctxt); -- -- free(myoptions); -- free(loc); -- } -- -- ret = mount_multi_triggers(ap, m_root, me, "/"); -- if (ret == -1) { -- warn(ap->logopt, -- MODPREFIX "failed to mount offset triggers"); -- cache_multi_unlock(me); -- cache_unlock(mc); -- free(options); -- pthread_setcancelstate(cur_state, NULL); -- return 1; -- } -- -- /* -- * Convert fail on nonstrict, non-empty multi-mount -- * to success -- */ -- if (rv < 0 && ret > 0) -- rv = 0; -+ rv = mount_subtree(ap, me, name, NULL, options, ctxt); - - cache_multi_unlock(me); - cache_unlock(mc); -@@ -1461,24 +1694,15 @@ mount_it: - MODPREFIX "core of entry: options=%s, loc=%.*s", - options, loclen, loc); - -- rv = sun_mount(ap, ap->path, name, name_len, loc, loclen, options, ctxt); -+ cache_readlock(mc); -+ cache_multi_lock(me); -+ -+ rv = mount_subtree(ap, me, name, loc, options, ctxt); - - free(loc); - free(options); - -- /* -- * If it's a multi-mount insert the triggers -- * These are always direct mount triggers so root = "" -- */ -- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); -- cache_readlock(mc); -- me = cache_lookup_distinct(mc, name); -- if (me) { -- int ret = mount_subtree_offsets(ap, mc, me); -- /* Convert fail on nonstrict, non-empty multi-mount to success */ -- if (rv < 0 && ret > 0) -- rv = 0; -- } -+ cache_multi_unlock(me); - cache_unlock(mc); - pthread_setcancelstate(cur_state, NULL); - } diff --git a/autofs-5.0.3-fix-multi-source-messages.patch b/autofs-5.0.3-fix-multi-source-messages.patch deleted file mode 100644 index de6df18..0000000 --- a/autofs-5.0.3-fix-multi-source-messages.patch +++ /dev/null @@ -1,182 +0,0 @@ -autofs-5.0.3 - fix multi source messages - -From: Ian Kent - -There are incorrect "key not found" messages seen for master map -entries that have multiple sources (direct mounts). - -For example, for the direct mount entries: - -/- auto.one -/- auto.two - -if a mount lookup is done and is not found in auto.one we see a -not found message even though it may be found in auto.two. - -This patch moves the "key not found" reporting out to the higher -level lookup and reports status at the end of the lookup. ---- - - daemon/lookup.c | 3 +++ - modules/lookup_file.c | 11 ++--------- - modules/lookup_ldap.c | 10 ++-------- - modules/lookup_nisplus.c | 12 +++--------- - modules/lookup_program.c | 2 +- - modules/lookup_yp.c | 10 ++-------- - 6 files changed, 13 insertions(+), 35 deletions(-) - - -diff --git a/daemon/lookup.c b/daemon/lookup.c -index 3c22a35..d33aadc 100644 ---- a/daemon/lookup.c -+++ b/daemon/lookup.c -@@ -903,6 +903,9 @@ int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const c - send_map_update_request(ap); - pthread_cleanup_pop(1); - -+ if (result == NSS_STATUS_NOTFOUND) -+ error(ap->logopt, "key \"%s\" not found in map.", name); -+ - return !result; - } - -diff --git a/modules/lookup_file.c b/modules/lookup_file.c -index 894f6fd..807ceab 100644 ---- a/modules/lookup_file.c -+++ b/modules/lookup_file.c -@@ -1074,7 +1074,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - me = cache_lookup_distinct(mc, key); - if (me && me->status >= time(NULL)) { - cache_unlock(mc); -- return NSS_STATUS_NOTFOUND; -+ return NSS_STATUS_UNAVAIL; - } - cache_unlock(mc); - -@@ -1105,11 +1105,6 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - if (status) { - if (status == NSS_STATUS_COMPLETED) - return NSS_STATUS_SUCCESS; -- -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map", -- name); -- - return NSS_STATUS_NOTFOUND; - } - } -@@ -1154,9 +1149,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - } - cache_unlock(mc); - } -- } else -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map.", name); -+ } - - if (ret) - return NSS_STATUS_TRYAGAIN; -diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c -index 5cc2148..7777e90 100644 ---- a/modules/lookup_ldap.c -+++ b/modules/lookup_ldap.c -@@ -2586,12 +2586,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - - status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); - free(lkp_key); -- if (status) { -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map", -- name); -+ if (status) - return status; -- } - } - - cache_readlock(mc); -@@ -2633,9 +2629,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - } - cache_unlock(mc); - } -- } else -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map", name); -+ } - - if (ret) - return NSS_STATUS_TRYAGAIN; -diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c -index 3c19fd3..4666161 100644 ---- a/modules/lookup_nisplus.c -+++ b/modules/lookup_nisplus.c -@@ -520,12 +520,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - ap->entry->current = source; - - status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); -- if (status) { -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map", -- name); -+ if (status) - return status; -- } - } - - cache_readlock(mc); -@@ -566,12 +562,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - } - cache_unlock(mc); - } -- } else -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map", name); -+ } - - if (ret) -- return NSS_STATUS_NOTFOUND; -+ return NSS_STATUS_TRYAGAIN; - - return NSS_STATUS_SUCCESS; - } -diff --git a/modules/lookup_program.c b/modules/lookup_program.c -index 7c266d6..daf874d 100644 ---- a/modules/lookup_program.c -+++ b/modules/lookup_program.c -@@ -390,7 +390,7 @@ out_free: - me->status = now + ap->negative_timeout; - } - cache_unlock(mc); -- return NSS_STATUS_UNAVAIL; -+ return NSS_STATUS_TRYAGAIN; - } - - return NSS_STATUS_SUCCESS; -diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c -index 14f981c..ee06551 100644 ---- a/modules/lookup_yp.c -+++ b/modules/lookup_yp.c -@@ -626,12 +626,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - - status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); - free(lkp_key); -- if (status) { -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map", -- name); -+ if (status) - return status; -- } - } - - cache_readlock(mc); -@@ -672,9 +668,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * - } - cache_unlock(mc); - } -- } else -- error(ap->logopt, -- MODPREFIX "key \"%s\" not found in map", name); -+ } - - if (ret) - return NSS_STATUS_TRYAGAIN; diff --git a/autofs-5.0.3-fix-nfs4-colon-escape.patch b/autofs-5.0.3-fix-nfs4-colon-escape.patch deleted file mode 100644 index 1bff3f4..0000000 --- a/autofs-5.0.3-fix-nfs4-colon-escape.patch +++ /dev/null @@ -1,28 +0,0 @@ -autofs-5.0.3 - fix nfs4 colon escape handling - -From: Ian Kent - -When fstype=nfs4 is given for a mount entry that should be bind -mounted because it has a ":" escaped location the colon can be -discarded before the mount module is called. This causes an -incorrect mount fail return since the replicated selection code -expects the colon to be present for parsing. ---- - - modules/parse_sun.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - - -diff --git a/modules/parse_sun.c b/modules/parse_sun.c -index b548520..333f8a5 100644 ---- a/modules/parse_sun.c -+++ b/modules/parse_sun.c -@@ -638,7 +638,7 @@ static int sun_mount(struct autofs_point *ap, const char *root, - } - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); -- if (!strcmp(fstype, "nfs")) { -+ if (!strcmp(fstype, "nfs") || !strcmp(fstype, "nfs4")) { - what = alloca(loclen + 1); - memcpy(what, loc, loclen); - what[loclen] = '\0'; diff --git a/autofs-5.0.3-fix-percent-hack.patch b/autofs-5.0.3-fix-percent-hack.patch deleted file mode 100644 index e02a77a..0000000 --- a/autofs-5.0.3-fix-percent-hack.patch +++ /dev/null @@ -1,369 +0,0 @@ -From jmoyer@redhat.com Thu Jul 17 10:12:13 2008 - -From: Ian Kent - -Hi, Ian, - -As I mentioned, the encode and decode routines for the % hack were -corrupting heap space. I put together a patch to fix things as they -stand today. The comments document the assumptions I made. - -I tested this code by compiling a program that only included -these functions and passing them arbitrary input and validating the -reuslts. I then compiled them into the automounter and verified that -no heap corruption occurred (by running automount -f on a fedora -system where such things are reported). - -Now, I don't think that we should ever have to encode the percent -hack. Shouldn't we just need to decode it, walking through all of the -returned entries until we find an exact match for the key being looked -up? - -Comments welcome. - -IMK: You're right, but we'll keep it for the moment. - -Cheers, -Jeff ---- - - modules/lookup_ldap.c | 267 +++++++++++++++++++++++++++++++++++-------------- - 1 files changed, 193 insertions(+), 74 deletions(-) - - -diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c -index 7777e90..3990f8c 100644 ---- a/modules/lookup_ldap.c -+++ b/modules/lookup_ldap.c -@@ -1512,6 +1512,65 @@ next: - return NSS_STATUS_SUCCESS; - } - -+static int get_percent_decoded_len(const char *name) -+{ -+ int escapes = 0; -+ int escaped = 0; -+ char *tmp = name; -+ int look_for_close = 0; -+ -+ while (*tmp) { -+ if (*tmp == '%') { -+ /* assume escapes aren't interpreted inside brackets */ -+ if (look_for_close) { -+ tmp++; -+ continue; -+ } -+ /* check for escaped % */ -+ if (escaped) { -+ tmp++; -+ escaped = 0; -+ continue; -+ } -+ escapes++; -+ tmp++; -+ if (*tmp == '[') { -+ escapes++; -+ tmp++; -+ look_for_close = 1; -+ } else -+ escaped = 1; -+ } else if (*tmp == ']' && look_for_close) { -+ escaped = 0; -+ escapes++; -+ tmp++; -+ look_for_close = 0; -+ } else { -+ tmp++; -+ escaped = 0; -+ } -+ } -+ -+ assert(strlen(name) > escapes); -+ return strlen(name) - escapes; -+} -+ -+/* -+ * Try to catch heap corruption if our logic happens to be incorrect. -+ */ -+static void validate_string_len(const char *orig, char *start, -+ char *end, unsigned int len) -+{ -+ debug(LOGOPT_NONE, MODPREFIX "string %s encoded as %s", orig, start); -+ /* make sure we didn't overflow the allocated space */ -+ if (end - start > len + 1) { -+ crit(LOGOPT_ANY, MODPREFIX "orig %s, len %d", orig, len); -+ crit(LOGOPT_ANY, MODPREFIX "en/decoded %s, len %d", start, -+ end - start); -+ } -+ assert(end-start <= len + 1); -+} -+ - /* - * Deal with encode and decode of % hack. - * Return -@@ -1519,131 +1578,191 @@ next: - * -1 => syntax error or alloc fail. - * 1 transofrmed value returned. - */ -+/* -+ * Assumptions: %'s must be escaped by %'s. %'s are not used to escape -+ * anything else except capital letters (so you can't escape a closing -+ * bracket, for example). -+ */ - static int decode_percent_hack(const char *name, char **key) - { - const char *tmp; - char *ptr, *new; -+ unsigned int len; -+ int escaped = 0, look_for_close = 0; - - if (!key) - return -1; - - *key = NULL; - -- tmp = name; -- while (*tmp && *tmp != '%' && *tmp != '[' && *tmp != ']') -- tmp++; -- if (!*tmp) -- return 0; -+ len = get_percent_decoded_len(name); -+ new = malloc(len + 1); -+ if (!new) -+ return -1; - -+ ptr = new; - tmp = name; - while (*tmp) { - if (*tmp == '%') { -- tmp++; -- if (!*tmp) -- return -1; -- if (*tmp != '[') -+ if (escaped) { -+ *ptr++ = *tmp++; -+ if (!look_for_close) -+ escaped = 0; - continue; -+ } - tmp++; -- while (*tmp && *tmp != ']') { -- if (*tmp == '%') -- tmp++; -+ if (*tmp == '[') { - tmp++; -- } -- if (!tmp) -- return -1; -- } -- tmp++; -- } -- -- new = malloc(strlen(name) + 1); -- if (!new) -- return -1; -- -- ptr = new; -- tmp = name; -- while (*tmp) { -- if (*tmp == '%' || *tmp == '[' || *tmp == ']') { -+ look_for_close = 1; -+ escaped = 1; -+ } else -+ escaped = 1; -+ } else if (*tmp == ']' && look_for_close) { - tmp++; -- if (*tmp && *tmp != '%') -- continue; -+ look_for_close = 0; -+ } else { -+ escaped = 0; -+ *ptr++ = *tmp++; - } -- *ptr++ = *tmp++; - } - *ptr = '\0'; -- - *key = new; - -+ validate_string_len(name, new, ptr, len); - return strlen(new); - } - --static int encode_percent_hack(const char *name, char **key, unsigned int use_class) -+/* -+ * Calculate the length of a string replacing all capital letters with %letter. -+ * For example: -+ * Sale -> %Sale -+ * SALE -> %S%A%L%E -+ */ -+static int get_encoded_len_escaping_every_cap(const char *name) - { - const char *tmp; -- unsigned int len = 0; -- char *ptr, *new; -+ unsigned int escapes = 0; /* number of % escape characters */ - -- if (!key) -- return -1; -+ tmp = name; -+ while (*tmp) { -+ /* We'll need to escape percents */ -+ if (*tmp == '%' || isupper(*tmp)) -+ escapes++; -+ tmp++; -+ } - -- *key = NULL; -+ return strlen(name) + escapes; -+} -+ -+/* -+ * Calculate the length of a string replacing sequences (1 or more) of capital -+ * letters with %[letters]. For example: -+ * FOO -> %[FOO] -+ * Work -> %[W]ork -+ * WorksForMe -> %[W]orks%[F]or%[M]e -+ * aaBBaa -> aa%[BB]aa -+ */ -+static int get_encoded_len_escaping_sequences(const char *name) -+{ -+ const char *tmp; -+ unsigned int escapes = 0; - - tmp = name; - while (*tmp) { -+ /* escape percents */ - if (*tmp == '%') -- len++; -+ escapes++; - else if (isupper(*tmp)) { -- tmp++; -- len++; -- if (!use_class) -- len++; -- else { -- if (*tmp && isupper(*tmp)) -- len += 2; -- else -- return 0; -- while (*tmp && isupper(*tmp)) { -- len++; -- tmp++; -- } -- } -+ /* start an escape block %[...] */ -+ escapes += 3; /* %[] */ -+ while (*tmp && isupper(*tmp)) -+ tmp++; - continue; - } -- len++; - tmp++; - } -- if (len == strlen(name)) -- return 0; - -- new = malloc(len + 1); -- if (!new) -- return -1; -+ return strlen(name) + escapes; -+} -+ -+static void encode_individual(const char *name, char *new, unsigned int len) -+{ -+ const char *tmp; -+ char *ptr; - - ptr = new; - tmp = name; - while (*tmp) { -- if (*tmp == '%') -+ if (*tmp == '%' || isupper(*tmp)) - *ptr++ = '%'; -- else if (isupper(*tmp)) { -- char next = *tmp++; -+ *ptr++ = *tmp++; -+ } -+ *ptr = '\0'; -+ validate_string_len(name, new, ptr, len); -+} -+ -+static void encode_sequence(const char *name, char *new, unsigned int len) -+{ -+ const char *tmp; -+ char *ptr; -+ -+ ptr = new; -+ tmp = name; -+ while (*tmp) { -+ if (*tmp == '%') { - *ptr++ = '%'; -- if (*tmp && (!isupper(*tmp) || !use_class)) -- *ptr++ = next; -- else { -- *ptr++ = '['; -- *ptr++ = next; -- while (*tmp && isupper(*tmp)) -- *ptr++ = *tmp++; -- *ptr++ = ']'; -+ *ptr++ = *tmp++; -+ } else if (isupper(*tmp)) { -+ *ptr++ = '%'; -+ *ptr++ = '['; -+ *ptr++ = *tmp++; -+ -+ while (*tmp && isupper(*tmp)) { -+ *ptr++ = *tmp; -+ tmp++; - } -- continue; -- } -- *ptr++ = *tmp++; -+ *ptr++ = ']'; -+ } else -+ *ptr++ = *tmp++; - } - *ptr = '\0'; -+ validate_string_len(name, new, ptr, len); -+} - -- *key = new; -+/* -+ * use_class: 1 means encode string as %[CAPITALS], 0 means encode as -+ * %C%A%P%I%T%A%L%S -+ */ -+static int encode_percent_hack(const char *name, char **key, unsigned int use_class) -+{ -+ unsigned int len = 0; - -- return strlen(new); -+ if (!key) -+ return -1; -+ -+ if (use_class) -+ len = get_encoded_len_escaping_sequences(name); -+ else -+ len = get_encoded_len_escaping_every_cap(name); -+ -+ /* If there is no escaping to be done, return 0 */ -+ if (len == strlen(name)) -+ return 0; -+ -+ *key = malloc(len + 1); -+ if (!*key) -+ return -1; -+ -+ if (use_class) -+ encode_sequence(name, *key, len); -+ else -+ encode_individual(name, *key, len); -+ -+ if (strlen(*key) != len) -+ crit(LOGOPT_ANY, MODPREFIX "encoded key length mismatch: key " -+ "%s len %d strlen %d", *key, len, strlen(*key)); -+ -+ return strlen(*key); - } - - static int do_paged_query(struct ldap_search_params *sp, struct lookup_context *ctxt) diff --git a/autofs-5.0.3-fix-proximity-other-timeout.patch b/autofs-5.0.3-fix-proximity-other-timeout.patch deleted file mode 100644 index e15937a..0000000 --- a/autofs-5.0.3-fix-proximity-other-timeout.patch +++ /dev/null @@ -1,36 +0,0 @@ -autofs-5.0.3 - fix proximity other rpc ping timeout - -From: Ian Kent - -The timeout for the RCP ping for hosts that are on a network other -than the local subnet or network is mistakenly set quite short. This -can lead to unexplained intermittent failures for hosts on remote -networks. ---- - - modules/replicated.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - - -diff --git a/modules/replicated.c b/modules/replicated.c -index efbe6b4..925f641 100644 ---- a/modules/replicated.c -+++ b/modules/replicated.c -@@ -552,7 +552,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host, - - if (host->proximity == PROXIMITY_NET) - timeout = RPC_TIMEOUT * 2; -- else if (host->proximity == PROXIMITY_NET) -+ else if (host->proximity == PROXIMITY_OTHER) - timeout = RPC_TIMEOUT * 8; - - rpc_info.host = host->name; -@@ -609,7 +609,7 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, - - if (host->proximity == PROXIMITY_NET) - timeout = RPC_TIMEOUT * 2; -- else if (host->proximity == PROXIMITY_NET) -+ else if (host->proximity == PROXIMITY_OTHER) - timeout = RPC_TIMEOUT * 8; - - rpc_info.host = host->name; diff --git a/autofs-5.0.3-fix-rootless-direct-multi-mount-expire.patch b/autofs-5.0.3-fix-rootless-direct-multi-mount-expire.patch deleted file mode 100644 index b50c2fb..0000000 --- a/autofs-5.0.3-fix-rootless-direct-multi-mount-expire.patch +++ /dev/null @@ -1,36 +0,0 @@ -autofs-5.0.3 - don't close direct root - -From: Ian Kent - -For direct mount multi-mounts with no real mount at their base we -need to leave the file handle open so they will be expired. This -patch corrects the check done at mount completion to do this so -they will be expired. ---- - - daemon/direct.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - - ---- autofs-5.0.3.orig/daemon/direct.c -+++ autofs-5.0.3/daemon/direct.c -@@ -1311,8 +1311,17 @@ static void *do_mount_direct(void *arg) - !master_find_submount(ap, mt.name))) - close_fd = 1; - cache_writelock(mt.mc); -- if (!close_fd && (me = cache_lookup_distinct(mt.mc, mt.name))) -- me->ioctlfd = mt.ioctlfd; -+ if ((me = cache_lookup_distinct(mt.mc, mt.name))) { -+ /* -+ * Careful here, we need to leave the file handle open -+ * for direct mount multi-mounts with no real mount at -+ * their base so they will be expired. -+ */ -+ if (close_fd && me == me->multi) -+ close_fd = 0; -+ if (!close_fd) -+ me->ioctlfd = mt.ioctlfd; -+ } - send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); - cache_unlock(mt.mc); - if (close_fd) diff --git a/autofs-5.0.3-handle-zero-length-nis-key-update.patch b/autofs-5.0.3-handle-zero-length-nis-key-update.patch deleted file mode 100644 index f0ec782..0000000 --- a/autofs-5.0.3-handle-zero-length-nis-key-update.patch +++ /dev/null @@ -1,57 +0,0 @@ -autofs-5.0.3 - handle zero length nis key update - -From: Ian Kent - -A zero length key is invalid but so is a single character -non-printable key and it causes the parser to get confused -as well. ---- - - modules/lookup_yp.c | 17 +++++++++++++---- - 1 files changed, 13 insertions(+), 4 deletions(-) - - -diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c -index ee06551..8b6408b 100644 ---- a/modules/lookup_yp.c -+++ b/modules/lookup_yp.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -168,9 +169,13 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen, - if (status != YP_TRUE) - return status; - -- /* Ignore zero length keys */ -- if (ypkeylen == 0) -+ /* Ignore zero length and single non-printable char keys */ -+ if (ypkeylen == 0 || (ypkeylen == 1 && !isprint(*ypkey))) { -+ warn(logopt, MODPREFIX -+ "ignoring invalid map entry, zero length or " -+ "single character non-printable key"); - return 0; -+ } - - /* - * Ignore keys beginning with '+' as plus map -@@ -267,9 +272,13 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen, - if (status != YP_TRUE) - return status; - -- /* Ignore zero length keys */ -- if (ypkeylen == 0) -+ /* Ignore zero length and single non-printable char keys */ -+ if (ypkeylen == 0 || (ypkeylen == 1 && !isprint(*ypkey))) { -+ warn(logopt, MODPREFIX -+ "ignoring invalid map entry, zero length or " -+ "single character non-printable key"); - return 0; -+ } - - /* - * Ignore keys beginning with '+' as plus map diff --git a/autofs-5.0.3-handle-zero-length-nis-key.patch b/autofs-5.0.3-handle-zero-length-nis-key.patch deleted file mode 100644 index 0185f2a..0000000 --- a/autofs-5.0.3-handle-zero-length-nis-key.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff -up autofs-5.0.3/CHANGELOG.handle-zero-length-nis-key autofs-5.0.3/CHANGELOG ---- autofs-5.0.3/CHANGELOG.handle-zero-length-nis-key 2008-03-24 14:07:30.000000000 +0900 -+++ autofs-5.0.3/CHANGELOG 2008-03-24 14:08:08.000000000 +0900 -@@ -8,6 +8,7 @@ - - another fix for don't fail on empty master map. - - fix expire working harder than needed. - - fix unlink of mount tree incorrectly causing autofs mount fail. -+- add missing check for zero length NIS key (Wengang Wang). - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff -up autofs-5.0.3/modules/lookup_yp.c.handle-zero-length-nis-key autofs-5.0.3/modules/lookup_yp.c ---- autofs-5.0.3/modules/lookup_yp.c.handle-zero-length-nis-key 2008-01-14 13:39:16.000000000 +0900 -+++ autofs-5.0.3/modules/lookup_yp.c 2008-03-24 14:07:45.000000000 +0900 -@@ -168,6 +168,10 @@ int yp_all_master_callback(int status, c - if (status != YP_TRUE) - return status; - -+ /* Ignore zero length keys */ -+ if (ypkeylen == 0) -+ return 0; -+ - /* - * Ignore keys beginning with '+' as plus map - * inclusion is only valid in file maps. -@@ -263,6 +267,10 @@ int yp_all_callback(int status, char *yp - if (status != YP_TRUE) - return status; - -+ /* Ignore zero length keys */ -+ if (ypkeylen == 0) -+ return 0; -+ - /* - * Ignore keys beginning with '+' as plus map - * inclusion is only valid in file maps. diff --git a/autofs-5.0.3-ldap-page-control-configure-fix.patch b/autofs-5.0.3-ldap-page-control-configure-fix.patch deleted file mode 100644 index 3838b5c..0000000 --- a/autofs-5.0.3-ldap-page-control-configure-fix.patch +++ /dev/null @@ -1,406 +0,0 @@ -diff --git a/CHANGELOG b/CHANGELOG -index 624fe9e..98855f5 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -1,3 +1,7 @@ -+??/??/2008 autofs-5.0.4 -+----------------------- -+- correct configure test for ldapr page control functions. -+ - 14/01/2008 autofs-5.0.3 - ----------------------- - - include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it). -diff --git a/aclocal.m4 b/aclocal.m4 -index 118ef0d..f24e076 100644 ---- a/aclocal.m4 -+++ b/aclocal.m4 -@@ -222,3 +222,69 @@ AC_TRY_LINK( - LDFLAGS="$af_check_hesiod_save_ldflags" - ]) - -+dnl -------------------------------------------------------------------------- -+dnl AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL -+dnl -+dnl Check for function ldap_create_page_control -+dnl -------------------------------------------------------------------------- -+AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL], -+[AC_MSG_CHECKING(for ldap_create_page_control in -lldap) -+ -+# save current ldflags -+af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" -+LDFLAGS="$LDFLAGS -lldap_r" -+ -+AC_TRY_LINK( -+ [ #include ], -+ [ LDAP *ld; -+ ber_int_t ps; -+ struct berval *c; -+ int ic, ret; -+ LDAPControl **clp; -+ ret = ldap_create_page_control(ld,ps,c,ic,clp); ], -+ [ af_have_ldap_create_page_control=yes -+ AC_MSG_RESULT(yes) ], -+ [ AC_MSG_RESULT(no) ]) -+ -+if test "$af_have_ldap_create_page_control" = "yes"; then -+ AC_DEFINE(HAVE_LDAP_CREATE_PAGE_CONTROL, 1, -+ [Define to 1 if you have the `ldap_create_page_control' function.]) -+fi -+ -+# restore ldflags -+LDFLAGS="$af_check_ldap_create_page_control_save_ldflags" -+]) -+ -+dnl -------------------------------------------------------------------------- -+dnl AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL -+dnl -+dnl Check for function ldap_parse_page_control -+dnl -------------------------------------------------------------------------- -+AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL], -+[AC_MSG_CHECKING(for ldap_parse_page_control in -lldap) -+ -+# save current ldflags -+af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" -+LDFLAGS="$LDFLAGS -lldap_r" -+ -+AC_TRY_LINK( -+ [ #include ], -+ [ LDAP *ld; -+ ber_int_t ct; -+ struct berval *c; -+ int ret; -+ LDAPControl **clp; -+ ret = ldap_parse_page_control(ld,clp,ct,c); ], -+ [ af_have_ldap_parse_page_control=yes -+ AC_MSG_RESULT(yes) ], -+ [ AC_MSG_RESULT(no) ]) -+ -+if test "$af_have_ldap_create_page_control" = "yes"; then -+ AC_DEFINE(HAVE_LDAP_PARSE_PAGE_CONTROL, 1, -+ [Define to 1 if you have the `ldap_parse_page_control' function.]) -+fi -+ -+# restore ldflags -+LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags" -+]) -+ -diff --git a/configure b/configure -index d212b05..e872392 100755 ---- a/configure -+++ b/configure -@@ -3631,7 +3631,7 @@ if test "${with_hesiod+set}" = set; then - fi - - --if test -z "$HAVE_HESIOD" -+if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0" - then - HAVE_HESIOD=0 - { echo "$as_me:$LINENO: checking for libhesiod" >&5 -@@ -4498,7 +4498,7 @@ if test "${with_openldap+set}" = set; then - - fi - --if test -z "$HAVE_LDAP"; then -+if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then - HAVE_LDAP=0 - LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1" - { echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5 -@@ -4566,71 +4566,106 @@ if test $ac_cv_lib_ldap_ldap_initialize = yes; then - HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv" - fi - -- if test "$HAVE_LDAP" == "1"; then -+ if test "$HAVE_LDAP" = "1"; then - - cat >>confdefs.h <<\_ACEOF - #define WITH_LDAP 1 - _ACEOF - - fi -+ { echo "$as_me:$LINENO: checking for ldap_create_page_control in -lldap" >&5 -+echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; } -+ -+# save current ldflags -+af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" -+LDFLAGS="$LDFLAGS -lldap_r" -+ -+cat >conftest.$ac_ext <<_ACEOF -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ #include -+int -+main () -+{ -+ LDAP *ld; -+ ber_int_t ps; -+ struct berval *c; -+ int ic, ret; -+ LDAPControl **clp; -+ ret = ldap_create_page_control(ld,ps,c,ic,clp); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (ac_try="$ac_link" -+case "(($ac_try" in -+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -+ *) ac_try_echo=$ac_try;; -+esac -+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -+ (eval "$ac_link") 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { -+ test -z "$ac_c_werror_flag" || -+ test ! -s conftest.err -+ } && test -s conftest$ac_exeext && -+ $as_test_x conftest$ac_exeext; then -+ af_have_ldap_create_page_control=yes -+ { echo "$as_me:$LINENO: result: yes" >&5 -+echo "${ECHO_T}yes" >&6; } -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ { echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6; } - fi - -+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ -+ conftest$ac_exeext conftest.$ac_ext - -+if test "$af_have_ldap_create_page_control" = "yes"; then - -+cat >>confdefs.h <<\_ACEOF -+#define HAVE_LDAP_CREATE_PAGE_CONTROL 1 -+_ACEOF - --LDFLAGS="${AF_tmp_ldflags}" -+fi - -+# restore ldflags -+LDFLAGS="$af_check_ldap_create_page_control_save_ldflags" - -+ { echo "$as_me:$LINENO: checking for ldap_parse_page_control in -lldap" >&5 -+echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; } - --for ac_func in ldap_create_page_control ldap_parse_page_control --do --as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` --{ echo "$as_me:$LINENO: checking for $ac_func" >&5 --echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } --if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then -- echo $ECHO_N "(cached) $ECHO_C" >&6 --else -- cat >conftest.$ac_ext <<_ACEOF -+# save current ldflags -+af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" -+LDFLAGS="$LDFLAGS -lldap_r" -+ -+cat >conftest.$ac_ext <<_ACEOF - /* confdefs.h. */ - _ACEOF - cat confdefs.h >>conftest.$ac_ext - cat >>conftest.$ac_ext <<_ACEOF - /* end confdefs.h. */ --/* Define $ac_func to an innocuous variant, in case declares $ac_func. -- For example, HP-UX 11i declares gettimeofday. */ --#define $ac_func innocuous_$ac_func -- --/* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func (); below. -- Prefer to if __STDC__ is defined, since -- exists even on freestanding compilers. */ -- --#ifdef __STDC__ --# include --#else --# include --#endif -- --#undef $ac_func -- --/* Override any GCC internal prototype to avoid an error. -- Use char because int might match the return type of a GCC -- builtin and then its argument prototype would still apply. */ --#ifdef __cplusplus --extern "C" --#endif --char $ac_func (); --/* The GNU C library defines this for functions which it implements -- to always fail with ENOSYS. Some functions are actually named -- something starting with __ and the normal name is an alias. */ --#if defined __stub_$ac_func || defined __stub___$ac_func --choke me --#endif -- -+ #include - int - main () - { --return $ac_func (); -+ LDAP *ld; -+ ber_int_t ct; -+ struct berval *c; -+ int ret; -+ LDAPControl **clp; -+ ret = ldap_parse_page_control(ld,clp,ct,c); - ; - return 0; - } -@@ -4653,28 +4688,37 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then -- eval "$as_ac_var=yes" -+ af_have_ldap_parse_page_control=yes -+ { echo "$as_me:$LINENO: result: yes" >&5 -+echo "${ECHO_T}yes" >&6; } - else - echo "$as_me: failed program was:" >&5 - sed 's/^/| /' conftest.$ac_ext >&5 - -- eval "$as_ac_var=no" -+ { echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6; } - fi - - rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext --fi --ac_res=`eval echo '${'$as_ac_var'}'` -- { echo "$as_me:$LINENO: result: $ac_res" >&5 --echo "${ECHO_T}$ac_res" >&6; } --if test `eval echo '${'$as_ac_var'}'` = yes; then -- cat >>confdefs.h <<_ACEOF --#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+ -+if test "$af_have_ldap_create_page_control" = "yes"; then -+ -+cat >>confdefs.h <<\_ACEOF -+#define HAVE_LDAP_PARSE_PAGE_CONTROL 1 - _ACEOF - - fi --done - -+# restore ldflags -+LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags" -+ -+fi -+ -+ -+ -+ -+LDFLAGS="${AF_tmp_ldflags}" - - # - # SASL support -@@ -4703,7 +4747,7 @@ if test "${with_sasl+set}" = set; then - - fi - --if test -z "$HAVE_SASL" -a "$HAVE_LIBXML" == "1" -+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1" - then - HAVE_SASL=0 - { echo "$as_me:$LINENO: checking for sasl_client_start in -lsasl2" >&5 -diff --git a/configure.in b/configure.in -index 952d040..a9c86dd 100644 ---- a/configure.in -+++ b/configure.in -@@ -155,7 +155,7 @@ AC_ARG_WITH(hesiod, - fi - ) - --if test -z "$HAVE_HESIOD" -+if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0" - then - HAVE_HESIOD=0 - AF_CHECK_LIBHESIOD() -@@ -194,15 +194,17 @@ AC_ARG_WITH(openldap, - LDAP_FLAGS="-I${withval}/include" - fi - ) --if test -z "$HAVE_LDAP"; then -+if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then - HAVE_LDAP=0 - LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1" - AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv", , - -llber -lresolv $LIBS) -- if test "$HAVE_LDAP" == "1"; then -+ if test "$HAVE_LDAP" = "1"; then - AC_DEFINE(WITH_LDAP,1, - [Define if using LDAP as a source of automount maps]) - fi -+ AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL() -+ AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL() - fi - - AC_SUBST(LDAP_FLAGS) -@@ -210,8 +212,6 @@ AC_SUBST(HAVE_LDAP) - AC_SUBST(LIBLDAP) - LDFLAGS="${AF_tmp_ldflags}" - --AC_CHECK_FUNCS(ldap_create_page_control ldap_parse_page_control) -- - # - # SASL support - # configure magic taken from: -@@ -236,7 +236,7 @@ AC_ARG_WITH(sasl, - SASL_FLAGS="-I${withval}/include" - fi - ) --if test -z "$HAVE_SASL" -a "$HAVE_LIBXML" == "1" -+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1" - then - HAVE_SASL=0 - AC_CHECK_LIB(sasl2, sasl_client_start, HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2", , -lsasl2 $LIBS) -diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c -index 0723fd8..e8530f6 100644 ---- a/modules/lookup_ldap.c -+++ b/modules/lookup_ldap.c -@@ -55,7 +55,7 @@ struct ldap_search_params { - char *query, **attrs; - struct berval *cookie; - int morePages; -- unsigned int totalCount; -+ ber_int_t totalCount; - LDAPMessage *result; - time_t age; - }; -@@ -63,7 +63,7 @@ struct ldap_search_params { - static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *); - - #ifndef HAVE_LDAP_CREATE_PAGE_CONTROL --int ldap_create_page_control(LDAP *ldap, unsigned int pagesize, -+int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize, - struct berval *cookie, char isCritical, - LDAPControl **output) - { -@@ -93,7 +93,7 @@ int ldap_create_page_control(LDAP *ldap, unsigned int pagesize, - - #ifndef HAVE_LDAP_PARSE_PAGE_CONTROL - int ldap_parse_page_control(LDAP *ldap, LDAPControl **controls, -- unsigned int *totalcount, struct berval **cookie) -+ ber_int_t *totalcount, struct berval **cookie) - { - int i, rc; - BerElement *theBer; -@@ -1644,7 +1644,7 @@ static int do_paged_query(struct ldap_search_params *sp, struct lookup_context * - struct autofs_point *ap = sp->ap; - LDAPControl *pageControl=NULL, *controls[2] = { NULL, NULL }; - LDAPControl **returnedControls = NULL; -- static unsigned long pageSize = 1000; -+ static ber_int_t pageSize = 1000; - static char pagingCriticality = 'T'; - int rv, scope = LDAP_SCOPE_SUBTREE; - diff --git a/autofs-5.0.3-library-reload-fix.patch b/autofs-5.0.3-library-reload-fix.patch deleted file mode 100644 index 01cc782..0000000 --- a/autofs-5.0.3-library-reload-fix.patch +++ /dev/null @@ -1,164 +0,0 @@ -autofs-5.0.3 - library reload fix - -From: Ian Kent - -During a map re-read autofs needs to re-open its lookup libraries but -dependent shared libraries can't handle being unloaded and then re-loaded -by the same process. This patch preventis dependent libraries from being -unloaded during this re-open. ---- - - daemon/automount.c | 1 - - daemon/lookup.c | 21 +++++++++------------ - daemon/state.c | 3 +++ - include/master.h | 17 +++-------------- - lib/master.c | 28 ++++++++++++++++++++++------ - 5 files changed, 37 insertions(+), 33 deletions(-) - - ---- autofs-5.0.3.orig/daemon/automount.c -+++ autofs-5.0.3/daemon/automount.c -@@ -85,7 +85,6 @@ int aquire_flag_file(void); - void release_flag_file(void); - static int umount_all(struct autofs_point *ap, int force); - --extern pthread_mutex_t master_mutex; - extern struct master *master_list; - - static int do_mkdir(const char *parent, const char *path, mode_t mode) ---- autofs-5.0.3.orig/daemon/lookup.c -+++ autofs-5.0.3/daemon/lookup.c -@@ -267,17 +267,17 @@ static int do_read_map(struct autofs_poi - struct lookup_mod *lookup; - int status; - -- if (!map->lookup) { -- lookup = open_lookup(map->type, "", -- map->format, map->argc, map->argv); -- if (!lookup) { -- debug(ap->logopt, "lookup module %s failed", map->type); -- return NSS_STATUS_UNAVAIL; -- } -- map->lookup = lookup; -+ lookup = open_lookup(map->type, "", map->format, map->argc, map->argv); -+ if (!lookup) { -+ debug(ap->logopt, "lookup module %s failed", map->type); -+ return NSS_STATUS_UNAVAIL; - } - -- lookup = map->lookup; -+ master_source_writelock(ap->entry); -+ if (map->lookup) -+ close_lookup(map->lookup); -+ map->lookup = lookup; -+ master_source_unlock(ap->entry); - - /* If we don't need to create directories then there's no use - * reading the map. We just need to test that the map is valid -@@ -463,8 +463,6 @@ int lookup_nss_read_map(struct autofs_po - * point in the master map) do the nss lookup to - * locate the map and read it. - */ -- pthread_cleanup_push(master_source_lock_cleanup, entry); -- master_source_readlock(entry); - if (source) - map = source; - else -@@ -557,7 +555,6 @@ int lookup_nss_read_map(struct autofs_po - - map = map->next; - } -- pthread_cleanup_pop(1); - - if (!result || at_least_one) - return 1; ---- autofs-5.0.3.orig/daemon/state.c -+++ autofs-5.0.3/daemon/state.c -@@ -387,9 +387,12 @@ static void *do_readmap(void *arg) - - info(ap->logopt, "re-reading map for %s", ap->path); - -+ pthread_cleanup_push(master_mutex_lock_cleanup, NULL); -+ master_mutex_lock(); - status = lookup_nss_read_map(ap, NULL, now); - if (!status) - pthread_exit(NULL); -+ pthread_cleanup_pop(1); - - if (ap->type == LKP_INDIRECT) { - lookup_prune_cache(ap, now); ---- autofs-5.0.3.orig/include/master.h -+++ autofs-5.0.3/include/master.h -@@ -70,6 +70,9 @@ int master_parse_entry(const char *, uns - - /* From master.c master parser utility routines */ - -+void master_mutex_lock(void); -+void master_mutex_unlock(void); -+void master_mutex_lock_cleanup(void *); - void master_set_default_timeout(void); - void master_set_default_ghost_mode(void); - int master_add_autofs_point(struct master_mapent *, time_t, unsigned, unsigned, int); -@@ -108,18 +111,4 @@ extern inline unsigned int master_get_lo - int master_list_empty(struct master *); - int master_kill(struct master *); - --#define master_mutex_lock() \ --do { \ -- int status = pthread_mutex_lock(&master_mutex); \ -- if (status) \ -- fatal(status); \ --} while (0) -- --#define master_mutex_unlock() \ --do { \ -- int status = pthread_mutex_unlock(&master_mutex); \ -- if (status) \ -- fatal(status); \ --} while (0) -- - #endif ---- autofs-5.0.3.orig/lib/master.c -+++ autofs-5.0.3/lib/master.c -@@ -41,8 +41,28 @@ static struct map_source * - __master_find_map_source(struct master_mapent *, - const char *, const char *, int, const char **); - --pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER; --pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; -+static pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER; -+static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; -+ -+void master_mutex_lock(void) -+{ -+ int status = pthread_mutex_lock(&master_mutex); -+ if (status) -+ fatal(status); -+} -+ -+void master_mutex_unlock(void) -+{ -+ int status = pthread_mutex_unlock(&master_mutex); -+ if (status) -+ fatal(status); -+} -+ -+void master_mutex_lock_cleanup(void *arg) -+{ -+ master_mutex_unlock(); -+ return; -+} - - int master_add_autofs_point(struct master_mapent *entry, - time_t timeout, unsigned logopt, unsigned ghost, int submount) -@@ -1109,10 +1129,6 @@ int master_mount_mounts(struct master *m - continue; - } - -- master_source_writelock(ap->entry); -- lookup_close_lookup(ap); -- master_source_unlock(ap->entry); -- - cache_readlock(nc); - ne = cache_lookup_distinct(nc, this->path); - if (ne && this->age > ne->age) { diff --git a/autofs-5.0.3-lookup-next-soucre-stale-entry.patch b/autofs-5.0.3-lookup-next-soucre-stale-entry.patch deleted file mode 100644 index f63ebf9..0000000 --- a/autofs-5.0.3-lookup-next-soucre-stale-entry.patch +++ /dev/null @@ -1,131 +0,0 @@ -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-make-handle_mounts-startup-cond-distinct.patch b/autofs-5.0.3-make-handle_mounts-startup-cond-distinct.patch deleted file mode 100644 index 5277ade..0000000 --- a/autofs-5.0.3-make-handle_mounts-startup-cond-distinct.patch +++ /dev/null @@ -1,309 +0,0 @@ -autofs-5.0.3 - make handle_mounts startup condition distinct - -From: Ian Kent - -When starting a number of mounts we can get contention for the startup -condition used to synchronize the handle_mounts thread completion. This -patch makes the condition used distinct for each thread creation. ---- - - CHANGELOG | 1 + - daemon/automount.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---- - include/automount.h | 4 +++ - lib/master.c | 29 +++++++++++----------- - modules/mount_autofs.c | 35 +++++++++++++-------------- - 5 files changed, 93 insertions(+), 38 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index 3921552..9da7be3 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -25,6 +25,7 @@ - - fix couple of memory leaks. - - add command line option to override check for daemon already running. - - don't use proc file system when checking if the daemon is running. -+- make handle_mounts startup condition distinct. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/daemon/automount.c b/daemon/automount.c -index dbf267c..086affb 100644 ---- a/daemon/automount.c -+++ b/daemon/automount.c -@@ -1461,6 +1461,55 @@ static void mutex_operation_wait(pthread_mutex_t *mutex) - return; - } - -+int handle_mounts_startup_cond_init(struct startup_cond *suc) -+{ -+ int status; -+ -+ status = pthread_mutex_init(&suc->mutex, NULL); -+ if (status) -+ return status; -+ -+ status = pthread_cond_init(&suc->cond, NULL); -+ if (status) { -+ status = pthread_mutex_destroy(&suc->mutex); -+ if (status) -+ fatal(status); -+ return status; -+ } -+ -+ status = pthread_mutex_lock(&suc->mutex); -+ if (status) { -+ status = pthread_mutex_destroy(&suc->mutex); -+ if (status) -+ fatal(status); -+ status = pthread_cond_destroy(&suc->cond); -+ if (status) -+ fatal(status); -+ } -+ -+ return 0; -+} -+ -+void handle_mounts_startup_cond_destroy(void *arg) -+{ -+ struct startup_cond *suc = (struct startup_cond *) arg; -+ int status; -+ -+ status = pthread_mutex_unlock(&suc->mutex); -+ if (status) -+ fatal(status); -+ -+ status = pthread_mutex_destroy(&suc->mutex); -+ if (status) -+ fatal(status); -+ -+ status = pthread_cond_destroy(&suc->cond); -+ if (status) -+ fatal(status); -+ -+ return; -+} -+ - static void handle_mounts_cleanup(void *arg) - { - struct autofs_point *ap; -@@ -1512,17 +1561,20 @@ static void handle_mounts_cleanup(void *arg) - - void *handle_mounts(void *arg) - { -+ struct startup_cond *suc; - struct autofs_point *ap; - int cancel_state, status = 0; - -- ap = (struct autofs_point *) arg; -+ suc = (struct startup_cond *) arg; -+ -+ ap = suc->ap; - -- pthread_cleanup_push(return_start_status, &suc); -+ pthread_cleanup_push(return_start_status, suc); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); - - state_mutex_lock(ap); - -- status = pthread_mutex_lock(&suc.mutex); -+ status = pthread_mutex_lock(&suc->mutex); - if (status) { - logerr("failed to lock startup condition mutex!"); - fatal(status); -@@ -1530,7 +1582,7 @@ void *handle_mounts(void *arg) - - if (mount_autofs(ap) < 0) { - crit(ap->logopt, "mount of %s failed!", ap->path); -- suc.status = 1; -+ suc->status = 1; - state_mutex_unlock(ap); - umount_autofs(ap, 1); - pthread_setcancelstate(cancel_state, NULL); -@@ -1540,7 +1592,7 @@ void *handle_mounts(void *arg) - if (ap->ghost && ap->type != LKP_DIRECT) - info(ap->logopt, "ghosting enabled"); - -- suc.status = 0; -+ suc->status = 0; - pthread_cleanup_pop(1); - - /* We often start several automounters at the same time. Add some -diff --git a/include/automount.h b/include/automount.h -index da1bf8f..1a20cd9 100644 ---- a/include/automount.h -+++ b/include/automount.h -@@ -331,10 +331,14 @@ int ncat_path(char *buf, size_t len, - struct startup_cond { - pthread_mutex_t mutex; - pthread_cond_t cond; -+ struct autofs_point *ap; - unsigned int done; - unsigned int status; - }; - -+int handle_mounts_startup_cond_init(struct startup_cond *suc); -+void handle_mounts_startup_cond_destroy(void *arg); -+ - struct master_readmap_cond { - pthread_mutex_t mutex; - pthread_cond_t cond; -diff --git a/lib/master.c b/lib/master.c -index 4a34dd4..edd3bdc 100644 ---- a/lib/master.c -+++ b/lib/master.c -@@ -997,28 +997,31 @@ next: - - static int master_do_mount(struct master_mapent *entry) - { -+ struct startup_cond suc; - struct autofs_point *ap; - pthread_t thid; - int status; - -- status = pthread_mutex_lock(&suc.mutex); -- if (status) -- fatal(status); -+ ap = entry->ap; -+ -+ if (handle_mounts_startup_cond_init(&suc)) { -+ crit(ap->logopt, -+ "failed to init startup cond for mount %s", entry->path); -+ return 0; -+ } - -+ suc.ap = ap; - suc.done = 0; - suc.status = 0; - -- ap = entry->ap; -- - debug(ap->logopt, "mounting %s", entry->path); - -- if (pthread_create(&thid, &thread_attr, handle_mounts, ap)) { -+ status = pthread_create(&thid, &thread_attr, handle_mounts, &suc); -+ if (status) { - crit(ap->logopt, - "failed to create mount handler thread for %s", - entry->path); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - return 0; - } - entry->thid = thid; -@@ -1031,15 +1034,11 @@ static int master_do_mount(struct master_mapent *entry) - - if (suc.status) { - error(ap->logopt, "failed to startup mount"); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - return 0; - } - -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ handle_mounts_startup_cond_destroy(&suc); - - return 1; - } -diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c -index 356fb14..6f66564 100644 ---- a/modules/mount_autofs.c -+++ b/modules/mount_autofs.c -@@ -46,6 +46,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - int name_len, const char *what, const char *fstype, - const char *c_options, void *context) - { -+ struct startup_cond suc; - pthread_t thid; - char *fullpath; - const char **argv; -@@ -210,34 +211,34 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - source->mc = cache_init(entry->ap, source); - if (!source->mc) { - error(ap->logopt, MODPREFIX "failed to init source cache"); -+ master_free_map_source(source, 0); - master_free_mapent(entry); - return 1; - } - - mounts_mutex_lock(ap); - -- status = pthread_mutex_lock(&suc.mutex); -- if (status) { -- crit(ap->logopt, -- MODPREFIX "failed to lock startup condition mutex!"); -- cache_release(source); -+ if (handle_mounts_startup_cond_init(&suc)) { -+ crit(ap->logopt, MODPREFIX -+ "failed to init startup cond for mount %s", entry->path); -+ mounts_mutex_unlock(ap); -+ master_free_map_source(source, 1); - master_free_mapent(entry); - return 1; - } - -+ suc.ap = nap; - suc.done = 0; - suc.status = 0; - -- if (pthread_create(&thid, NULL, handle_mounts, nap)) { -+ if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) { - crit(ap->logopt, - MODPREFIX - "failed to create mount handler thread for %s", - fullpath); -+ handle_mounts_startup_cond_destroy(&suc); - mounts_mutex_unlock(ap); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -- cache_release(source); -+ master_free_map_source(source, 1); - master_free_mapent(entry); - return 1; - } -@@ -246,8 +247,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - while (!suc.done) { - status = pthread_cond_wait(&suc.cond, &suc.mutex); - if (status) { -+ handle_mounts_startup_cond_destroy(&suc); - mounts_mutex_unlock(ap); -- pthread_mutex_unlock(&suc.mutex); -+ master_free_map_source(source, 1); -+ master_free_mapent(entry); - fatal(status); - } - } -@@ -255,10 +258,9 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - if (suc.status) { - crit(ap->logopt, - MODPREFIX "failed to create submount for %s", fullpath); -+ handle_mounts_startup_cond_destroy(&suc); - mounts_mutex_unlock(ap); -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -+ master_free_map_source(source, 1); - master_free_mapent(entry); - return 1; - } -@@ -266,12 +268,9 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - ap->submnt_count++; - list_add(&nap->mounts, &ap->submounts); - -+ handle_mounts_startup_cond_destroy(&suc); - mounts_mutex_unlock(ap); - -- status = pthread_mutex_unlock(&suc.mutex); -- if (status) -- fatal(status); -- - return 0; - } - diff --git a/autofs-5.0.3-map-type-in-map-name-fix.patch b/autofs-5.0.3-map-type-in-map-name-fix.patch deleted file mode 100644 index bb5fae2..0000000 --- a/autofs-5.0.3-map-type-in-map-name-fix.patch +++ /dev/null @@ -1,27 +0,0 @@ -autofs-5.0.3 - map type in map name fix - -From: Ian Kent - -Fix incorrect match of map type as a host name. -Actually the original patch didn't match upstream or RHEL -so this syncs the source with those. It appears the problem -was fixed here some time ago but slightly differently. ---- - - lib/master_tok.l | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - - ---- autofs-5.0.3.orig/lib/master_tok.l -+++ autofs-5.0.3/lib/master_tok.l -@@ -202,7 +202,9 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|-- - } - } - -- {MTYPE}/({DNSERVERSTR}|{DNATTRSTR}=)? { -+ {MTYPE} | -+ {MTYPE}/{DNSERVERSTR}{DNATTRSTR} | -+ {MTYPE}/{DNATTRSTR}= { - tlen = master_leng - 1; - if (bptr != buff && isblank(master_text[tlen])) { - strncat(buff, master_text, tlen); diff --git a/autofs-5.0.3-map-type-in-map-name.patch b/autofs-5.0.3-map-type-in-map-name.patch deleted file mode 100644 index 591448b..0000000 --- a/autofs-5.0.3-map-type-in-map-name.patch +++ /dev/null @@ -1,65 +0,0 @@ -diff -up autofs-5.0.3/lib/master_tok.l.map-type-in-map-name autofs-5.0.3/lib/master_tok.l ---- autofs-5.0.3/lib/master_tok.l.map-type-in-map-name 2008-04-01 11:14:00.000000000 +0800 -+++ autofs-5.0.3/lib/master_tok.l 2008-04-01 11:14:00.000000000 +0800 -@@ -77,6 +77,7 @@ int my_yyinput(char *, int); - char buff[1024]; - char *bptr; - char *optr = buff; -+unsigned int tlen; - - %} - -@@ -190,13 +191,27 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|-- - {OPTWS}\\\n{OPTWS} {} - - {MULTI} { -- strcpy(master_lval.strtype, master_text); -- return(MULTITYPE); -+ tlen = master_leng - 1; -+ if (bptr != buff && isblank(master_text[tlen])) { -+ strncat(buff, master_text, tlen); -+ bptr += tlen; -+ yyless(tlen); -+ } else { -+ strcpy(master_lval.strtype, master_text); -+ return(MULTITYPE); -+ } - } - -- {MTYPE} { -- strcpy(master_lval.strtype, master_text); -- return(MAPTYPE); -+ {MTYPE}/({DNSERVERSTR}|{DNATTRSTR}=)? { -+ tlen = master_leng - 1; -+ if (bptr != buff && isblank(master_text[tlen])) { -+ strncat(buff, master_text, tlen); -+ bptr += tlen; -+ yyless(tlen); -+ } else { -+ strcpy(master_lval.strtype, master_text); -+ return(MAPTYPE); -+ } - } - - {MULTISEP} { return(DDASH); } -@@ -226,7 +241,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|-- - yyless(0); - } - -- {DNSERVERSTR} { -+ {DNSERVERSTR}{DNATTRSTR} { - BEGIN(DNSTR); - yyless(0); - } -diff -up autofs-5.0.3/lib/master_parse.y.map-type-in-map-name autofs-5.0.3/lib/master_parse.y -diff -up autofs-5.0.3/CHANGELOG.map-type-in-map-name autofs-5.0.3/CHANGELOG ---- autofs-5.0.3/CHANGELOG.map-type-in-map-name 2008-04-01 11:14:00.000000000 +0800 -+++ autofs-5.0.3/CHANGELOG 2008-04-01 11:14:00.000000000 +0800 -@@ -10,6 +10,7 @@ - - fix unlink of mount tree incorrectly causing autofs mount fail. - - add missing check for zero length NIS key (Wengang Wang). - - init SASL callbacks on every ldap lookup library load. -+- fix incorrect match of map type name when included in map name. - - 14/01/2008 autofs-5.0.3 - ----------------------- 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 deleted file mode 100644 index 016ec50..0000000 --- a/autofs-5.0.3-mount-thread-create-cond-handling-fix.patch +++ /dev/null @@ -1,223 +0,0 @@ -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-mount-thread-create-cond-handling.patch b/autofs-5.0.3-mount-thread-create-cond-handling.patch deleted file mode 100644 index fa73b56..0000000 --- a/autofs-5.0.3-mount-thread-create-cond-handling.patch +++ /dev/null @@ -1,308 +0,0 @@ ---- autofs-5.0.3.orig/daemon/indirect.c -+++ autofs-5.0.3/daemon/indirect.c -@@ -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; - } ---- autofs-5.0.3.orig/daemon/direct.c -+++ autofs-5.0.3/daemon/direct.c -@@ -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, strlen(mt.name)); - /* - * 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; - } ---- autofs-5.0.3.orig/CHANGELOG -+++ autofs-5.0.3/CHANGELOG -@@ -11,6 +11,7 @@ - - add missing check for zero length NIS key (Wengang Wang). - - init SASL callbacks on every ldap lookup library load. - - fix incorrect match of map type name when included in map name. -+- fix incorrect pthreads condition handling for mount requests. - - 14/01/2008 autofs-5.0.3 - ----------------------- diff --git a/autofs-5.0.3-mtab-as-proc-mounts-fix.patch b/autofs-5.0.3-mtab-as-proc-mounts-fix.patch deleted file mode 100644 index dc01908..0000000 --- a/autofs-5.0.3-mtab-as-proc-mounts-fix.patch +++ /dev/null @@ -1,25 +0,0 @@ -autofs-5.0.3 - check for mtab pointing to /proc/mounts fix - -From: Ian Kent - -Fix incorrect initialization in spawn_bind_mount() which -caused bind mounts to not be added to mtab. ---- - - daemon/spawn.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - - -diff --git a/daemon/spawn.c b/daemon/spawn.c -index 85cf9b8..17f92f4 100644 ---- a/daemon/spawn.c -+++ b/daemon/spawn.c -@@ -432,7 +432,7 @@ int spawn_bind_mount(unsigned logopt, ...) - char arg_fake[] = "-f"; - unsigned int options; - unsigned int retries = MTAB_LOCK_RETRIES; -- int update_mtab = 0, ret, printed = 0; -+ int update_mtab = 1, ret, printed = 0; - char buf[PATH_MAX]; - - /* If we use mount locking we can't validate the location */ diff --git a/autofs-5.0.3-mtab-as-proc-mounts.patch b/autofs-5.0.3-mtab-as-proc-mounts.patch deleted file mode 100644 index 8a657ab..0000000 --- a/autofs-5.0.3-mtab-as-proc-mounts.patch +++ /dev/null @@ -1,170 +0,0 @@ -autofs-5.0.3 - check for mtab pointing to /proc/mounts - -From: Ian Kent - -autofs has problems if /etc/mtab points to /proc/mounts. -This patchs adds a check to see if this is the case. If it is then -autofs uses the mount(8) "-n" option which disables the normal mtab -update error checking. ---- - - CHANGELOG | 1 + - daemon/spawn.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 61 insertions(+), 6 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index 50c9a27..d2fe0a6 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -33,6 +33,7 @@ - - add replicated server selection debug logging. - - update replicated server selection documentation. - - use /dev/urandom instead of /dev/random. -+- check for mtab pointing to /proc/mounts. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/daemon/spawn.c b/daemon/spawn.c -index 6b26c41..85cf9b8 100644 ---- a/daemon/spawn.c -+++ b/daemon/spawn.c -@@ -305,11 +305,13 @@ int spawn_mount(unsigned logopt, ...) - char **argv, **p; - char prog[] = PATH_MOUNT; - char arg0[] = PATH_MOUNT; -+ char argn[] = "-n"; - /* In case we need to use the fake option to mount */ - char arg_fake[] = "-f"; - unsigned int options; - unsigned int retries = MTAB_LOCK_RETRIES; -- int ret, printed = 0; -+ int update_mtab = 1, ret, printed = 0; -+ char buf[PATH_MAX]; - - /* If we use mount locking we can't validate the location */ - #ifdef ENABLE_MOUNT_LOCKING -@@ -322,6 +324,17 @@ int spawn_mount(unsigned logopt, ...) - for (argc = 1; va_arg(arg, char *); argc++); - va_end(arg); - -+ ret = readlink(_PATH_MOUNTED, buf, PATH_MAX); -+ if (ret != -1) { -+ buf[ret] = '\0'; -+ if (!strcmp(buf, _PROC_MOUNTS)) { -+ debug(logopt, -+ "mtab link detected, passing -n to mount"); -+ argc++; -+ update_mtab = 0; -+ } -+ } -+ - /* Alloc 1 extra slot in case we need to use the "-f" option */ - if (!(argv = alloca(sizeof(char *) * argc + 2))) - return -1; -@@ -329,7 +342,12 @@ int spawn_mount(unsigned logopt, ...) - argv[0] = arg0; - - va_start(arg, logopt); -- p = argv + 1; -+ if (update_mtab) -+ p = argv + 1; -+ else { -+ argv[1] = argn; -+ p = argv + 2; -+ } - while ((*p = va_arg(arg, char *))) { - if (options == SPAWN_OPT_NONE && !strcmp(*p, "-o")) { - *(++p) = va_arg(arg, char *); -@@ -409,11 +427,13 @@ int spawn_bind_mount(unsigned logopt, ...) - char prog[] = PATH_MOUNT; - char arg0[] = PATH_MOUNT; - char bind[] = "--bind"; -+ char argn[] = "-n"; - /* In case we need to use the fake option to mount */ - char arg_fake[] = "-f"; - unsigned int options; - unsigned int retries = MTAB_LOCK_RETRIES; -- int ret, printed = 0; -+ int update_mtab = 0, ret, printed = 0; -+ char buf[PATH_MAX]; - - /* If we use mount locking we can't validate the location */ - #ifdef ENABLE_MOUNT_LOCKING -@@ -430,6 +450,17 @@ int spawn_bind_mount(unsigned logopt, ...) - for (argc = 2; va_arg(arg, char *); argc++); - va_end(arg); - -+ ret = readlink(_PATH_MOUNTED, buf, PATH_MAX); -+ if (ret != -1) { -+ buf[ret] = '\0'; -+ if (!strcmp(buf, _PROC_MOUNTS)) { -+ debug(logopt, -+ "mtab link detected, passing -n to mount"); -+ argc++; -+ update_mtab = 0; -+ } -+ } -+ - if (!(argv = alloca(sizeof(char *) * argc + 2))) - return -1; - -@@ -437,7 +468,12 @@ int spawn_bind_mount(unsigned logopt, ...) - argv[1] = bind; - - va_start(arg, logopt); -- p = argv + 2; -+ if (update_mtab) -+ p = argv + 2; -+ else { -+ argv[2] = argn; -+ p = argv + 3; -+ } - while ((*p++ = va_arg(arg, char *))); - va_end(arg); - -@@ -499,10 +535,12 @@ int spawn_umount(unsigned logopt, ...) - char **argv, **p; - char prog[] = PATH_UMOUNT; - char arg0[] = PATH_UMOUNT; -+ char argn[] = "-n"; - unsigned int options; - unsigned int retries = MTAB_LOCK_RETRIES; -- int ret, printed = 0; -+ int update_mtab = 1, ret, printed = 0; - unsigned int wait = defaults_get_umount_wait(); -+ char buf[PATH_MAX]; - - #ifdef ENABLE_MOUNT_LOCKING - options = SPAWN_OPT_LOCK; -@@ -514,13 +552,29 @@ int spawn_umount(unsigned logopt, ...) - for (argc = 1; va_arg(arg, char *); argc++); - va_end(arg); - -+ ret = readlink(_PATH_MOUNTED, buf, PATH_MAX); -+ if (ret != -1) { -+ buf[ret] = '\0'; -+ if (!strcmp(buf, _PROC_MOUNTS)) { -+ debug(logopt, -+ "mtab link detected, passing -n to mount"); -+ argc++; -+ update_mtab = 0; -+ } -+ } -+ - if (!(argv = alloca(sizeof(char *) * argc + 1))) - return -1; - - argv[0] = arg0; - - va_start(arg, logopt); -- p = argv + 1; -+ if (update_mtab) -+ p = argv + 1; -+ else { -+ argv[1] = argn; -+ p = argv + 2; -+ } - while ((*p++ = va_arg(arg, char *))); - va_end(arg); - diff --git a/autofs-5.0.3-nfs4-tcp-only.patch b/autofs-5.0.3-nfs4-tcp-only.patch deleted file mode 100644 index 370d77e..0000000 --- a/autofs-5.0.3-nfs4-tcp-only.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/CHANGELOG b/CHANGELOG -index b172579..5a85a8e 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -3,6 +3,7 @@ - - correct configure test for ldapr page control functions. - - catch "-xfn" map type and issue "no supported" message. - - correction for handling of LDAP base dns with spaces. -+- avoid using UDP for probing NFSv4 mount requests. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c -index 0e7aebe..df01fd6 100644 ---- a/modules/mount_nfs.c -+++ b/modules/mount_nfs.c -@@ -129,7 +129,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int - } - - if (strcmp(fstype, "nfs4") == 0) -- vers = NFS4_VERS_MASK | NFS_PROTO_MASK; -+ vers = NFS4_VERS_MASK | TCP_SUPPORTED; - else - vers = NFS_VERS_MASK | NFS_PROTO_MASK; - diff --git a/autofs-5.0.3-nisplus-partial-and-free.patch b/autofs-5.0.3-nisplus-partial-and-free.patch deleted file mode 100644 index 9333873..0000000 --- a/autofs-5.0.3-nisplus-partial-and-free.patch +++ /dev/null @@ -1,54 +0,0 @@ -autofs-5.0.3 - nisplus partial and free - -From: Jeff Bastian - -During a nisplus key lookup nis_list() can return NIS_PARTIAL -as well as possibly NIS_NOTFOUND or NIS_S_NOTFOUND when the key -doesn't exist. This patch adds this to the checks and fixes a use -after free of the result struct. ---- - - modules/lookup_nisplus.c | 16 ++++++++++------ - 1 file changed, 10 insertions(+), 6 deletions(-) - - ---- autofs-5.0.3.orig/modules/lookup_nisplus.c -+++ autofs-5.0.3/modules/lookup_nisplus.c -@@ -285,13 +285,15 @@ static int lookup_one(struct autofs_poin - - result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) { -+ nis_error rs = result->status; - nis_freeresult(result); - pthread_setcancelstate(cur_state, NULL); -- if (result->status == NIS_NOTFOUND || -- result->status == NIS_S_NOTFOUND) -+ if (rs == NIS_NOTFOUND || -+ rs == NIS_S_NOTFOUND || -+ rs == NIS_PARTIAL) - return CHE_MISSING; - -- return -result->status; -+ return -rs; - } - - -@@ -338,13 +340,15 @@ static int lookup_wild(struct autofs_poi - - result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) { -+ nis_error rs = result->status; - nis_freeresult(result); - pthread_setcancelstate(cur_state, NULL); -- if (result->status == NIS_NOTFOUND || -- result->status == NIS_S_NOTFOUND) -+ if (rs == NIS_NOTFOUND || -+ rs == NIS_S_NOTFOUND || -+ rs == NIS_PARTIAL) - return CHE_MISSING; - -- return -result->status; -+ return -rs; - } - - this = NIS_RES_OBJECT(result); diff --git a/autofs-5.0.3-nss-source-any.patch b/autofs-5.0.3-nss-source-any.patch deleted file mode 100644 index 157e283..0000000 --- a/autofs-5.0.3-nss-source-any.patch +++ /dev/null @@ -1,158 +0,0 @@ -autofs-5.0.3 - ignore nsswitch sources that aren't supported - -From: Ian Kent - -Allow any source name in nsswitch and ignore those we don't support. -This has the side affect of also ignoring any action associated with -a source that isn't supported by autofs. ---- - - CHANGELOG | 1 + - lib/nss_parse.y | 31 ++++++++++++++++--------------- - lib/nss_tok.l | 22 ++++++++++++---------- - 3 files changed, 29 insertions(+), 25 deletions(-) - - ---- autofs-5.0.3.orig/CHANGELOG -+++ autofs-5.0.3/CHANGELOG -@@ -13,6 +13,7 @@ - - fix incorrect match of map type name when included in map name. - - 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. - - 14/01/2008 autofs-5.0.3 - ----------------------- ---- autofs-5.0.3.orig/lib/nss_parse.y -+++ autofs-5.0.3/lib/nss_parse.y -@@ -64,7 +64,6 @@ char strval[128]; - %token SOURCE - %token STATUS - %token ACTION --%token OTHER - - %start file - -@@ -83,7 +82,9 @@ sources: nss_source - - nss_source: SOURCE - { -- if (strcmp($1, "winbind")) -+ if (!strcmp($1, "files") || !strcmp($1, "yp") || -+ !strcmp($1, "nis") || !strcmp($1, "ldap") || -+ !strcmp($1, "nisplus") || !strcmp($1, "hesiod")) - src = add_source(nss_list, $1); - else - nss_ignore($1); -@@ -91,7 +92,9 @@ nss_source: SOURCE - { - enum nsswitch_status a; - -- if (strcmp($1, "winbind")) { -+ if (!strcmp($1, "files") || !strcmp($1, "yp") || -+ !strcmp($1, "nis") || !strcmp($1, "ldap") || -+ !strcmp($1, "nisplus") || !strcmp($1, "hesiod")) { - src = add_source(nss_list, $1); - for (a = 0; a < NSS_STATUS_MAX; a++) { - if (act[a].action != NSS_ACTION_UNKNOWN) { -@@ -101,12 +104,10 @@ nss_source: SOURCE - } - } else - nss_ignore($1); --} | SOURCE LBRACKET status_exp_list SOURCE { nss_error($4); YYABORT; } -- | SOURCE LBRACKET status_exp_list OTHER { nss_error($4); YYABORT; } -- | SOURCE LBRACKET status_exp_list NL { nss_error("no closing bracket"); YYABORT; } -- | SOURCE LBRACKET OTHER { nss_error($3); YYABORT; } -- | SOURCE OTHER { nss_error("no opening bracket"); YYABORT; } -- | error OTHER { nss_error($2); YYABORT; }; -+} | SOURCE LBRACKET status_exp_list SOURCE { nss_error("missing close bracket"); YYABORT; } -+ | SOURCE LBRACKET status_exp_list NL { nss_error("missing close bracket"); YYABORT; } -+ | SOURCE LBRACKET SOURCE { nss_error($3); YYABORT; } -+ | error SOURCE { nss_error($2); YYABORT; }; - - status_exp_list: status_exp - | status_exp status_exp_list -@@ -117,17 +118,17 @@ status_exp: STATUS EQUAL ACTION - } | BANG STATUS EQUAL ACTION - { - set_action(act, $2, $4, 1); --} | STATUS EQUAL OTHER {nss_error($3); YYABORT; } -- | STATUS OTHER {nss_error($2); YYABORT; } -- | BANG STATUS EQUAL OTHER {nss_error($4); YYABORT; } -- | BANG STATUS OTHER {nss_error($3); YYABORT; } -- | BANG OTHER {nss_error($2); YYABORT; }; -+} | STATUS EQUAL SOURCE {nss_error($3); YYABORT; } -+ | STATUS SOURCE {nss_error($2); YYABORT; } -+ | BANG STATUS EQUAL SOURCE {nss_error($4); YYABORT; } -+ | BANG STATUS SOURCE {nss_error($3); YYABORT; } -+ | BANG SOURCE {nss_error($2); YYABORT; }; - - %% - - static int nss_ignore(const char *s) - { -- logmsg("ignored invalid nsswitch config near [ %s ]", s); -+ logmsg("ignored unsupported autofs nsswitch source \"%s\"", s); - return(0); - } - ---- autofs-5.0.3.orig/lib/nss_tok.l -+++ autofs-5.0.3/lib/nss_tok.l -@@ -62,13 +62,13 @@ extern unsigned int nss_automount_found; - - %option nounput - --%x AUTOMOUNT -+%x AUTOMOUNT ACTIONSTR - - WS [[:blank:]]+ - - automount ([Aa][Uu][Tt][Oo][Mm][Oo][Uu][Nn][Tt]) - --source files|yp|nis|nisplus|ldap|hesiod|winbind -+source [[:alnum:]@$%^&*()-+_":;?,<>./'{}~`]+ - - success ([Ss][Uu][Cc][Cc][Ee][Ss][Ss]) - notfound ([Nn][Oo][Tt][Ff][Oo][Uu][Nn][Dd]) -@@ -82,8 +82,6 @@ return ([Rr][Ee][Tt][Uu][Rr][Nn]) - - action ({continue}|{return}) - --other [[:alnum:]@$%^&*()-+_":;?,<>./'{}~`]+ -- - %% - - ^{automount}: { -@@ -101,6 +99,14 @@ other [[:alnum:]@$%^&*()-+_":;?,<>./'{} - return SOURCE; - } - -+ "[" { BEGIN(ACTIONSTR); yyless(0); } -+ -+ \n { BEGIN(INITIAL); return NL; } -+} -+ -+{ -+ {WS} { } -+ - {status} { - strcpy(nss_lval.strval, nss_text); - return STATUS; -@@ -112,15 +118,11 @@ other [[:alnum:]@$%^&*()-+_":;?,<>./'{} - } - - "[" { return LBRACKET; } -- "]" { return RBRACKET; } -+ "]" { BEGIN(AUTOMOUNT); return RBRACKET; } - "=" { return EQUAL; } - "!" { return BANG; } - -- {other} { -- strcpy(nss_lval.strval, nss_text); -- return OTHER; -- } -- -+ . { BEGIN(AUTOMOUNT); yyless(0); } - \n { BEGIN(INITIAL); return NL; } - } - diff --git a/autofs-5.0.3-override-is-running-check.patch b/autofs-5.0.3-override-is-running-check.patch deleted file mode 100644 index 8d6f5e1..0000000 --- a/autofs-5.0.3-override-is-running-check.patch +++ /dev/null @@ -1,121 +0,0 @@ -autofs-5.0.3 - add command line option to override is running check - -From: Ian Kent - -autofs common usage is to have a single instance of the daemon running -and it checks for this and exits if another instance is found to be -running. But there are situations were people need to run multiple -instances and this patch adds a command line option to overrid the -check. Please note that this doesn't mean that autofs will function -properly and it is the users responsibility to check that the -configuration in use will function properly. ---- - - CHANGELOG | 1 + - daemon/automount.c | 14 +++++++++++--- - man/automount.8 | 10 ++++++++++ - 3 files changed, 22 insertions(+), 3 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index 5901c75..f40a941 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -23,6 +23,7 @@ - - fix direct mount path length not being checked. - - fix incorrect if check in get user info. - - fix couple of memory leaks. -+- add command line option to override check for daemon already running. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/daemon/automount.c b/daemon/automount.c -index 7ce9828..48ac30a 100644 ---- a/daemon/automount.c -+++ b/daemon/automount.c -@@ -1694,6 +1694,8 @@ static void usage(void) - " specify global mount options\n" - " -l --set-log-priority priority path [path,...]\n" - " set daemon log verbosity\n" -+ " -C --dont-check-daemon\n" -+ " don't check if daemon is already running\n" - " -V --version print version, build config and exit\n" - , program); - } -@@ -1814,7 +1816,7 @@ int main(int argc, char *argv[]) - { - int res, opt, status; - int logpri = -1; -- unsigned ghost, logging; -+ unsigned ghost, logging, daemon_check; - unsigned foreground, have_global_options; - time_t timeout; - time_t age = time(NULL); -@@ -1833,6 +1835,7 @@ int main(int argc, char *argv[]) - {"global-options", 1, 0, 'O'}, - {"version", 0, 0, 'V'}, - {"set-log-priority", 1, 0, 'l'}, -+ {"dont-check-daemon", 0, 0, 'C'}, - {0, 0, 0, 0} - }; - -@@ -1851,9 +1854,10 @@ int main(int argc, char *argv[]) - global_options = NULL; - have_global_options = 0; - foreground = 0; -+ daemon_check = 1; - - opterr = 0; -- while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:", long_options, NULL)) != EOF) { -+ while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:C", long_options, NULL)) != EOF) { - switch (opt) { - case 'h': - usage(); -@@ -1922,6 +1926,10 @@ int main(int argc, char *argv[]) - } - break; - -+ case 'C': -+ daemon_check = 0; -+ break; -+ - case '?': - case ':': - printf("%s: Ambiguous or unknown options\n", program); -@@ -1965,7 +1973,7 @@ int main(int argc, char *argv[]) - exit(exit_code); - } - -- if (is_automount_running() > 0) { -+ if (daemon_check && is_automount_running() > 0) { - fprintf(stderr, "%s: program is already running.\n", - program); - exit(1); -diff --git a/man/automount.8 b/man/automount.8 -index 59ad50e..d9285bf 100644 ---- a/man/automount.8 -+++ b/man/automount.8 -@@ -81,6 +81,9 @@ be disabled, returning the daemon to verbose logging. - .P - The \fIpath\fP argument corresponds to the automounted - path name as specified in the master map. -+.TP -+.I "\-C, \-\-dont-check-daemon" -+Don't check if the daemon is currently running (see NOTES). - .SH ARGUMENTS - \fBautomount\fP takes one optional argument, the name of the master map to - use. -@@ -122,6 +125,13 @@ until they are no longer in use by the processes that held them busy. - If automount managed filesystems are found mounted when autofs is - started they will be recoverd unless they are no longer present in - the map in which case they need to umounted manually. -+.P -+If the option to disable the check to see if the daemon is already -+running is used be aware that autofs currently may not function correctly -+for certain types of automount maps. The mounts of the seperate daemons -+might interfere with one another. The implications of running multiple -+daemon instances needs to be checked and tested before we can say this -+is supported. - .SH "SEE ALSO" - .BR autofs (5), - .BR autofs (8), diff --git a/autofs-5.0.3-refactor-mount-request-vars.patch b/autofs-5.0.3-refactor-mount-request-vars.patch deleted file mode 100644 index 6a7248d..0000000 --- a/autofs-5.0.3-refactor-mount-request-vars.patch +++ /dev/null @@ -1,1217 +0,0 @@ -autofs-5.0.3 - refactor mount request vars - -From: Ian Kent - -There is code duplication between the direct and indirect mount -modules that sets up the variables available to maps. This patch -reorganizes and moves that code to a common location. - -Signed-off-by: Ian Kent ---- - - daemon/direct.c | 131 ---------------- - daemon/indirect.c | 131 ---------------- - include/automount.h | 56 ------- - include/mounts.h | 91 +++++++++++ - include/parse_subs.h | 3 - lib/mounts.c | 410 ++++++++++++++++++++++++++++++++++++++++++++------ - lib/parse_subs.c | 230 ---------------------------- - 7 files changed, 458 insertions(+), 594 deletions(-) - create mode 100644 include/mounts.h - - -diff --git a/daemon/direct.c b/daemon/direct.c -index 072ef97..a3869a5 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -35,8 +35,6 @@ - #include - #include - #include --#include --#include - - #include "automount.h" - -@@ -1237,15 +1235,6 @@ static void *do_mount_direct(void *arg) - { - struct pending_args *args, mt; - struct autofs_point *ap; -- struct passwd pw; -- struct passwd *ppw = &pw; -- struct passwd **pppw = &ppw; -- struct group gr; -- struct group *pgr; -- struct group **ppgr; -- char *pw_tmp, *gr_tmp; -- struct thread_stdenv_vars *tsv; -- int tmplen, grplen; - struct stat st; - int status, state; - -@@ -1291,126 +1280,8 @@ static void *do_mount_direct(void *arg) - - info(ap->logopt, "attempting to mount entry %s", mt.name); - -- /* -- * Setup thread specific data values for macro -- * substution in map entries during the mount. -- * Best effort only as it must go ahead. -- */ -- -- tsv = malloc(sizeof(struct thread_stdenv_vars)); -- if (!tsv) -- goto cont; -- -- tsv->uid = mt.uid; -- tsv->gid = mt.gid; -- -- /* Try to get passwd info */ -- -- tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- pw_tmp = malloc(tmplen + 1); -- if (!pw_tmp) { -- error(ap->logopt, "failed to malloc buffer for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- 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); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->user = strdup(pw.pw_name); -- if (!tsv->user) { -- error(ap->logopt, "failed to malloc buffer for user"); -- free(tsv); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->home = strdup(pw.pw_dir); -- if (!tsv->home) { -- error(ap->logopt, "failed to malloc buffer for home"); -- free(pw_tmp); -- free(tsv->user); -- free(tsv); -- goto cont; -- } -- -- free(pw_tmp); -- -- /* Try to get group info */ -- -- grplen = sysconf(_SC_GETGR_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- -- gr_tmp = NULL; -- tmplen = grplen; -- while (1) { -- char *tmp = realloc(gr_tmp, tmplen + 1); -- if (!tmp) { -- error(ap->logopt, "failed to malloc buffer for getgrgid_r"); -- if (gr_tmp) -- free(gr_tmp); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- gr_tmp = tmp; -- pgr = &gr; -- ppgr = &pgr; -- status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr); -- if (status != ERANGE) -- break; -- tmplen += grplen; -- } -- -- if (status || !pgr) { -- error(ap->logopt, "failed to get group info from getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- tsv->group = strdup(gr.gr_name); -- if (!tsv->group) { -- error(ap->logopt, "failed to malloc buffer for group"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- free(gr_tmp); -- -- status = pthread_setspecific(key_thread_stdenv_vars, tsv); -- if (status) { -- error(ap->logopt, "failed to set stdenv thread var"); -- free(tsv->group); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- } -+ set_tsd_user_vars(ap->logopt, mt.uid, mt.gid); - --cont: - status = lookup_nss_mount(ap, NULL, mt.name, mt.len); - /* - * Direct mounts are always a single mount. If it fails there's -diff --git a/daemon/indirect.c b/daemon/indirect.c -index ccdd8bf..3922f3f 100644 ---- a/daemon/indirect.c -+++ b/daemon/indirect.c -@@ -33,8 +33,6 @@ - #include - #include - #include --#include --#include - - #include "automount.h" - -@@ -672,15 +670,7 @@ static void *do_mount_indirect(void *arg) - struct autofs_point *ap; - char buf[PATH_MAX + 1]; - struct stat st; -- struct passwd pw; -- struct passwd *ppw = &pw; -- struct passwd **pppw = &ppw; -- struct group gr; -- struct group *pgr; -- struct group **ppgr; -- char *pw_tmp, *gr_tmp; -- struct thread_stdenv_vars *tsv; -- int len, tmplen, grplen, status, state; -+ int len, status, state; - - args = (struct pending_args *) arg; - -@@ -722,125 +712,8 @@ static void *do_mount_indirect(void *arg) - - info(ap->logopt, "attempting to mount entry %s", buf); - -- /* -- * Setup thread specific data values for macro -- * substution in map entries during the mount. -- * Best effort only as it must go ahead. -- */ -- -- tsv = malloc(sizeof(struct thread_stdenv_vars)); -- if (!tsv) -- goto cont; -- -- tsv->uid = mt.uid; -- tsv->gid = mt.gid; -- -- /* Try to get passwd info */ -- -- tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- pw_tmp = malloc(tmplen + 1); -- if (!pw_tmp) { -- error(ap->logopt, "failed to malloc buffer for getpwuid_r"); -- free(tsv); -- goto cont; -- } -- -- 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); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->user = strdup(pw.pw_name); -- if (!tsv->user) { -- error(ap->logopt, "failed to malloc buffer for user"); -- free(tsv); -- free(pw_tmp); -- goto cont; -- } -- -- tsv->home = strdup(pw.pw_dir); -- if (!tsv->home) { -- error(ap->logopt, "failed to malloc buffer for home"); -- free(pw_tmp); -- free(tsv->user); -- free(tsv); -- goto cont; -- } -+ set_tsd_user_vars(ap->logopt, mt.uid, mt.gid); - -- free(pw_tmp); -- -- /* Try to get group info */ -- -- grplen = sysconf(_SC_GETGR_R_SIZE_MAX); -- if (tmplen < 0) { -- error(ap->logopt, "failed to get buffer size for getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- -- gr_tmp = NULL; -- tmplen = grplen; -- while (1) { -- char *tmp = realloc(gr_tmp, tmplen + 1); -- if (!tmp) { -- error(ap->logopt, "failed to malloc buffer for getgrgid_r"); -- if (gr_tmp) -- free(gr_tmp); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- goto cont; -- } -- gr_tmp = tmp; -- pgr = &gr; -- ppgr = &pgr; -- status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr); -- if (status != ERANGE) -- break; -- tmplen += grplen; -- } -- -- if (status || !pgr) { -- error(ap->logopt, "failed to get group info from getgrgid_r"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- tsv->group = strdup(gr.gr_name); -- if (!tsv->group) { -- error(ap->logopt, "failed to malloc buffer for group"); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- free(gr_tmp); -- goto cont; -- } -- -- free(gr_tmp); -- -- status = pthread_setspecific(key_thread_stdenv_vars, tsv); -- if (status) { -- error(ap->logopt, "failed to set stdenv thread var"); -- free(tsv->group); -- free(tsv->user); -- free(tsv->home); -- free(tsv); -- } --cont: - status = lookup_nss_mount(ap, NULL, mt.name, mt.len); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); - if (status) { -diff --git a/include/automount.h b/include/automount.h -index 72e2457..da1bf8f 100644 ---- a/include/automount.h -+++ b/include/automount.h -@@ -28,6 +28,7 @@ - #include "macros.h" - #include "log.h" - #include "rpc_subs.h" -+#include "mounts.h" - #include "parse_subs.h" - - #ifdef WITH_DMALLOC -@@ -323,61 +324,6 @@ int cat_path(char *buf, size_t len, const char *dir, const char *base); - int ncat_path(char *buf, size_t len, - const char *dir, const char *base, size_t blen); - --/* mount table utilities */ -- --#define MNTS_ALL 0x0001 --#define MNTS_REAL 0x0002 --#define MNTS_AUTOFS 0x0004 -- --struct mnt_list { -- char *path; -- char *fs_name; -- char *fs_type; -- char *opts; -- pid_t owner; -- /* -- * List operations ie. get_mnt_list. -- */ -- struct mnt_list *next; -- /* -- * Tree operations ie. tree_make_tree, -- * tree_get_mnt_list etc. -- */ -- struct mnt_list *left; -- struct mnt_list *right; -- struct list_head self; -- struct list_head list; -- struct list_head entries; -- struct list_head sublist; -- /* -- * Offset mount handling ie. add_ordered_list -- * and get_offset. -- */ -- struct list_head ordered; --}; -- --unsigned int query_kproto_ver(void); --unsigned int get_kver_major(void); --unsigned int get_kver_minor(void); --char *make_options_string(char *path, int kernel_pipefd, char *extra); --char *make_mnt_name_string(char *path); --struct mnt_list *get_mnt_list(const char *table, const char *path, int include); --struct mnt_list *reverse_mnt_list(struct mnt_list *list); --void free_mnt_list(struct mnt_list *list); --int contained_in_local_fs(const char *path); --int is_mounted(const char *table, const char *path, unsigned int type); --int has_fstab_option(const char *opt); --char *find_mnt_ino(const char *table, dev_t dev, ino_t ino); --char *get_offset(const char *prefix, char *offset, -- struct list_head *head, struct list_head **pos); --void add_ordered_list(struct mnt_list *ent, struct list_head *head); --void tree_free_mnt_tree(struct mnt_list *tree); --struct mnt_list *tree_make_mnt_tree(const char *table, const char *path); --int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include); --int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include); --int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path); --int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type); -- - /* Core automount definitions */ - - #define MNT_DETACH 0x00000002 /* Just detach from the tree */ -diff --git a/include/mounts.h b/include/mounts.h -new file mode 100644 -index 0000000..7120351 ---- /dev/null -+++ b/include/mounts.h -@@ -0,0 +1,91 @@ -+/* ----------------------------------------------------------------------- * -+ * -+ * mounts.h - header file for mount utilities module. -+ * -+ * Copyright 2008 Red Hat, Inc. All rights reserved. -+ * Copyright 2004-2006 Ian Kent - All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, -+ * USA; either version 2 of the License, or (at your option) any later -+ * version; incorporated herein by reference. -+ * -+ * ----------------------------------------------------------------------- */ -+ -+#ifndef MOUNTS_H -+#define MOUNTS_H -+ -+#define AUTOFS_TYPE_ANY 0x0000 -+#define AUTOFS_TYPE_INDIRECT 0x0001 -+#define AUTOFS_TYPE_DIRECT 0x0002 -+#define AUTOFS_TYPE_OFFSET 0x0004 -+ -+#define MNTS_ALL 0x0001 -+#define MNTS_REAL 0x0002 -+#define MNTS_AUTOFS 0x0004 -+ -+#define REMOUNT_SUCCESS 0x0000 -+#define REMOUNT_OPEN_FAIL 0x0001 -+#define REMOUNT_STAT_FAIL 0x0002 -+#define REMOUNT_READ_MAP 0x0004 -+ -+extern const unsigned int indirect; -+extern const unsigned int direct; -+extern const unsigned int offset; -+ -+struct mapent; -+ -+struct mnt_list { -+ char *path; -+ char *fs_name; -+ char *fs_type; -+ char *opts; -+ pid_t owner; -+ /* -+ * List operations ie. get_mnt_list. -+ */ -+ struct mnt_list *next; -+ /* -+ * Tree operations ie. tree_make_tree, -+ * tree_get_mnt_list etc. -+ */ -+ struct mnt_list *left; -+ struct mnt_list *right; -+ struct list_head self; -+ struct list_head list; -+ struct list_head entries; -+ struct list_head sublist; -+ /* -+ * Offset mount handling ie. add_ordered_list -+ * and get_offset. -+ */ -+ struct list_head ordered; -+}; -+ -+unsigned int query_kproto_ver(void); -+unsigned int get_kver_major(void); -+unsigned int get_kver_minor(void); -+char *make_options_string(char *path, int kernel_pipefd, const char *extra); -+char *make_mnt_name_string(char *path); -+struct mnt_list *get_mnt_list(const char *table, const char *path, int include); -+struct mnt_list *reverse_mnt_list(struct mnt_list *list); -+void free_mnt_list(struct mnt_list *list); -+int contained_in_local_fs(const char *path); -+int is_mounted(const char *table, const char *path, unsigned int type); -+int has_fstab_option(const char *opt); -+char *get_offset(const char *prefix, char *offset, -+ struct list_head *head, struct list_head **pos); -+void add_ordered_list(struct mnt_list *ent, struct list_head *head); -+void tree_free_mnt_tree(struct mnt_list *tree); -+struct mnt_list *tree_make_mnt_tree(const char *table, const char *path); -+int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include); -+int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include); -+int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path); -+int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type); -+void set_tsd_user_vars(unsigned int, uid_t, gid_t); -+int umount_ent(struct autofs_point *, const char *); -+int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); -+int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); -+ -+#endif -diff --git a/include/parse_subs.h b/include/parse_subs.h -index 10c6083..643ad68 100644 ---- a/include/parse_subs.h -+++ b/include/parse_subs.h -@@ -27,8 +27,5 @@ int strmcmp(const char *, const char *, int); - char *dequote(const char *, int, unsigned int); - int span_space(const char *, unsigned int); - char *sanitize_path(const char *, int, unsigned int, unsigned int); --int umount_ent(struct autofs_point *, const char *); --int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); --int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *); - - #endif -diff --git a/lib/mounts.c b/lib/mounts.c -index b987fbb..a4bf86c 100644 ---- a/lib/mounts.c -+++ b/lib/mounts.c -@@ -1,6 +1,6 @@ - /* ----------------------------------------------------------------------- * - * -- * mounts.c - module for Linux automount mount table lookup functions -+ * mounts.c - module for mount utilities. - * - * Copyright 2002-2005 Ian Kent - All Rights Reserved - * -@@ -23,12 +23,21 @@ - #include - #include - #include -+#include -+#include -+#include -+#include - - #include "automount.h" - - #define MAX_OPTIONS_LEN 80 - #define MAX_MNT_NAME_LEN 30 - -+const unsigned int indirect = AUTOFS_TYPE_INDIRECT; -+const unsigned int direct = AUTOFS_TYPE_DIRECT; -+const unsigned int offset = AUTOFS_TYPE_OFFSET; -+const unsigned int type_count = 3; -+ - static const char options_template[] = "fd=%d,pgrp=%u,minproto=5,maxproto=%d"; - static const char options_template_extra[] = "fd=%d,pgrp=%u,minproto=5,maxproto=%d,%s"; - static const char mnt_name_template[] = "automount(pid%u)"; -@@ -119,7 +128,7 @@ unsigned int get_kver_minor(void) - /* - * Make common autofs mount options string - */ --char *make_options_string(char *path, int pipefd, char *extra) -+char *make_options_string(char *path, int pipefd, const char *extra) - { - char *options; - int len; -@@ -462,51 +471,6 @@ int has_fstab_option(const char *opt) - return ret; - } - --char *find_mnt_ino(const char *table, dev_t dev, ino_t ino) --{ -- struct mntent mnt_wrk; -- struct mntent *mnt; -- char buf[PATH_MAX * 3]; -- char *path = NULL; -- unsigned long l_dev = (unsigned long) dev; -- unsigned long l_ino = (unsigned long) ino; -- FILE *tab; -- -- tab = setmntent(table, "r"); -- if (!tab) { -- char *estr = strerror_r(errno, buf, (size_t) PATH_MAX - 1); -- logerr("setmntent: %s", estr); -- return 0; -- } -- -- while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { -- char *p_dev, *p_ino; -- unsigned long m_dev, m_ino; -- -- if (strcmp(mnt->mnt_type, "autofs")) -- continue; -- -- p_dev = strstr(mnt->mnt_opts, "dev="); -- if (!p_dev) -- continue; -- sscanf(p_dev, "dev=%lu", &m_dev); -- if (m_dev != l_dev) -- continue; -- -- p_ino = strstr(mnt->mnt_opts, "ino="); -- if (!p_ino) -- continue; -- sscanf(p_ino, "ino=%lu", &m_ino); -- if (m_ino == l_ino) { -- path = strdup(mnt->mnt_dir); -- break; -- } -- } -- endmntent(tab); -- -- return path; --} -- - char *get_offset(const char *prefix, char *offset, - struct list_head *head, struct list_head **pos) - { -@@ -982,3 +946,355 @@ int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type) - return mounted; - } - -+void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid) -+{ -+ struct thread_stdenv_vars *tsv; -+ struct passwd pw; -+ struct passwd *ppw = &pw; -+ struct passwd **pppw = &ppw; -+ struct group gr; -+ struct group *pgr; -+ struct group **ppgr; -+ char *pw_tmp, *gr_tmp; -+ int status, tmplen, grplen; -+ -+ /* -+ * Setup thread specific data values for macro -+ * substution in map entries during the mount. -+ * Best effort only as it must go ahead. -+ */ -+ -+ tsv = malloc(sizeof(struct thread_stdenv_vars)); -+ if (!tsv) { -+ error(logopt, "failed alloc tsv storage"); -+ return; -+ } -+ -+ tsv->uid = uid; -+ tsv->gid = gid; -+ -+ /* Try to get passwd info */ -+ -+ tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); -+ if (tmplen < 0) { -+ error(logopt, "failed to get buffer size for getpwuid_r"); -+ goto free_tsv; -+ } -+ -+ pw_tmp = malloc(tmplen + 1); -+ if (!pw_tmp) { -+ error(logopt, "failed to malloc buffer for getpwuid_r"); -+ goto free_tsv; -+ } -+ -+ status = getpwuid_r(uid, ppw, pw_tmp, tmplen, pppw); -+ if (status || !ppw) { -+ error(logopt, "failed to get passwd info from getpwuid_r"); -+ free(pw_tmp); -+ goto free_tsv; -+ } -+ -+ tsv->user = strdup(pw.pw_name); -+ if (!tsv->user) { -+ error(logopt, "failed to malloc buffer for user"); -+ free(pw_tmp); -+ goto free_tsv; -+ } -+ -+ tsv->home = strdup(pw.pw_dir); -+ if (!tsv->home) { -+ error(logopt, "failed to malloc buffer for home"); -+ free(pw_tmp); -+ goto free_tsv_user; -+ } -+ -+ free(pw_tmp); -+ -+ /* Try to get group info */ -+ -+ grplen = sysconf(_SC_GETGR_R_SIZE_MAX); -+ if (tmplen < 0) { -+ error(logopt, "failed to get buffer size for getgrgid_r"); -+ goto free_tsv_home; -+ } -+ -+ gr_tmp = NULL; -+ tmplen = grplen; -+ while (1) { -+ char *tmp = realloc(gr_tmp, tmplen + 1); -+ if (!tmp) { -+ error(logopt, "failed to malloc buffer for getgrgid_r"); -+ if (gr_tmp) -+ free(gr_tmp); -+ goto free_tsv_home; -+ } -+ gr_tmp = tmp; -+ pgr = &gr; -+ ppgr = &pgr; -+ status = getgrgid_r(gid, pgr, gr_tmp, tmplen, ppgr); -+ if (status != ERANGE) -+ break; -+ tmplen += grplen; -+ } -+ -+ if (status || !pgr) { -+ error(logopt, "failed to get group info from getgrgid_r"); -+ free(gr_tmp); -+ goto free_tsv_home; -+ } -+ -+ tsv->group = strdup(gr.gr_name); -+ if (!tsv->group) { -+ error(logopt, "failed to malloc buffer for group"); -+ free(gr_tmp); -+ goto free_tsv_home; -+ } -+ -+ free(gr_tmp); -+ -+ status = pthread_setspecific(key_thread_stdenv_vars, tsv); -+ if (status) { -+ error(logopt, "failed to set stdenv thread var"); -+ goto free_tsv_group; -+ } -+ -+ return; -+ -+free_tsv_group: -+ free(tsv->group); -+free_tsv_home: -+ free(tsv->home); -+free_tsv_user: -+ free(tsv->user); -+free_tsv: -+ free(tsv); -+ return; -+} -+ -+int umount_ent(struct autofs_point *ap, const char *path) -+{ -+ struct stat st; -+ struct statfs fs; -+ int sav_errno; -+ int status, is_smbfs = 0; -+ int ret, rv = 1; -+ -+ ret = statfs(path, &fs); -+ if (ret == -1) { -+ warn(ap->logopt, "could not stat fs of %s", path); -+ is_smbfs = 0; -+ } else { -+ int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER; -+ int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC; -+ is_smbfs = (cifsfs | smbfs) ? 1 : 0; -+ } -+ -+ status = lstat(path, &st); -+ sav_errno = errno; -+ -+ if (status < 0) -+ warn(ap->logopt, "lstat of %s failed with %d", path, status); -+ -+ /* -+ * lstat failed and we're an smbfs fs returning an error that is not -+ * EIO or EBADSLT or the lstat failed so it's a bad path. Return -+ * a fail. -+ * -+ * EIO appears to correspond to an smb mount that has gone away -+ * and EBADSLT relates to CD changer not responding. -+ */ -+ if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) { -+ rv = spawn_umount(ap->logopt, path, NULL); -+ } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) { -+ rv = spawn_umount(ap->logopt, path, NULL); -+ } -+ -+ /* We are doing a forced shutcwdown down so unlink busy mounts */ -+ if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { -+ ret = stat(path, &st); -+ if (ret == -1 && errno == ENOENT) { -+ warn(ap->logopt, "mount point does not exist"); -+ return 0; -+ } -+ -+ if (ret == 0 && !S_ISDIR(st.st_mode)) { -+ warn(ap->logopt, "mount point is not a directory"); -+ return 0; -+ } -+ -+ if (ap->state == ST_SHUTDOWN_FORCE) { -+ info(ap->logopt, "forcing umount of %s", path); -+ rv = spawn_umount(ap->logopt, "-l", path, NULL); -+ } -+ -+ /* -+ * Verify that we actually unmounted the thing. This is a -+ * belt and suspenders approach to not eating user data. -+ * We have seen cases where umount succeeds, but there is -+ * still a file system mounted on the mount point. How -+ * this happens has not yet been determined, but we want to -+ * make sure to return failure here, if that is the case, -+ * so that we do not try to call rmdir_path on the -+ * directory. -+ */ -+ if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { -+ crit(ap->logopt, -+ "the umount binary reported that %s was " -+ "unmounted, but there is still something " -+ "mounted on this path.", path); -+ rv = -1; -+ } -+ } -+ -+ return rv; -+} -+ -+int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) -+{ -+ char path[PATH_MAX + 1]; -+ char *offset = path; -+ struct mapent *oe; -+ struct list_head *pos = NULL; -+ unsigned int fs_path_len; -+ unsigned int mounted; -+ int ret, start; -+ -+ fs_path_len = strlen(root) + strlen(base); -+ if (fs_path_len > PATH_MAX) -+ return -1; -+ -+ strcpy(path, root); -+ strcat(path, base); -+ -+ mounted = 0; -+ start = strlen(root); -+ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); -+ while (offset) { -+ int plen = fs_path_len + strlen(offset); -+ -+ if (plen > PATH_MAX) { -+ warn(ap->logopt, "path loo long"); -+ goto cont; -+ } -+ -+ oe = cache_lookup_offset(base, offset, start, &me->multi_list); -+ if (!oe || !oe->mapent) -+ goto cont; -+ -+ debug(ap->logopt, "mount offset %s", oe->key); -+ -+ ret = mount_autofs_offset(ap, oe); -+ if (ret >= MOUNT_OFFSET_OK) -+ mounted++; -+ else { -+ if (ret != MOUNT_OFFSET_IGNORE) -+ warn(ap->logopt, "failed to mount offset"); -+ else { -+ debug(ap->logopt, -+ "ignoring \"nohide\" trigger %s", -+ oe->key); -+ free(oe->mapent); -+ oe->mapent = NULL; -+ } -+ } -+cont: -+ offset = cache_get_offset(base, -+ offset, start, &me->multi_list, &pos); -+ } -+ -+ return mounted; -+} -+ -+int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) -+{ -+ char path[PATH_MAX + 1]; -+ char *offset; -+ struct mapent *oe; -+ struct list_head *mm_root, *pos; -+ const char o_root[] = "/"; -+ const char *mm_base; -+ int left, start; -+ -+ left = 0; -+ start = strlen(root); -+ -+ mm_root = &me->multi->multi_list; -+ -+ if (!base) -+ mm_base = o_root; -+ else -+ mm_base = base; -+ -+ pos = NULL; -+ offset = path; -+ -+ /* Make sure "none" of the offsets have an active mount. */ -+ while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -+ char *oe_base; -+ -+ oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -+ /* root offset is a special case */ -+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) -+ continue; -+ -+ /* -+ * Check for and umount subtree offsets resulting from -+ * nonstrict mount fail. -+ */ -+ oe_base = oe->key + strlen(root); -+ left += umount_multi_triggers(ap, root, oe, oe_base); -+ -+ if (oe->ioctlfd != -1) -+ left++; -+ } -+ -+ if (left) -+ return left; -+ -+ pos = NULL; -+ offset = path; -+ -+ /* Make sure "none" of the offsets have an active mount. */ -+ while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -+ oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -+ /* root offset is a special case */ -+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) -+ continue; -+ -+ debug(ap->logopt, "umount offset %s", oe->key); -+ -+ if (umount_autofs_offset(ap, oe)) { -+ warn(ap->logopt, "failed to umount offset"); -+ left++; -+ } -+ } -+ -+ if (!left && me->multi == me) { -+ struct mapent_cache *mc = me->mc; -+ int status; -+ -+ /* -+ * Special case. -+ * If we can't umount the root container then we can't -+ * delete the offsets from the cache and we need to put -+ * the offset triggers back. -+ */ -+ if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { -+ info(ap->logopt, "unmounting dir = %s", root); -+ if (umount_ent(ap, root)) { -+ if (mount_multi_triggers(ap, root, me, "/") < 0) -+ warn(ap->logopt, -+ "failed to remount offset triggers"); -+ return left++; -+ } -+ } -+ -+ /* We're done - clean out the offsets */ -+ status = cache_delete_offset_list(mc, me->key); -+ if (status != CHE_OK) -+ warn(ap->logopt, "couldn't delete offset list"); -+ } -+ -+ return left; -+} -+ -diff --git a/lib/parse_subs.c b/lib/parse_subs.c -index 27cb0fc..3a04dd6 100644 ---- a/lib/parse_subs.c -+++ b/lib/parse_subs.c -@@ -18,10 +18,7 @@ - #include - #include - #include --#include --#include - #include --#include - #include "automount.h" - - /* -@@ -304,230 +301,3 @@ char *sanitize_path(const char *path, int origlen, unsigned int type, unsigned i - return s_path; - } - --int umount_ent(struct autofs_point *ap, const char *path) --{ -- struct stat st; -- struct statfs fs; -- int sav_errno; -- int status, is_smbfs = 0; -- int ret, rv = 1; -- -- ret = statfs(path, &fs); -- if (ret == -1) { -- warn(ap->logopt, "could not stat fs of %s", path); -- is_smbfs = 0; -- } else { -- int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER; -- int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC; -- is_smbfs = (cifsfs | smbfs) ? 1 : 0; -- } -- -- status = lstat(path, &st); -- sav_errno = errno; -- -- if (status < 0) -- warn(ap->logopt, "lstat of %s failed with %d", path, status); -- -- /* -- * lstat failed and we're an smbfs fs returning an error that is not -- * EIO or EBADSLT or the lstat failed so it's a bad path. Return -- * a fail. -- * -- * EIO appears to correspond to an smb mount that has gone away -- * and EBADSLT relates to CD changer not responding. -- */ -- if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) { -- rv = spawn_umount(ap->logopt, path, NULL); -- } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) { -- rv = spawn_umount(ap->logopt, path, NULL); -- } -- -- /* We are doing a forced shutcwdown down so unlink busy mounts */ -- if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { -- ret = stat(path, &st); -- if (ret == -1 && errno == ENOENT) { -- warn(ap->logopt, "mount point does not exist"); -- return 0; -- } -- -- if (ret == 0 && !S_ISDIR(st.st_mode)) { -- warn(ap->logopt, "mount point is not a directory"); -- return 0; -- } -- -- if (ap->state == ST_SHUTDOWN_FORCE) { -- info(ap->logopt, "forcing umount of %s", path); -- rv = spawn_umount(ap->logopt, "-l", path, NULL); -- } -- -- /* -- * Verify that we actually unmounted the thing. This is a -- * belt and suspenders approach to not eating user data. -- * We have seen cases where umount succeeds, but there is -- * still a file system mounted on the mount point. How -- * this happens has not yet been determined, but we want to -- * make sure to return failure here, if that is the case, -- * so that we do not try to call rmdir_path on the -- * directory. -- */ -- if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { -- crit(ap->logopt, -- "the umount binary reported that %s was " -- "unmounted, but there is still something " -- "mounted on this path.", path); -- rv = -1; -- } -- } -- -- return rv; --} -- --int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) --{ -- char path[PATH_MAX + 1]; -- char *offset = path; -- struct mapent *oe; -- struct list_head *pos = NULL; -- unsigned int fs_path_len; -- unsigned int mounted; -- int ret, start; -- -- fs_path_len = strlen(root) + strlen(base); -- if (fs_path_len > PATH_MAX) -- return -1; -- -- strcpy(path, root); -- strcat(path, base); -- -- mounted = 0; -- start = strlen(root); -- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); -- while (offset) { -- int plen = fs_path_len + strlen(offset); -- -- if (plen > PATH_MAX) { -- warn(ap->logopt, "path loo long"); -- goto cont; -- } -- -- oe = cache_lookup_offset(base, offset, start, &me->multi_list); -- if (!oe || !oe->mapent) -- goto cont; -- -- debug(ap->logopt, "mount offset %s", oe->key); -- -- ret = mount_autofs_offset(ap, oe); -- if (ret >= MOUNT_OFFSET_OK) -- mounted++; -- else { -- if (ret != MOUNT_OFFSET_IGNORE) -- warn(ap->logopt, "failed to mount offset"); -- else { -- debug(ap->logopt, -- "ignoring \"nohide\" trigger %s", -- oe->key); -- free(oe->mapent); -- oe->mapent = NULL; -- } -- } --cont: -- offset = cache_get_offset(base, -- offset, start, &me->multi_list, &pos); -- } -- -- return mounted; --} -- --int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base) --{ -- char path[PATH_MAX + 1]; -- char *offset; -- struct mapent *oe; -- struct list_head *mm_root, *pos; -- const char o_root[] = "/"; -- const char *mm_base; -- int left, start; -- -- left = 0; -- start = strlen(root); -- -- mm_root = &me->multi->multi_list; -- -- if (!base) -- mm_base = o_root; -- else -- mm_base = base; -- -- pos = NULL; -- offset = path; -- -- /* Make sure "none" of the offsets have an active mount. */ -- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -- char *oe_base; -- -- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -- /* root offset is a special case */ -- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) -- continue; -- -- /* -- * Check for and umount subtree offsets resulting from -- * nonstrict mount fail. -- */ -- oe_base = oe->key + strlen(root); -- left += umount_multi_triggers(ap, root, oe, oe_base); -- -- if (oe->ioctlfd != -1) -- left++; -- } -- -- if (left) -- return left; -- -- pos = NULL; -- offset = path; -- -- /* Make sure "none" of the offsets have an active mount. */ -- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { -- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); -- /* root offset is a special case */ -- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) -- continue; -- -- debug(ap->logopt, "umount offset %s", oe->key); -- -- if (umount_autofs_offset(ap, oe)) { -- warn(ap->logopt, "failed to umount offset"); -- left++; -- } -- } -- -- if (!left && me->multi == me) { -- struct mapent_cache *mc = me->mc; -- int status; -- -- /* -- * Special case. -- * If we can't umount the root container then we can't -- * delete the offsets from the cache and we need to put -- * the offset triggers back. -- */ -- if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { -- info(ap->logopt, "unmounting dir = %s", root); -- if (umount_ent(ap, root)) { -- if (mount_multi_triggers(ap, root, me, "/") < 0) -- warn(ap->logopt, -- "failed to remount offset triggers"); -- return left++; -- } -- } -- -- /* We're done - clean out the offsets */ -- status = cache_delete_offset_list(mc, me->key); -- if (status != CHE_OK) -- warn(ap->logopt, "couldn't delete offset list"); -- } -- -- return left; --} -- diff --git a/autofs-5.0.3-remove-redundant-dns-name-lookups.patch b/autofs-5.0.3-remove-redundant-dns-name-lookups.patch deleted file mode 100644 index a2c2771..0000000 --- a/autofs-5.0.3-remove-redundant-dns-name-lookups.patch +++ /dev/null @@ -1,239 +0,0 @@ -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-5.0.3-submount-shutdown-recovery-12-fix.patch b/autofs-5.0.3-submount-shutdown-recovery-12-fix.patch deleted file mode 100644 index a59f3ab..0000000 --- a/autofs-5.0.3-submount-shutdown-recovery-12-fix.patch +++ /dev/null @@ -1,32 +0,0 @@ -autofs-5.0.3 - submount shutdown recovery fix - -From: Ian Kent - -I was sure I fixed this in the final patch but evidently -not. ---- - - daemon/direct.c | 2 -- - 1 files changed, 0 insertions(+), 2 deletions(-) - - -diff --git a/daemon/direct.c b/daemon/direct.c -index 34e882b..afb354e 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -1129,7 +1129,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - */ - crit(ap->logopt, "can't find map entry for (%lu,%lu)", - (unsigned long) pkt->dev, (unsigned long) pkt->ino); -- cache_unlock(mc); - master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; -@@ -1374,7 +1373,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - */ - logerr("can't find map entry for (%lu,%lu)", - (unsigned long) pkt->dev, (unsigned long) pkt->ino); -- cache_unlock(mc); - master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; diff --git a/autofs-5.0.3-submount-shutdown-recovery-12.patch b/autofs-5.0.3-submount-shutdown-recovery-12.patch deleted file mode 100644 index 5bdcab4..0000000 --- a/autofs-5.0.3-submount-shutdown-recovery-12.patch +++ /dev/null @@ -1,1924 +0,0 @@ -autofs-5.0.3 - fix submount shutdown handling. - -From: Ian Kent - -When using submount maps on a busy system autofs can hang. - -This problem comes about because of processes walking into the -submount filesystem when it is in the process of shutting down. -While this race has been fixed for other types of mounts it -still isn't possible to to block processes from walking into -submounts that are expiring so we need to be able to recover -when this happens. - -This patch improves the submount shutdown logic and allows -submounts that become busy during shutdown to recover. ---- - - CHANGELOG | 1 - daemon/automount.c | 208 +++++++++++++++++++----------------------- - daemon/direct.c | 97 ++++++++++++++------ - daemon/indirect.c | 114 ++++++++++++++++++----- - daemon/lookup.c | 11 -- - daemon/state.c | 235 +++++++++++++++++++++++++++++++++--------------- - include/automount.h | 17 --- - include/master.h | 5 - - include/state.h | 9 ++ - lib/alarm.c | 14 --- - lib/master.c | 180 +++++++------------------------------ - modules/mount_autofs.c | 2 - 12 files changed, 458 insertions(+), 435 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index 9da7be3..ff04985 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -26,6 +26,7 @@ - - add command line option to override check for daemon already running. - - don't use proc file system when checking if the daemon is running. - - make handle_mounts startup condition distinct. -+- fix submount shutdown recovery handling. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/daemon/automount.c b/daemon/automount.c -index 086affb..68bf1d3 100644 ---- a/daemon/automount.c -+++ b/daemon/automount.c -@@ -369,6 +369,18 @@ int count_mounts(unsigned logopt, const char *path, dev_t dev) - - static void check_rm_dirs(struct autofs_point *ap, const char *path, int incl) - { -+ /* -+ * If we're a submount the kernel can't know we're trying to -+ * shutdown and so cannot block processes walking into the -+ * mount point directory. If this is the call to umount_multi() -+ * made during shutdown (incl == 0) we have to leave any mount -+ * point directories in place so we can recover if needed. The -+ * umount itself will clean these directories up for us -+ * automagically. -+ */ -+ if (!incl && ap->submount) -+ return; -+ - if ((!ap->ghost) || - (ap->state == ST_SHUTDOWN_PENDING || - ap->state == ST_SHUTDOWN_FORCE || -@@ -390,8 +402,6 @@ static void update_map_cache(struct autofs_point *ap, const char *path) - else - key = path; - -- pthread_cleanup_push(master_source_lock_cleanup, ap->entry); -- master_source_readlock(ap->entry); - map = ap->entry->maps; - while (map) { - struct mapent *me = NULL; -@@ -413,7 +423,6 @@ static void update_map_cache(struct autofs_point *ap, const char *path) - - map = map->next; - } -- pthread_cleanup_pop(1); - - return; - } -@@ -918,38 +927,22 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt) - } - - if (fds[1].revents & POLLIN) { -- enum states next_state, post_state; -+ enum states next_state; - size_t read_size = sizeof(next_state); - int state_pipe; - -- next_state = post_state = ST_INVAL; -+ next_state = ST_INVAL; - -- state_mutex_lock(ap); -+ st_mutex_lock(); - - state_pipe = ap->state_pipe[0]; - - if (fullread(state_pipe, &next_state, read_size)) { -- state_mutex_unlock(ap); -+ st_mutex_unlock(); - continue; - } - -- if (next_state != ST_INVAL && next_state != ap->state) { -- if (next_state != ST_SHUTDOWN) -- post_state = next_state; -- else -- ap->state = ST_SHUTDOWN; -- } -- -- state_mutex_unlock(ap); -- -- if (post_state != ST_INVAL) { -- if (post_state == ST_SHUTDOWN_PENDING || -- post_state == ST_SHUTDOWN_FORCE) { -- alarm_delete(ap); -- st_remove_tasks(ap); -- } -- st_add_task(ap, post_state); -- } -+ st_mutex_unlock(); - - if (next_state == ST_SHUTDOWN) - return -1; -@@ -985,11 +978,14 @@ int do_expire(struct autofs_point *ap, const char *name, int namelen) - - info(ap->logopt, "expiring path %s", buf); - -+ pthread_cleanup_push(master_source_lock_cleanup, ap->entry); -+ master_source_readlock(ap->entry); - ret = umount_multi(ap, buf, 1); - if (ret == 0) - info(ap->logopt, "expired %s", buf); - else - warn(ap->logopt, "couldn't complete expire of %s", buf); -+ pthread_cleanup_pop(1); - - return ret; - } -@@ -1069,7 +1065,7 @@ static int mount_autofs(struct autofs_point *ap) - if (status < 0) - return -1; - -- ap->state = ST_READY; -+ st_add_task(ap, ST_READY); - - return 0; - } -@@ -1423,44 +1419,6 @@ static void return_start_status(void *arg) - fatal(status); - } - --static void mutex_operation_wait(pthread_mutex_t *mutex) --{ -- int status; -- -- /* -- * Unlock a mutex, but wait for a pending operation -- * if one is in progress -- */ -- status = pthread_mutex_trylock(mutex); -- if (status) { -- if (status == EBUSY) { -- /* Mutex locked - do we own it */ -- status = pthread_mutex_unlock(mutex); -- if (status) { -- if (status != EPERM) -- fatal(status); -- } else -- return; -- -- status = pthread_mutex_lock(mutex); -- if (status) -- fatal(status); -- } else -- fatal(status); -- -- /* Operation complete, release it */ -- status = pthread_mutex_unlock(mutex); -- if (status) -- fatal(status); -- } else { -- status = pthread_mutex_unlock(mutex); -- if (status) -- fatal(status); -- } -- -- return; --} -- - int handle_mounts_startup_cond_init(struct startup_cond *suc) - { - int status; -@@ -1526,22 +1484,25 @@ static void handle_mounts_cleanup(void *arg) - if (!submount && strcmp(ap->path, "/-") && ap->dir_created) - clean = 1; - -- /* If we have been canceled then we may hold the state mutex. */ -- mutex_operation_wait(&ap->state_mutex); -+ if (submount) { -+ /* We are finishing up */ -+ ap->parent->submnt_count--; -+ list_del_init(&ap->mounts); -+ } - -- alarm_delete(ap); -- st_remove_tasks(ap); -+ master_remove_mapent(ap->entry); -+ master_source_unlock(ap->entry); - -- umount_autofs(ap, 1); -+ if (submount) { -+ mounts_mutex_unlock(ap->parent); -+ master_source_unlock(ap->parent->entry); -+ } -+ master_mutex_unlock(); - - destroy_logpri_fifo(ap); -- master_signal_submount(ap, MASTER_SUBMNT_JOIN); -- master_remove_mapent(ap->entry); - master_free_mapent_sources(ap->entry, 1); - master_free_mapent(ap->entry); - -- sched_yield(); -- - if (clean) { - if (rmdir(path) == -1) { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); -@@ -1572,8 +1533,6 @@ void *handle_mounts(void *arg) - pthread_cleanup_push(return_start_status, suc); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); - -- state_mutex_lock(ap); -- - status = pthread_mutex_lock(&suc->mutex); - if (status) { - logerr("failed to lock startup condition mutex!"); -@@ -1583,7 +1542,6 @@ void *handle_mounts(void *arg) - if (mount_autofs(ap) < 0) { - crit(ap->logopt, "mount of %s failed!", ap->path); - suc->status = 1; -- state_mutex_unlock(ap); - umount_autofs(ap, 1); - pthread_setcancelstate(cancel_state, NULL); - pthread_exit(NULL); -@@ -1600,56 +1558,70 @@ void *handle_mounts(void *arg) - if (!ap->submount && ap->exp_timeout) - alarm_add(ap, ap->exp_runfreq + rand() % ap->exp_runfreq); - -- pthread_cleanup_push(handle_mounts_cleanup, ap); - pthread_setcancelstate(cancel_state, NULL); - -- state_mutex_unlock(ap); -- - while (ap->state != ST_SHUTDOWN) { - if (handle_packet(ap)) { -- int ret, result; -+ int ret, cur_state; -+ -+ /* -+ * If we're a submount we need to ensure our parent -+ * doesn't try to mount us again until our shutdown -+ * is complete and that any outstanding mounts are -+ * completed before we try to shutdown. -+ */ -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); -+ -+ master_mutex_lock(); -+ -+ if (ap->submount) { -+ master_source_writelock(ap->parent->entry); -+ mounts_mutex_lock(ap->parent); -+ } -+ -+ master_source_writelock(ap->entry); -+ -+ if (ap->state != ST_SHUTDOWN) { -+ if (!ap->submount) -+ alarm_add(ap, ap->exp_runfreq); -+ /* Return to ST_READY is done immediately */ -+ st_add_task(ap, ST_READY); -+ master_source_unlock(ap->entry); -+ if (ap->submount) { -+ mounts_mutex_unlock(ap->parent); -+ master_source_unlock(ap->parent->entry); -+ } -+ -+ master_mutex_unlock(); -+ -+ pthread_setcancelstate(cur_state, NULL); -+ continue; -+ } -+ -+ alarm_delete(ap); -+ st_remove_tasks(ap); -+ st_wait_task(ap, ST_ANY, 0); - -- state_mutex_lock(ap); - /* - * For a direct mount map all mounts have already gone -- * by the time we get here. -+ * by the time we get here and since we only ever -+ * umount direct mounts at shutdown there is no need -+ * to check for possible recovery. - */ - if (ap->type == LKP_DIRECT) { -- status = 1; -- state_mutex_unlock(ap); -+ umount_autofs(ap, 1); - break; - } - - /* -- * If the ioctl fails assume the kernel doesn't have -- * AUTOFS_IOC_ASKUMOUNT and just continue. -+ * If umount_autofs returns non-zero it wasn't able -+ * to complete the umount and has left the mount intact -+ * so we can continue. This can happen if a lookup -+ * occurs while we're trying to umount. - */ -- ret = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &result); -- if (ret == -1) { -- state_mutex_unlock(ap); -+ ret = umount_autofs(ap, 1); -+ if (!ret) - break; -- } -- -- /* OK to exit */ -- if (ap->state == ST_SHUTDOWN) { -- if (result) { -- state_mutex_unlock(ap); -- break; -- } --#ifdef ENABLE_IGNORE_BUSY_MOUNTS -- /* -- * There weren't any active mounts but if the -- * filesystem is busy there may be a mount -- * request in progress so return to the ready -- * state unless a shutdown has been explicitly -- * requested. -- */ -- if (ap->shutdown) { -- state_mutex_unlock(ap); -- break; -- } --#endif -- } - - /* Failed shutdown returns to ready */ - warn(ap->logopt, -@@ -1657,14 +1629,22 @@ void *handle_mounts(void *arg) - ap->path); - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); -- nextstate(ap->state_pipe[1], ST_READY); -+ /* Return to ST_READY is done immediately */ -+ st_add_task(ap, ST_READY); -+ master_source_unlock(ap->entry); -+ if (ap->submount) { -+ mounts_mutex_unlock(ap->parent); -+ master_source_unlock(ap->parent->entry); -+ } -+ -+ master_mutex_unlock(); -+ -+ pthread_setcancelstate(cur_state, NULL); - -- state_mutex_unlock(ap); - } - } - -- pthread_cleanup_pop(1); -- sched_yield(); -+ handle_mounts_cleanup(ap); - - return NULL; - } -diff --git a/daemon/direct.c b/daemon/direct.c -index a3869a5..334a4b6 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -216,8 +216,6 @@ int umount_autofs_direct(struct autofs_point *ap) - - mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); - pthread_cleanup_push(mnts_cleanup, mnts); -- pthread_cleanup_push(master_source_lock_cleanup, ap->entry); -- master_source_readlock(ap->entry); - nc = ap->entry->master->nc; - cache_readlock(nc); - pthread_cleanup_push(cache_lock_cleanup, nc); -@@ -244,7 +242,6 @@ int umount_autofs_direct(struct autofs_point *ap) - } - pthread_cleanup_pop(1); - pthread_cleanup_pop(1); -- pthread_cleanup_pop(1); - - return 0; - } -@@ -572,9 +569,10 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) - return 1; - } else if (!status) { - if (ap->state != ST_SHUTDOWN_FORCE) { -- error(ap->logopt, -- "ask umount returned busy for %s", -- me->key); -+ if (ap->shutdown) -+ error(ap->logopt, -+ "ask umount returned busy for %s", -+ me->key); - return 1; - } else { - me->ioctlfd = -1; -@@ -904,7 +902,10 @@ void *expire_proc_direct(void *arg) - * All direct mounts must be present in the map - * entry cache. - */ -+ pthread_cleanup_push(master_source_lock_cleanup, ap->entry); -+ master_source_readlock(ap->entry); - me = lookup_source_mapent(ap, next->path, LKP_DISTINCT); -+ pthread_cleanup_pop(1); - if (!me) - continue; - -@@ -1110,6 +1111,8 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - struct pending_args *mt; - char buf[MAX_ERR_BUF]; - pthread_t thid; -+ struct timespec wait; -+ struct timeval now; - int status, state; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); -@@ -1124,7 +1127,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - * and since it got mounted we have to trust that - * there is an entry in the cache. - */ -- master_source_readlock(ap->entry); -+ master_source_writelock(ap->entry); - map = ap->entry->maps; - while (map) { - mc = map->mc; -@@ -1135,7 +1138,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - cache_unlock(mc); - map = map->next; - } -- master_source_unlock(ap->entry); - - if (!me) { - /* -@@ -1144,10 +1146,28 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - */ - crit(ap->logopt, "can't find map entry for (%lu,%lu)", - (unsigned long) pkt->dev, (unsigned long) pkt->ino); -+ cache_unlock(mc); -+ master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; - } - -+ /* Can't expire it if it isn't mounted */ -+ if (me->ioctlfd == -1) { -+ int ioctlfd = open(me->key, O_RDONLY); -+ if (ioctlfd == -1) { -+ crit(ap->logopt, "can't open ioctlfd for %s", -+ me->key); -+ pthread_setcancelstate(state, NULL); -+ return 1; -+ } -+ send_ready(ap->logopt, ioctlfd, pkt->wait_queue_token); -+ close(ioctlfd); -+ cache_unlock(mc); -+ master_source_unlock(ap->entry); -+ pthread_setcancelstate(state, NULL); -+ return 0; -+ } - - mt = malloc(sizeof(struct pending_args)); - if (!mt) { -@@ -1155,6 +1175,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - error(ap->logopt, "malloc: %s", estr); - send_fail(ap->logopt, me->ioctlfd, pkt->wait_queue_token); - cache_unlock(mc); -+ master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; - } -@@ -1184,6 +1205,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - error(ap->logopt, "expire thread create failed"); - send_fail(ap->logopt, mt->ioctlfd, pkt->wait_queue_token); - cache_unlock(mc); -+ master_source_unlock(ap->entry); - expire_mutex_unlock(NULL); - pending_cond_destroy(mt); - free_pending_args(mt); -@@ -1192,14 +1214,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di - } - - cache_unlock(mc); -+ master_source_unlock(ap->entry); - - pthread_cleanup_push(expire_mutex_unlock, NULL); - pthread_setcancelstate(state, NULL); - - mt->signaled = 0; - while (!mt->signaled) { -+ gettimeofday(&now, NULL); -+ wait.tv_sec = now.tv_sec + 2; -+ wait.tv_nsec = now.tv_usec * 1000; - status = pthread_cond_wait(&mt->cond, &ea_mutex); -- if (status) -+ if (status && status != ETIMEDOUT) - fatal(status); - } - -@@ -1263,6 +1289,9 @@ static void *do_mount_direct(void *arg) - if (status == -1) { - error(ap->logopt, - "can't stat direct mount trigger %s", mt.name); -+ send_fail(ap->logopt, -+ mt.ioctlfd, mt.wait_queue_token); -+ close(mt.ioctlfd); - pthread_setcancelstate(state, NULL); - pthread_exit(NULL); - } -@@ -1272,6 +1301,8 @@ static void *do_mount_direct(void *arg) - error(ap->logopt, - "direct trigger not valid or already mounted %s", - mt.name); -+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); -+ close(mt.ioctlfd); - pthread_setcancelstate(state, NULL); - pthread_exit(NULL); - } -@@ -1290,19 +1321,12 @@ static void *do_mount_direct(void *arg) - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); - if (status) { - struct mapent *me; -- int real_mount, set_fd; -- cache_readlock(mt.mc); -+ cache_writelock(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); -- if (set_fd) { -+ if (me) - 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); -+ cache_unlock(mt.mc); - info(ap->logopt, "mounted %s", mt.name); - } else { - send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token); -@@ -1325,11 +1349,21 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - struct pending_args *mt; - char buf[MAX_ERR_BUF]; - int status = 0; -+ struct timespec wait; -+ struct timeval now; - int ioctlfd, len, cl_flags, state; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); - -- master_source_readlock(ap->entry); -+ /* -+ * If our parent is a direct or offset mount that has been -+ * covered by a mount and another lookup occurs after the -+ * mount but before the device and inode are set in the -+ * cache entry we will not be able to find the mapent. So -+ * we must take the source writelock to ensure the parent -+ * has mount is complete before we look for the entry. -+ */ -+ master_source_writelock(ap->entry); - map = ap->entry->maps; - while (map) { - /* -@@ -1349,7 +1383,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - cache_unlock(mc); - map = map->next; - } -- master_source_unlock(ap->entry); - - if (!me) { - /* -@@ -1358,6 +1391,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - */ - logerr("can't find map entry for (%lu,%lu)", - (unsigned long) pkt->dev, (unsigned long) pkt->ino); -+ cache_unlock(mc); -+ master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; - } -@@ -1371,6 +1406,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - - if (ioctlfd == -1) { - cache_unlock(mc); -+ master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - crit(ap->logopt, "failed to create ioctl fd for %s", me->key); - /* TODO: how do we clear wait q in kernel ?? */ -@@ -1386,12 +1422,11 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - (unsigned long) pkt->wait_queue_token, me->key, pkt->pid); - - /* Ignore packet if we're trying to shut down */ -- if (ap->shutdown || -- ap->state == ST_SHUTDOWN_FORCE || -- ap->state == ST_SHUTDOWN) { -+ if (ap->shutdown || ap->state == ST_SHUTDOWN_FORCE) { - send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token); - close(ioctlfd); - cache_unlock(mc); -+ master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; - } -@@ -1402,6 +1437,7 @@ 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); -+ master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; - } -@@ -1413,6 +1449,7 @@ 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); -+ master_source_unlock(ap->entry); - pthread_setcancelstate(state, NULL); - return 1; - } -@@ -1447,6 +1484,7 @@ 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); -+ master_source_unlock(ap->entry); - mount_mutex_unlock(mt); - pending_cond_destroy(mt); - pending_mutex_destroy(mt); -@@ -1456,6 +1494,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - } - - cache_unlock(mc); -+ master_source_unlock(ap->entry); -+ - pthread_cleanup_push(free_pending_args, mt); - pthread_cleanup_push(pending_mutex_destroy, mt); - pthread_cleanup_push(pending_cond_destroy, mt); -@@ -1464,8 +1504,11 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - - mt->signaled = 0; - while (!mt->signaled) { -- status = pthread_cond_wait(&mt->cond, &mt->mutex); -- if (status) -+ gettimeofday(&now, NULL); -+ wait.tv_sec = now.tv_sec + 2; -+ wait.tv_nsec = now.tv_usec * 1000; -+ status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait); -+ if (status && status != ETIMEDOUT) - fatal(status); - } - -diff --git a/daemon/indirect.c b/daemon/indirect.c -index 3922f3f..17bed3e 100644 ---- a/daemon/indirect.c -+++ b/daemon/indirect.c -@@ -230,11 +230,8 @@ int mount_autofs_indirect(struct autofs_point *ap) - return 0; - } - --int umount_autofs_indirect(struct autofs_point *ap) -+static void close_mount_fds(struct autofs_point *ap) - { -- char buf[MAX_ERR_BUF]; -- int ret, rv, retries; -- - /* - * Since submounts look after themselves the parent never knows - * it needs to close the ioctlfd for offset mounts so we have -@@ -244,6 +241,25 @@ int umount_autofs_indirect(struct autofs_point *ap) - if (ap->submount) - lookup_source_close_ioctlfd(ap->parent, ap->path); - -+ close(ap->state_pipe[0]); -+ close(ap->state_pipe[1]); -+ ap->state_pipe[0] = -1; -+ ap->state_pipe[1] = -1; -+ -+ if (ap->pipefd >= 0) -+ close(ap->pipefd); -+ -+ if (ap->kpipefd >= 0) -+ close(ap->kpipefd); -+ -+ return; -+} -+ -+int umount_autofs_indirect(struct autofs_point *ap) -+{ -+ char buf[MAX_ERR_BUF]; -+ int ret, rv, retries; -+ - /* If we are trying to shutdown make sure we can umount */ - rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret); - if (rv == -1) { -@@ -251,24 +267,20 @@ int umount_autofs_indirect(struct autofs_point *ap) - logerr("ioctl failed: %s", estr); - return 1; - } else if (!ret) { -+#if defined(ENABLE_IGNORE_BUSY_MOUNTS) || defined(ENABLE_FORCED_SHUTDOWN) -+ if (!ap->shutdown) -+ return 1; - error(ap->logopt, "ask umount returned busy %s", ap->path); -+#else - return 1; -+#endif - } - -- ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0); -+ if (ap->shutdown) -+ ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0); -+ - close(ap->ioctlfd); - ap->ioctlfd = -1; -- close(ap->state_pipe[0]); -- close(ap->state_pipe[1]); -- ap->state_pipe[0] = -1; -- ap->state_pipe[1] = -1; -- -- if (ap->pipefd >= 0) -- close(ap->pipefd); -- -- if (ap->kpipefd >= 0) -- close(ap->kpipefd); -- - sched_yield(); - - retries = UMOUNT_RETRIES; -@@ -285,24 +297,61 @@ int umount_autofs_indirect(struct autofs_point *ap) - case EINVAL: - error(ap->logopt, - "mount point %s does not exist", ap->path); -+ close_mount_fds(ap); - return 0; - break; - case EBUSY: -- error(ap->logopt, -+ debug(ap->logopt, - "mount point %s is in use", ap->path); -- if (ap->state == ST_SHUTDOWN_FORCE) -+ if (ap->state == ST_SHUTDOWN_FORCE) { -+ close_mount_fds(ap); - goto force_umount; -- else -- return 0; -+ } else { -+ int cl_flags; -+ /* -+ * If the umount returns EBUSY there may be -+ * a mount request in progress so we need to -+ * recover unless we have been explicitly -+ * asked to shutdown and configure option -+ * ENABLE_IGNORE_BUSY_MOUNTS is enabled. -+ */ -+#ifdef ENABLE_IGNORE_BUSY_MOUNTS -+ if (ap->shutdown) { -+ close_mount_fds(ap); -+ return 0; -+ } -+#endif -+ ap->ioctlfd = open(ap->path, O_RDONLY); -+ if (ap->ioctlfd < 0) { -+ warn(ap->logopt, -+ "could not recover autofs path %s", -+ ap->path); -+ close_mount_fds(ap); -+ return 0; -+ } -+ -+ if ((cl_flags = fcntl(ap->ioctlfd, F_GETFD, 0)) != -1) { -+ cl_flags |= FD_CLOEXEC; -+ fcntl(ap->ioctlfd, F_SETFD, cl_flags); -+ } -+ } - break; - case ENOTDIR: - error(ap->logopt, "mount point is not a directory"); -+ close_mount_fds(ap); - return 0; - break; - } - return 1; - } - -+ /* -+ * We have successfully umounted the mount so we now close -+ * the descriptors. The kernel end of the kernel pipe will -+ * have been put during the umount super block cleanup. -+ */ -+ close_mount_fds(ap); -+ - force_umount: - if (rv != 0) { - warn(ap->logopt, -@@ -439,9 +488,12 @@ void *expire_proc_indirect(void *arg) - * Otherwise it's a top level indirect mount (possibly - * with offsets in it) and we use the usual ioctlfd. - */ -+ pthread_cleanup_push(master_source_lock_cleanup, ap->entry); -+ master_source_readlock(ap->entry); - me = lookup_source_mapent(ap, next->path, LKP_DISTINCT); - if (!me && ind_key) - me = lookup_source_mapent(ap, ind_key, LKP_NORMAL); -+ pthread_cleanup_pop(1); - if (!me) - continue; - -@@ -586,6 +638,8 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_ - struct pending_args *mt; - char buf[MAX_ERR_BUF]; - pthread_t thid; -+ struct timespec wait; -+ struct timeval now; - int status, state; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); -@@ -632,8 +686,11 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_ - - mt->signaled = 0; - while (!mt->signaled) { -- status = pthread_cond_wait(&mt->cond, &ea_mutex); -- if (status) -+ gettimeofday(&now, NULL); -+ wait.tv_sec = now.tv_sec + 2; -+ wait.tv_nsec = now.tv_usec * 1000; -+ status = pthread_cond_timedwait(&mt->cond, &ea_mutex, &wait); -+ if (status && status != ETIMEDOUT) - fatal(status); - } - -@@ -735,6 +792,8 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin - pthread_t thid; - char buf[MAX_ERR_BUF]; - struct pending_args *mt; -+ struct timespec wait; -+ struct timeval now; - int status, state; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); -@@ -743,9 +802,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin - (unsigned long) pkt->wait_queue_token, pkt->name, pkt->pid); - - /* Ignore packet if we're trying to shut down */ -- if (ap->shutdown || -- ap->state == ST_SHUTDOWN_FORCE || -- ap->state == ST_SHUTDOWN) { -+ if (ap->shutdown || ap->state == ST_SHUTDOWN_FORCE) { - send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token); - pthread_setcancelstate(state, NULL); - return 0; -@@ -802,8 +859,11 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin - - mt->signaled = 0; - while (!mt->signaled) { -- status = pthread_cond_wait(&mt->cond, &mt->mutex); -- if (status) -+ gettimeofday(&now, NULL); -+ wait.tv_sec = now.tv_sec + 2; -+ wait.tv_nsec = now.tv_usec * 1000; -+ status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait); -+ if (status && status != ETIMEDOUT) - fatal(status); - } - -diff --git a/daemon/lookup.c b/daemon/lookup.c -index 2277623..85ac519 100644 ---- a/daemon/lookup.c -+++ b/daemon/lookup.c -@@ -935,16 +935,10 @@ void lookup_close_lookup(struct autofs_point *ap) - if (!map) - return; - -- /* -- * Make sure we don't kill the context if a mount -- * request has come in while were shutting down. -- */ -- master_source_writelock(ap->entry); - while (map) { - lookup_close_lookup_instances(map); - map = map->next; - } -- master_source_unlock(ap->entry); - - return; - } -@@ -1122,7 +1116,6 @@ struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, un - struct mapent_cache *mc; - struct mapent *me = NULL; - -- master_source_readlock(entry); - map = entry->maps; - while (map) { - mc = map->mc; -@@ -1136,7 +1129,6 @@ struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, un - cache_unlock(mc); - map = map->next; - } -- master_source_unlock(entry); - - return me; - } -@@ -1149,8 +1141,6 @@ int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key) - struct mapent *me; - int ret = 0; - -- pthread_cleanup_push(master_source_lock_cleanup, entry); -- master_source_readlock(entry); - map = entry->maps; - while (map) { - mc = map->mc; -@@ -1168,7 +1158,6 @@ int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key) - cache_unlock(mc); - map = map->next; - } -- pthread_cleanup_pop(1); - - return ret; - } -diff --git a/daemon/state.c b/daemon/state.c -index 5804707..122177c 100644 ---- a/daemon/state.c -+++ b/daemon/state.c -@@ -37,19 +37,19 @@ static LIST_HEAD(state_queue); - static void st_set_thid(struct autofs_point *, pthread_t); - static void st_set_done(struct autofs_point *ap); - --#define st_mutex_lock() \ --do { \ -- int status = pthread_mutex_lock(&mutex); \ -- if (status) \ -- fatal(status); \ --} while (0) -- --#define st_mutex_unlock() \ --do { \ -- int status = pthread_mutex_unlock(&mutex); \ -- if (status) \ -- fatal(status); \ --} while (0) -+void st_mutex_lock(void) -+{ -+ int status = pthread_mutex_lock(&mutex); -+ if (status) -+ fatal(status); -+} -+ -+void st_mutex_unlock(void) -+{ -+ int status = pthread_mutex_unlock(&mutex); -+ if (status) -+ fatal(status); -+} - - int do_mount_autofs_direct(struct autofs_point *, struct mnt_list *, struct mapent *); - -@@ -96,21 +96,19 @@ void expire_cleanup(void *arg) - pthread_t thid = pthread_self(); - struct expire_args *ec; - struct autofs_point *ap; -- int statefd, success; -+ int success; - enum states next = ST_INVAL; - - ec = (struct expire_args *) arg; - ap = ec->ap; - success = ec->status; - -- state_mutex_lock(ap); -+ st_mutex_lock(); - - debug(ap->logopt, - "got thid %lu path %s stat %d", - (unsigned long) thid, ap->path, success); - -- statefd = ap->state_pipe[1]; -- - /* Check to see if expire process finished */ - if (thid == ap->exp_thread) { - int rv, idle; -@@ -199,11 +197,11 @@ void expire_cleanup(void *arg) - } - - if (next != ST_INVAL) -- nextstate(statefd, next); -+ __st_add_task(ap, next); - - st_set_done(ap); - -- state_mutex_unlock(ap); -+ st_mutex_unlock(); - - return; - } -@@ -216,9 +214,6 @@ static unsigned int st_ready(struct autofs_point *ap) - ap->shutdown = 0; - ap->state = ST_READY; - -- if (ap->submount) -- master_signal_submount(ap, MASTER_SUBMNT_CONTINUE); -- - return 1; - } - -@@ -333,18 +328,18 @@ static void do_readmap_cleanup(void *arg) - ra = (struct readmap_args *) arg; - - ap = ra->ap; -- ap->readmap_thread = 0; - -- state_mutex_lock(ap); -+ st_mutex_lock(); - -- nextstate(ap->state_pipe[1], ST_READY); -+ ap->readmap_thread = 0; -+ st_ready(ap); - st_set_done(ap); - -- state_mutex_unlock(ap); -- - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); - -+ st_mutex_unlock(); -+ - free(ra); - - return; -@@ -499,10 +494,8 @@ static unsigned int st_readmap(struct autofs_point *ap) - ra = malloc(sizeof(struct readmap_args)); - if (!ra) { - error(ap->logopt, "failed to malloc reamap cond struct"); -- state_mutex_lock(ap); -- nextstate(ap->state_pipe[1], ST_READY); -- state_mutex_unlock(ap); - /* It didn't work: return to ready */ -+ st_ready(ap); - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); - return 0; -@@ -528,10 +521,8 @@ static unsigned int st_readmap(struct autofs_point *ap) - error(ap->logopt, "read map thread create failed"); - st_readmap_cleanup(ra); - free(ra); -- state_mutex_lock(ap); -- nextstate(ap->state_pipe[1], ST_READY); -- state_mutex_unlock(ap); - /* It didn't work: return to ready */ -+ st_ready(ap); - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); - return 0; -@@ -570,7 +561,7 @@ static unsigned int st_prepare_shutdown(struct autofs_point *ap) - /* It didn't work: return to ready */ - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); -- nextstate(ap->state_pipe[1], ST_READY); -+ st_ready(ap); - return 0; - - case EXP_STARTED: -@@ -596,7 +587,7 @@ static unsigned int st_force_shutdown(struct autofs_point *ap) - /* It didn't work: return to ready */ - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); -- nextstate(ap->state_pipe[1], ST_READY); -+ st_ready(ap); - return 0; - - case EXP_STARTED: -@@ -605,6 +596,18 @@ static unsigned int st_force_shutdown(struct autofs_point *ap) - return 0; - } - -+static unsigned int st_shutdown(struct autofs_point *ap) -+{ -+ debug(ap->logopt, "state %d path %s", ap->state, ap->path); -+ -+ assert(ap->state == ST_SHUTDOWN_PENDING || ap->state == ST_SHUTDOWN_FORCE); -+ -+ ap->state = ST_SHUTDOWN; -+ nextstate(ap->state_pipe[1], ST_SHUTDOWN); -+ -+ return 0; -+} -+ - static unsigned int st_prune(struct autofs_point *ap) - { - debug(ap->logopt, "state %d path %s", ap->state, ap->path); -@@ -617,7 +620,7 @@ static unsigned int st_prune(struct autofs_point *ap) - case EXP_PARTIAL: - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); -- nextstate(ap->state_pipe[1], ST_READY); -+ st_ready(ap); - return 0; - - case EXP_STARTED: -@@ -638,7 +641,7 @@ static unsigned int st_expire(struct autofs_point *ap) - case EXP_PARTIAL: - if (!ap->submount) - alarm_add(ap, ap->exp_runfreq); -- nextstate(ap->state_pipe[1], ST_READY); -+ st_ready(ap); - return 0; - - case EXP_STARTED: -@@ -665,43 +668,35 @@ static struct state_queue *st_alloc_task(struct autofs_point *ap, enum states st - return task; - } - --/* Insert alarm entry on ordered list. */ --int st_add_task(struct autofs_point *ap, enum states state) -+/* -+ * Insert alarm entry on ordered list. -+ * State queue mutex and ap state mutex, in that order, must be held. -+ */ -+int __st_add_task(struct autofs_point *ap, enum states state) - { - struct list_head *head; - struct list_head *p, *q; - struct state_queue *new; -- enum states ap_state; - unsigned int empty = 1; - int status; - - /* Task termination marker, poke state machine */ - if (state == ST_READY) { -- state_mutex_lock(ap); - st_ready(ap); -- state_mutex_unlock(ap); -- -- st_mutex_lock(); - - signaled = 1; - status = pthread_cond_signal(&cond); - if (status) - fatal(status); - -- st_mutex_unlock(); -- - return 1; - } - -- state_mutex_lock(ap); -- ap_state = ap->state; -- if (ap_state == ST_SHUTDOWN) { -- state_mutex_unlock(ap); -+ if (ap->state == ST_SHUTDOWN) - return 1; -- } -- state_mutex_unlock(ap); - -- st_mutex_lock(); -+ if (state == ST_SHUTDOWN) -+ return st_shutdown(ap); - - head = &state_queue; - -@@ -718,8 +713,8 @@ int st_add_task(struct autofs_point *ap, enum states state) - - /* Don't add duplicate tasks */ - if ((task->state == state && !task->done) || -- (ap_state == ST_SHUTDOWN_PENDING || -- ap_state == ST_SHUTDOWN_FORCE)) -+ (ap->state == ST_SHUTDOWN_PENDING || -+ ap->state == ST_SHUTDOWN_FORCE)) - break; - - /* No pending tasks */ -@@ -736,8 +731,8 @@ int st_add_task(struct autofs_point *ap, enum states state) - p_task = list_entry(q, struct state_queue, pending); - - if (p_task->state == state || -- (ap_state == ST_SHUTDOWN_PENDING || -- ap_state == ST_SHUTDOWN_FORCE)) -+ (ap->state == ST_SHUTDOWN_PENDING || -+ ap->state == ST_SHUTDOWN_FORCE)) - goto done; - } - -@@ -760,11 +755,24 @@ done: - if (status) - fatal(status); - -+ return 1; -+} -+ -+int st_add_task(struct autofs_point *ap, enum states state) -+{ -+ int ret; -+ -+ st_mutex_lock(); -+ ret = __st_add_task(ap, state); - st_mutex_unlock(); - -- return 1; -+ return ret; - } - -+/* -+ * Remove state queue tasks for ap. -+ * State queue mutex and ap state mutex, in that order, must be held. -+ */ - void st_remove_tasks(struct autofs_point *ap) - { - struct list_head *head; -@@ -772,14 +780,10 @@ void st_remove_tasks(struct autofs_point *ap) - struct state_queue *task, *waiting; - int status; - -- st_mutex_lock(); -- - head = &state_queue; - -- if (list_empty(head)) { -- st_mutex_unlock(); -+ if (list_empty(head)) - return; -- } - - p = head->next; - while (p != head) { -@@ -816,12 +820,107 @@ void st_remove_tasks(struct autofs_point *ap) - if (status) - fatal(status); - -+ return; -+} -+ -+static int st_task_active(struct autofs_point *ap, enum states state) -+{ -+ struct list_head *head; -+ struct list_head *p, *q; -+ struct state_queue *task, *waiting; -+ unsigned int active = 0; -+ -+ st_mutex_lock(); -+ -+ head = &state_queue; -+ -+ list_for_each(p, head) { -+ task = list_entry(p, struct state_queue, list); -+ -+ if (task->ap != ap) -+ continue; -+ -+ if (task->state == state) { -+ active = 1; -+ break; -+ } -+ -+ if (state == ST_ANY) { -+ active = 1; -+ break; -+ } -+ -+ list_for_each(q, &task->pending) { -+ waiting = list_entry(q, struct state_queue, pending); -+ -+ if (waiting->state == state) { -+ active = 1; -+ break; -+ } -+ -+ if (state == ST_ANY) { -+ active = 1; -+ break; -+ } -+ } -+ } -+ - st_mutex_unlock(); - -- return; -+ return active; -+} -+ -+int st_wait_task(struct autofs_point *ap, enum states state, unsigned int seconds) -+{ -+ unsigned int wait = 0; -+ unsigned int duration = 0; -+ int ret = 0; - -+ while (1) { -+ struct timespec t = { 0, 200000000 }; -+ struct timespec r; -+ -+ while (nanosleep(&t, &r) == -1 && errno == EINTR) -+ memcpy(&t, &r, sizeof(struct timespec)); -+ -+ if (wait++ == 4) { -+ wait = 0; -+ duration++; -+ } -+ -+ if (!st_task_active(ap, state)) { -+ ret = 1; -+ break; -+ } -+ -+ if (seconds && duration >= seconds) -+ break; -+ } -+ -+ return ret; - } - -+int st_wait_state(struct autofs_point *ap, enum states state) -+{ -+ while (1) { -+ struct timespec t = { 0, 200000000 }; -+ struct timespec r; -+ -+ while (nanosleep(&t, &r) == -1 && errno == EINTR) -+ memcpy(&t, &r, sizeof(struct timespec)); -+ -+ st_mutex_lock(); -+ if (ap->state == state) { -+ st_mutex_unlock(); -+ return 1; -+ } -+ st_mutex_unlock(); -+ } -+ -+ return 0; -+} -+ -+ - static int run_state_task(struct state_queue *task) - { - struct autofs_point *ap; -@@ -831,8 +930,6 @@ static int run_state_task(struct state_queue *task) - ap = task->ap; - next_state = task->state; - -- state_mutex_lock(ap); -- - state = ap->state; - - if (next_state != state) { -@@ -862,8 +959,6 @@ static int run_state_task(struct state_queue *task) - } - } - -- state_mutex_unlock(ap); -- - return ret; - } - -@@ -888,8 +983,6 @@ static void st_set_done(struct autofs_point *ap) - struct list_head *p, *head; - struct state_queue *task; - -- st_mutex_lock(); -- - head = &state_queue; - list_for_each(p, head) { - task = list_entry(p, struct state_queue, list); -@@ -899,8 +992,6 @@ static void st_set_done(struct autofs_point *ap) - } - } - -- st_mutex_unlock(); -- - return; - } - -diff --git a/include/automount.h b/include/automount.h -index 1a20cd9..8ff24a7 100644 ---- a/include/automount.h -+++ b/include/automount.h -@@ -399,7 +399,6 @@ struct autofs_point { - unsigned logopt; /* Per map logging */ - pthread_t exp_thread; /* Thread that is expiring */ - pthread_t readmap_thread; /* Thread that is reading maps */ -- pthread_mutex_t state_mutex; /* Protect state changes */ - enum states state; /* Current state */ - int state_pipe[2]; /* State change router pipe */ - unsigned dir_created; /* Directory created for this mount? */ -@@ -407,8 +406,6 @@ struct autofs_point { - * host from which to mount */ - struct autofs_point *parent; /* Owner of mounts list for submount */ - pthread_mutex_t mounts_mutex; /* Protect mount lists */ -- pthread_cond_t mounts_cond; /* Submounts condition variable */ -- unsigned int mounts_signaled; /* Submount signals task complete */ - struct list_head mounts; /* List of autofs mounts at current level */ - unsigned int submount; /* Is this a submount */ - unsigned int shutdown; /* Shutdown notification */ -@@ -446,20 +443,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ - void rm_unwanted(unsigned logopt, const char *path, int incl, dev_t dev); - int count_mounts(unsigned logopt, const char *path, dev_t dev); - --#define state_mutex_lock(ap) \ --do { \ -- int _st_lock = pthread_mutex_lock(&ap->state_mutex); \ -- if (_st_lock) \ -- fatal(_st_lock); \ --} while(0) -- --#define state_mutex_unlock(ap) \ --do{ \ -- int _st_unlock = pthread_mutex_unlock(&ap->state_mutex); \ -- if (_st_unlock) \ -- fatal(_st_unlock); \ --} while (0) -- - #define mounts_mutex_lock(ap) \ - do { \ - int _m_lock = pthread_mutex_lock(&ap->mounts_mutex); \ -diff --git a/include/master.h b/include/master.h -index 5f10d1f..86ae045 100644 ---- a/include/master.h -+++ b/include/master.h -@@ -20,10 +20,6 @@ - #ifndef MASTER_H - #define MASTER_H - --#define MASTER_SUBMNT_WAIT 0 --#define MASTER_SUBMNT_CONTINUE 1 --#define MASTER_SUBMNT_JOIN 2 -- - struct map_source { - char *type; - char *format; -@@ -104,7 +100,6 @@ struct master *master_new(const char *, unsigned int, unsigned int); - int master_read_master(struct master *, time_t, int); - int master_submount_list_empty(struct autofs_point *ap); - int master_notify_submount(struct autofs_point *, const char *path, enum states); --void master_signal_submount(struct autofs_point *, unsigned int); - void master_notify_state_change(struct master *, int); - int master_mount_mounts(struct master *, time_t, int); - extern inline unsigned int master_get_logopt(void); -diff --git a/include/state.h b/include/state.h -index 8aed234..d7349d9 100644 ---- a/include/state.h -+++ b/include/state.h -@@ -38,7 +38,8 @@ - * - */ - enum states { -- ST_INVAL = -1, -+ ST_ANY = -2, -+ ST_INVAL, - ST_INIT, - ST_READY, - ST_EXPIRE, -@@ -81,12 +82,18 @@ struct readmap_args { - time_t now; /* Time when map is read */ - }; - -+void st_mutex_lock(void); -+void st_mutex_unlock(void); -+ - void expire_cleanup(void *); - void expire_proc_cleanup(void *); - void nextstate(int, enum states); - - int st_add_task(struct autofs_point *, enum states); -+int __st_add_task(struct autofs_point *, enum states); - void st_remove_tasks(struct autofs_point *); -+int st_wait_task(struct autofs_point *, enum states, unsigned int); -+int st_wait_state(struct autofs_point *ap, enum states state); - int st_start_handler(void); - - #endif -diff --git a/lib/alarm.c b/lib/alarm.c -index 6a70ed1..1e32291 100755 ---- a/lib/alarm.c -+++ b/lib/alarm.c -@@ -178,7 +178,6 @@ static void *alarm_handler(void *arg) - head = &alarms; - - while (1) { -- - if (list_empty(head)) { - /* No alarms, wait for one to be added */ - status = pthread_cond_wait(&cond, &mutex); -@@ -211,19 +210,8 @@ static void *alarm_handler(void *arg) - - if (!first->cancel) { - struct autofs_point *ap = first->ap; -- /* -- * We need to unlock the alarm list in case -- * some other thread holds the state_mutex -- *_lock(ap), and is currently trying to do -- * some alarm_* function (i.e if we don't -- * unlock, we might deadlock). -- */ - alarm_unlock(); -- -- state_mutex_lock(ap); -- nextstate(ap->state_pipe[1], ST_EXPIRE); -- state_mutex_unlock(ap); -- -+ st_add_task(ap, ST_EXPIRE); - alarm_lock(); - } - free(first); -diff --git a/lib/master.c b/lib/master.c -index edd3bdc..522b919 100644 ---- a/lib/master.c -+++ b/lib/master.c -@@ -90,41 +90,20 @@ int master_add_autofs_point(struct master_mapent *entry, - ap->logopt = logopt; - - ap->parent = NULL; -+ ap->thid = 0; - ap->submnt_count = 0; - ap->submount = submount; - INIT_LIST_HEAD(&ap->mounts); - INIT_LIST_HEAD(&ap->submounts); - ap->shutdown = 0; - -- status = pthread_mutex_init(&ap->state_mutex, NULL); -- if (status) { -- free(ap->path); -- free(ap); -- return 0; -- } -- - status = pthread_mutex_init(&ap->mounts_mutex, NULL); - if (status) { -- status = pthread_mutex_destroy(&ap->state_mutex); -- if (status) -- fatal(status); - free(ap->path); - free(ap); - return 0; - } - -- status = pthread_cond_init(&ap->mounts_cond, NULL); -- if (status) { -- status = pthread_mutex_destroy(&ap->mounts_mutex); -- if (status) -- fatal(status); -- status = pthread_mutex_destroy(&ap->state_mutex); -- if (status) -- fatal(status); -- free(ap->path); -- free(ap); -- return 0; -- } - entry->ap = ap; - - return 1; -@@ -137,18 +116,10 @@ void master_free_autofs_point(struct autofs_point *ap) - if (!ap) - return; - -- status = pthread_mutex_destroy(&ap->state_mutex); -- if (status) -- fatal(status); -- - status = pthread_mutex_destroy(&ap->mounts_mutex); - if (status) - fatal(status); - -- status = pthread_cond_destroy(&ap->mounts_cond); -- if (status) -- fatal(status); -- - free(ap->path); - free(ap); - } -@@ -295,11 +266,9 @@ struct map_source *master_find_map_source(struct master_mapent *entry, - { - struct map_source *source = NULL; - -- master_mutex_lock(); -- -+ master_source_readlock(entry); - source = __master_find_map_source(entry, type, format, argc, argv); -- -- master_mutex_unlock(); -+ master_source_unlock(entry); - - return source; - } -@@ -519,13 +488,7 @@ void send_map_update_request(struct autofs_point *ap) - if (!need_update) - return; - -- status = pthread_mutex_lock(&ap->state_mutex); -- if (status) -- fatal(status); -- nextstate(ap->state_pipe[1], ST_READMAP); -- status = pthread_mutex_unlock(&ap->state_mutex); -- if (status) -- fatal(status); -+ st_add_task(ap, ST_READMAP); - - return; - } -@@ -695,17 +658,13 @@ void master_remove_mapent(struct master_mapent *entry) - if (entry->ap->submount) - return; - -- master_mutex_lock(); - if (!list_empty(&entry->list)) - list_del_init(&entry->list); -- master_mutex_unlock(); - return; - } - - void master_free_mapent_sources(struct master_mapent *entry, unsigned int free_cache) - { -- master_source_writelock(entry); -- - if (entry->maps) { - struct map_source *m, *n; - -@@ -718,8 +677,6 @@ void master_free_mapent_sources(struct master_mapent *entry, unsigned int free_c - entry->maps = NULL; - } - -- master_source_unlock(entry); -- - return; - } - -@@ -827,10 +784,9 @@ int master_submount_list_empty(struct autofs_point *ap) - int master_notify_submount(struct autofs_point *ap, const char *path, enum states state) - { - struct list_head *head, *p; -- struct autofs_point *this; -- pthread_t thid; -+ struct autofs_point *this = NULL; - size_t plen = strlen(path); -- int status, ret = 1; -+ int ret = 1; - - mounts_mutex_lock(ap); - -@@ -869,33 +825,25 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state - - /* Now we have a submount to expire */ - -- state_mutex_lock(this); -+ st_mutex_lock(); - - if (this->state == ST_SHUTDOWN) { -- state_mutex_unlock(this); -+ this = NULL; -+ st_mutex_unlock(); - break; - } - -- nextstate(this->state_pipe[1], state); -+ this->shutdown = ap->shutdown; - -- state_mutex_unlock(this); -+ __st_add_task(this, state); - -- thid = this->thid; -- ap->mounts_signaled = MASTER_SUBMNT_WAIT; -- while (ap->mounts_signaled == MASTER_SUBMNT_WAIT) { -- status = pthread_cond_wait(&ap->mounts_cond, &ap->mounts_mutex); -- if (status) -- fatal(status); -- } -+ st_mutex_unlock(); -+ mounts_mutex_unlock(ap); - -- if (ap->mounts_signaled == MASTER_SUBMNT_JOIN) { -- status = pthread_join(thid, NULL); -- if (status) -- fatal(status); -- } else -- ret = 0; -+ st_wait_task(this, state, 0); -+ -+ return ret; - -- break; - } - - mounts_mutex_unlock(ap); -@@ -903,38 +851,12 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state - return ret; - } - --void master_signal_submount(struct autofs_point *ap, unsigned int join) --{ -- int status; -- -- if (!ap->parent || !ap->submount) -- return; -- -- mounts_mutex_lock(ap->parent); -- -- ap->parent->mounts_signaled = join; -- -- if (join == MASTER_SUBMNT_JOIN) { -- /* We are finishing up */ -- ap->parent->submnt_count--; -- list_del(&ap->mounts); -- } -- -- status = pthread_cond_signal(&ap->parent->mounts_cond); -- if (status) -- fatal(status); -- -- mounts_mutex_unlock(ap->parent); -- -- return; --} -- - void master_notify_state_change(struct master *master, int sig) - { - struct master_mapent *entry; - struct autofs_point *ap; - struct list_head *p; -- int state_pipe, cur_state; -+ int cur_state; - unsigned int logopt; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); -@@ -948,13 +870,11 @@ void master_notify_state_change(struct master *master, int sig) - ap = entry->ap; - logopt = ap->logopt; - -- state_mutex_lock(ap); -+ st_mutex_lock(); - - if (ap->state == ST_SHUTDOWN) - goto next; - -- state_pipe = ap->state_pipe[1]; -- - switch (sig) { - case SIGTERM: - case SIGINT: -@@ -962,7 +882,7 @@ void master_notify_state_change(struct master *master, int sig) - ap->state != ST_SHUTDOWN_FORCE) { - next = ST_SHUTDOWN_PENDING; - ap->shutdown = 1; -- nextstate(state_pipe, next); -+ __st_add_task(ap, next); - } - break; - #ifdef ENABLE_FORCED_SHUTDOWN -@@ -970,14 +890,15 @@ void master_notify_state_change(struct master *master, int sig) - if (ap->state != ST_SHUTDOWN_FORCE && - ap->state != ST_SHUTDOWN_PENDING) { - next = ST_SHUTDOWN_FORCE; -- nextstate(state_pipe, next); -+ ap->shutdown = 1; -+ __st_add_task(ap, next); - } - break; - #endif - case SIGUSR1: - assert(ap->state == ST_READY); - next = ST_PRUNE; -- nextstate(state_pipe, next); -+ __st_add_task(ap, next); - break; - } - next: -@@ -986,7 +907,7 @@ next: - "sig %d switching %s from %d to %d", - sig, ap->path, ap->state, next); - -- state_mutex_unlock(ap); -+ st_mutex_unlock(); - } - - master_mutex_unlock(); -@@ -1024,7 +945,6 @@ static int master_do_mount(struct master_mapent *entry) - handle_mounts_startup_cond_destroy(&suc); - return 0; - } -- entry->thid = thid; - - while (!suc.done) { - status = pthread_cond_wait(&suc.cond, &suc.mutex); -@@ -1037,45 +957,18 @@ static int master_do_mount(struct master_mapent *entry) - handle_mounts_startup_cond_destroy(&suc); - return 0; - } -+ entry->thid = thid; - - handle_mounts_startup_cond_destroy(&suc); - - return 1; - } - --static void shutdown_entry(struct master_mapent *entry) --{ -- int state_pipe; -- struct autofs_point *ap; -- struct stat st; -- int ret; -- -- ap = entry->ap; -- -- debug(ap->logopt, "%s", entry->path); -- -- state_mutex_lock(ap); -- -- state_pipe = ap->state_pipe[1]; -- -- ret = fstat(state_pipe, &st); -- if (ret == -1) -- goto next; -- -- nextstate(state_pipe, ST_SHUTDOWN_PENDING); --next: -- state_mutex_unlock(ap); -- -- return; --} -- - static void check_update_map_sources(struct master_mapent *entry, int readall) - { - struct map_source *source, *last; -- int state_pipe, map_stale = 0; - struct autofs_point *ap; -- struct stat st; -- int ret; -+ int map_stale = 0; - - if (readall) - map_stale = 1; -@@ -1128,17 +1021,8 @@ static void check_update_map_sources(struct master_mapent *entry, int readall) - master_source_unlock(entry); - - /* The map sources have changed */ -- if (map_stale) { -- state_mutex_lock(ap); -- -- state_pipe = entry->ap->state_pipe[1]; -- -- ret = fstat(state_pipe, &st); -- if (ret != -1) -- nextstate(state_pipe, ST_READMAP); -- -- state_mutex_unlock(ap); -- } -+ if (map_stale) -+ st_add_task(ap, ST_READMAP); - - return; - } -@@ -1169,17 +1053,19 @@ int master_mount_mounts(struct master *master, time_t age, int readall) - - /* A master map entry has gone away */ - if (this->age < age) { -- shutdown_entry(this); -+ st_add_task(ap, ST_SHUTDOWN_PENDING); - continue; - } - -+ master_source_writelock(ap->entry); - lookup_close_lookup(ap); -+ master_source_unlock(ap->entry); - - cache_readlock(nc); - ne = cache_lookup_distinct(nc, this->path); - if (ne && this->age > ne->age) { - cache_unlock(nc); -- shutdown_entry(this); -+ st_add_task(ap, ST_SHUTDOWN_PENDING); - continue; - } - nested = cache_partial_match(nc, this->path); -@@ -1195,7 +1081,7 @@ int master_mount_mounts(struct master *master, time_t age, int readall) - - check_update_map_sources(this, readall); - -- state_mutex_lock(ap); -+ st_mutex_lock(); - - state_pipe = this->ap->state_pipe[1]; - -@@ -1203,7 +1089,7 @@ int master_mount_mounts(struct master *master, time_t age, int readall) - ret = fstat(state_pipe, &st); - save_errno = errno; - -- state_mutex_unlock(ap); -+ st_mutex_unlock(); - - if (ret == -1 && save_errno == EBADF) - if (!master_do_mount(this)) { -diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c -index 6f66564..d6cbda8 100644 ---- a/modules/mount_autofs.c -+++ b/modules/mount_autofs.c -@@ -242,7 +242,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - master_free_mapent(entry); - return 1; - } -- nap->thid = thid; - - while (!suc.done) { - status = pthread_cond_wait(&suc.cond, &suc.mutex); -@@ -264,6 +263,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, - master_free_mapent(entry); - return 1; - } -+ nap->thid = thid; - - ap->submnt_count++; - list_add(&nap->mounts, &ap->submounts); diff --git a/autofs-5.0.3-unlink-mount-return-fix.patch b/autofs-5.0.3-unlink-mount-return-fix.patch deleted file mode 100644 index ea833f1..0000000 --- a/autofs-5.0.3-unlink-mount-return-fix.patch +++ /dev/null @@ -1,52 +0,0 @@ -diff --git a/CHANGELOG b/CHANGELOG -index eb4cce1..a0c7fa3 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -7,6 +7,7 @@ - - use libldap instead of libldap_r (Guillaume Rousse). - - another fix for don't fail on empty master map. - - fix expire working harder than needed. -+- fix unlink of mount tree incorrectly causing autofs mount fail. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/daemon/direct.c b/daemon/direct.c -index 760fbd4..8d1e9c6 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -275,7 +275,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list) - else - rv = umount2(mnt->path, MNT_DETACH); - if (rv == -1) { -- ret = 0; - debug(ap->logopt, - "can't unlink %s from mount tree", mnt->path); - -@@ -287,6 +286,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list) - - case ENOENT: - case EFAULT: -+ ret = 0; - warn(ap->logopt, "bad path for mount"); - break; - } -diff --git a/daemon/indirect.c b/daemon/indirect.c -index 39b42da..f0409ac 100644 ---- a/daemon/indirect.c -+++ b/daemon/indirect.c -@@ -65,7 +65,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) - else - rv = umount2(this->path, MNT_DETACH); - if (rv == -1) { -- ret = 0; - debug(ap->logopt, - "can't unlink %s from mount tree", this->path); - -@@ -77,6 +76,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) - - case ENOENT: - case EFAULT: -+ ret = 0; - warn(ap->logopt, "bad path for mount"); - break; - } diff --git a/autofs-5.0.3-update-replicated-doco.patch b/autofs-5.0.3-update-replicated-doco.patch deleted file mode 100644 index 2094f15..0000000 --- a/autofs-5.0.3-update-replicated-doco.patch +++ /dev/null @@ -1,103 +0,0 @@ -autofs-5.0.3 - update replicated server selection documentation - -From: Ian Kent - -Update the replicated server selection README documentation to -reflect the selection rules now used. ---- - - CHANGELOG | 1 + - README.replicated-server | 53 ++++++++++++++++++++++------------------------ - 2 files changed, 26 insertions(+), 28 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index af3318a..be39e33 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -31,6 +31,7 @@ - umount during expire. - - make mount of multi-mounts wuth a root offset atomic. - - add replicated server selection debug logging. -+- update replicated server selection documentation. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/README.replicated-server b/README.replicated-server -index 333dea3..1d771d3 100644 ---- a/README.replicated-server -+++ b/README.replicated-server -@@ -3,48 +3,45 @@ Supported forms for mount paths are: - Normal single-host (these are unchanged) - host:/path/path - -+Single host entries are not probed for a server response. -+ - Multiple replicated hosts, same path: - host1,host2,hostn:/path/path - --This will do an initial RPC call with a .1 second timeout to all hosts to --find best match. If this fails, it will try a 10 second timeout, if this --fails it takes the first host. -- - Multiple hosts, some with same path, some with another - host1,host2:/blah host3:/some/other/path - --Works as expected -- - Multiple replicated hosts, different (potentially) paths: - host1:/path/pathA host2:/path/pathB - --Same as above with RPC calls.. -- - Mutliple weighted, replicated hosts same path: -- - host1(5),host2(6),host3(1):/path/path - --Will pick lowest weighted host that responds to RPC call. --RPC time is not counted, only whether the call got a reply --at all. Initially does a .1 second timeout, if all hosts --fail this, moves to 10 second timeout. If one of the hosts --is localhost, the automounter will choose that regardless of --its weight. (This has been done to remain compatible with --Sun's automounter) -- - Multiple weighted, replicated hosts different (potentially) - paths: - host1(3):/path/pathA host2(5):/path/pathB - --Same as above with RPC calls/weighting. -- --Anything else is questionable and unsupported, but these --variations will also work: -- host1(3),host:/blah -- --Unsupported and I don't know why you would use this, but will --work. Weighted host always gets precedence if it responds to RPC -- --Anything else, I ain't making no promises. -+For these formats a priority ordered list of hosts is created by using -+the following selection rules. -+ -+1) Highest priority in selection is proximity. -+ Proximity, in order of precedence is: -+ - PROXIMITY_LOCAL, host corresponds to a local interface. -+ - PROXIMITY_SUBNET, host is located in a subnet reachable -+ through a local interface. -+ - PROXIMITY_NETWORK, host is located in a network reachable -+ through a local interface. -+ - PROXIMITY_OTHER, host is on a network not directlty -+ reachable through a local interface. -+ -+2) NFS version and protocol is selected by caclculating the largest -+ number of hosts supporting an NFS version and protocol that -+ have the closest proximity. These hosts are added to the list -+ in response time order. Hosts may have a corresponding weight -+ which essentially increases response time and so influences the -+ host order. -+ -+3) Hosts at further proximity that support the selected NFS version -+ and protocol are also added to the list in response time order as -+ in 2 above. - --Jason diff --git a/autofs-5.0.3-use-dev-urandom.patch b/autofs-5.0.3-use-dev-urandom.patch deleted file mode 100644 index 4f1c2bf..0000000 --- a/autofs-5.0.3-use-dev-urandom.patch +++ /dev/null @@ -1,39 +0,0 @@ -autofs-5.0.3 - use /dev/urandom instead of /dev/random - -From: Ian Kent - -It has been reported that some headless systems hang when using -/dev/random. It's also been pointed out that /dev/urandom is -sufficient for the needs of autofs. ---- - - CHANGELOG | 1 + - modules/replicated.c | 2 +- - 2 files changed, 2 insertions(+), 1 deletions(-) - - -diff --git a/CHANGELOG b/CHANGELOG -index be39e33..50c9a27 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -32,6 +32,7 @@ - - make mount of multi-mounts wuth a root offset atomic. - - add replicated server selection debug logging. - - update replicated server selection documentation. -+- use /dev/urandom instead of /dev/random. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/modules/replicated.c b/modules/replicated.c -index e41713e..362ab1b 100644 ---- a/modules/replicated.c -+++ b/modules/replicated.c -@@ -79,7 +79,7 @@ void seed_random(void) - int fd; - unsigned int seed; - -- fd = open("/dev/random", O_RDONLY); -+ fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { - srandom(time(NULL)); - return; diff --git a/autofs-5.0.3-wait-submount-expire-complete.patch b/autofs-5.0.3-wait-submount-expire-complete.patch deleted file mode 100644 index 45d9684..0000000 --- a/autofs-5.0.3-wait-submount-expire-complete.patch +++ /dev/null @@ -1,48 +0,0 @@ -autofs-5.0.3 - wait submount expire complete - -From: Ian Kent - -When expiring a submount expires away and proceeds to shutdown we -can reach the end of the expire of the parent before the submount -goes away. This can cause an incomplete expire during shutdown in -some cases so, for the case the submount goes to state ST_SHUTDOWN, -we need to wait until the submount either goes away or fails to -shutdown before continuing. ---- - - lib/master.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - - ---- autofs-5.0.3.orig/lib/master.c -+++ autofs-5.0.3/lib/master.c -@@ -870,6 +870,29 @@ int master_notify_submount(struct autofs - - st_wait_task(this, state, 0); - -+ /* -+ * If our submount gets to state ST_SHUTDOWN we need to -+ * wait until it goes away or changes to ST_READY. -+ */ -+ mounts_mutex_lock(ap); -+ st_mutex_lock(); -+ while ((this = __master_find_submount(ap, path))) { -+ struct timespec t = { 0, 300000000 }; -+ struct timespec r; -+ -+ if (this->state != ST_SHUTDOWN) -+ break; -+ -+ st_mutex_unlock(); -+ mounts_mutex_unlock(ap); -+ while (nanosleep(&t, &r) == -1 && errno == EINTR) -+ memcpy(&t, &r, sizeof(struct timespec)); -+ mounts_mutex_lock(ap); -+ st_mutex_lock(); -+ } -+ st_mutex_unlock(); -+ mounts_mutex_unlock(ap); -+ - return ret; - - } diff --git a/autofs-5.0.3-xfn-not-supported.patch b/autofs-5.0.3-xfn-not-supported.patch deleted file mode 100644 index ebbee86..0000000 --- a/autofs-5.0.3-xfn-not-supported.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff --git a/CHANGELOG b/CHANGELOG -index 98855f5..8d09e93 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -1,6 +1,7 @@ - ??/??/2008 autofs-5.0.4 - ----------------------- - - correct configure test for ldapr page control functions. -+- catch "-xfn" map type and issue "no supported" message. - - 14/01/2008 autofs-5.0.3 - ----------------------- -diff --git a/lib/master_parse.y b/lib/master_parse.y -index b450122..2184b4f 100644 ---- a/lib/master_parse.y -+++ b/lib/master_parse.y -@@ -50,6 +50,7 @@ static int add_multi_mapstr(void); - - static int master_error(const char *s); - static int master_notify(const char *s); -+static int master_msg(const char *s); - - static char *path; - static char *type; -@@ -119,6 +120,7 @@ static int master_fprintf(FILE *, char *, ...); - %token DNNAME - %token MAPHOSTS - %token MAPNULL -+%token MAPXFN - %token MAPNAME - %token NUMBER - %token OPTION -@@ -283,6 +285,12 @@ map: PATH - YYABORT; - } - } -+ | MAPXFN -+ { -+ master_notify($1); -+ master_msg("X/Open Federated Naming service not supported"); -+ YYABORT; -+ } - | MAPNULL - { - type = master_strdup($1 + 1); -@@ -598,6 +606,12 @@ static int master_notify(const char *s) - return(0); - } - -+static int master_msg(const char *s) -+{ -+ logmsg("%s", s); -+ return 0; -+} -+ - static void local_init_vars(void) - { - path = NULL; -diff --git a/lib/master_tok.l b/lib/master_tok.l -index d908047..2a6fdf9 100644 ---- a/lib/master_tok.l -+++ b/lib/master_tok.l -@@ -215,6 +215,12 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo - return MAPNULL; - } - -+ "-xfn" { -+ BEGIN(OPTSTR); -+ strcpy(master_lval.strtype, master_text); -+ return MAPXFN; -+ } -+ - "//" { - BEGIN(DNSTR); - yyless(0);