From d651ebc00779dcf4c6387ed14f91fe5368fc761d Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Wed, 8 Jun 2022 08:12:30 +0000 Subject: [PATCH] Auto sync2gitlab import of autofs-5.1.4-83.el8.src.rpm --- .gitignore | 1 + EMPTY | 1 - ...es.rules-remove-samples-from-SUBDIRS.patch | 66 + autofs-5.1.4-account-for-libnsl-changes.patch | 557 ++ ...NULL-check-in-prepare_attempt_prefix.patch | 34 + ...ap-entry-to-the-installed-master-map.patch | 42 + ...ditional-inclusion-of-fedfs-binaries.patch | 184 + ...add-error-handling-for-ext_mount_add.patch | 121 + autofs-5.1.4-add-fedfs-getsrvinfo_c.patch | 402 + autofs-5.1.4-add-fedfs-map-nfs4_c.patch | 342 + ...ge-note-about-extra-slashes-in-paths.patch | 40 + ...pseudo-options-for-mount-propagation.patch | 179 + autofs-5.1.4-add-mount_fedfs_c.patch | 696 ++ ...-systemd-service-command-line-option.patch | 137 + ...-After-line-to-include-statd-service.patch | 39 + ...r-handle-hesiod-support-not-built-in.patch | 130 + ...-type-naming-to-better-reflect-usage.patch | 136 + autofs-5.1.4-covarity-fixes-1.patch | 425 + ...ing-slash-in-master-map-mount-points.patch | 48 + ...e-array-for-path-when-not-neccessary.patch | 56 + autofs-5.1.4-fix-NFS-version-mask-usage.patch | 69 + autofs-5.1.4-fix-age-setting-at-startup.patch | 42 + ...-fix-amd-parser-opts-option-handling.patch | 66 + autofs-5.1.4-fix-deadlock-in-dumpmaps.patch | 40 + ....1.4-fix-directory-create-permission.patch | 207 + ...1.4-fix-error-return-in-do_nfs_mount.patch | 35 + ...-fix-fd-leak-in-rpc_do_create_client.patch | 46 + autofs-5.1.4-fix-flag-file-permission.patch | 41 + ...-fix-incorrect-locking-in-sss-lookup.patch | 40 + ...-5.1.4-fix-libresolv-configure-check.patch | 94 + autofs-5.1.4-fix-monotonic_elapsed.patch | 49 + ...efix-option-handling-in-expand_entry.patch | 55 + autofs-5.1.4-fix-program-usage-message.patch | 40 + ...sublink-option-not-set-from-defaults.patch | 48 + ...date_negative_cache-map-source-usage.patch | 98 + ...e-after-free-in-do_master_list_reset.patch | 55 + ...-use-after-free-in-parse_ldap_config.patch | 34 + ...mprove-hostname-lookup-error-logging.patch | 123 + ...e-umount_ent-recognise-forced-umount.patch | 41 + ....4-mark-removed-cache-entry-negative.patch | 64 + ...e-stdio-descriptors-to-become_daemon.patch | 117 + ....1.4-remove-autofs4-module-load-code.patch | 222 + ...4-remove-unused-function-dump_master.patch | 37 + ...-set-bind-mount-as-propagation-slave.patch | 69 + ...tch-for-autofs-typo-and-possible-bug.patch | 48 + ...5.1.4-update-build-info-with-systemd.patch | 41 + ...fs-5.1.4-use-defines-for-expire-type.patch | 100 + ...se-flags-for-startup-boolean-options.patch | 217 + ...1.4-use-systemd-sd_notify-at-startup.patch | 1357 ++++ ...dnt-prevent-selection-among-replicas.patch | 226 + ...ULL-check-for-get_addr_string-return.patch | 39 + ...onfig-option-for-ignore-mount-option.patch | 155 + autofs-5.1.5-add-glibc-getmntent.patch | 127 + autofs-5.1.5-add-ignore-mount-option.patch | 90 + ...d-mount_verbose-configuration-option.patch | 174 + ...-5.1.5-add-strictexpire-mount-option.patch | 200 + ...od-following-macro-in-selector-value.patch | 34 + ....5-also-use-strictexpire-for-offsets.patch | 42 + ...-use-PROC_MOUNTS-to-make-mount-lists.patch | 405 + ...e-tree_is_mounted-for-mounted-checks.patch | 172 + ...s-5.1.5-fix-additional-typing-errors.patch | 383 + autofs-5.1.5-fix-amd-entry-memory-leak.patch | 33 + ...-hesiod-string-check-in-master_parse.patch | 49 + ...x-macro-expansion-in-selector-values.patch | 419 + ...initialization-of-autofs_point-flags.patch | 34 + ...link_mount_tree-not-umounting-mounts.patch | 136 + ...ll-arguments-if-mount_verbose-is-set.patch | 222 + ...ake-expire-remaining-log-level-debug.patch | 55 + ...ve-unlink_mount_tree-to-lib_mounts_c.patch | 134 + ...lly-log-mount-requestor-process-info.patch | 155 + ...tor-unlink_active_mounts-in-direct_c.patch | 116 + ...emove-a-couple-of-old-debug-messages.patch | 38 + ...ove-unused-function-has_fstab_option.patch | 71 + ...ove-unused-function-reverse_mnt_list.patch | 63 + ...s-for-autofs-mount-types-in-mnt_list.patch | 279 + ...ore-option-for-offset-mounts-as-well.patch | 44 + ...se-local-getmntent_r-in-get_mnt_list.patch | 53 + ...ocal-getmntent_r-in-table_is_mounted.patch | 53 + ...cal-getmntent_r-in-tree_get_mnt_list.patch | 55 + ...al_getmntent_r-for-unlink_mount_tree.patch | 179 + autofs-5.1.5-use-malloc-in-spawn_c.patch | 161 + ...-instead-of-path-in-mnt_list-entries.patch | 436 ++ ...-for-both-direct-and-indirect-mounts.patch | 271 + ...s-5.1.6-add-a-hash-index-to-mnt_list.patch | 202 + ...-force-unlink-mounts-and-exit-option.patch | 248 + ...s-5.1.6-add-hashtable-implementation.patch | 334 + ...helper-to-construct-mount-point-path.patch | 225 + ...-add-sss-ECONREFUSED-return-handling.patch | 66 + ...or-new-sss-autofs-proto-version-call.patch | 120 + ...mountpoint-to-mp-in-struct-ext_mount.patch | 74 + ...logpri-fifo-pipes-on-unlink-and-exit.patch | 101 + ...-5.1.6-dont-prune-offset-map-entries.patch | 49 + ...-regression-with-map-instance-lookup.patch | 310 + ...ix-autofs-mount-options-construction.patch | 273 + ...dir-not-re-created-on-symlink-expire.patch | 52 + ...-direct-mount-unlink_mount_tree-path.patch | 40 + ...5.1.6-fix-double-quoting-in-auto.smb.patch | 36 + ...ing-of-ampersand-in-auto.smb-as-well.patch | 35 + ...s-list-return-from-unlink_mount_tree.patch | 47 + ...logical-compare-in-unlink_mount_tree.patch | 33 + ...systemctl-command-syntax-in-autofs-8.patch | 34 + ...ss_read_master-nsswicth-check-return.patch | 42 + ...-multi-mount-lookup-after-mount-fail.patch | 60 + ...d-string-length-calc-in-expandsunent.patch | 44 + autofs-5.1.6-fix-remount-expire.patch | 48 + ...-retries-check-in-setautomntent_wait.patch | 38 + ...5.1.6-fix-sss-master-map-wait-timing.patch | 60 + ...ale-offset-directories-disable-mount.patch | 57 + ...-trailing-dollar-sun-entry-expansion.patch | 46 + autofs-5.1.6-fix-typo-in-open_sss_lib.patch | 37 + ...5.1.6-fix-unlink-mounts-umount-order.patch | 89 + ...rce-unlink-mounts-option-description.patch | 39 + ...-sss-getautomntbyname-error-handling.patch | 189 + ...ove-sss-getautomntent-error-handling.patch | 205 + ...ove-sss-setautomntent-error-handling.patch | 159 + ...truct-addrinfo-for-getaddrinfo-calls.patch | 104 + ...-mounts-propagation-slave-by-default.patch | 220 + ...rnal-mounts-independent-of-amd_entry.patch | 382 + ...xternal-mounts-use-simpler-hashtable.patch | 128 + autofs-5.1.6-make-umount_autofs-static.patch | 86 + ..._c-fix-local-rdma-share-not-mounting.patch | 49 + ...move-lib_master_c-to-daemon_master_c.patch | 6877 +++++++++++++++++ ....1.6-move-readall-into-struct-master.patch | 203 + ...unt-check-into-conditional_alarm_add.patch | 201 + ...y-add-expire-alarm-for-active-mounts.patch | 334 + ...-5.1.6-refactor-sss-getautomntbyname.patch | 172 + autofs-5.1.6-refactor-sss-getautomntent.patch | 150 + autofs-5.1.6-refactor-sss-setautomntent.patch | 198 + ...move-force-parameter-from-umount_all.patch | 63 + ...6-remove-intr-hosts-map-mount-option.patch | 113 + ...ove-logpri-fifo-on-autofs-mount-fail.patch | 36 + ...ve-unused-function-tree_get_mnt_list.patch | 366 + ....1.6-simplify-sss-source-stale-check.patch | 120 + ...ce-a-flag-to-indicate-map-being-read.patch | 235 + ...ntroduce-retries-calcuation-function.patch | 133 + ...-ldap-READMEs-and-schema-definitions.patch | 841 ++ autofs-5.1.6-update-list_h.patch | 513 ++ ...1.6-update-sss-timeout-documentation.patch | 155 + ...id-timeout-in-lookup_prune_one_cache.patch | 78 + ...use-bit-flag-for-force-unlink-mounts.patch | 45 + ...ame-in-sss-context-for-setautomntent.patch | 96 + ...ster_list_empty-for-list-empty-check.patch | 119 + autofs-5.1.6-use-mnt_list-for-amdmounts.patch | 547 ++ autofs-5.1.6-use-mnt_list-for-submounts.patch | 472 ++ ...uct-mnt_list-mounted-list-for-expire.patch | 620 ++ ...uct-mnt_list-to-track-mounted-mounts.patch | 360 + ...d-a-len-field-to-struct-autofs_point.patch | 122 + ...dd-ext_mount_hash_mutex-lock-helpers.patch | 100 + ...ength-check-in-umount_subtree_mounts.patch | 38 + ...5.1.7-add-mapent-tree-implementation.patch | 167 + ...ssing-description-of-null-map-option.patch | 51 + ....7-add-missing-free-in-handle_mounts.patch | 38 + ...d-mount-and-umount-offsets-functions.patch | 304 + ...-5.1.7-add-set_offset_tree_catatonic.patch | 46 + ...fs-5.1.7-add-some-multi-mount-macros.patch | 522 ++ autofs-5.1.7-add-tree_mapent_add_node.patch | 123 + ....1.7-add-tree_mapent_cleanup_offsets.patch | 88 + ...5.1.7-add-tree_mapent_delete_offsets.patch | 113 + ...1.7-add-tree_mapent_traverse_subtree.patch | 79 + autofs-5.1.7-add-xdr_exports.patch | 325 + ...-mounts-list-in-mnts_get_expire_list.patch | 40 + ...ck-for-offset-with-no-mount-location.patch | 46 + ...-5.1.7-cleanup-cache_delete-a-little.patch | 60 + ...ffset-mounts-to-mounted-mounts-table.patch | 197 + ...-pass-root-to-do_mount_autofs_offset.patch | 60 + ...nt-try-umount-after-stat-ENOENT-fail.patch | 41 + ...lloc-in-host-exports-list-processing.patch | 107 + ...-eliminate-cache_lookup_offset-usage.patch | 372 + ...eliminate-clean_stale_multi_triggers.patch | 285 + ...unt_mounts-from-expire_proc_indirect.patch | 132 + ...cache-lookup-in-tree_mapent_add_node.patch | 82 + ...some-strlen-calls-in-offset-handling.patch | 124 + autofs-5.1.7-fix-amd-hosts-mount-expire.patch | 48 + ....7-fix-amd-section-mounts-map-reload.patch | 120 + autofs-5.1.7-fix-arg-not-used-in-print.patch | 36 + ....1.7-fix-dead-code-in-mnts_add_mount.patch | 51 + autofs-5.1.7-fix-direct-mount-deadlock.patch | 129 + ....1.7-fix-double-free-in-parse_mapent.patch | 35 + ...1.7-fix-double-unlock-in-parse_mount.patch | 33 + ...5.1.7-fix-flag-check-in-umount_multi.patch | 34 + autofs-5.1.7-fix-hosts-map-offset-order.patch | 289 + ...-inconsistent-locking-in-parse_mount.patch | 245 + ...ent-locking-in-umount_subtree_mounts.patch | 129 + ...s-mounted-check-on-non-existent-path.patch | 58 + ...p_prune_one_cache-refactoring-change.patch | 56 + ...issing-lock-release-in-mount_subtree.patch | 32 + ...expire_list-expire-list-construction.patch | 36 + ...mnts_remove_amdmount-uses-wrong-list.patch | 34 + autofs-5.1.7-fix-mount_fullpath.patch | 61 + ...nonstrict-offset-mount-fail-handling.patch | 54 + autofs-5.1.7-fix-offset-entries-order.patch | 199 + ...possible-memory-leak-in-master_parse.patch | 34 + ...ble-memory-leak-in-mnts_add_amdmount.patch | 54 + ...subtree_mounts-on-offset-list-delete.patch | 40 + ...tree-implementation-data-independent.patch | 346 + ...amd-mounts-removal-into-lib_mounts_c.patch | 110 + ...-mapent_cache-to-update_offset_entry.patch | 68 + ...7-pass-root-length-to-mount_fullpath.patch | 153 + ....1.7-reduce-umount-EBUSY-check-delay.patch | 75 + ...efactor-lookup_prune_one_cache-a-bit.patch | 71 + ...5.1.7-refactor-umount_multi_triggers.patch | 255 + ...move-mount_x-and-rpcgen-dependencies.patch | 544 ++ autofs-5.1.7-remove-mounts_mutex.patch | 168 + autofs-5.1.7-remove-obsolete-functions.patch | 739 ++ ...-master_add_amd_mount_section_mounts.patch | 36 + autofs-5.1.7-remove-redundant-if-check.patch | 36 + ...e-redundant-local-var-from-sun_mount.patch | 70 + ...t-variables-from-mount_autofs_offset.patch | 174 + ...-function-master_submount_list_empty.patch | 54 + ...ache_dump_multi-and-cache_dump_cache.patch | 59 + ...sed-mount-offset-list-lock-functions.patch | 173 + ...arameter-form-do_mount_autofs_offset.patch | 62 + ...ove-unused-variable-from-get_exports.patch | 32 + ...h-to-m_offset-in-update_offset_entry.patch | 155 + ...rename-tree-implementation-functions.patch | 196 + ...offset-parent-in-update_offset_entry.patch | 96 + autofs-5.1.7-simplify-get_parent.patch | 101 + ...7-simplify-mount_subtree-mount-check.patch | 42 + ...-use-tree-implementation-for-offsets.patch | 398 + ...t-tree-root-for-tree_mapent_add_node.patch | 111 + ..._fullpath-in-one-spot-in-parse_mount.patch | 70 + ...rintf-when-constructing-hosts-mapent.patch | 72 + ...ific-with-NULL-key_thread_attempt_id.patch | 35 + ...-fail-on-duplicate-host-export-entry.patch | 46 + ...s-5.1.8-dont-use-initgroups-at-spawn.patch | 131 + ...-of-incorrect-return-from-umount_ent.patch | 110 + ...fix-kernel-mount-status-notification.patch | 135 + ...under-run-in-cache_get_offset_parent.patch | 36 + ...5.1.8-fix-memory-leak-in-xdr_exports.patch | 40 + ...t-fail-handling-of-last-offset-mount.patch | 38 + ...5.1.8-fix-root-offset-error-handling.patch | 86 + autofs-5.1.8-fix-set-open-file-limit.patch | 57 + ...fs-5.1.8-fix-sysconf-return-handling.patch | 64 + ...ee-in-tree_mapent_delete_offset_tree.patch | 55 + ...rove-descriptor-open-error-reporting.patch | 165 + ...eter-from-tree_mapent_umount_offsets.patch | 77 + ...fs-5.1.8-simplify-cache_add-a-little.patch | 44 + autofs.spec | 3024 ++++++++ sources | 1 + 239 files changed, 43720 insertions(+), 1 deletion(-) create mode 100644 .gitignore delete mode 100644 EMPTY create mode 100644 autofs-5.1.4-Makefiles.rules-remove-samples-from-SUBDIRS.patch create mode 100644 autofs-5.1.4-account-for-libnsl-changes.patch create mode 100644 autofs-5.1.4-add-NULL-check-in-prepare_attempt_prefix.patch create mode 100644 autofs-5.1.4-add-an-example-fedfs-master-map-entry-to-the-installed-master-map.patch create mode 100644 autofs-5.1.4-add-conditional-inclusion-of-fedfs-binaries.patch create mode 100644 autofs-5.1.4-add-error-handling-for-ext_mount_add.patch create mode 100644 autofs-5.1.4-add-fedfs-getsrvinfo_c.patch create mode 100644 autofs-5.1.4-add-fedfs-map-nfs4_c.patch create mode 100644 autofs-5.1.4-add-man-page-note-about-extra-slashes-in-paths.patch create mode 100644 autofs-5.1.4-add-master-map-pseudo-options-for-mount-propagation.patch create mode 100644 autofs-5.1.4-add-mount_fedfs_c.patch create mode 100644 autofs-5.1.4-add-systemd-service-command-line-option.patch create mode 100644 autofs-5.1.4-add-units-After-line-to-include-statd-service.patch create mode 100644 autofs-5.1.4-better-handle-hesiod-support-not-built-in.patch create mode 100644 autofs-5.1.4-change-expire-type-naming-to-better-reflect-usage.patch create mode 100644 autofs-5.1.4-covarity-fixes-1.patch create mode 100644 autofs-5.1.4-dont-allow-trailing-slash-in-master-map-mount-points.patch create mode 100644 autofs-5.1.4-dont-use-array-for-path-when-not-neccessary.patch create mode 100644 autofs-5.1.4-fix-NFS-version-mask-usage.patch create mode 100644 autofs-5.1.4-fix-age-setting-at-startup.patch create mode 100644 autofs-5.1.4-fix-amd-parser-opts-option-handling.patch create mode 100644 autofs-5.1.4-fix-deadlock-in-dumpmaps.patch create mode 100644 autofs-5.1.4-fix-directory-create-permission.patch create mode 100644 autofs-5.1.4-fix-error-return-in-do_nfs_mount.patch create mode 100644 autofs-5.1.4-fix-fd-leak-in-rpc_do_create_client.patch create mode 100644 autofs-5.1.4-fix-flag-file-permission.patch create mode 100644 autofs-5.1.4-fix-incorrect-locking-in-sss-lookup.patch create mode 100644 autofs-5.1.4-fix-libresolv-configure-check.patch create mode 100644 autofs-5.1.4-fix-monotonic_elapsed.patch create mode 100644 autofs-5.1.4-fix-prefix-option-handling-in-expand_entry.patch create mode 100644 autofs-5.1.4-fix-program-usage-message.patch create mode 100644 autofs-5.1.4-fix-sublink-option-not-set-from-defaults.patch create mode 100644 autofs-5.1.4-fix-update_negative_cache-map-source-usage.patch create mode 100644 autofs-5.1.4-fix-use-after-free-in-do_master_list_reset.patch create mode 100644 autofs-5.1.4-fix-use-after-free-in-parse_ldap_config.patch create mode 100644 autofs-5.1.4-improve-hostname-lookup-error-logging.patch create mode 100644 autofs-5.1.4-make-umount_ent-recognise-forced-umount.patch create mode 100644 autofs-5.1.4-mark-removed-cache-entry-negative.patch create mode 100644 autofs-5.1.4-move-close-stdio-descriptors-to-become_daemon.patch create mode 100644 autofs-5.1.4-remove-autofs4-module-load-code.patch create mode 100644 autofs-5.1.4-remove-unused-function-dump_master.patch create mode 100644 autofs-5.1.4-set-bind-mount-as-propagation-slave.patch create mode 100644 autofs-5.1.4-tiny-patch-for-autofs-typo-and-possible-bug.patch create mode 100644 autofs-5.1.4-update-build-info-with-systemd.patch create mode 100644 autofs-5.1.4-use-defines-for-expire-type.patch create mode 100644 autofs-5.1.4-use-flags-for-startup-boolean-options.patch create mode 100644 autofs-5.1.4-use-systemd-sd_notify-at-startup.patch create mode 100644 autofs-5.1.4-use_hostname_for_mounts-shouldnt-prevent-selection-among-replicas.patch create mode 100644 autofs-5.1.5-add-NULL-check-for-get_addr_string-return.patch create mode 100644 autofs-5.1.5-add-config-option-for-ignore-mount-option.patch create mode 100644 autofs-5.1.5-add-glibc-getmntent.patch create mode 100644 autofs-5.1.5-add-ignore-mount-option.patch create mode 100644 autofs-5.1.5-add-mount_verbose-configuration-option.patch create mode 100644 autofs-5.1.5-add-strictexpire-mount-option.patch create mode 100644 autofs-5.1.5-allow-period-following-macro-in-selector-value.patch create mode 100644 autofs-5.1.5-also-use-strictexpire-for-offsets.patch create mode 100644 autofs-5.1.5-always-use-PROC_MOUNTS-to-make-mount-lists.patch create mode 100644 autofs-5.1.5-dont-use-tree_is_mounted-for-mounted-checks.patch create mode 100644 autofs-5.1.5-fix-additional-typing-errors.patch create mode 100644 autofs-5.1.5-fix-amd-entry-memory-leak.patch create mode 100644 autofs-5.1.5-fix-hesiod-string-check-in-master_parse.patch create mode 100644 autofs-5.1.5-fix-macro-expansion-in-selector-values.patch create mode 100644 autofs-5.1.5-fix-missing-initialization-of-autofs_point-flags.patch create mode 100644 autofs-5.1.5-fix-unlink_mount_tree-not-umounting-mounts.patch create mode 100644 autofs-5.1.5-log-mount-call-arguments-if-mount_verbose-is-set.patch create mode 100644 autofs-5.1.5-make-expire-remaining-log-level-debug.patch create mode 100644 autofs-5.1.5-move-unlink_mount_tree-to-lib_mounts_c.patch create mode 100644 autofs-5.1.5-optionally-log-mount-requestor-process-info.patch create mode 100644 autofs-5.1.5-refactor-unlink_active_mounts-in-direct_c.patch create mode 100644 autofs-5.1.5-remove-a-couple-of-old-debug-messages.patch create mode 100644 autofs-5.1.5-remove-unused-function-has_fstab_option.patch create mode 100644 autofs-5.1.5-remove-unused-function-reverse_mnt_list.patch create mode 100644 autofs-5.1.5-use-bit-flags-for-autofs-mount-types-in-mnt_list.patch create mode 100644 autofs-5.1.5-use-ignore-option-for-offset-mounts-as-well.patch create mode 100644 autofs-5.1.5-use-local-getmntent_r-in-get_mnt_list.patch create mode 100644 autofs-5.1.5-use-local-getmntent_r-in-table_is_mounted.patch create mode 100644 autofs-5.1.5-use-local-getmntent_r-in-tree_get_mnt_list.patch create mode 100644 autofs-5.1.5-use-local_getmntent_r-for-unlink_mount_tree.patch create mode 100644 autofs-5.1.5-use-malloc-in-spawn_c.patch create mode 100644 autofs-5.1.5-use-mp-instead-of-path-in-mnt_list-entries.patch create mode 100644 autofs-5.1.5-use-single-unlink_umount_tree-for-both-direct-and-indirect-mounts.patch create mode 100644 autofs-5.1.6-add-a-hash-index-to-mnt_list.patch create mode 100644 autofs-5.1.6-add-force-unlink-mounts-and-exit-option.patch create mode 100644 autofs-5.1.6-add-hashtable-implementation.patch create mode 100644 autofs-5.1.6-add-helper-to-construct-mount-point-path.patch create mode 100644 autofs-5.1.6-add-sss-ECONREFUSED-return-handling.patch create mode 100644 autofs-5.1.6-add-support-for-new-sss-autofs-proto-version-call.patch create mode 100644 autofs-5.1.6-change-mountpoint-to-mp-in-struct-ext_mount.patch create mode 100644 autofs-5.1.6-cleanup-stale-logpri-fifo-pipes-on-unlink-and-exit.patch create mode 100644 autofs-5.1.6-dont-prune-offset-map-entries.patch create mode 100644 autofs-5.1.6-fix-a-regression-with-map-instance-lookup.patch create mode 100644 autofs-5.1.6-fix-autofs-mount-options-construction.patch create mode 100644 autofs-5.1.6-fix-browse-dir-not-re-created-on-symlink-expire.patch create mode 100644 autofs-5.1.6-fix-direct-mount-unlink_mount_tree-path.patch create mode 100644 autofs-5.1.6-fix-double-quoting-in-auto.smb.patch create mode 100644 autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch create mode 100644 autofs-5.1.6-fix-empty-mounts-list-return-from-unlink_mount_tree.patch create mode 100644 autofs-5.1.6-fix-incorrect-logical-compare-in-unlink_mount_tree.patch create mode 100644 autofs-5.1.6-fix-incorrect-systemctl-command-syntax-in-autofs-8.patch create mode 100644 autofs-5.1.6-fix-lookup_nss_read_master-nsswicth-check-return.patch create mode 100644 autofs-5.1.6-fix-program-map-multi-mount-lookup-after-mount-fail.patch create mode 100644 autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch create mode 100644 autofs-5.1.6-fix-remount-expire.patch create mode 100644 autofs-5.1.6-fix-retries-check-in-setautomntent_wait.patch create mode 100644 autofs-5.1.6-fix-sss-master-map-wait-timing.patch create mode 100644 autofs-5.1.6-fix-stale-offset-directories-disable-mount.patch create mode 100644 autofs-5.1.6-fix-trailing-dollar-sun-entry-expansion.patch create mode 100644 autofs-5.1.6-fix-typo-in-open_sss_lib.patch create mode 100644 autofs-5.1.6-fix-unlink-mounts-umount-order.patch create mode 100644 autofs-5.1.6-improve-force-unlink-mounts-option-description.patch create mode 100644 autofs-5.1.6-improve-sss-getautomntbyname-error-handling.patch create mode 100644 autofs-5.1.6-improve-sss-getautomntent-error-handling.patch create mode 100644 autofs-5.1.6-improve-sss-setautomntent-error-handling.patch create mode 100644 autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch create mode 100644 autofs-5.1.6-make-bind-mounts-propagation-slave-by-default.patch create mode 100644 autofs-5.1.6-make-external-mounts-independent-of-amd_entry.patch create mode 100644 autofs-5.1.6-make-external-mounts-use-simpler-hashtable.patch create mode 100644 autofs-5.1.6-make-umount_autofs-static.patch create mode 100644 autofs-5.1.6-mount_nfs_c-fix-local-rdma-share-not-mounting.patch create mode 100644 autofs-5.1.6-move-lib_master_c-to-daemon_master_c.patch create mode 100644 autofs-5.1.6-move-readall-into-struct-master.patch create mode 100644 autofs-5.1.6-move-submount-check-into-conditional_alarm_add.patch create mode 100644 autofs-5.1.6-only-add-expire-alarm-for-active-mounts.patch create mode 100644 autofs-5.1.6-refactor-sss-getautomntbyname.patch create mode 100644 autofs-5.1.6-refactor-sss-getautomntent.patch create mode 100644 autofs-5.1.6-refactor-sss-setautomntent.patch create mode 100644 autofs-5.1.6-remove-force-parameter-from-umount_all.patch create mode 100644 autofs-5.1.6-remove-intr-hosts-map-mount-option.patch create mode 100644 autofs-5.1.6-remove-logpri-fifo-on-autofs-mount-fail.patch create mode 100644 autofs-5.1.6-remove-unused-function-tree_get_mnt_list.patch create mode 100644 autofs-5.1.6-simplify-sss-source-stale-check.patch create mode 100644 autofs-5.1.6-sss-introduce-a-flag-to-indicate-map-being-read.patch create mode 100644 autofs-5.1.6-sss-introduce-retries-calcuation-function.patch create mode 100644 autofs-5.1.6-update-ldap-READMEs-and-schema-definitions.patch create mode 100644 autofs-5.1.6-update-list_h.patch create mode 100644 autofs-5.1.6-update-sss-timeout-documentation.patch create mode 100644 autofs-5.1.6-use-a-valid-timeout-in-lookup_prune_one_cache.patch create mode 100644 autofs-5.1.6-use-bit-flag-for-force-unlink-mounts.patch create mode 100644 autofs-5.1.6-use-mapname-in-sss-context-for-setautomntent.patch create mode 100644 autofs-5.1.6-use-master_list_empty-for-list-empty-check.patch create mode 100644 autofs-5.1.6-use-mnt_list-for-amdmounts.patch create mode 100644 autofs-5.1.6-use-mnt_list-for-submounts.patch create mode 100644 autofs-5.1.6-use-struct-mnt_list-mounted-list-for-expire.patch create mode 100644 autofs-5.1.6-use-struct-mnt_list-to-track-mounted-mounts.patch create mode 100644 autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch create mode 100644 autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch create mode 100644 autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch create mode 100644 autofs-5.1.7-add-mapent-tree-implementation.patch create mode 100644 autofs-5.1.7-add-missing-description-of-null-map-option.patch create mode 100644 autofs-5.1.7-add-missing-free-in-handle_mounts.patch create mode 100644 autofs-5.1.7-add-mount-and-umount-offsets-functions.patch create mode 100644 autofs-5.1.7-add-set_offset_tree_catatonic.patch create mode 100644 autofs-5.1.7-add-some-multi-mount-macros.patch create mode 100644 autofs-5.1.7-add-tree_mapent_add_node.patch create mode 100644 autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch create mode 100644 autofs-5.1.7-add-tree_mapent_delete_offsets.patch create mode 100644 autofs-5.1.7-add-tree_mapent_traverse_subtree.patch create mode 100644 autofs-5.1.7-add-xdr_exports.patch create mode 100644 autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch create mode 100644 autofs-5.1.7-check-for-offset-with-no-mount-location.patch create mode 100644 autofs-5.1.7-cleanup-cache_delete-a-little.patch create mode 100644 autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch create mode 100644 autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch create mode 100644 autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch create mode 100644 autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch create mode 100644 autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch create mode 100644 autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch create mode 100644 autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch create mode 100644 autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch create mode 100644 autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch create mode 100644 autofs-5.1.7-fix-amd-hosts-mount-expire.patch create mode 100644 autofs-5.1.7-fix-amd-section-mounts-map-reload.patch create mode 100644 autofs-5.1.7-fix-arg-not-used-in-print.patch create mode 100644 autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch create mode 100644 autofs-5.1.7-fix-direct-mount-deadlock.patch create mode 100644 autofs-5.1.7-fix-double-free-in-parse_mapent.patch create mode 100644 autofs-5.1.7-fix-double-unlock-in-parse_mount.patch create mode 100644 autofs-5.1.7-fix-flag-check-in-umount_multi.patch create mode 100644 autofs-5.1.7-fix-hosts-map-offset-order.patch create mode 100644 autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch create mode 100644 autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch create mode 100644 autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch create mode 100644 autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch create mode 100644 autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch create mode 100644 autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch create mode 100644 autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch create mode 100644 autofs-5.1.7-fix-mount_fullpath.patch create mode 100644 autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch create mode 100644 autofs-5.1.7-fix-offset-entries-order.patch create mode 100644 autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch create mode 100644 autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch create mode 100644 autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch create mode 100644 autofs-5.1.7-make-tree-implementation-data-independent.patch create mode 100644 autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch create mode 100644 autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch create mode 100644 autofs-5.1.7-pass-root-length-to-mount_fullpath.patch create mode 100644 autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch create mode 100644 autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch create mode 100644 autofs-5.1.7-refactor-umount_multi_triggers.patch create mode 100644 autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch create mode 100644 autofs-5.1.7-remove-mounts_mutex.patch create mode 100644 autofs-5.1.7-remove-obsolete-functions.patch create mode 100644 autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch create mode 100644 autofs-5.1.7-remove-redundant-if-check.patch create mode 100644 autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch create mode 100644 autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch create mode 100644 autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch create mode 100644 autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch create mode 100644 autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch create mode 100644 autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch create mode 100644 autofs-5.1.7-remove-unused-variable-from-get_exports.patch create mode 100644 autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch create mode 100644 autofs-5.1.7-rename-tree-implementation-functions.patch create mode 100644 autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch create mode 100644 autofs-5.1.7-simplify-get_parent.patch create mode 100644 autofs-5.1.7-simplify-mount_subtree-mount-check.patch create mode 100644 autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch create mode 100644 autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch create mode 100644 autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch create mode 100644 autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch create mode 100644 autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch create mode 100644 autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch create mode 100644 autofs-5.1.8-dont-use-initgroups-at-spawn.patch create mode 100644 autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch create mode 100644 autofs-5.1.8-fix-kernel-mount-status-notification.patch create mode 100644 autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch create mode 100644 autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch create mode 100644 autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch create mode 100644 autofs-5.1.8-fix-root-offset-error-handling.patch create mode 100644 autofs-5.1.8-fix-set-open-file-limit.patch create mode 100644 autofs-5.1.8-fix-sysconf-return-handling.patch create mode 100644 autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch create mode 100644 autofs-5.1.8-improve-descriptor-open-error-reporting.patch create mode 100644 autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch create mode 100644 autofs-5.1.8-simplify-cache_add-a-little.patch create mode 100644 autofs.spec create mode 100644 sources diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..13ecd52 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/autofs-5.1.4.tar.gz diff --git a/EMPTY b/EMPTY deleted file mode 100644 index 0519ecb..0000000 --- a/EMPTY +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/autofs-5.1.4-Makefiles.rules-remove-samples-from-SUBDIRS.patch b/autofs-5.1.4-Makefiles.rules-remove-samples-from-SUBDIRS.patch new file mode 100644 index 0000000..d06748d --- /dev/null +++ b/autofs-5.1.4-Makefiles.rules-remove-samples-from-SUBDIRS.patch @@ -0,0 +1,66 @@ +autofs-5.1.4 - Makefiles.rules: remove 'samples' from SUBDIRS + +From: NeilBrown + +The rules in Makefile make it quite clear that +'samples' is not expected to be part of SUBDIRS. +e.g. + - The rule for "clean" handles both $(SUBDIRS) *and* samples. + - There are separate "install" and "install_samples" targets. + +However SUBDIRS does contain 'samples'. This means that +a simple "make; make install" will over-write your configuration files. + +So remove 'samples' from SUBDIRS. Note that it has been removed in +the past, but then got added back again. + +Signed-off-by: NeilBrown +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + Makefile.rules | 2 +- + autofs.spec | 6 ++++++ + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 313730b1..1e5ec15b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -11,6 +11,7 @@ xx/xx/2018 autofs-5.1.5 + - account for recent libnsl changes. + - use_hostname_for_mounts shouldn't prevent selection among replicas. + - fix monotonic_elapsed. ++- Makefiles.rules: remove 'samples' from SUBDIRS. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/Makefile.rules b/Makefile.rules +index 2bfa043c..4deab3b9 100644 +--- a/Makefile.rules ++++ b/Makefile.rules +@@ -3,7 +3,7 @@ + # + + # Root directory contents +-SUBDIRS = lib daemon modules man samples ++SUBDIRS = lib daemon modules man + INCDIRS = include + INCFILES = COPYING COPYRIGHT NEWS README* TODO Makefile Makefile.rules \ + Makefile.conf.in .version .autofs-* configure.in aclocal.m4 \ +diff --git a/autofs.spec b/autofs.spec +index 6da0655d..57d8db46 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -121,6 +121,12 @@ install -m 755 redhat/autofs.init $RPM_BUILD_ROOT/etc/rc.d/init.d/autofs + install -m 644 redhat/autofs.conf $RPM_BUILD_ROOT/etc/autofs.conf + install -m 644 redhat/autofs.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/autofs + ++install -m 644 samples/auto.master $RPM_BUILD_ROOT/etc/auto.master ++install -m 644 samples/auto.misc $RPM_BUILD_ROOT/etc/auto.misc ++install -m 644 samples/auto.net $RPM_BUILD_ROOT/etc/auto.net ++install -m 644 samples/auto.smb $RPM_BUILD_ROOT/etc/auto.smb ++install -m 600 samples/autofs_ldap_auth.conf $RPM_BUILD_ROOT/etc/autofs_ldap_auth.conf ++ + %clean + [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + diff --git a/autofs-5.1.4-account-for-libnsl-changes.patch b/autofs-5.1.4-account-for-libnsl-changes.patch new file mode 100644 index 0000000..baf0af1 --- /dev/null +++ b/autofs-5.1.4-account-for-libnsl-changes.patch @@ -0,0 +1,557 @@ +autofs-5.1.4 - account for recent libnsl changes + +From: Ian Kent + +The glibc RPC code has been dropped. + +The NIS functionality comes in the libnsl library but it installs +its files into sub directories of the system include and library +directories. + +So configure needs to check for this and allow for it in the +compile and linking of the NIS and NIS+ lookup modules. +--- + CHANGELOG | 1 + Makefile.conf.in | 4 - + Makefile.rules | 2 + aclocal.m4 | 45 ++++++++ + configure | 288 ++++++++++++++++++++++++++++++++++++++++++++++++--- + configure.in | 27 ++--- + include/config.h.in | 3 + + modules/Makefile | 10 ++ + 8 files changed, 343 insertions(+), 37 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 9d19c0a7..2d5d5b1f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -8,6 +8,7 @@ xx/xx/2018 autofs-5.1.5 + - fix sublink option not set from defaults. + - fix error return in do_nfs_mount(). + - add error handling for ext_mount_add(). ++- account for recent libnsl changes. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/Makefile.conf.in b/Makefile.conf.in +index f879e262..85662654 100644 +--- a/Makefile.conf.in ++++ b/Makefile.conf.in +@@ -14,8 +14,8 @@ DAEMON_LDFLAGS = @DAEMON_LDFLAGS@ + # Glibc < 2.17 requires librt for clock_gettime() + LIBCLOCK_GETTIME = @LIBCLOCK_GETTIME@ + +-# Special parameters for glibc (libc 6) +-LIBNSL = @LIBNSL@ ++NSLLIB = @NSL_LIBS@ ++NSLCFLAGS = @NSL_CFLAGS@ + LIBRESOLV = @LIBRESOLV@ + + # Hesiod support: yes (1) no (0) +diff --git a/Makefile.rules b/Makefile.rules +index 0edf9bfe..2bfa043c 100644 +--- a/Makefile.rules ++++ b/Makefile.rules +@@ -54,8 +54,6 @@ ifdef DMALLOCLIB + LIBS += $(DMALLOCLIB) + endif + +-LIBS += $(LIBNSL) +- + LIBS += $(LIBCLOCK_GETTIME) + + # Standard rules +diff --git a/aclocal.m4 b/aclocal.m4 +index 51772043..f1ed3870 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -417,3 +417,48 @@ fi + LIBS="$af_check_ldap_parse_page_control_save_libs" + ]) + ++dnl -------------------------------------------------------------------------- ++dnl AF_CHECK_YPCLNT_HEADER ++dnl ++dnl Check for include file rpcsvc/ypclnt.h for YellowPages support. ++dnl -------------------------------------------------------------------------- ++AC_DEFUN([AF_CHECK_YPCLNT_HEADER], ++[ ++# save current CFLAGS ++af_check_ypclnt_header_save_cflags="$CFLAGS" ++CFLAGS="$CFLAGS $NSL_CFLAGS $TIRPC_CFLAGS" ++ ++HAVE_YPCLNT=0 ++AC_CHECK_HEADER([rpcsvc/ypclnt.h], HAVE_YPCLNT=1) ++AC_SUBST(HAVE_YPCLNT) ++if test "$HAVE_YPCLNT" = "1"; then ++ AC_DEFINE(HAVE_YPCLNT, 1, ++ [Define if using YellowPages]) ++fi ++ ++# restore libs ++CFLAGS="$af_check_ypclnt_header_save_cflags" ++]) ++ ++dnl -------------------------------------------------------------------------- ++dnl AF_CHECK_NIS_HEADER ++dnl ++dnl Check for include file rpcsvc/nis.h for NIS+ support. ++dnl -------------------------------------------------------------------------- ++AC_DEFUN([AF_CHECK_NIS_HEADER], ++[ ++# save current CFLAGS ++af_check_nis_header_save_cflags="$CFLAGS" ++CFLAGS="$CFLAGS $NSL_CFLAGS $TIRPC_CFLAGS" ++ ++HAVE_NISPLUS=0 ++AC_CHECK_HEADER([rpcsvc/nis.h], HAVE_NISPLUS=1) ++AC_SUBST(HAVE_NISPLUS) ++if test "$HAVE_NISPLUS" = "1"; then ++ AC_DEFINE(HAVE_NISPLUS, 1, ++ [Define if using NIS+]) ++fi ++ ++# restore libs ++CFLAGS="$af_check_nis_header_save_cflags" ++]) +diff --git a/configure b/configure +index 476cea4b..2d517aac 100755 +--- a/configure ++++ b/configure +@@ -634,8 +634,8 @@ XML_FLAGS + LIBLDAP + HAVE_LDAP + LDAP_FLAGS +-HAVE_YPCLNT + HAVE_NISPLUS ++HAVE_YPCLNT + EGREP + GREP + CPP +@@ -643,7 +643,8 @@ HESIOD_FLAGS + LIBHESIOD + HAVE_HESIOD + LIBRESOLV +-LIBNSL ++NSL_LIBS ++NSL_CFLAGS + LIBCLOCK_GETTIME + KRB5_CONFIG + XML_CONFIG +@@ -764,6 +765,8 @@ CFLAGS + LDFLAGS + LIBS + CPPFLAGS ++NSL_CFLAGS ++NSL_LIBS + CPP' + + +@@ -1417,6 +1420,8 @@ Some influential environment variables: + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory ++ NSL_CFLAGS C compiler flags for NSL, overriding pkg-config ++ NSL_LIBS linker flags for NSL, overriding pkg-config + CPP C preprocessor + + Use these variables to override the choices made by `configure' or to help +@@ -4500,9 +4505,186 @@ fi + + + +-# +-# glibc/libc 6 new libraries +-# ++ ++ ++ ++ ++ ++ ++ ++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. ++set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++PKG_CONFIG=$ac_cv_path_PKG_CONFIG ++if test -n "$PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 ++$as_echo "$PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_path_PKG_CONFIG"; then ++ ac_pt_PKG_CONFIG=$PKG_CONFIG ++ # Extract the first word of "pkg-config", so it can be a program name with args. ++set dummy pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $ac_pt_PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG ++if test -n "$ac_pt_PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 ++$as_echo "$ac_pt_PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_pt_PKG_CONFIG" = x; then ++ PKG_CONFIG="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ PKG_CONFIG=$ac_pt_PKG_CONFIG ++ fi ++else ++ PKG_CONFIG="$ac_cv_path_PKG_CONFIG" ++fi ++ ++fi ++if test -n "$PKG_CONFIG"; then ++ _pkg_min_version=0.9.0 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 ++$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } ++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ PKG_CONFIG="" ++ fi ++fi ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NSL" >&5 ++$as_echo_n "checking for NSL... " >&6; } ++ ++if test -n "$NSL_CFLAGS"; then ++ pkg_cv_NSL_CFLAGS="$NSL_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libnsl") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_NSL_CFLAGS=`$PKG_CONFIG --cflags "libnsl" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$NSL_LIBS"; then ++ pkg_cv_NSL_LIBS="$NSL_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libnsl") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_NSL_LIBS=`$PKG_CONFIG --libs "libnsl" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ NSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnsl" 2>&1` ++ else ++ NSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnsl" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$NSL_PKG_ERRORS" >&5 ++ ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yp_match in -lnsl" >&5 + $as_echo_n "checking for yp_match in -lnsl... " >&6; } + if ${ac_cv_lib_nsl_yp_match+:} false; then : +@@ -4540,10 +4722,66 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_yp_match" >&5 + $as_echo "$ac_cv_lib_nsl_yp_match" >&6; } + if test "x$ac_cv_lib_nsl_yp_match" = xyes; then : +- LIBNSL="-lnsl" ++ NSL_LIBS="-lnsl" + fi + + ++NSL_CFLAGS="" ++ ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for yp_match in -lnsl" >&5 ++$as_echo_n "checking for yp_match in -lnsl... " >&6; } ++if ${ac_cv_lib_nsl_yp_match+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lnsl $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* 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 yp_match (); ++int ++main () ++{ ++return yp_match (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_nsl_yp_match=yes ++else ++ ac_cv_lib_nsl_yp_match=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_yp_match" >&5 ++$as_echo "$ac_cv_lib_nsl_yp_match" >&6; } ++if test "x$ac_cv_lib_nsl_yp_match" = xyes; then : ++ NSL_LIBS="-lnsl" ++fi ++ ++ ++NSL_CFLAGS="" ++ ++else ++ NSL_CFLAGS=$pkg_cv_NSL_CFLAGS ++ NSL_LIBS=$pkg_cv_NSL_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_query in -lresolv" >&5 + $as_echo_n "checking for res_query in -lresolv... " >&6; } +@@ -4659,8 +4897,6 @@ fi + + LDFLAGS="${AF_tmp_ldflags}" + +-# NIS+ support? +-HAVE_NISPLUS=0 + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5058,15 +5294,11 @@ fi + done + + +-ac_fn_c_check_header_mongrel "$LINENO" "rpcsvc/nis.h" "ac_cv_header_rpcsvc_nis_h" "$ac_includes_default" +-if test "x$ac_cv_header_rpcsvc_nis_h" = xyes; then : +- HAVE_NISPLUS=1 +-fi +- + ++# save current CFLAGS ++af_check_ypclnt_header_save_cflags="$CFLAGS" ++CFLAGS="$CFLAGS $NSL_CFLAGS $TIRPC_CFLAGS" + +- +-# YellowPages support? + HAVE_YPCLNT=0 + ac_fn_c_check_header_mongrel "$LINENO" "rpcsvc/ypclnt.h" "ac_cv_header_rpcsvc_ypclnt_h" "$ac_includes_default" + if test "x$ac_cv_header_rpcsvc_ypclnt_h" = xyes; then : +@@ -5081,6 +5313,32 @@ $as_echo "#define HAVE_YPCLNT 1" >>confdefs.h + + fi + ++# restore libs ++CFLAGS="$af_check_ypclnt_header_save_cflags" ++ ++ ++# save current CFLAGS ++af_check_nis_header_save_cflags="$CFLAGS" ++CFLAGS="$CFLAGS $NSL_CFLAGS $TIRPC_CFLAGS" ++ ++HAVE_NISPLUS=0 ++ac_fn_c_check_header_mongrel "$LINENO" "rpcsvc/nis.h" "ac_cv_header_rpcsvc_nis_h" "$ac_includes_default" ++if test "x$ac_cv_header_rpcsvc_nis_h" = xyes; then : ++ HAVE_NISPLUS=1 ++fi ++ ++ ++ ++if test "$HAVE_NISPLUS" = "1"; then ++ ++$as_echo "#define HAVE_NISPLUS 1" >>confdefs.h ++ ++fi ++ ++# restore libs ++CFLAGS="$af_check_nis_header_save_cflags" ++ ++ + # + # OpenLDAP support? Expect that this may have a special directory... + # +diff --git a/configure.in b/configure.in +index d3660923..d74775cc 100644 +--- a/configure.in ++++ b/configure.in +@@ -209,11 +209,13 @@ fi + AC_CHECK_LIB(rt, clock_gettime, LIBCLOCK_GETTIME="-lrt") + AC_SUBST(LIBCLOCK_GETTIME) + +-# +-# glibc/libc 6 new libraries +-# +-AC_CHECK_LIB(nsl, yp_match, LIBNSL="-lnsl") +-AC_SUBST(LIBNSL) ++PKG_PROG_PKG_CONFIG() ++PKG_CHECK_MODULES([NSL],[libnsl],, ++[ ++AC_CHECK_LIB(nsl, yp_match, NSL_LIBS="-lnsl") ++AC_SUBST(NSL_LIBS) ++NSL_CFLAGS="" ++]) + + AC_CHECK_LIB(resolv, res_query, LIBRESOLV="-lresolv") + AC_SUBST(LIBRESOLV) +@@ -254,19 +256,8 @@ AC_SUBST(LIBHESIOD) + AC_SUBST(HESIOD_FLAGS) + LDFLAGS="${AF_tmp_ldflags}" + +-# NIS+ support? +-HAVE_NISPLUS=0 +-AC_CHECK_HEADER(rpcsvc/nis.h, HAVE_NISPLUS=1) +-AC_SUBST(HAVE_NISPLUS) +- +-# YellowPages support? +-HAVE_YPCLNT=0 +-AC_CHECK_HEADER([rpcsvc/ypclnt.h], HAVE_YPCLNT=1) +-AC_SUBST(HAVE_YPCLNT) +-if test "$HAVE_YPCLNT" = "1"; then +- AC_DEFINE(HAVE_YPCLNT, 1, +- [Define if using YellowPages]) +-fi ++AF_CHECK_YPCLNT_HEADER() ++AF_CHECK_NIS_HEADER() + + # + # OpenLDAP support? Expect that this may have a special directory... +diff --git a/include/config.h.in b/include/config.h.in +index 04873e8f..991a2bda 100644 +--- a/include/config.h.in ++++ b/include/config.h.in +@@ -57,6 +57,9 @@ + /* define if you have MOUNT_NFS */ + #undef HAVE_MOUNT_NFS + ++/* Define if using NIS+ */ ++#undef HAVE_NISPLUS ++ + /* define if the umount command supports the -c option */ + #undef HAVE_NO_CANON_UMOUNT + +diff --git a/modules/Makefile b/modules/Makefile +index d9ab06c5..0447559a 100644 +--- a/modules/Makefile ++++ b/modules/Makefile +@@ -116,6 +116,16 @@ parse_amd.so: parse_amd.c amd_parse.tab.o amd_tok.o + # + # Ad hoc compilation rules for modules which need auxilliary libraries + # ++lookup_yp.so: lookup_yp.c ++ $(CC) $(SOLDFLAGS) $(CFLAGS) $(NSLCFLAGS) -o lookup_yp.so \ ++ lookup_yp.c $(LDFLAGS) $(AUTOFS_LIB) $(LIBS) $(NSLLIB) ++ $(STRIP) lookup_yp.so ++ ++lookup_nisplus.so: lookup_nisplus.c ++ $(CC) $(SOLDFLAGS) $(CFLAGS) $(NSLCFLAGS) -o lookup_nisplus.so \ ++ lookup_nisplus.c $(LDFLAGS) $(AUTOFS_LIB) $(LIBS) $(NSLLIB) ++ $(STRIP) lookup_nisplus.so ++ + lookup_hesiod.so: lookup_hesiod.c + $(CC) $(SOLDFLAGS) $(CFLAGS) $(HESIOD_FLAGS) -o lookup_hesiod.so \ + lookup_hesiod.c $(LDFLAGS) $(AUTOFS_LIB) $(LIBHESIOD) $(LIBRESOLV) $(LIBS) diff --git a/autofs-5.1.4-add-NULL-check-in-prepare_attempt_prefix.patch b/autofs-5.1.4-add-NULL-check-in-prepare_attempt_prefix.patch new file mode 100644 index 0000000..cd730cf --- /dev/null +++ b/autofs-5.1.4-add-NULL-check-in-prepare_attempt_prefix.patch @@ -0,0 +1,34 @@ +autofs-5.1.4 - add NULL check in prepare_attempt_prefix() + +From: Ian Kent + +prepare_attempt_prefix() calls calloc(3) and continues without +checking if the allocation succeeded. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/log.c | 2 ++ + 2 files changed, 3 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -39,6 +39,7 @@ xx/xx/2018 autofs-5.1.5 + - better handle hesiod support not built in. + - fix hesiod string check in master_parse(). + - remove autofs4 module load code. ++- add NULL check in prepare_attempt_prefix(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/log.c ++++ autofs-5.1.4/lib/log.c +@@ -44,6 +44,8 @@ static char *prepare_attempt_prefix(cons + + snprintf(buffer, ATTEMPT_ID_SIZE, "%02lx", *attempt_id); + prefixed_msg = (char *) calloc(len, sizeof(char)); ++ if (!prefixed_msg) ++ return NULL; + strcpy(prefixed_msg, buffer); + strcat(prefixed_msg, "|"); + strcat(prefixed_msg, msg); diff --git a/autofs-5.1.4-add-an-example-fedfs-master-map-entry-to-the-installed-master-map.patch b/autofs-5.1.4-add-an-example-fedfs-master-map-entry-to-the-installed-master-map.patch new file mode 100644 index 0000000..ff3f5cc --- /dev/null +++ b/autofs-5.1.4-add-an-example-fedfs-master-map-entry-to-the-installed-master-map.patch @@ -0,0 +1,42 @@ +autofs-5.1.4 - add an example fedfs master map entry to the installed master map + +From: Ian Kent + +Add an example of using the fedfs program map (to facilitate access +to fedfs domain mounts) to the installed master map. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + samples/auto.master | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index bbe8019e..f771a433 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -18,6 +18,7 @@ xx/xx/2018 autofs-5.1.5 + - add mount.fedfs.c. + - add fedfs-map-nfs4.c. + - add conditional inclusion of fedfs binaries. ++- add an example fedfs master map entry to the installed master map. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/samples/auto.master b/samples/auto.master +index 0f2c8ab0..9a9968a3 100644 +--- a/samples/auto.master ++++ b/samples/auto.master +@@ -17,6 +17,12 @@ + # + +dir:/etc/auto.master.d + # ++# If you have fedfs set up and the related binaries, either ++# built as part of autofs or installed from another package, ++# uncomment this line to use the fedfs program map to access ++# your fedfs mounts. ++#/nfs4 /usr/sbin/fedfs-map-nfs4 nobind ++# + # Include central master map if it can be found using + # nsswitch sources. + # diff --git a/autofs-5.1.4-add-conditional-inclusion-of-fedfs-binaries.patch b/autofs-5.1.4-add-conditional-inclusion-of-fedfs-binaries.patch new file mode 100644 index 0000000..536165e --- /dev/null +++ b/autofs-5.1.4-add-conditional-inclusion-of-fedfs-binaries.patch @@ -0,0 +1,184 @@ +autofs-5.1.4 - add conditional inclusion of fedfs binaries + +From: Ian Kent + +Add conditional inclusion of the fedfs binaries. + +Using configure a --with-fedfs is needed to build and install +the fedfs binaries. + +Using rpmbuild -tb it's necessary to add the option +--without fedfs to exclude the fedfs binaries from the resulting +rpm package. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + Makefile.conf.in | 2 ++ + Makefile.rules | 6 +++++- + autofs.spec | 12 +++++++++++- + configure | 16 ++++++++++++++++ + configure.in | 9 +++++++++ + 6 files changed, 44 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 412e3382..bbe8019e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -17,6 +17,7 @@ xx/xx/2018 autofs-5.1.5 + - add fedfs-getsrvinfo.c. + - add mount.fedfs.c. + - add fedfs-map-nfs4.c. ++- add conditional inclusion of fedfs binaries. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/Makefile.conf.in b/Makefile.conf.in +index 85662654..3fe1a0a0 100644 +--- a/Makefile.conf.in ++++ b/Makefile.conf.in +@@ -58,6 +58,8 @@ EXT3FS = @HAVE_E3FSCK@ + # Support for calling e4fsck when mounting ext4 filesystems + EXT4FS = @HAVE_E4FSCK@ + ++FEDFS = @ENABLE_FEDFS@ ++ + LEX = @PATH_LEX@ + YACC = @PATH_YACC@ + RPCGEN = @PATH_RPCGEN@ +diff --git a/Makefile.rules b/Makefile.rules +index fc9f6019..2ccb1f6e 100644 +--- a/Makefile.rules ++++ b/Makefile.rules +@@ -3,12 +3,16 @@ + # + + # Root directory contents +-SUBDIRS = lib daemon fedfs modules man ++SUBDIRS = lib daemon modules man + INCDIRS = include + INCFILES = COPYING COPYRIGHT NEWS README* TODO Makefile Makefile.rules \ + Makefile.conf.in .version .autofs-* configure.in aclocal.m4 \ + configure *.patch autofs.spec + ++ifeq ($(FEDFS), 1) ++ SUBDIRS += fedfs ++endif ++ + # Attempt to be friends with autotools + INSTALLROOT = $(DESTDIR) + +diff --git a/autofs.spec b/autofs.spec +index 157c09b4..2cb09ef0 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -16,6 +16,10 @@ + # disable them. + %define with_libtirpc %{?_without_libtirpc: 0} %{?!_without_libtirpc: 1} + ++# Use --without fedfs in your rpmbuild command or force values to 0 to ++# disable them. ++%define with_fedfs %{?_without_fedfs: 0} %{?!_without_fedfs: 1} ++ + Summary: A tool from automatically mounting and umounting filesystems. + Name: autofs + %define version 5.1.4 +@@ -82,6 +86,9 @@ echo %{version}-%{release} > .version + %if %{with_libtirpc} + %define libtirpc_configure_arg --with-libtirpc + %endif ++%if %{with_fedfs} ++ %define fedfs_configure_arg --enable-fedfs ++%endif + + %build + CFLAGS="$RPM_OPT_FLAGS -Wall" \ +@@ -90,7 +97,8 @@ LDFLAGS="-Wl,-z,now" \ + --disable-mount-locking \ + --enable-ignore-busy \ + %{?systemd_configure_arg:} \ +- %{?libtirpc_configure_arg:} ++ %{?libtirpc_configure_arg:} \ ++ %{?fedfs_configure_arg:} + CFLAGS="$RPM_OPT_FLAGS -Wall" LDFLAGS="-Wl,-z,now" make initdir=/etc/rc.d/init.d DONTSTRIP=1 + + %install +@@ -191,8 +199,10 @@ fi + %config(noreplace) /etc/sysconfig/autofs + %config(noreplace) /etc/autofs_ldap_auth.conf + %{_sbindir}/automount ++%if %{with_fedfs} + %{_sbindir}/mount.fedfs + %{_sbindir}/fedfs-map-nfs4 ++%endif + %dir %{_libdir}/autofs + %{_libdir}/autofs/* + %{_mandir}/*/* +diff --git a/configure b/configure +index 5c8aae30..9682b36f 100755 +--- a/configure ++++ b/configure +@@ -648,6 +648,7 @@ NSL_CFLAGS + LIBCLOCK_GETTIME + KRB5_CONFIG + XML_CONFIG ++ENABLE_FEDFS + sssldir + HAVE_SSS_AUTOFS + PATH_RPCGEN +@@ -743,6 +744,7 @@ with_libtirpc + with_dmalloc + enable_sloppy_mount + enable_no_canon_umount ++enable_fedfs + with_hesiod + with_openldap + with_sasl +@@ -1377,6 +1379,7 @@ Optional Features: + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-sloppy-mount enable the use of the -s option to mount + --enable-no-canon-umount enable the use of the -c option to umount ++ --enable-fedfs enable inclusion of fedfs binaries mount.fedfs and fedfs-map-nfs4 + --disable-ext-env disable search in environment for substitution variable + --disable-mount-locking disable use of locking when spawning mount command + --enable-force-shutdown enable USR1 signal to force unlink umount of any +@@ -4246,6 +4249,19 @@ $as_echo "#define HAVE_NO_CANON_UMOUNT 1" >>confdefs.h + + fi + ++ENABLE_FEDFS="" ++# Check whether --enable-fedfs was given. ++if test "${enable_fedfs+set}" = set; then : ++ enableval=$enable_fedfs; ++else ++ enable_fedfs=no ++fi ++ ++if test x$enable_fedfs = xyes; then ++ ENABLE_FEDFS="1" ++fi ++ ++ + # LDAP SASL auth needs libxml and Kerberos + for ac_prog in xml2-config + do +diff --git a/configure.in b/configure.in +index 4d1208f5..de06a96d 100644 +--- a/configure.in ++++ b/configure.in +@@ -195,6 +195,15 @@ if test x$enable_no_canon_umount = xyes; then + AC_DEFINE(HAVE_NO_CANON_UMOUNT, 1, [define if the umount command supports the -c option]) + fi + ++ENABLE_FEDFS="" ++AC_ARG_ENABLE(fedfs, ++[ --enable-fedfs enable inclusion of fedfs binaries mount.fedfs and fedfs-map-nfs4],, ++ enable_fedfs=no) ++if test x$enable_fedfs = xyes; then ++ ENABLE_FEDFS="1" ++fi ++AC_SUBST(ENABLE_FEDFS) ++ + # LDAP SASL auth needs libxml and Kerberos + AF_CHECK_LIBXML() + AF_CHECK_KRB5() diff --git a/autofs-5.1.4-add-error-handling-for-ext_mount_add.patch b/autofs-5.1.4-add-error-handling-for-ext_mount_add.patch new file mode 100644 index 0000000..814ae30 --- /dev/null +++ b/autofs-5.1.4-add-error-handling-for-ext_mount_add.patch @@ -0,0 +1,121 @@ +autofs-5.1.4 - add error handling for ext_mount_add() + +From: Ian Kent + +Add error handling (memory allocation failures) for ext_mount_add(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 5 +---- + modules/parse_amd.c | 42 ++++++++++++++++++++++++++++++------------ + 3 files changed, 32 insertions(+), 16 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index d0cfa19b..9d19c0a7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -7,6 +7,7 @@ xx/xx/2018 autofs-5.1.5 + - fix prefix option handling in expand_entry(). + - fix sublink option not set from defaults. + - fix error return in do_nfs_mount(). ++- add error handling for ext_mount_add(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/lib/mounts.c b/lib/mounts.c +index 6fa304aa..f46fab2b 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -715,15 +715,12 @@ int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount + } + + em = malloc(sizeof(struct ext_mount)); +- if (!em) { +- ret = -1; ++ if (!em) + goto done; +- } + + em->mountpoint = strdup(path); + if (!em->mountpoint) { + free(em); +- ret = -1; + goto done; + } + em->umount = umount; +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 2a5d9a30..e7debc56 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1080,7 +1080,14 @@ static int do_generic_mount(struct autofs_point *ap, const char *name, + umount = 1; + } + /* We have an external mount */ +- ext_mount_add(&entry->ext_mount, entry->fs, umount); ++ if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) { ++ umount_ent(ap, entry->fs); ++ error(ap->logopt, MODPREFIX ++ "error: could not add external mount %s", ++ entry->fs); ++ ret = 1; ++ goto out; ++ } + ret = do_link_mount(ap, name, entry, flags); + } + out: +@@ -1124,7 +1131,13 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, + umount = 1; + } + /* We might be using an external mount */ +- ext_mount_add(&entry->ext_mount, entry->fs, umount); ++ if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) { ++ umount_ent(ap, entry->fs); ++ error(ap->logopt, MODPREFIX ++ "error: could not add external mount %s", entry->fs); ++ ret = 1; ++ goto out; ++ } + ret = do_link_mount(ap, name, entry, flags); + } + out: +@@ -1309,6 +1322,9 @@ static int do_program_mount(struct autofs_point *ap, + */ + if (ext_mount_inuse(entry->fs)) { + rv = 0; ++ /* An external mount with path entry->fs exists ++ * so ext_mount_add() won't fail. ++ */ + ext_mount_add(&entry->ext_mount, entry->fs, 1); + } else { + rv = mkdir_path(entry->fs, mp_mode); +@@ -1325,17 +1341,19 @@ static int do_program_mount(struct autofs_point *ap, + + rv = spawnv(ap->logopt, prog, (const char * const *) argv); + if (WIFEXITED(rv) && !WEXITSTATUS(rv)) { +- rv = 0; +- ext_mount_add(&entry->ext_mount, entry->fs, 1); +- debug(ap->logopt, MODPREFIX +- "%s: mounted %s", entry->type, entry->fs); +- } else { +- if (!ext_mount_inuse(entry->fs)) +- rmdir_path(ap, entry->fs, ap->dev); +- error(ap->logopt, MODPREFIX +- "%s: failed to mount using: %s", +- entry->type, entry->mount); ++ if (ext_mount_add(&entry->ext_mount, entry->fs, 1)) { ++ rv = 0; ++ debug(ap->logopt, MODPREFIX ++ "%s: mounted %s", entry->type, entry->fs); ++ goto do_free; ++ } ++ umount_ent(ap, entry->fs); + } ++ ++ if (!ext_mount_inuse(entry->fs)) ++ rmdir_path(ap, entry->fs, ap->dev); ++ error(ap->logopt, MODPREFIX ++ "%s: failed to mount using %s", entry->type, entry->mount); + } + do_free: + free_argv(argc, (const char **) argv); diff --git a/autofs-5.1.4-add-fedfs-getsrvinfo_c.patch b/autofs-5.1.4-add-fedfs-getsrvinfo_c.patch new file mode 100644 index 0000000..6863304 --- /dev/null +++ b/autofs-5.1.4-add-fedfs-getsrvinfo_c.patch @@ -0,0 +1,402 @@ +autofs-5.1.4 - add fedfs-getsrvinfo.c + +From: Ian Kent + +Add the fedfs domain information discovery library functions. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + fedfs/fedfs-getsrvinfo.c | 311 ++++++++++++++++++++++++++++++++++++++++++++++ + fedfs/fedfs-getsrvinfo.h | 52 ++++++++ + 3 files changed, 364 insertions(+) + create mode 100644 fedfs/fedfs-getsrvinfo.c + create mode 100644 fedfs/fedfs-getsrvinfo.h + +diff --git a/CHANGELOG b/CHANGELOG +index dbfb8389..8d6c737c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -14,6 +14,7 @@ xx/xx/2018 autofs-5.1.5 + - Makefiles.rules: remove 'samples' from SUBDIRS. + - dont allow trailing slash in master map mount points. + - fix libresolv configure check. ++- add fedfs-getsrvinfo.c. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/fedfs/fedfs-getsrvinfo.c b/fedfs/fedfs-getsrvinfo.c +new file mode 100644 +index 00000000..02ad16b5 +--- /dev/null ++++ b/fedfs/fedfs-getsrvinfo.c +@@ -0,0 +1,311 @@ ++/* ++ * Copyright 2011 Oracle. All rights reserved. ++ * ++ * This file is part of fedfs-utils. ++ * ++ * fedfs-utils is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2.0 as ++ * published by the Free Software Foundation. ++ * ++ * fedfs-utils 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 version 2.0 for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * version 2.0 along with fedfs-utils. If not, see: ++ * ++ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fedfs-getsrvinfo.h" ++ ++/** ++ * Parsing overlay for DNS query result record header. Fields are ++ * in network byte order. ++ */ ++struct rechdr { ++ uint16_t type; ++ uint16_t class; ++ uint32_t ttl; ++ uint16_t length; ++} __attribute__((__packed__)); ++ ++/** ++ * Parsing overlay for DNS query result SRV record data. Fields ++ * are in network byte order. ++ */ ++struct srv { ++ uint16_t priority; ++ uint16_t weight; ++ uint16_t port; ++ unsigned char *target; ++} __attribute__((__packed__)); ++ ++/** ++ * Return C string matching error value of "status" ++ * ++ * @param status error status returned by getsrvinfo ++ * @return pointer to static NUL-terminated C string containing error message ++ */ ++const char * ++gsi_strerror(int status) ++{ ++ static char buf[256]; ++ ++ switch (status) { ++ case ESI_SUCCESS: ++ return "Success"; ++ case ESI_NONAME: ++ return "Name not found"; ++ case ESI_AGAIN: ++ return "Temporary failure in name resolution"; ++ case ESI_FAIL: ++ return "Non-recoverable failure in name resolution"; ++ case ESI_NODATA: ++ return "No SRV record returned"; ++ case ESI_SERVICE: ++ return "Service is not available"; ++ case ESI_MEMORY: ++ return "Memory allocation failure"; ++ case ESI_SYSTEM: ++ snprintf(buf, sizeof(buf), "System error (%d): %s", ++ status, strerror(errno)); ++ return buf; ++ case ESI_PARSE: ++ return "Failed to parse server response"; ++ } ++ ++ snprintf(buf, sizeof(buf), "Unknown error (%d)", status); ++ return buf; ++} ++ ++/** ++ * Release a list of SRV records allocated by getsrvinfo() ++ * ++ * @param si pointer to first element of a list of struct srvinfo ++ * ++ */ ++void freesrvinfo(struct srvinfo *si) ++{ ++ struct srvinfo *tmp; ++ ++ while (si != NULL) { ++ tmp = si; ++ si = si->si_next; ++ free(tmp->si_target); ++ free(tmp); ++ } ++} ++ ++/** ++ * Ordering predicate for srvinfo lists ++ * ++ * @param a a srvinfo list element to compare ++ * @param b another srvinfo list element to compare ++ * @return true if "b" should fall later in the list than "a" ++ * ++ * See RFC 2782. The list is ordered as follows: ++ * ++ * o Lowest priority first. ++ * o In each priority class, highest weight first. ++ */ ++static _Bool ++srvinfo_is_after(const struct srvinfo *a, const struct srvinfo *b) ++{ ++ if (a->si_priority > b->si_priority) ++ return true; ++ if (a->si_priority < b->si_priority) ++ return false; ++ ++ if (a->si_weight < b->si_weight) ++ return true; ++ return false; ++} ++ ++/** ++ * Insert a srvinfo element into a list ++ * ++ * @param head pointer to head of list of elements ++ * @param entry new list element to insert ++ * ++ */ ++static void ++insert_srvinfo(struct srvinfo **head, struct srvinfo *entry) ++{ ++ entry->si_next = *head; ++ *head = entry; ++} ++ ++/** ++ * Insert a srvinfo element into a list, in order ++ * ++ * @param head pointer to head of list of elements ++ * @param entry new list element to insert ++ * ++ */ ++static void ++insert_srvinfo_sorted(struct srvinfo **head, struct srvinfo *entry) ++{ ++ struct srvinfo *spot, *back; ++ ++ spot = *head; ++ back = NULL; ++ while (spot && srvinfo_is_after(spot, entry)) { ++ back = spot; ++ spot = spot->si_next; ++ } ++ ++ if (spot == (*head)) ++ insert_srvinfo(head, entry); ++ else { ++ insert_srvinfo(&spot, entry); ++ /* off the end of the list? */ ++ if (spot == entry) ++ back->si_next = entry; ++ } ++} ++ ++/** ++ * Retrieve list of SRV records from DNS service ++ * ++ * @param srvname NUL-terminated C string containing record type to look up ++ * @param domainname NUL-terminated C string containing domain name to look up ++ * @param si OUT: list of SRV record information retrieved ++ * @return zero on success, or an ESI_ status code describing the error ++ * ++ * Caller must free list of records using freesrvinfo(). ++ */ ++int ++getsrvinfo(const char *srvname, const char *domainname, struct srvinfo **si) ++{ ++ unsigned char *msg, *eom, *comp_dn; ++ struct srvinfo *results; ++ unsigned short count, i; ++ int status, len; ++ char *exp_dn; ++ HEADER *hdr; ++ ++ msg = calloc(1, NS_MAXMSG); ++ exp_dn = calloc(1, NS_MAXDNAME); ++ if (msg == NULL || exp_dn == NULL) { ++ status = ESI_MEMORY; ++ goto out; ++ } ++ ++ _res.options |= RES_AAONLY; ++ len = res_querydomain(srvname, domainname, C_IN, T_SRV, msg, NS_MAXMSG); ++ if (len == -1) { ++ switch (h_errno) { ++ case HOST_NOT_FOUND: ++ status = ESI_NONAME; ++ break; ++ case TRY_AGAIN: ++ status = ESI_AGAIN; ++ break; ++ case NO_RECOVERY: ++ status = ESI_FAIL; ++ break; ++ case NO_DATA: ++ status = ESI_NODATA; ++ break; ++ default: ++ fprintf(stderr, "SRV query failed for %s.%s: %s\n", ++ srvname, domainname, hstrerror(h_errno)); ++ status = ESI_FAIL; ++ } ++ goto out; ++ } ++ ++ hdr = (HEADER *)msg; ++ count = ntohs(hdr->ancount); ++ if (count == 0) { ++ status = ESI_NODATA; ++ goto out; ++ } ++ eom = msg + len; ++ ++ comp_dn = &msg[HFIXEDSZ]; ++ comp_dn += dn_skipname(comp_dn, eom) + QFIXEDSZ; ++ ++ results = NULL; ++ for (i = 0; i < count; i++) { ++ struct srvinfo *new; ++ struct srv *record; ++ int l; ++ ++ l = dn_expand(msg, eom, comp_dn, exp_dn, NS_MAXDNAME); ++ if (l == -1) { ++ status = ESI_PARSE; ++ goto out_free; ++ } ++ comp_dn += l; ++ ++ record = (struct srv *)&comp_dn[10]; ++ comp_dn += 16; ++ ++ l = dn_expand(msg, eom, comp_dn, exp_dn, NS_MAXDNAME); ++ if (l == -1) { ++ status = ESI_PARSE; ++ goto out_free; ++ } ++ comp_dn += l; ++ ++ if (count == 1 && strcmp(exp_dn, ".") == 0) { ++ status = ESI_SERVICE; ++ goto out_free; ++ } ++ ++ new = calloc(1, sizeof(*new)); ++ if (new == NULL) { ++ status = ESI_MEMORY; ++ goto out; ++ } ++ ++ new->si_target = strdup(exp_dn); ++ if (new->si_target == NULL) { ++ free(new); ++ status = ESI_MEMORY; ++ goto out; ++ } ++ new->si_priority = ntohs(record->priority); ++ new->si_weight = ntohs(record->weight); ++ new->si_port = ntohs(record->port); ++ ++ insert_srvinfo_sorted(&results, new); ++ } ++ ++ status = ESI_SUCCESS; ++ *si = results; ++ ++out: ++ free(exp_dn); ++ free(msg); ++ return status; ++ ++out_free: ++ freesrvinfo(results); ++ goto out; ++} +diff --git a/fedfs/fedfs-getsrvinfo.h b/fedfs/fedfs-getsrvinfo.h +new file mode 100644 +index 00000000..13170359 +--- /dev/null ++++ b/fedfs/fedfs-getsrvinfo.h +@@ -0,0 +1,52 @@ ++/* ++ * Copyright 2011 Oracle. All rights reserved. ++ * ++ * This file is part of fedfs-utils. ++ * ++ * fedfs-utils is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2.0 as ++ * published by the Free Software Foundation. ++ * ++ * fedfs-utils 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 version 2.0 for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * version 2.0 along with fedfs-utils. If not, see: ++ * ++ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt ++ */ ++ ++#ifndef _FEDFS_GETSRVINFO_H_ ++#define _FEDFS_GETSRVINFO_H_ ++ ++/** ++ * Single list element containing SRV record data ++ */ ++struct srvinfo { ++ struct srvinfo *si_next; ++ char *si_target; ++ unsigned short si_priority; ++ unsigned short si_weight; ++ unsigned short si_port; ++}; ++ ++enum { ++ ESI_SUCCESS = 0, ++ ESI_NONAME = -2, ++ ESI_AGAIN = -3, ++ ESI_FAIL = -4, ++ ESI_NODATA = -5, ++ ESI_SERVICE = -8, ++ ESI_MEMORY = -10, ++ ESI_SYSTEM = -11, ++ ESI_PARSE = -1000, ++}; ++ ++int getsrvinfo(const char *srvname, const char *domainname, ++ struct srvinfo **si); ++void freesrvinfo(struct srvinfo *si); ++const char *gsi_strerror(int status); ++ ++#endif /* !_FEDFS_GETSRVINFO_H_ */ diff --git a/autofs-5.1.4-add-fedfs-map-nfs4_c.patch b/autofs-5.1.4-add-fedfs-map-nfs4_c.patch new file mode 100644 index 0000000..1563f68 --- /dev/null +++ b/autofs-5.1.4-add-fedfs-map-nfs4_c.patch @@ -0,0 +1,342 @@ +autofs-5.1.4 - add fedfs-map-nfs4.c + +From: Ian Kent + +Add build (and install) of the fedfs program map, fedfs-map-nfs4. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + autofs.spec | 1 + fedfs/Makefile | 12 ++- + fedfs/fedfs-map-nfs4.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++ + fedfs/fedfs-token.h | 40 +++++++++ + 5 files changed, 256 insertions(+), 2 deletions(-) + create mode 100644 fedfs/fedfs-map-nfs4.c + create mode 100644 fedfs/fedfs-token.h + +diff --git a/CHANGELOG b/CHANGELOG +index 88992147..412e3382 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -16,6 +16,7 @@ xx/xx/2018 autofs-5.1.5 + - fix libresolv configure check. + - add fedfs-getsrvinfo.c. + - add mount.fedfs.c. ++- add fedfs-map-nfs4.c. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/autofs.spec b/autofs.spec +index 2cc0e38f..157c09b4 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -192,6 +192,7 @@ fi + %config(noreplace) /etc/autofs_ldap_auth.conf + %{_sbindir}/automount + %{_sbindir}/mount.fedfs ++%{_sbindir}/fedfs-map-nfs4 + %dir %{_libdir}/autofs + %{_libdir}/autofs/* + %{_mandir}/*/* +diff --git a/fedfs/Makefile b/fedfs/Makefile +index cb325bed..dff749e4 100644 +--- a/fedfs/Makefile ++++ b/fedfs/Makefile +@@ -6,11 +6,13 @@ + include ../Makefile.rules + + SRCS = mount.fedfs.c +-HDRS = fedfs-getsrvinfo.h fedfs-gpl-boiler.h fedfs-nls.h ++HDRS = fedfs-getsrvinfo.h fedfs-gpl-boiler.h fedfs-nls.h \ ++ fedfs-token.h + + fedfs-getsrvinfo_OBJ = fedfs-getsrvinfo.o + + mount_fedfs_OBJ = mount.fedfs.o ++fedfs-map-nfs4_OBJ = fedfs-map-nfs4.o + + version := $(shell cat ../.version) + +@@ -18,18 +20,24 @@ CFLAGS += -rdynamic $(DAEMON_CFLAGS) -D_GNU_SOURCE -I../include + CFLAGS += -DVERSION_STRING=\"$(version)\" + LDFLAGS += -rdynamic + +-all: mount.fedfs ++all: mount.fedfs fedfs-map-nfs4 + + mount.fedfs: $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS) + $(CC) -o mount.fedfs \ + $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) \ + $(LDFLAGS) $(LIBRESOLV) $(LIBS) + ++fedfs-map-nfs4: $(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS) ++ $(CC) -o fedfs-map-nfs4 \ ++ $(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) \ ++ $(LDFLAGS) $(LIBRESOLV) $(LIBS) ++ + clean: + rm -f *.o *.s *~ mount.fedfs + + install: all + install -d -m 755 $(INSTALLROOT)$(sbindir) ++ install -c fedfs-map-nfs4 -m 755 $(INSTALLROOT)$(sbindir); \ + if ! test -x $(INSTALLROOT)$(sbindir)/mount.fedfs; \ + then \ + install -c mount.fedfs -m 755 $(INSTALLROOT)$(sbindir); \ +diff --git a/fedfs/fedfs-map-nfs4.c b/fedfs/fedfs-map-nfs4.c +new file mode 100644 +index 00000000..9f831cd7 +--- /dev/null ++++ b/fedfs/fedfs-map-nfs4.c +@@ -0,0 +1,204 @@ ++/* ++ * Copyright 2011 Oracle. All rights reserved. ++ * ++ * This file is part of fedfs-utils. ++ * ++ * fedfs-utils is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2.0 as ++ * published by the Free Software Foundation. ++ * ++ * fedfs-utils 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 version 2.0 for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * version 2.0 along with fedfs-utils. If not, see: ++ * ++ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fedfs-nls.h" ++#include "fedfs-token.h" ++#include "fedfs-getsrvinfo.h" ++#include "fedfs-gpl-boiler.h" ++ ++/** ++ * Name of SRV record containing NFSv4 FedFS root ++ */ ++#define FEDFS_NFS_DOMAINROOT "_nfs-domainroot._tcp" ++ ++/** ++ * Export pathname of NFSv4 FedFS root ++ */ ++#define FEDFS_NFS_EXPORTPATH "/.domainroot" ++ ++static char *progname; ++ ++/** ++ * Display usage message ++ */ ++static void ++fedfs_map_usage(void) ++{ ++ printf(_("\nUsage: %s [domain]\n\n"), progname); ++ ++ printf("%s", fedfs_gpl_boilerplate); ++} ++ ++/** ++ * Construct an NFSv4 map entry for "domainname" with one server ++ * ++ * @param si single-entry list of SRV records ++ * @param domainname NUL-terminated UTF-8 string containing name of FedFS domain ++ * @return command exit status ++ */ ++static int fedfs_map_nfs4_oneserver(struct srvinfo *si, const char *domainname) ++{ ++ printf("-fstype=nfs,vers=4,fg"); ++ if (si->si_port != 2049) ++ printf(",port=%u", si->si_port); ++ printf(" %s:%s/%s\n", si->si_target, FEDFS_NFS_EXPORTPATH, domainname); ++ return 0; ++} ++ ++/** ++ * Construct an NFSv4 map entry for "domainname" with multiple servers ++ * ++ * @param si list of SRV records for requested FedFS domain ++ * @param domainname NUL-terminated UTF-8 string containing name of FedFS domain ++ * @return command exit status ++ */ ++static int fedfs_map_nfs4_replicas(struct srvinfo *si, const char *domainname) ++{ ++ struct srvinfo *cur; ++ unsigned short port; ++ _Bool comma; ++ ++ /* ++ * Unfortunately our automounter can't handle a list of ++ * replicas where the various servers live on different ++ * ports from one another. ++ */ ++ port = si->si_port; ++ for (cur = si; cur != NULL; cur = cur->si_next) ++ if (cur->si_port != port) { ++ fprintf(stderr, _("%s: Replicas on different ports not supported\n"), ++ progname); ++ return 1; ++ } ++ ++ if (port != 2049) ++ printf("-fstype=nfs,vers=4,fg,port=%u ", port); ++ else ++ printf("-fstype=nfs,vers=4,fg "); ++ ++ /* ++ * Note that the export path is required to be indentical ++ * for all domain root servers for this domain. ++ */ ++ for (comma = false, cur = si; cur != NULL; cur = cur->si_next) { ++ if (comma) ++ printf(","); ++ printf("%s(%u)", cur->si_target, cur->si_weight); ++ comma = true; ++ } ++ printf(":%s/%s\n", FEDFS_NFS_EXPORTPATH, domainname); ++ ++ return 0; ++} ++ ++/** ++ * Construct an NFSv4 map entry for "domainname" ++ * ++ * @param domainname NUL-terminated UTF-8 string containing name of FedFS domain ++ * @return command exit status ++ */ ++static int fedfs_map_nfs4(const char *domainname) ++{ ++ struct srvinfo *cur, *si = NULL; ++ unsigned int count; ++ int error, result; ++ ++ result = 1; ++ error = getsrvinfo(FEDFS_NFS_DOMAINROOT, domainname, &si); ++ switch (error) { ++ case ESI_SUCCESS: ++ break; ++ case ESI_NONAME: ++ fprintf(stderr, _("%s: Domain name %s not found\n"), ++ progname, domainname); ++ goto out; ++ case ESI_SERVICE: ++ fprintf(stderr, _("%s: No FedFS domain root available for %s\n"), ++ progname, domainname); ++ goto out; ++ default: ++ fprintf(stderr, _("%s: Failed to resolve %s: %s\n"), ++ progname, domainname, gsi_strerror(error)); ++ goto out; ++ } ++ ++ for (count = 0, cur = si; cur != NULL; cur = cur->si_next) ++ count++; ++ if (count == 1) ++ result = fedfs_map_nfs4_oneserver(si, domainname); ++ else ++ result = fedfs_map_nfs4_replicas(si, domainname); ++ ++out: ++ freesrvinfo(si); ++ return result; ++} ++ ++/** ++ * Program entry point ++ * ++ * @param argc count of command line arguments ++ * @param argv array of NUL-terminated C strings containing command line arguments ++ * @return program exit status ++ */ ++int main(int argc, char *argv[]) ++{ ++ (void)setlocale(LC_ALL, ""); ++ ++ progname = basename(argv[0]); ++ ++ if (argc != 2) { ++ fedfs_map_usage(); ++ return 1; ++ } ++ ++ if (strcmp(progname, "fedfs-map-nfs4") == 0) ++ return fedfs_map_nfs4(argv[1]); ++#ifdef EXAMPLE ++ /* CIFS support might plug in here */ ++ else if (strcmp(progname, "fedfs-map-cifs") == 0) ++ return fedfs_map_cifs(argv[1]); ++#endif ++ ++ fprintf(stderr, _("%s: Unsupported file system type\n"), progname); ++ return 1; ++} +diff --git a/fedfs/fedfs-token.h b/fedfs/fedfs-token.h +new file mode 100644 +index 00000000..5651409d +--- /dev/null ++++ b/fedfs/fedfs-token.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) 2007 Oracle. All rights reserved. ++ * Copyright (C) 2007 Chuck Lever ++ * ++ * This file is part of fedfs-utils. ++ * ++ * fedfs-utils is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2.0 as ++ * published by the Free Software Foundation. ++ * ++ * fedfs-utils 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 version 2.0 for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * version 2.0 along with fedfs-utils. If not, see: ++ * ++ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt ++ */ ++ ++#ifndef _FEDFS_UTILS_TOKEN_H ++#define _FEDFS_UTILS_TOKEN_H ++ ++#include ++ ++/** ++ * Private tokenizer state object ++ */ ++struct tokenizer; ++ ++__attribute_malloc__ ++struct tokenizer *tk_new_tokenizer(const char *string, ++ const char delimiter); ++__attribute_malloc__ ++char *tk_next_token(struct tokenizer *state); ++void tk_free_tokenizer(struct tokenizer *state); ++int tk_tokenizer_error(const struct tokenizer *state); ++ ++#endif /* !_FEDFS_UTILS_TOKEN_H */ diff --git a/autofs-5.1.4-add-man-page-note-about-extra-slashes-in-paths.patch b/autofs-5.1.4-add-man-page-note-about-extra-slashes-in-paths.patch new file mode 100644 index 0000000..45b3646 --- /dev/null +++ b/autofs-5.1.4-add-man-page-note-about-extra-slashes-in-paths.patch @@ -0,0 +1,40 @@ +autofs-5.1.4 - add-man page note about extra slashes in paths + +From: Ian Kent + +Make note of the effect unnecessary multiple slashes can have in map +paths in auto.master(5). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/auto.master.5.in | 8 ++++++++ + 2 files changed, 9 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -25,6 +25,7 @@ xx/xx/2018 autofs-5.1.5 + - use systemd sd_notify() at startup. + - fix NFS version mask usage. + - fix fd leak in rpc_do_create_client(). ++- add-man page note about extra slashes in paths. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/man/auto.master.5.in ++++ autofs-5.1.4/man/auto.master.5.in +@@ -66,6 +66,14 @@ will process the map according to the sp + map entries. Indirect map entries must be unique in the master map so + second and subsequent entries for an indirect mount point are ignored by + .BR automount (8). ++.TP ++.B NOTE: ++autofs currently does not collapse multiple slashes in paths, so it is ++important to ensure paths used in maps are correct. If unnecessary multiple ++slashes are present in a path it can lead to unexpected failures such as ++an inability to expire automounts. An exception to this is a trailing slash ++at the end of the automount point path in the master map which will be ++removed if present. + .SH "FORMAT" + Master map entries have three fields separated by an arbitrary number + of spaces or tabs. Lines beginning with # are comments. The first field diff --git a/autofs-5.1.4-add-master-map-pseudo-options-for-mount-propagation.patch b/autofs-5.1.4-add-master-map-pseudo-options-for-mount-propagation.patch new file mode 100644 index 0000000..7a4c649 --- /dev/null +++ b/autofs-5.1.4-add-master-map-pseudo-options-for-mount-propagation.patch @@ -0,0 +1,179 @@ +autofs-5.1.4 - add master map pseudo options for mount propagation + +From: Ian Kent + +Add master map entry pseudo mount option of "slave" or "private" to +allow mount propagation of bind mounts to be set to either "slave" or +"private". + +This option may be needed when using multi-mounts that have bind mounts +that bind to a file system that is propagation shared. This is becuase +the bind mount will have the same properties as its target which causes +problems for offset mounts. When this happens an unwanted offset mount +is propagated back to the target file system resulting in a deadlock +when attempting to access the offset. + +By default bind mounts will inherit the mount propagation of the target +file system. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 4 ++++ + lib/master_parse.y | 13 +++++++++++++ + lib/master_tok.l | 2 ++ + man/auto.master.5.in | 12 ++++++++++++ + modules/mount_bind.c | 30 +++++++++++++++++++----------- + 6 files changed, 51 insertions(+), 11 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -31,6 +31,7 @@ xx/xx/2018 autofs-5.1.5 + - fix update_negative_cache() map source usage. + - mark removed cache entry negative. + - set bind mount as propagation slave. ++- add master map pseudo options for mount propagation. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -549,6 +549,10 @@ struct kernel_mod_version { + /* Read amd map even if it's not to be ghosted (browsable) */ + #define MOUNT_FLAG_AMD_CACHE_ALL 0x0080 + ++/* Set mount propagation for bind mounts */ ++#define MOUNT_FLAG_SLAVE 0x0100 ++#define MOUNT_FLAG_PRIVATE 0x0200 ++ + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ +--- autofs-5.1.4.orig/lib/master_parse.y ++++ autofs-5.1.4/lib/master_parse.y +@@ -58,6 +58,8 @@ static char *format; + static long timeout; + static long negative_timeout; + static unsigned symlnk; ++static unsigned slave; ++static unsigned private; + static unsigned nobind; + static unsigned ghost; + extern unsigned global_selection_options; +@@ -103,6 +105,7 @@ static int master_fprintf(FILE *, char * + %token MAP + %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE + %token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE ++%token OPT_SLAVE OPT_PRIVATE + %token COLON COMMA NL DDASH + %type map + %type options +@@ -196,6 +199,8 @@ line: + | PATH OPT_DEBUG { master_notify($1); YYABORT; } + | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } + | PATH OPT_SYMLINK { master_notify($1); YYABORT; } ++ | PATH OPT_SLAVE { master_notify($1); YYABORT; } ++ | PATH OPT_PRIVATE { master_notify($1); YYABORT; } + | PATH OPT_NOBIND { master_notify($1); YYABORT; } + | PATH OPT_GHOST { master_notify($1); YYABORT; } + | PATH OPT_NOGHOST { master_notify($1); YYABORT; } +@@ -600,6 +605,8 @@ option: daemon_option + daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } + | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } + | OPT_SYMLINK { symlnk = 1; } ++ | OPT_SLAVE { slave = 1; } ++ | OPT_PRIVATE { private = 1; } + | OPT_NOBIND { nobind = 1; } + | OPT_NOGHOST { ghost = 0; } + | OPT_GHOST { ghost = 1; } +@@ -672,6 +679,8 @@ static void local_init_vars(void) + timeout = -1; + negative_timeout = 0; + symlnk = 0; ++ slave = 0; ++ private = 0; + nobind = 0; + ghost = defaults_get_browse_mode(); + random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; +@@ -878,6 +887,10 @@ int master_parse_entry(const char *buffe + entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; + if (symlnk) + entry->ap->flags |= MOUNT_FLAG_SYMLINK; ++ if (slave) ++ entry->ap->flags |= MOUNT_FLAG_SLAVE; ++ if (private) ++ entry->ap->flags |= MOUNT_FLAG_PRIVATE; + if (negative_timeout) + entry->ap->negative_timeout = negative_timeout; + if (mode && mode < LONG_MAX) +--- autofs-5.1.4.orig/lib/master_tok.l ++++ autofs-5.1.4/lib/master_tok.l +@@ -389,6 +389,8 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTW + -?symlink { return(OPT_SYMLINK); } + -?nobind { return(OPT_NOBIND); } + -?nobrowse { return(OPT_NOGHOST); } ++ -?slave { return(OPT_SLAVE); } ++ -?private { return(OPT_PRIVATE); } + -g|--ghost|-?browse { return(OPT_GHOST); } + -v|--verbose { return(OPT_VERBOSE); } + -d|--debug { return(OPT_DEBUG); } +--- autofs-5.1.4.orig/man/auto.master.5.in ++++ autofs-5.1.4/man/auto.master.5.in +@@ -199,6 +199,18 @@ entries only, either in the master map ( + or with individual map entries. The option is ignored for direct mounts + and non-root offest mount entries. + .TP ++.I slave \fPor\fI private ++This option allows mount propagation of bind mounts to be set to ++either \fIslave\fP or \fIprivate\fP. This option may be needed when using ++multi-mounts that have bind mounts that bind to a file system that is ++propagation shared. This is becuase the bind mount will have the same ++properties as its target which causes problems for offset mounts. When ++this happens an unwanted offset mount is propagated back to the target ++file system resulting in a deadlock when attempting to access the offset. ++This option is a an autofs pseudo mount option that can be used in the ++master map only. By default bind mounts will inherit the mount propagation ++of the target file system. ++.TP + .I "\-r, \-\-random-multimount-selection" + Enables the use of random selection when choosing a host from a + list of replicated servers. This option is applied to this mount +--- autofs-5.1.4.orig/modules/mount_bind.c ++++ autofs-5.1.4/modules/mount_bind.c +@@ -186,17 +186,25 @@ int mount_mount(struct autofs_point *ap, + what, fstype, fullpath); + } + +- /* The bind mount has succeeded but if the target +- * mount is propagation shared propagation of child +- * mounts (autofs offset mounts for example) back to +- * the target of the bind mount must be avoided or +- * autofs trigger mounts will deadlock. +- */ +- err = mount(NULL, fullpath, NULL, MS_SLAVE, NULL); +- if (err) +- warn(ap->logopt, +- "failed to set propagation type for %s", +- fullpath); ++ if (ap->flags & (MOUNT_FLAG_SLAVE | MOUNT_FLAG_PRIVATE)) { ++ int flags = MS_SLAVE; ++ ++ if (ap->flags & MOUNT_FLAG_PRIVATE) ++ flags = MS_PRIVATE; ++ ++ /* The bind mount has succeeded but if the target ++ * mount is propagation shared propagation of child ++ * mounts (autofs offset mounts for example) back to ++ * the target of the bind mount must be avoided or ++ * autofs trigger mounts will deadlock. ++ */ ++ err = mount(NULL, fullpath, NULL, flags, NULL); ++ if (err) { ++ warn(ap->logopt, ++ "failed to set propagation for %s", ++ fullpath, root); ++ } ++ } + + return 0; + } else { diff --git a/autofs-5.1.4-add-mount_fedfs_c.patch b/autofs-5.1.4-add-mount_fedfs_c.patch new file mode 100644 index 0000000..9bda028 --- /dev/null +++ b/autofs-5.1.4-add-mount_fedfs_c.patch @@ -0,0 +1,696 @@ +autofs-5.1.4 - add mount.fedfs.c + +From: Ian Kent + +Add build and install of the mount.fedfs binary. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + Makefile | 3 + Makefile.rules | 2 + autofs.spec | 1 + fedfs/Makefile | 36 +++ + fedfs/fedfs-gpl-boiler.h | 40 ++++ + fedfs/fedfs-nls.h | 38 ++++ + fedfs/mount.fedfs.c | 485 ++++++++++++++++++++++++++++++++++++++++++++++ + 8 files changed, 605 insertions(+), 1 deletion(-) + create mode 100644 fedfs/Makefile + create mode 100644 fedfs/fedfs-gpl-boiler.h + create mode 100644 fedfs/fedfs-nls.h + create mode 100644 fedfs/mount.fedfs.c + +diff --git a/CHANGELOG b/CHANGELOG +index 8d6c737c..88992147 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -15,6 +15,7 @@ xx/xx/2018 autofs-5.1.5 + - dont allow trailing slash in master map mount points. + - fix libresolv configure check. + - add fedfs-getsrvinfo.c. ++- add mount.fedfs.c. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/Makefile b/Makefile +index e560a7cb..99db2c75 100644 +--- a/Makefile ++++ b/Makefile +@@ -19,6 +19,9 @@ kernel: + samples: + set -e; if [ -d samples ]; then $(MAKE) -C samples all; fi + ++fedfs: ++ set -e; if [ -d fedfs ]; then $(MAKE) -C fedfs all; fi ++ + clean: + for i in $(SUBDIRS) samples; do \ + if [ -d $$i ]; then $(MAKE) -C $$i clean; fi; done +diff --git a/Makefile.rules b/Makefile.rules +index 4deab3b9..fc9f6019 100644 +--- a/Makefile.rules ++++ b/Makefile.rules +@@ -3,7 +3,7 @@ + # + + # Root directory contents +-SUBDIRS = lib daemon modules man ++SUBDIRS = lib daemon fedfs modules man + INCDIRS = include + INCFILES = COPYING COPYRIGHT NEWS README* TODO Makefile Makefile.rules \ + Makefile.conf.in .version .autofs-* configure.in aclocal.m4 \ +diff --git a/autofs.spec b/autofs.spec +index 2464e741..2cc0e38f 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -191,6 +191,7 @@ fi + %config(noreplace) /etc/sysconfig/autofs + %config(noreplace) /etc/autofs_ldap_auth.conf + %{_sbindir}/automount ++%{_sbindir}/mount.fedfs + %dir %{_libdir}/autofs + %{_libdir}/autofs/* + %{_mandir}/*/* +diff --git a/fedfs/Makefile b/fedfs/Makefile +new file mode 100644 +index 00000000..cb325bed +--- /dev/null ++++ b/fedfs/Makefile +@@ -0,0 +1,36 @@ ++# ++# Makefile for mount.fedfs ++# ++ ++-include ../Makefile.conf ++include ../Makefile.rules ++ ++SRCS = mount.fedfs.c ++HDRS = fedfs-getsrvinfo.h fedfs-gpl-boiler.h fedfs-nls.h ++ ++fedfs-getsrvinfo_OBJ = fedfs-getsrvinfo.o ++ ++mount_fedfs_OBJ = mount.fedfs.o ++ ++version := $(shell cat ../.version) ++ ++CFLAGS += -rdynamic $(DAEMON_CFLAGS) -D_GNU_SOURCE -I../include ++CFLAGS += -DVERSION_STRING=\"$(version)\" ++LDFLAGS += -rdynamic ++ ++all: mount.fedfs ++ ++mount.fedfs: $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS) ++ $(CC) -o mount.fedfs \ ++ $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) \ ++ $(LDFLAGS) $(LIBRESOLV) $(LIBS) ++ ++clean: ++ rm -f *.o *.s *~ mount.fedfs ++ ++install: all ++ install -d -m 755 $(INSTALLROOT)$(sbindir) ++ if ! test -x $(INSTALLROOT)$(sbindir)/mount.fedfs; \ ++ then \ ++ install -c mount.fedfs -m 755 $(INSTALLROOT)$(sbindir); \ ++ fi +diff --git a/fedfs/fedfs-gpl-boiler.h b/fedfs/fedfs-gpl-boiler.h +new file mode 100644 +index 00000000..1353e736 +--- /dev/null ++++ b/fedfs/fedfs-gpl-boiler.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright 2011 Oracle. All rights reserved. ++ * ++ * This file is part of fedfs-utils. ++ * ++ * fedfs-utils is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2.0 as ++ * published by the Free Software Foundation. ++ * ++ * fedfs-utils 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 version 2.0 for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * version 2.0 along with fedfs-utils. If not, see: ++ * ++ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt ++ */ ++ ++#ifndef _GPL_BOILER_H_ ++#define _GPL_BOILER_H_ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++/** ++ * GPLv2 boilerplate for usage messages ++ */ ++static const char *fedfs_gpl_boilerplate = ++ "\nCopyright 2010, 2011, 2012, 2013 Oracle. " ++ "All rights reserved.\n\n" ++ "License GPLv2: " ++ "\n" ++ "This is free software. " ++ "You are free to change and redistribute it.\n" ++ "There is NO WARRANTY, to the extent permitted by law.\n"; ++ ++#endif /* !_GPL_BOILER_H_ */ +diff --git a/fedfs/fedfs-nls.h b/fedfs/fedfs-nls.h +new file mode 100644 +index 00000000..92f968d3 +--- /dev/null ++++ b/fedfs/fedfs-nls.h +@@ -0,0 +1,38 @@ ++/* ++ * From util-linux/include/nls.h (GPLv2) ++ */ ++ ++#ifndef UTIL_LINUX_NLS_H ++#define UTIL_LINUX_NLS_H ++ ++int main(int argc, char *argv[]); ++ ++#ifndef LOCALEDIR ++#define LOCALEDIR "/usr/share/locale" ++#endif ++ ++#ifdef HAVE_LOCALE_H ++# include ++#else ++# undef setlocale ++# define setlocale(Category, Locale) ({}) /* empty */ ++#endif ++ ++#ifdef ENABLE_NLS ++# include ++# define _(Text) gettext (Text) ++# ifdef gettext_noop ++# define N_(String) gettext_noop (String) ++# else ++# define N_(String) (String) ++# endif ++#else ++# undef bindtextdomain ++# define bindtextdomain(Domain, Directory) /* empty */ ++# undef textdomain ++# define textdomain(Domain) /* empty */ ++# define _(Text) (Text) ++# define N_(Text) (Text) ++#endif ++ ++#endif /* UTIL_LINUX_NLS_H */ +diff --git a/fedfs/mount.fedfs.c b/fedfs/mount.fedfs.c +new file mode 100644 +index 00000000..bd434395 +--- /dev/null ++++ b/fedfs/mount.fedfs.c +@@ -0,0 +1,485 @@ ++/* ++ * Copyright 2011 Oracle. All rights reserved. ++ * ++ * This file is part of fedfs-utils. ++ * ++ * fedfs-utils is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2.0 as ++ * published by the Free Software Foundation. ++ * ++ * fedfs-utils 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 version 2.0 for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * version 2.0 along with fedfs-utils. If not, see: ++ * ++ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fedfs-nls.h" ++#include "fedfs-getsrvinfo.h" ++#include "fedfs-gpl-boiler.h" ++ ++/** ++ * Top-level directory on client under which we mount NFSv4 domain roots ++ */ ++#define FEDFS_NFS4_TLDIR "nfs4" ++ ++/** ++ * Name of SRV record containing NFSv4 FedFS root ++ */ ++#define FEDFS_NFS_DOMAINROOT "_nfs-domainroot._tcp" ++ ++/** ++ * Export path of NFSv4 FedFS root ++ */ ++#define FEDFS_NFS_EXPORTPATH "/.domainroot" ++ ++/** ++ * Pathname to mount.nfs ++ */ ++#define MOUNT_NFS_EXECUTABLE "/sbin/mount.nfs" ++ ++/** ++ * Mount status values, lifted from util-linux ++ */ ++enum { ++ EX_SUCCESS = 0, ++ EX_USAGE = 1, ++ EX_FAIL = 32, ++}; ++ ++static char *progname; ++static int nomtab; ++static int verbose; ++static _Bool readonly; ++static _Bool sloppy; ++static _Bool fake; ++ ++/** ++ * Short form command line options ++ */ ++static const char fedfs_opts[] = "fhno:rsvVw"; ++ ++/** ++ * Long form command line options ++ */ ++static const struct option fedfs_longopts[] = ++{ ++ { "fake", 0, NULL, 'f' }, ++ { "help", 0, NULL, 'h' }, ++ { "no-mtab", 0, NULL, 'n' }, ++ { "options", 1, NULL, 'o' }, ++ { "read-only", 0, NULL, 'r' }, ++ { "read-write", 0, NULL, 'w' }, ++ { "ro", 0, NULL, 'r' }, ++ { "rw", 0, NULL, 'w' }, ++ { "sloppy", 0, NULL, 's' }, ++ { "verbose", 0, NULL, 'v' }, ++ { "version", 0, NULL, 'V' }, ++ { NULL, 0, NULL, 0 } ++}; ++ ++/** ++ * Display mount.fedfs usage message ++ */ ++static void ++mount_usage(void) ++{ ++ printf(_("\nUsage: %s remotedir localdir [-fhnrsvVw]\n\n"), progname); ++ printf(_("options:\n")); ++ printf(_("\t-f\t\tFake mount, do not actually mount\n")); ++ printf(_("\t-h\t\tPrint this help\n")); ++ printf(_("\t-n\t\tDo not update /etc/mtab\n")); ++ printf(_("\t-r\t\tMount file system readonly\n")); ++ printf(_("\t-s\t\tTolerate sloppy mount options\n")); ++ printf(_("\t-v\t\tVerbose\n")); ++ printf(_("\t-V\t\tPrint version\n")); ++ printf(_("\t-w\t\tMount file system read-write\n")); ++ ++ printf("%s", fedfs_gpl_boilerplate); ++} ++ ++/** ++ * Concatenate three strings ++ * ++ * @param s NUL-terminated C string ++ * @param t NUL-terminated C string ++ * @param u NUL-terminated C string ++ * @return pointer to NUL-terminated C string or NULL ++ * ++ * Caller must free the returned string with free(3). Always frees ++ * its first arg - typical use: s = xstrconcat3(s,t,u); ++ * ++ * Lifted from util-linux. ++ */ ++static char * ++xstrconcat3(char *s, const char *t, const char *u) ++{ ++ _Bool free_s = true; ++ char *result; ++ ++ if (s == NULL) { ++ s = ""; ++ free_s = false; ++ } ++ if (t == NULL) ++ t = ""; ++ if (u == NULL) ++ u = ""; ++ result = malloc(strlen(s) + strlen(t) + strlen(u) + 1); ++ if (result == NULL) ++ goto out; ++ ++ strcpy(result, s); ++ strcat(result, t); ++ strcat(result, u); ++ ++out: ++ if (free_s) ++ free(s); ++ return result; ++} ++ ++/** ++ * Exec mount.nfs ++ * ++ * @param server NUL-terminated C string containing name of NFS server ++ * @param port server port to use when mounting ++ * @param domainname NUL-terminated C string containing FedFS domain name ++ * @param export_path NUL-terminated C string containing server export path ++ * @param mounted_on_dir NUL-terminated C string containing local mounted-on directory ++ * @param text_options NUL-terminated C string containing user's mount options ++ * ++ */ ++static void ++exec_mount_nfs4(const char *server, unsigned short port, ++ const char *domainname, const char *export_path, ++ const char *mounted_on_dir, const char *text_options) ++{ ++ static char special[2048]; ++ static char options[2048]; ++ char *args[16]; ++ int count = 0; ++ ++ snprintf(special, sizeof(special), "%s:%s/%s%s", server, ++ FEDFS_NFS_EXPORTPATH, domainname, export_path); ++ ++ if (text_options != NULL && strcmp(text_options, "") != 0) ++ snprintf(options, sizeof(options), "%s,vers=4,fg,port=%u", ++ text_options, port); ++ else ++ snprintf(options, sizeof(options), "vers=4,fg,port=%u", port); ++ ++ if (verbose) { ++ printf(_("%s: Special device: %s\n"), ++ progname, special); ++ printf(_("%s: Mounted-on directory: %s\n"), ++ progname, mounted_on_dir); ++ printf(_("%s: Mount options: %s\n"), ++ progname, options); ++ } ++ ++ args[count++] = MOUNT_NFS_EXECUTABLE; ++ args[count++] = special; ++ args[count++] = (char *)mounted_on_dir; ++ if (verbose) ++ args[count++] = "-v"; ++ if (fake) ++ args[count++] = "-f"; ++ if (nomtab) ++ args[count++] = "-n"; ++ if (readonly) ++ args[count++] = "-r"; ++ if (sloppy) ++ args[count++] = "-s"; ++ args[count++] = "-o"; ++ args[count++] = options; ++ ++ args[count] = NULL; ++ execv(args[0], args); ++} ++ ++/** ++ * Mount a FedFS domain root via NFSv4 ++ * ++ * @param domainname NUL-terminated C string containing FedFS domain name ++ * @param export_path NUL-terminated C string containing server export path ++ * @param mounted_on_dir NUL-terminated C string containing local mounted-on directory ++ * @param text_options NUL-terminated C string containing user's mount options ++ * @return exit status code from the mount.nfs command ++ * ++ * Construct the server:/export string and the mounted-on directory string ++ * based on the DNS SRV query results, then fork and exec mount.nfs to do ++ * the actual mount request. ++ */ ++static int ++nfs4_mount(const char *domainname, const char *export_path, ++ const char *mounted_on_dir, const char *text_options) ++{ ++ struct srvinfo *tmp, *si = NULL; ++ int error, status; ++ ++ status = EX_FAIL; ++ ++ error = getsrvinfo(FEDFS_NFS_DOMAINROOT, domainname, &si); ++ switch (error) { ++ case ESI_SUCCESS: ++ break; ++ case ESI_NONAME: ++ fprintf(stderr, _("%s: Domain name %s not found\n"), ++ progname, domainname); ++ goto out; ++ case ESI_SERVICE: ++ fprintf(stderr, _("%s: No FedFS domain root available for %s\n"), ++ progname, domainname); ++ goto out; ++ default: ++ fprintf(stderr, _("%s: Failed to resolve %s: %s\n"), ++ progname, domainname, gsi_strerror(error)); ++ goto out; ++ } ++ ++ /* ++ * The srvinfo list is already in RFC 2782 sorted order. Try each ++ * SRV record once, in the foreground. Go with the first one that ++ * works. ++ */ ++ for (tmp = si; tmp != NULL; tmp = tmp->si_next) { ++ pid_t pid; ++ ++ pid = fork(); ++ switch (pid) { ++ case 0: ++ exec_mount_nfs4(tmp->si_target, tmp->si_port, ++ domainname, export_path, mounted_on_dir, ++ text_options); ++ /*NOTREACHED*/ ++ fprintf(stderr, _("%s: Failed to exec: %s\n"), ++ progname, strerror(errno)); ++ exit(EX_FAIL); ++ case -1: ++ fprintf(stderr, _("%s: Failed to fork: %s\n"), ++ progname, strerror(errno)); ++ goto out; ++ default: ++ waitpid(pid, &status, 0); ++ if (status == EX_SUCCESS) ++ goto out; ++ } ++ } ++ ++out: ++ freesrvinfo(si); ++ return status; ++} ++ ++/** ++ * Try one mount request ++ * ++ * @param source NUL-terminated C string containing name of "special device" ++ * @param target NUL-terminated C string containing local mounted-on directory ++ * @param text_options NUL-terminated C string containing user's mount options ++ * @return an exit status code ++ * ++ * Parse the pathname in "source." It contains the file system protocol ++ * and FedFS domain name. Then pass these arguments to the appropriate ++ * mount helper subcommand. ++ */ ++static int ++try_mount(const char *source, const char *target, const char *text_options) ++{ ++ char *global_name, *topdir, *domainname, *remaining; ++ int result; ++ ++ remaining = NULL; ++ result = EX_FAIL; ++ ++ global_name = strdup(source); ++ if (global_name == NULL) { ++ fprintf(stderr, _("%s: Unable to parse globally useful name\n"), ++ progname); ++ goto out; ++ } ++ ++ topdir = strtok(global_name, "/"); ++ if (topdir == NULL) { ++ fprintf(stderr, _("%s: Invalid globally useful name: %s\n"), ++ progname, source); ++ goto out; ++ } ++ if (verbose) ++ printf(_("%s: Top-level directory: %s\n"), ++ progname, topdir); ++ ++ domainname = strtok(NULL, "/"); ++ if (domainname == NULL) { ++ fprintf(stderr, _("%s: Missing domain name in globally " ++ "useful name: %s\n"), progname, source); ++ goto out; ++ } ++ if (verbose) ++ printf(_("%s: Domain name: %s\n"), ++ progname, domainname); ++ ++ remaining = strtok(NULL, "/"); ++ if (remaining == NULL) { ++ remaining = strdup("/"); ++ if (remaining == NULL) { ++ fprintf(stderr, _("%s: No memory\n"), progname); ++ goto out; ++ } ++ } else { ++ char *tmp; ++ ++ tmp = malloc(strlen(remaining) + 1); ++ if (tmp == NULL) { ++ fprintf(stderr, _("%s: No memory\n"), progname); ++ remaining = NULL; ++ goto out; ++ } ++ strcpy(tmp, "/"); ++ strcat(tmp, remaining); ++ remaining = tmp; ++ } ++ if (verbose) ++ printf(_("%s: Export path: %s\n"), ++ progname, remaining); ++ ++ if (strcmp(topdir, FEDFS_NFS4_TLDIR) == 0) ++ result = nfs4_mount(domainname, remaining, target, text_options); ++#if 0 ++ /* example: SMB support plugs in here */ ++ else if (strcmp(topdir, FEDFS_SMB_TLDIR) == 0) ++ result = smb_mount(domainname, remaining, target, text_options); ++#endif ++ else ++ fprintf(stderr, _("%s: Unrecognized file system protocol\n"), progname); ++ ++out: ++ free(global_name); ++ free(remaining); ++ ++ return result; ++} ++ ++/** ++ * Program entry point ++ * ++ * @param argc count of command line arguments ++ * @param argv array of NUL-terminated C strings containing command line arguments ++ * @return program exit status ++ */ ++int main(int argc, char *argv[]) ++{ ++ char *source, *target, *text_options; ++ int c, mnt_err; ++ ++ (void)setlocale(LC_ALL, ""); ++ ++ progname = basename(argv[0]); ++ ++ if (argv[1] && argv[1][0] == '-') { ++ if(argv[1][1] == 'V') ++ printf("%s (VERSION_STRING)\n", progname); ++ else ++ mount_usage(); ++ exit(EX_SUCCESS); ++ } ++ ++ if (argc < 3) { ++ mount_usage(); ++ exit(EX_USAGE); ++ } ++ ++ source = argv[1]; ++ target = argv[2]; ++ ++ mnt_err = EX_USAGE; ++ text_options = NULL; ++ readonly = false; ++ sloppy = false; ++ fake = false; ++ argv[2] = argv[0]; /* so that getopt error messages are correct */ ++ while ((c = getopt_long(argc - 2, argv + 2, fedfs_opts, ++ fedfs_longopts, NULL)) != -1) { ++ switch (c) { ++ case 'f': ++ fake = true; ++ break; ++ case 'n': ++ ++nomtab; ++ break; ++ case 'o': ++ /* Ugh. */ ++ if (text_options != NULL) ++ text_options = xstrconcat3(text_options, ",", optarg); ++ else ++ text_options = strdup(optarg); ++ if (text_options == NULL) { ++ fprintf(stderr, _("%s: No memory\n"), progname); ++ goto out; ++ } ++ break; ++ case 'r': ++ readonly = true; ++ break; ++ case 's': ++ sloppy = true; ++ break; ++ case 'v': ++ ++verbose; ++ break; ++ case 'V': ++ printf("%s: (VERSION_STRING)\n", progname); ++ mnt_err = EX_SUCCESS; ++ goto out; ++ case 'w': ++ readonly = false; ++ break; ++ case 'h': ++ default: ++ mount_usage(); ++ goto out; ++ } ++ } ++ ++ /* Extra non-option words at the end are bogus... */ ++ if (optind != argc - 2) { ++ mount_usage(); ++ goto out; ++ } ++ ++ if (getuid() != 0 && geteuid() != 0) { ++ fprintf(stderr, _("%s: Not installed setuid - " ++ "\"user\" FedFS mounts are not supported\n"), progname); ++ mnt_err = EX_FAIL; ++ goto out; ++ } ++ ++ mnt_err = try_mount(source, target, text_options); ++ ++out: ++ free(text_options); ++ exit(mnt_err); ++} diff --git a/autofs-5.1.4-add-systemd-service-command-line-option.patch b/autofs-5.1.4-add-systemd-service-command-line-option.patch new file mode 100644 index 0000000..ba8838d --- /dev/null +++ b/autofs-5.1.4-add-systemd-service-command-line-option.patch @@ -0,0 +1,137 @@ +autofs-5.1.4 - add systemd service command line option + +From: Ian Kent + +When run as a systemd service using the systemd notification method to +synchronise startup, logging should be done to syslog so the log entry +format is consistent between daemon and systemd usage. + +So, rather than run use the forground option, add an option to tell +the automounter it's being run as a systemd service and use syslog +for logging when its present on the command line. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 22 +++++++++++++++++++--- + include/automount.h | 1 + + man/automount.8 | 4 ++++ + samples/autofs.service.in | 2 +- + 5 files changed, 26 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -43,6 +43,7 @@ xx/xx/2018 autofs-5.1.5 + - update build info with systemd. + - use flags for startup boolean options. + - move close stdio descriptors to become_daemon(). ++- add systemd service command line option. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1210,13 +1210,21 @@ static void become_daemon(unsigned int f + } + + /* Detach from foreground process */ +- if (flags & DAEMON_FLAGS_FOREGROUND) { ++ if (flags & DAEMON_FLAGS_FOREGROUND && ++ !(flags & DAEMON_FLAGS_SYSTEMD_SERVICE)) { + if ((flags & DAEMON_FLAGS_CHECK_DAEMON) && !aquire_flag_file()) { + fprintf(stderr, "%s: program is already running.\n", + program); + exit(1); + } + log_to_stderr(); ++ } else if (flags & DAEMON_FLAGS_SYSTEMD_SERVICE) { ++ if ((flags & DAEMON_FLAGS_CHECK_DAEMON) && !aquire_flag_file()) { ++ fprintf(stderr, "%s: program is already running.\n", ++ program); ++ exit(1); ++ } ++ open_log(); + } else { + int nullfd; + +@@ -1925,6 +1933,8 @@ static void usage(void) + " -d --debug log debuging info\n" + " -Dvariable=value, --define variable=value\n" + " define global macro variable\n" ++ " -S --systemd-service\n" ++ " run automounter as a systemd service\n" + " -f --foreground do not fork into background\n" + " -r --random-multimount-selection\n" + " use ramdom replicated server selection\n" +@@ -2190,7 +2200,7 @@ int main(int argc, char *argv[]) + time_t timeout; + time_t age = monotonic_time(NULL); + struct rlimit rlim; +- const char *options = "+hp:t:vmdD:fVrO:l:n:CFM"; ++ const char *options = "+hp:t:vmdD:SfVrO:l:n:CFM"; + static const struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"pid-file", 1, 0, 'p'}, +@@ -2198,6 +2208,7 @@ int main(int argc, char *argv[]) + {"verbose", 0, 0, 'v'}, + {"debug", 0, 0, 'd'}, + {"define", 1, 0, 'D'}, ++ {"systemd-service", 0, 0, 'S'}, + {"foreground", 0, 0, 'f'}, + {"random-multimount-selection", 0, 0, 'r'}, + {"negative-timeout", 1, 0, 'n'}, +@@ -2266,6 +2277,10 @@ int main(int argc, char *argv[]) + macro_parse_globalvar(optarg); + break; + ++ case 'S': ++ flags |= DAEMON_FLAGS_SYSTEMD_SERVICE; ++ break; ++ + case 'f': + flags |= DAEMON_FLAGS_FOREGROUND; + break; +@@ -2653,7 +2668,8 @@ int main(int argc, char *argv[]) + } + + #ifdef WITH_SYSTEMD +- sd_notify(1, "READY=1"); ++ if (flags & DAEMON_FLAGS_SYSTEMD_SERVICE) ++ sd_notify(1, "READY=1"); + #endif + + state_mach_thid = pthread_self(); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -67,6 +67,7 @@ + #endif + + #define DAEMON_FLAGS_FOREGROUND 0x0001 ++#define DAEMON_FLAGS_SYSTEMD_SERVICE 0x0002 + #define DAEMON_FLAGS_HAVE_GLOBAL_OPTIONS 0x0004 + #define DAEMON_FLAGS_GHOST 0x0008 + #define DAEMON_FLAGS_CHECK_DAEMON 0x0010 +--- autofs-5.1.4.orig/man/automount.8 ++++ autofs-5.1.4/man/automount.8 +@@ -57,6 +57,10 @@ Define a global macro substitution varia + are over-ridden macro definitions of the same name specified in + mount entries. + .TP ++.I \-S, \-\-systemd-service ++Used when running the automounter as a systemd service to ensure log entry ++format is consistent with the log entry format when running as a daemon. ++.TP + .I "\-f, \-\-foreground" + Run the daemon in the foreground and log to stderr instead of syslog." + .TP +--- autofs-5.1.4.orig/samples/autofs.service.in ++++ autofs-5.1.4/samples/autofs.service.in +@@ -6,7 +6,7 @@ Wants=network-online.target rpc-statd.se + [Service] + Type=notify + EnvironmentFile=-@@autofsconfdir@@/autofs +-ExecStart=@@sbindir@@/automount $OPTIONS --foreground --dont-check-daemon ++ExecStart=@@sbindir@@/automount $OPTIONS --systemd-service --dont-check-daemon + ExecReload=/usr/bin/kill -HUP $MAINPID + KillMode=process + TimeoutSec=180 diff --git a/autofs-5.1.4-add-units-After-line-to-include-statd-service.patch b/autofs-5.1.4-add-units-After-line-to-include-statd-service.patch new file mode 100644 index 0000000..c5b6ee4 --- /dev/null +++ b/autofs-5.1.4-add-units-After-line-to-include-statd-service.patch @@ -0,0 +1,39 @@ +autofs-5.1.4 - add units After line to include statd service + +From: Ian Kent + +autofs needs to ensure statd is started before any NFS mounts +are attempted. This is because if the first NFS mount starts +the service and the mount is an automounted directory that is +included in the PATH used by systemctl (eg. /usr/local/bin) +the mount cannot complete. + +Add rpc-statd.service to the unit "After=" line to try and +ensure it is started before automount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + samples/autofs.service.in | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -21,6 +21,7 @@ xx/xx/2018 autofs-5.1.5 + - add an example fedfs master map entry to the installed master map. + - improve hostname lookup error logging. + - tiny patch for autofs typo and possible bug. ++- add units After line to include statd service. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/samples/autofs.service.in ++++ autofs-5.1.4/samples/autofs.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Automounts filesystems on demand +-After=network.target ypbind.service sssd.service network-online.target remote-fs.target ++After=network.target ypbind.service sssd.service network-online.target remote-fs.target rpc-statd.service rpcbind.service + Wants=network-online.target rpc-statd.service rpcbind.service + + [Service] diff --git a/autofs-5.1.4-better-handle-hesiod-support-not-built-in.patch b/autofs-5.1.4-better-handle-hesiod-support-not-built-in.patch new file mode 100644 index 0000000..eb62296 --- /dev/null +++ b/autofs-5.1.4-better-handle-hesiod-support-not-built-in.patch @@ -0,0 +1,130 @@ +autofs-5.1.4 - better handle hesiod support not built in + +From: Ian Kent + +The configure option --without-hesiod is not handled well. + +If this option is given and hesiod is seen in the master +map parser or the amd map parser issue a message telling +the user hesiod support isn't built in. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/master_parse.y | 18 ++++++++++++++++-- + modules/amd_parse.y | 7 +++++++ + modules/parse_amd.c | 28 +++++++++++++++++++++++++--- + 4 files changed, 49 insertions(+), 5 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -36,6 +36,7 @@ xx/xx/2018 autofs-5.1.5 + - fix use after free in parse_ldap_config(). + - fix incorrect locking in sss lookup. + - fix amd parser opts option handling. ++- better handle hesiod support not built in. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/master_parse.y ++++ autofs-5.1.4/lib/master_parse.y +@@ -171,7 +171,14 @@ line: + + if ((tmp = strchr($2, ','))) + *tmp++ = '\0'; +- ++#ifndef WITH_HESIOD ++ /* Map type or or map type parser is hesiod */ ++ if (!strcmp($2, "hesiod") || !strcmp(tmp, "hesiod")) { ++ master_error("hesiod support not built in"); ++ local_free_vars(); ++ YYABORT; ++ } ++#endif + if (type) + free(type); + type = master_strdup($2); +@@ -352,7 +359,14 @@ map: PATH + + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; +- ++#ifndef WITH_HESIOD ++ /* Map type or or map type parser is hesiod */ ++ if (!strcmp($1, "hesiod") || !strcmp(tmp, "hesiod")) { ++ master_error("hesiod support not built in"); ++ local_free_vars(); ++ YYABORT; ++ } ++#endif + if (type) + free(type); + if (strcmp($1, "exec")) +--- autofs-5.1.4.orig/modules/amd_parse.y ++++ autofs-5.1.4/modules/amd_parse.y +@@ -574,6 +574,13 @@ static int match_map_option_map_type(cha + !strcmp(map_type, "nisplus") || + !strcmp(map_type, "ldap") || + !strcmp(map_type, "hesiod")) { ++#ifndef WITH_HESIOD ++ if (!strcmp(map_type, "hesiod")) { ++ amd_msg("hesiod support not built in"); ++ free(map_type); ++ return 0; ++ } ++#endif + amd_set_value(&entry.map_type, map_type); + } else if (!strcmp(map_type, "exec")) { + /* autofs uses "program" for "exec" map type */ +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1871,15 +1871,25 @@ struct amd_entry *make_default_entry(str + if (amd_parse_list(ap, defaults, &dflts, &sv)) + return NULL; + defaults_entry = list_entry(dflts.next, struct amd_entry, list); +- list_del_init(&defaults_entry->list); + /* + * If map type isn't given try to inherit from + * parent. A NULL map type is valid and means + * use configured nss sources. + */ + map_type = conf_amd_get_map_type(ap->path); +- if (map_type) ++ if (map_type) { + defaults_entry->map_type = map_type; ++#ifndef HAVE_HESIOD ++ if (!strcmp(map_type, "hesiod")) { ++ warn(ap->logopt, MODPREFIX ++ "hesiod support not built in, " ++ "defaults map entry not set"); ++ defaults_entry = NULL; ++ } ++#endif ++ } ++ if (defaults_entry) ++ list_del_init(&defaults_entry->list); + /* The list should now be empty .... */ + free_amd_entry_list(&dflts); + return defaults_entry; +@@ -2005,8 +2015,20 @@ static struct amd_entry *get_defaults_en + * use configured nss sources. + */ + char *map_type = conf_amd_get_map_type(ap->path); +- if (map_type) ++ if (map_type) { + entry->map_type = map_type; ++#ifndef HAVE_HESIOD ++ if (!strcmp(map_type, "hesiod")) { ++ warn(ap->logopt, MODPREFIX ++ "hesiod support not built in, " ++ "attempting to use internal " ++ "default"); ++ free_amd_entry(entry); ++ free(expand); ++ goto out; ++ } ++#endif ++ } + } + free(expand); + } diff --git a/autofs-5.1.4-change-expire-type-naming-to-better-reflect-usage.patch b/autofs-5.1.4-change-expire-type-naming-to-better-reflect-usage.patch new file mode 100644 index 0000000..f84b343 --- /dev/null +++ b/autofs-5.1.4-change-expire-type-naming-to-better-reflect-usage.patch @@ -0,0 +1,136 @@ +autofs-5.1.4 - change expire type naming to better reflect usage + +From: Ian Kent + +Expires can request different types of expire, currently normal or +immediate (and later force). + +Change the naming used in the expire functions to better indicate +usage. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 8 ++++---- + daemon/indirect.c | 8 ++++---- + daemon/state.c | 4 ++-- + include/state.h | 2 +- + 5 files changed, 12 insertions(+), 11 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -54,6 +54,7 @@ xx/xx/2018 autofs-5.1.5 + - allow period following macro in selector value. + - fix macro expansion in selector values. + - also use strictexpire for offsets. ++- change expire type naming to better reflect usage. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -861,7 +861,7 @@ void *expire_proc_direct(void *arg) + struct expire_args ec; + struct autofs_point *ap; + struct mapent *me = NULL; +- unsigned int now; ++ unsigned int how; + int ioctlfd, cur_state; + int status, ret, left; + +@@ -872,7 +872,7 @@ void *expire_proc_direct(void *arg) + fatal(status); + + ap = ec.ap = ea->ap; +- now = ea->when; ++ how = ea->how; + ec.status = -1; + + ea->signaled = 1; +@@ -966,7 +966,7 @@ void *expire_proc_direct(void *arg) + + ioctlfd = me->ioctlfd; + +- ret = ops->expire(ap->logopt, ioctlfd, next->path, now); ++ ret = ops->expire(ap->logopt, ioctlfd, next->path, how); + if (ret) { + left++; + pthread_setcancelstate(cur_state, NULL); +@@ -992,7 +992,7 @@ void *expire_proc_direct(void *arg) + debug(ap->logopt, "send expire to trigger %s", next->path); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = ops->expire(ap->logopt, ioctlfd, next->path, now); ++ ret = ops->expire(ap->logopt, ioctlfd, next->path, how); + if (ret) + left++; + pthread_setcancelstate(cur_state, NULL); +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -402,7 +402,7 @@ void *expire_proc_indirect(void *arg) + struct mnt_list *mnts = NULL, *next; + struct expire_args *ea; + struct expire_args ec; +- unsigned int now; ++ unsigned int how; + int offsets, submnts, count; + int retries; + int ioctlfd, cur_state; +@@ -415,7 +415,7 @@ void *expire_proc_indirect(void *arg) + fatal(status); + + ap = ec.ap = ea->ap; +- now = ea->when; ++ how = ea->how; + ec.status = -1; + + ea->signaled = 1; +@@ -540,7 +540,7 @@ void *expire_proc_indirect(void *arg) + debug(ap->logopt, "expire %s", next->path); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = ops->expire(ap->logopt, ioctlfd, next->path, now); ++ ret = ops->expire(ap->logopt, ioctlfd, next->path, how); + if (ret) + left++; + pthread_setcancelstate(cur_state, NULL); +@@ -554,7 +554,7 @@ void *expire_proc_indirect(void *arg) + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + retries = (count_mounts(ap, ap->path, ap->dev) + 1); + while (retries--) { +- ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, now); ++ ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how); + if (ret) + left++; + } +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -267,7 +267,7 @@ void expire_proc_cleanup(void *arg) + return; + } + +-static enum expire expire_proc(struct autofs_point *ap, int now) ++static enum expire expire_proc(struct autofs_point *ap, int how) + { + pthread_t thid; + struct expire_args *ea; +@@ -295,7 +295,7 @@ static enum expire expire_proc(struct au + fatal(status); + + ea->ap = ap; +- ea->when = now; ++ ea->how = how; + ea->status = 1; + + if (ap->type == LKP_INDIRECT) +--- autofs-5.1.4.orig/include/state.h ++++ autofs-5.1.4/include/state.h +@@ -55,7 +55,7 @@ struct expire_args { + unsigned int signaled; + struct autofs_point *ap; /* autofs mount we are working on */ + enum states state; /* State prune or expire */ +- unsigned int when; /* Immediate expire ? */ ++ unsigned int how; /* Normal, immediate expire ? */ + int status; /* Return status */ + }; + diff --git a/autofs-5.1.4-covarity-fixes-1.patch b/autofs-5.1.4-covarity-fixes-1.patch new file mode 100644 index 0000000..e434734 --- /dev/null +++ b/autofs-5.1.4-covarity-fixes-1.patch @@ -0,0 +1,425 @@ +autofs-5.1.4 - covarity fixes 1 + +From: Ian Kent + +* remove conditional close of nullfd. +* fix memory leak of local_domain in lib/macros.c:macro_init(). +* check for NULL prior to several assignments in lib/master_parse.y. +* fix memory leak in lib/mounts.c:add_std_amd_vars(). +* add missing break in lib/rpc_subs.c:rpc_get_netid(). +* fix variable scope problem in modules/amd_parse.c:make_selector(). +* fix selector itself not freed in lib/parse_subs.c:free_selector(). +* fix possible memory leak in modules/lookup_ldap.c:parse_ldap_config(). +* fix possible memory leak in modules/lookup_ldap.c:decode_percent_hack(). +* fix usage of decode_percent_hack() in modules/lookup_ldap.c. +* initialize enc_key1 and enc_key2 in modules/lookup_ldap.c:lookup_one(). +* fix double alloc of map_type in modules/parse_amd.c:make_default_entry(). +* fix double alloc of map_type in modules/parse_amd.c:get_defaults_entry(). +* fix possible memory leak in modules/parse_sun.c:parse_reinit(). +* initialize myoptions and ro_loc in modules/parse_sun.c:mount_subtree(). +* initialize myoptions and loc in modules/parse_sun.c:parse_mount(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/log.c | 3 +-- + lib/macros.c | 1 + + lib/master_parse.y | 28 ++++++++++++++++++++++++++++ + lib/mounts.c | 4 +++- + lib/parse_subs.c | 1 + + lib/rpc_subs.c | 1 + + modules/amd_parse.y | 4 ++-- + modules/lookup_ldap.c | 27 ++++++++++++++++++++++----- + modules/parse_amd.c | 4 ++-- + modules/parse_sun.c | 10 +++++++++- + 11 files changed, 71 insertions(+), 13 deletions(-) + +--- autofs-5.1.4.orig/lib/log.c ++++ autofs-5.1.4/lib/log.c +@@ -336,8 +336,7 @@ void log_to_syslog(void) + exit(1); + } + +- if (nullfd > 2) +- close(nullfd); ++ close(nullfd); + + return; + } +--- autofs-5.1.4.orig/lib/macros.c ++++ autofs-5.1.4/lib/macros.c +@@ -137,6 +137,7 @@ void macro_init(void) + + macro_init_done = 1; + macro_unlock(); ++ free(local_domain); + return; + } + +--- autofs-5.1.4.orig/lib/master_parse.y ++++ autofs-5.1.4/lib/master_parse.y +@@ -157,6 +157,8 @@ line: + + trim_maptype($2); + ++ if (path) ++ free(path); + path = master_strdup($1); + if (!path) { + master_error("memory allocation error"); +@@ -167,6 +169,8 @@ line: + if ((tmp = strchr($2, ','))) + *tmp++ = '\0'; + ++ if (type) ++ free(type); + type = master_strdup($2); + if (!type) { + master_error("memory allocation error"); +@@ -174,6 +178,8 @@ line: + YYABORT; + } + if (tmp) { ++ if (format) ++ free(format); + format = master_strdup(tmp); + if (!format) { + master_error("memory allocation error"); +@@ -204,6 +210,8 @@ line: + + mapspec: map + { ++ if (local_argv) ++ free_argv(local_argc, (const char **) local_argv); + local_argc = tmp_argc; + local_argv = tmp_argv; + tmp_argc = 0; +@@ -211,6 +219,8 @@ mapspec: map + } + | map options + { ++ if (local_argv) ++ free_argv(local_argc, (const char **) local_argv); + local_argc = tmp_argc; + local_argv = tmp_argv; + tmp_argc = 0; +@@ -288,6 +298,8 @@ map: PATH + } + | MAPHOSTS + { ++ if (type) ++ free(type); + type = master_strdup($1 + 1); + if (!type) { + local_free_vars(); +@@ -302,6 +314,8 @@ map: PATH + } + | MAPNULL + { ++ if (type) ++ free(type); + type = master_strdup($1 + 1); + if (!type) { + local_free_vars(); +@@ -310,6 +324,8 @@ map: PATH + } + | dnattrs + { ++ if (type) ++ free(type); + type = master_strdup("ldap"); + if (!type) { + local_free_vars(); +@@ -332,6 +348,8 @@ map: PATH + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; + ++ if (type) ++ free(type); + if (strcmp($1, "exec")) + type = master_strdup($1); + else +@@ -342,6 +360,8 @@ map: PATH + YYABORT; + } + if (tmp) { ++ if (format) ++ free(format); + format = master_strdup(tmp); + if (!format) { + master_error("memory allocation error"); +@@ -366,6 +386,8 @@ map: PATH + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; + ++ if (type) ++ free(type); + if (strcmp($1, "exec")) + type = master_strdup($1); + else +@@ -376,6 +398,8 @@ map: PATH + YYABORT; + } + if (tmp) { ++ if (format) ++ free(format); + format = master_strdup(tmp); + if (!format) { + master_error("memory allocation error"); +@@ -400,6 +424,8 @@ map: PATH + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; + ++ if (type) ++ free(type); + if (strcmp($1, "exec")) + type = master_strdup($1); + else +@@ -410,6 +436,8 @@ map: PATH + YYABORT; + } + if (tmp) { ++ if (format) ++ free(format); + format = master_strdup(tmp); + if (!format) { + master_error("memory allocation error"); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -489,8 +489,10 @@ void add_std_amd_vars(struct substvar *s + const struct substvar *v = macro_findvar(sv, "domain", 4); + if (v && *v->val) { + tmp = strdup(v->val); +- if (tmp) ++ if (tmp) { + macro_global_addvar("cluster", 7, tmp); ++ free(tmp); ++ } + } + } + +--- autofs-5.1.4.orig/lib/parse_subs.c ++++ autofs-5.1.4/lib/parse_subs.c +@@ -189,6 +189,7 @@ void free_selector(struct selector *sele + free(s->func.arg2); + s = next; + } ++ free(selector); + return; + } + +--- autofs-5.1.4.orig/lib/rpc_subs.c ++++ autofs-5.1.4/lib/rpc_subs.c +@@ -389,6 +389,7 @@ static enum clnt_stat rpc_get_netid(cons + } + + *netid = nc_netid; ++ break; + } + endnetconfig(handle); + free(nc_proto); +--- autofs-5.1.4.orig/modules/amd_parse.y ++++ autofs-5.1.4/modules/amd_parse.y +@@ -822,13 +822,13 @@ static int make_selector(char *name, + if (!value1) + tmp = NULL; + else { +- char *tmp = amd_strdup(value1); ++ tmp = amd_strdup(value1); + if (!tmp) + goto error; + } + s->func.arg1 = tmp; + } else if (s->sel->flags & SEL_FLAG_FUNC2) { +- char *tmp = amd_strdup(value1); ++ tmp = amd_strdup(value1); + if (!tmp) + goto error; + s->func.arg1 = tmp; +--- autofs-5.1.4.orig/modules/lookup_ldap.c ++++ autofs-5.1.4/modules/lookup_ldap.c +@@ -1137,6 +1137,7 @@ int parse_ldap_config(unsigned logopt, s + error(logopt, + MODPREFIX "stat(2) failed with error %s.", + strerror(errno)); ++ free(auth_conf); + return 0; + } + +@@ -1148,6 +1149,7 @@ int parse_ldap_config(unsigned logopt, s + "Please make sure that it is owned by root, group " + "is root, and the mode is 0600.", + auth_conf); ++ free(auth_conf); + return -1; + } + +@@ -1182,9 +1184,11 @@ int parse_ldap_config(unsigned logopt, s + goto out; + } + +- if (!usetls || ctxt->port == LDAPS_PORT) ++ if (!usetls || ctxt->port == LDAPS_PORT) { + use_tls = LDAP_TLS_DONT_USE; +- else { ++ if (usetls) ++ free(usetls); ++ } else { + if (!strcasecmp(usetls, "yes")) + use_tls = LDAP_TLS_INIT; + else if (!strcasecmp(usetls, "no")) +@@ -1194,6 +1198,7 @@ int parse_ldap_config(unsigned logopt, s + MODPREFIX + "The usetls property must have value " + "\"yes\" or \"no\"."); ++ free(usetls); + ret = -1; + goto out; + } +@@ -1221,6 +1226,7 @@ int parse_ldap_config(unsigned logopt, s + MODPREFIX + "The tlsrequired property must have value " + "\"yes\" or \"no\"."); ++ free(tlsrequired); + ret = -1; + goto out; + } +@@ -1252,6 +1258,7 @@ int parse_ldap_config(unsigned logopt, s + MODPREFIX + "The authrequired property must have value " + "\"yes\", \"no\", \"autodetect\", or \"simple\"."); ++ free(authrequired); + ret = -1; + goto out; + } +@@ -1338,6 +1345,7 @@ auth_fail: + (void)get_property(logopt, root, "credentialcache", &client_cc); + + ctxt->auth_conf = auth_conf; ++ auth_conf = NULL; + ctxt->use_tls = use_tls; + ctxt->tls_required = tls_required; + ctxt->auth_required = auth_required; +@@ -1375,8 +1383,12 @@ auth_fail: + user, secret ? "specified" : "unspecified", + client_princ, client_cc); + } ++ if (authtype) ++ free(authtype); + out: + xmlFreeDoc(doc); ++ if (auth_conf) ++ free(auth_conf); + + if (fallback) + return 0; +@@ -1986,7 +1998,7 @@ int lookup_read_master(struct master *ma + } + } else if (count == 1) { + dec_len = decode_percent_hack(keyValue[0], &key); +- if (dec_len < 0) { ++ if (dec_len <= 0) { + error(logopt, MODPREFIX + "invalid map key %s - ignoring", + *keyValue); +@@ -1994,7 +2006,7 @@ int lookup_read_master(struct master *ma + } + } else { + dec_len = decode_percent_hack(keyValue[0], &key); +- if (dec_len < 0) { ++ if (dec_len <= 0) { + error(logopt, MODPREFIX + "invalid map key %s - ignoring", + *keyValue); +@@ -2004,7 +2016,7 @@ int lookup_read_master(struct master *ma + for (i = 1; i < count; i++) { + char *k; + dec_len = decode_percent_hack(keyValue[i], &k); +- if (dec_len < 0) { ++ if (dec_len <= 0) { + error(logopt, MODPREFIX + "invalid map key %s - ignoring", + *keyValue); +@@ -2159,6 +2171,8 @@ static int decode_percent_hack(const cha + *key = NULL; + + len = get_percent_decoded_len(name); ++ if (!len) ++ return 0; + new = malloc(len + 1); + if (!new) + return -1; +@@ -2998,6 +3012,9 @@ static int lookup_one(struct autofs_poin + attrs[1] = info; + attrs[2] = NULL; + ++ enc_key1 = NULL; ++ enc_key2 = NULL; ++ + if (*qKey == '*' && qKey_len == 1) + *qKey = '/'; + else if (!strcasecmp(class, "nisObject")) { +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1879,7 +1879,7 @@ struct amd_entry *make_default_entry(str + */ + map_type = conf_amd_get_map_type(ap->path); + if (map_type) +- defaults_entry->map_type = strdup(map_type); ++ defaults_entry->map_type = map_type; + /* The list should now be empty .... */ + free_amd_entry_list(&dflts); + return defaults_entry; +@@ -2006,7 +2006,7 @@ static struct amd_entry *get_defaults_en + */ + char *map_type = conf_amd_get_map_type(ap->path); + if (map_type) +- entry->map_type = strdup(map_type); ++ entry->map_type = map_type; + } + free(expand); + } +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -443,8 +443,10 @@ int parse_reinit(int argc, const char *c + + *new = default_context; + +- if (do_init(argc, argv, new)) ++ if (do_init(argc, argv, new)) { ++ free(new); + return 1; ++ } + + kill_context(ctxt); + +@@ -1143,6 +1145,9 @@ static int mount_subtree(struct autofs_p + const char *root; + int ro_len; + ++ myoptions = NULL; ++ ro_loc = NULL; ++ + rv = parse_mapent(ro->mapent, + options, &myoptions, &ro_loc, ap->logopt); + if (!rv) { +@@ -1524,6 +1529,9 @@ dont_expand: + p += l; + p = skipspace(p); + ++ myoptions = NULL; ++ loc = NULL; ++ + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { + cache_delete_offset_list(mc, name); +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -26,6 +26,7 @@ xx/xx/2018 autofs-5.1.5 + - fix NFS version mask usage. + - fix fd leak in rpc_do_create_client(). + - add-man page note about extra slashes in paths. ++- covarity fixes. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. diff --git a/autofs-5.1.4-dont-allow-trailing-slash-in-master-map-mount-points.patch b/autofs-5.1.4-dont-allow-trailing-slash-in-master-map-mount-points.patch new file mode 100644 index 0000000..456dc80 --- /dev/null +++ b/autofs-5.1.4-dont-allow-trailing-slash-in-master-map-mount-points.patch @@ -0,0 +1,48 @@ +autofs-5.1.4 - dont allow trailing slash in master map mount points + +From: Ian Kent + +If a master map mount point path has a trailing '/' this can cause +problems so remove them at parse time. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/master_parse.y | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 1e5ec15b..a7bb89dc 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -12,6 +12,7 @@ xx/xx/2018 autofs-5.1.5 + - use_hostname_for_mounts shouldn't prevent selection among replicas. + - fix monotonic_elapsed. + - Makefiles.rules: remove 'samples' from SUBDIRS. ++- dont allow trailing slash in master map mount points. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/lib/master_parse.y b/lib/master_parse.y +index 42e03c2d..761ade9b 100644 +--- a/lib/master_parse.y ++++ b/lib/master_parse.y +@@ -749,6 +749,7 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne + struct map_source *source; + unsigned int logopt = logging; + unsigned int m_logopt = master->logopt; ++ size_t mp_len; + int ret; + + local_init_vars(); +@@ -763,6 +764,10 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne + return 0; + } + ++ mp_len = strlen(path); ++ while (mp_len && path[--mp_len] == '/') ++ path[mp_len] = 0; ++ + nc = master->nc; + + /* Add null map entries to the null map cache */ diff --git a/autofs-5.1.4-dont-use-array-for-path-when-not-neccessary.patch b/autofs-5.1.4-dont-use-array-for-path-when-not-neccessary.patch new file mode 100644 index 0000000..b95f0ea --- /dev/null +++ b/autofs-5.1.4-dont-use-array-for-path-when-not-neccessary.patch @@ -0,0 +1,56 @@ +autofs-5.1.4 - dont use array for path when not necessary + +From: Ian Kent + +In parse_amd.c:do_link_mount() a character array is used to construct +a path when a pointer to the relevant amd entry field is sufficient. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 0f30596f..13f01397 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ xx/xx/2018 autofs-5.1.5 + - fix directory create permission. + - fix use after free in do_master_list_reset(). + - fix deadlock in dumpmaps. ++- dont use array for path when not necessary. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index c4b3ef0b..2cce5417 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -967,8 +967,8 @@ static int do_auto_mount(struct autofs_point *ap, const char *name, + static int do_link_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, unsigned int flags) + { +- char target[PATH_MAX + 1]; + const char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL; ++ char *target; + int ret; + + if (entry->sublink) { +@@ -977,14 +977,14 @@ static int do_link_mount(struct autofs_point *ap, const char *name, + "error: sublink option length is too long"); + return 0; + } +- strcpy(target, entry->sublink); ++ target = entry->sublink; + } else { + if (strlen(entry->fs) > PATH_MAX) { + error(ap->logopt, MODPREFIX + "error: fs option length is too long"); + return 0; + } +- strcpy(target, entry->fs); ++ target = entry->fs; + } + + if (!(flags & CONF_AUTOFS_USE_LOFS)) diff --git a/autofs-5.1.4-fix-NFS-version-mask-usage.patch b/autofs-5.1.4-fix-NFS-version-mask-usage.patch new file mode 100644 index 0000000..6e25027 --- /dev/null +++ b/autofs-5.1.4-fix-NFS-version-mask-usage.patch @@ -0,0 +1,69 @@ +autofs-5.1.4 - fix NFS version mask usage + +From: Ian Kent + +Upstream commit a8af65195 changed NFS_VERS_MASK to exclude NFSv2 +so NFSv2 would be excluded in the default availability probe. + +But NFS_VERS_MASK is used like a mask elsewhere and causes NFSv2 +to be cleared for the availability probe even when it is requested. + +So add a macro to NFS_VERS_DEFAULT (and accompanying macros) to be +used to set initial defaults and restore NFS_VERS_MASK to what it +should be when used as a mask. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/replicated.h | 5 ++++- + modules/mount_nfs.c | 6 +++--- + 3 files changed, 8 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -23,6 +23,7 @@ xx/xx/2018 autofs-5.1.5 + - tiny patch for autofs typo and possible bug. + - add units After line to include statd service. + - use systemd sd_notify() at startup. ++- fix NFS version mask usage. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/replicated.h ++++ autofs-5.1.4/include/replicated.h +@@ -26,7 +26,9 @@ + #define NFS2_SUPPORTED 0x0010 + #define NFS3_SUPPORTED 0x0020 + #define NFS4_SUPPORTED 0x0040 +-#define NFS_VERS_MASK (NFS3_SUPPORTED) ++#define NFS_VERS_DEFAULT (NFS3_SUPPORTED) ++#define NFS_VERS_MASK (NFS2_SUPPORTED|NFS3_SUPPORTED) ++#define NFS4_VERS_DEFAULT (NFS4_SUPPORTED) + #define NFS4_VERS_MASK (NFS4_SUPPORTED) + + #define NFS2_REQUESTED NFS2_SUPPORTED +@@ -39,6 +41,7 @@ + #define UDP_REQUESTED UDP_SUPPORTED + #define TCP6_REQUESTED 0x0100 + #define UDP6_REQUESTED 0x0200 ++#define NFS_PROTO_DEFAULT (TCP_SUPPORTED|UDP_SUPPORTED) + #define NFS_PROTO_MASK (TCP_SUPPORTED|UDP_SUPPORTED) + + #define NFS2_TCP_SUPPORTED NFS2_SUPPORTED +--- autofs-5.1.4.orig/modules/mount_nfs.c ++++ autofs-5.1.4/modules/mount_nfs.c +@@ -86,11 +86,11 @@ int mount_mount(struct autofs_point *ap, + root, name, what, fstype, options); + + mount_default_proto = defaults_get_mount_nfs_default_proto(); +- vers = NFS_VERS_MASK | NFS_PROTO_MASK; ++ vers = NFS_VERS_DEFAULT | NFS_PROTO_DEFAULT; + if (strcmp(fstype, "nfs4") == 0) +- vers = NFS4_VERS_MASK | TCP_SUPPORTED; ++ vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED; + else if (mount_default_proto == 4) +- vers = vers | NFS4_VERS_MASK; ++ vers = vers | NFS4_VERS_DEFAULT; + + /* Extract "nosymlink" pseudo-option which stops local filesystems + * from being symlinked. diff --git a/autofs-5.1.4-fix-age-setting-at-startup.patch b/autofs-5.1.4-fix-age-setting-at-startup.patch new file mode 100644 index 0000000..84e1f2b --- /dev/null +++ b/autofs-5.1.4-fix-age-setting-at-startup.patch @@ -0,0 +1,42 @@ +autofs-5.1.4 - fix age setting at startup + +From: Ian Kent + +Commit 2b567ace7d, which resets the master map list on startup +before retrying a read, incorrectly sets age using time() when +it should use monotonic_time(). + +This causes lookup failures for submounts in cases where a master +map read retry was needed. + +The failure happens because the mount entry age is greater than +the map entry age which is meant to indicate the map is no longer +valid which is not the case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -32,6 +32,7 @@ xx/xx/2018 autofs-5.1.5 + - mark removed cache entry negative. + - set bind mount as propagation slave. + - add master map pseudo options for mount propagation. ++- fix age setting at startup. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -2610,7 +2610,7 @@ int main(int argc, char *argv[]) + * we have anyway. + */ + do_master_list_reset(master_list); +- age = time(NULL); ++ age = monotonic_time(NULL); + master_read_master(master_list, age, 1); + } + } diff --git a/autofs-5.1.4-fix-amd-parser-opts-option-handling.patch b/autofs-5.1.4-fix-amd-parser-opts-option-handling.patch new file mode 100644 index 0000000..ffd1b1d --- /dev/null +++ b/autofs-5.1.4-fix-amd-parser-opts-option-handling.patch @@ -0,0 +1,66 @@ +autofs-5.1.4 - fix amd parser opts option handling + +From: Ian Kent + +The recent implementation of the amd map program mount feature +introduced a regression in the amd parser where only the first +option of a comma separated list of is applied to a mount entry. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/amd_parse.y | 4 ++-- + modules/parse_amd.c | 4 +++- + 3 files changed, 6 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -35,6 +35,7 @@ xx/xx/2018 autofs-5.1.5 + - fix age setting at startup. + - fix use after free in parse_ldap_config(). + - fix incorrect locking in sss lookup. ++- fix amd parser opts option handling. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/amd_parse.y ++++ autofs-5.1.4/modules/amd_parse.y +@@ -401,7 +401,7 @@ option_assignment: MAP_OPTION OPTION_ASS + } + | MNT_OPTION OPTION_ASSIGN options + { +- if (!match_mnt_option_options($1, $3)) { ++ if (!match_mnt_option_options($1, opts)) { + amd_notify($1); + YYABORT; + } +@@ -409,7 +409,7 @@ option_assignment: MAP_OPTION OPTION_ASS + } + | MNT_OPTION OPTION_ASSIGN QUOTE options QUOTE + { +- if (!match_mnt_option_options($1, $4)) { ++ if (!match_mnt_option_options($1, opts)) { + amd_notify($1); + YYABORT; + } +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -2136,6 +2136,7 @@ int parse_mount(struct autofs_point *ap, + list_del_init(&this->list); + cur_defaults = this; + update_with_defaults(defaults_entry, cur_defaults, sv); ++ debug(ap->logopt, "merged /defaults entry with defaults"); + continue; + } else if (this->flags & AMD_DEFAULTS_RESET) { + struct amd_entry *nd, *new; +@@ -2174,8 +2175,9 @@ int parse_mount(struct autofs_point *ap, + + at_least_one = 1; + +- debug(ap->logopt, "expand mount entry"); ++ debug(ap->logopt, "update mount entry with defaults"); + update_with_defaults(cur_defaults, this, sv); ++ debug(ap->logopt, "expand mount entry"); + sv = expand_entry(ap, this, flags, sv); + sv = merge_entry_options(ap, this, sv); + normalize_sublink(ap->logopt, this, sv); diff --git a/autofs-5.1.4-fix-deadlock-in-dumpmaps.patch b/autofs-5.1.4-fix-deadlock-in-dumpmaps.patch new file mode 100644 index 0000000..12bd077 --- /dev/null +++ b/autofs-5.1.4-fix-deadlock-in-dumpmaps.patch @@ -0,0 +1,40 @@ +autofs-5.1.4 - fix deadlock in dumpmaps + +From: Ian Kent + +Commit a223d11fa8e (autofs-5.1.3 - serialize calls to open_xxxx() +functions) introduces a deadlock when using the dumpmaps function. + +In this case the open fd mutex needs to be unlocked in the forked +child process of the do_spawn() function. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/spawn.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 2747327b..0f30596f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ xx/xx/2018 autofs-5.1.5 + - fix flag file permission. + - fix directory create permission. + - fix use after free in do_master_list_reset(). ++- fix deadlock in dumpmaps. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/daemon/spawn.c b/daemon/spawn.c +index fabe577e..dbbca7fa 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -338,6 +338,7 @@ static int do_spawn(unsigned logopt, unsigned int wait, + dup2(pipefd[1], STDOUT_FILENO); + dup2(pipefd[1], STDERR_FILENO); + close(pipefd[1]); ++ open_mutex_unlock(); + + /* what to mount must always be second last */ + while (*pargv++) diff --git a/autofs-5.1.4-fix-directory-create-permission.patch b/autofs-5.1.4-fix-directory-create-permission.patch new file mode 100644 index 0000000..9723031 --- /dev/null +++ b/autofs-5.1.4-fix-directory-create-permission.patch @@ -0,0 +1,207 @@ +autofs-5.1.4 - fix directory create permission + +From: Ian Kent + +autofs mount point directory creation is done using a permission of +0555. + +But it is necessary to create directories within autofs mount points +for some map entry types so write access should be set for the owner +on mount point directories. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 ++ + daemon/direct.c | 4 ++-- + daemon/indirect.c | 2 +- + daemon/lookup.c | 2 +- + include/automount.h | 1 + + modules/mount_bind.c | 6 +++--- + modules/mount_changer.c | 2 +- + modules/mount_ext2.c | 2 +- + modules/mount_generic.c | 2 +- + modules/mount_nfs.c | 2 +- + modules/parse_amd.c | 2 +- + 12 files changed, 16 insertions(+), 12 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index d07d88ce..4faab510 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,5 +1,6 @@ + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. ++- fix directory create permission. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/daemon/automount.c b/daemon/automount.c +index 5c739617..dcdc19fb 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -51,6 +51,8 @@ const char *libdir = AUTOFS_LIB_DIR; /* Location of library modules */ + const char *mapdir = AUTOFS_MAP_DIR; /* Location of mount maps */ + const char *confdir = AUTOFS_CONF_DIR; /* Location of autofs config file */ + ++unsigned int mp_mode = 0755; ++ + unsigned int nfs_mount_uses_string_options = 0; + static struct nfs_mount_vers vers, check = {1, 1, 1}; + +diff --git a/daemon/direct.c b/daemon/direct.c +index 9a134351..3fdecdb8 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -424,7 +424,7 @@ int do_mount_autofs_direct(struct autofs_point *ap, + } + + /* In case the directory doesn't exist, try to mkdir it */ +- if (mkdir_path(me->key, 0555) < 0) { ++ if (mkdir_path(me->key, mp_mode) < 0) { + if (errno != EEXIST && errno != EROFS) { + crit(ap->logopt, + "failed to create mount directory %s", me->key); +@@ -739,7 +739,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + strcat(mountpoint, offset); + + /* In case the directory doesn't exist, try to mkdir it */ +- if (mkdir_path(mountpoint, 0555) < 0) { ++ if (mkdir_path(mountpoint, mp_mode) < 0) { + if (errno == EEXIST) { + /* + * If the mount point directory is a real mount +diff --git a/daemon/indirect.c b/daemon/indirect.c +index ffb11b8c..03c081ed 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -133,7 +133,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + } + + /* In case the directory doesn't exist, try to mkdir it */ +- if (mkdir_path(root, 0555) < 0) { ++ if (mkdir_path(root, mp_mode) < 0) { + if (errno != EEXIST && errno != EROFS) { + crit(ap->logopt, + "failed to create autofs directory %s", +diff --git a/daemon/lookup.c b/daemon/lookup.c +index cb67e7d9..6a722b3b 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -802,7 +802,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root) + goto next; + } + +- ret = mkdir_path(fullpath, 0555); ++ ret = mkdir_path(fullpath, mp_mode); + if (ret < 0 && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + warn(ap->logopt, +diff --git a/include/automount.h b/include/automount.h +index 2e2c2b02..e5c19d23 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -269,6 +269,7 @@ void reset_signals(void); + int do_mount(struct autofs_point *ap, const char *root, const char *name, + int name_len, const char *what, const char *fstype, + const char *options); ++extern unsigned int mp_mode; + int mkdir_path(const char *path, mode_t mode); + int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev); + +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index 4864ea51..5effa880 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -151,7 +151,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +- status = mkdir_path(fullpath, 0555); ++ status = mkdir_path(fullpath, mp_mode); + if (status && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, +@@ -203,7 +203,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } else { + debug(ap->logopt, + MODPREFIX "calling mkdir_path %s", basepath); +- if (mkdir_path(basepath, 0555) && errno != EEXIST) { ++ if (mkdir_path(basepath, mp_mode) && errno != EEXIST) { + char *estr; + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, +@@ -219,7 +219,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + "failed to create symlink %s -> %s", + fullpath, what); + if ((ap->flags & MOUNT_FLAG_GHOST) && !status) { +- if (mkdir_path(fullpath, 0555) && errno != EEXIST) { ++ if (mkdir_path(fullpath, mp_mode) && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, + MODPREFIX "mkdir_path %s failed: %s", +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index 798f23b2..7d44a720 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -87,7 +87,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +- status = mkdir_path(fullpath, 0555); ++ status = mkdir_path(fullpath, mp_mode); + if (status && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, +diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c +index 90fc0876..3bbea95a 100644 +--- a/modules/mount_ext2.c ++++ b/modules/mount_ext2.c +@@ -69,7 +69,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +- status = mkdir_path(fullpath, 0555); ++ status = mkdir_path(fullpath, mp_mode); + if (status && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, +diff --git a/modules/mount_generic.c b/modules/mount_generic.c +index ae637875..b1a3adbf 100644 +--- a/modules/mount_generic.c ++++ b/modules/mount_generic.c +@@ -68,7 +68,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +- status = mkdir_path(fullpath, 0555); ++ status = mkdir_path(fullpath, mp_mode); + if (status && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index bf712a93..77166544 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -277,7 +277,7 @@ dont_probe: + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +- status = mkdir_path(fullpath, 0555); ++ status = mkdir_path(fullpath, mp_mode); + if (status && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index b40c1ad1..c4b3ef0b 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1288,7 +1288,7 @@ static int do_program_mount(struct autofs_point *ap, + rv = 0; + ext_mount_add(&entry->ext_mount, entry->fs, 1); + } else { +- rv = mkdir_path(entry->fs, 0555); ++ rv = mkdir_path(entry->fs, mp_mode); + if (rv && errno != EEXIST) { + char buf[MAX_ERR_BUF]; + char *estr; diff --git a/autofs-5.1.4-fix-error-return-in-do_nfs_mount.patch b/autofs-5.1.4-fix-error-return-in-do_nfs_mount.patch new file mode 100644 index 0000000..80d0a87 --- /dev/null +++ b/autofs-5.1.4-fix-error-return-in-do_nfs_mount.patch @@ -0,0 +1,35 @@ +autofs-5.1.4 - fix error return in do_nfs_mount() + +From: Ian Kent + +Fix incorrect error return in modules/parse_amd.c:do_nfs_mount(). +--- + CHANGELOG | 1 + + modules/parse_amd.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 756ef927..d0cfa19b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -6,6 +6,7 @@ xx/xx/2018 autofs-5.1.5 + - dont use array for path when not necessary. + - fix prefix option handling in expand_entry(). + - fix sublink option not set from defaults. ++- fix error return in do_nfs_mount(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 1c962fff..2a5d9a30 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1099,7 +1099,7 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, + if (strlen(entry->rhost) + strlen(entry->rfs) + 1 > PATH_MAX) { + error(ap->logopt, MODPREFIX + "error: rhost + rfs options length is too long"); +- return 0; ++ return 1; + } + + strcpy(target, entry->rhost); diff --git a/autofs-5.1.4-fix-fd-leak-in-rpc_do_create_client.patch b/autofs-5.1.4-fix-fd-leak-in-rpc_do_create_client.patch new file mode 100644 index 0000000..5a69084 --- /dev/null +++ b/autofs-5.1.4-fix-fd-leak-in-rpc_do_create_client.patch @@ -0,0 +1,46 @@ +autofs-5.1.4 - fix fd leak in rpc_do_create_client() + +From: Ian Kent + +Commit 94f87e203a (fix create_client() RPC client handling) fixed +possible use of an invalid RPC client handle but the change neglected +to account for a check in rpc_do_create_client() that would open a new +file descriptor without checking if the passed in descriptor was +already opened. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -24,6 +24,7 @@ xx/xx/2018 autofs-5.1.5 + - add units After line to include statd service. + - use systemd sd_notify() at startup. + - fix NFS version mask usage. ++- fix fd leak in rpc_do_create_client(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/rpc_subs.c ++++ autofs-5.1.4/lib/rpc_subs.c +@@ -183,7 +183,7 @@ static int rpc_do_create_client(struct s + in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY); + slen = sizeof(struct sockaddr_in); + +- if (!info->client) { ++ if (!info->client && *fd == RPC_ANYSOCK) { + struct sockaddr *laddr; + + *fd = open_sock(addr->sa_family, type, proto); +@@ -296,7 +296,7 @@ static int rpc_do_create_client(struct s + * it would bind to a reserved port, which has been shown to + * exhaust the reserved port range in some situations. + */ +- if (!info->client) { ++ if (!info->client && *fd == RPC_ANYSOCK) { + *fd = open_sock(addr->sa_family, type, proto); + if (*fd < 0) { + ret = -errno; diff --git a/autofs-5.1.4-fix-flag-file-permission.patch b/autofs-5.1.4-fix-flag-file-permission.patch new file mode 100644 index 0000000..c2f8fdb --- /dev/null +++ b/autofs-5.1.4-fix-flag-file-permission.patch @@ -0,0 +1,41 @@ +autofs-5.1.4 - fix flag file permission + +From: Ian Kent + +The flag file used to check if automount(8) is running was being +created with mode 0 which caused unnecessary dac_override AVC +failures. + +There's no reason to protect this file so just use 0644 as the +file permission. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 3 +++ + daemon/flag.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 246279ae..d07d88ce 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,6 @@ ++xx/xx/2018 autofs-5.1.5 ++- fix flag file permission. ++ + 19/12/2017 autofs-5.1.4 + - fix spec file url. + - fix unset tsd group name handling. +diff --git a/daemon/flag.c b/daemon/flag.c +index 99f26847..ff9858c8 100644 +--- a/daemon/flag.c ++++ b/daemon/flag.c +@@ -164,7 +164,7 @@ int aquire_flag_file(void) + while (!we_created_flagfile) { + int errsv, i, j; + +- i = open_fd_mode(linkf, O_WRONLY|O_CREAT, 0); ++ i = open_fd_mode(linkf, O_WRONLY|O_CREAT, 0644); + if (i < 0) { + release_flag_file(); + return 0; diff --git a/autofs-5.1.4-fix-incorrect-locking-in-sss-lookup.patch b/autofs-5.1.4-fix-incorrect-locking-in-sss-lookup.patch new file mode 100644 index 0000000..5917b5e --- /dev/null +++ b/autofs-5.1.4-fix-incorrect-locking-in-sss-lookup.patch @@ -0,0 +1,40 @@ +autofs-5.1.4 - fix incorrect locking in sss lookup + +From: Ian Kent + +Commit 766e0f6c4, autofs-5.0.7 - fix fix wildcard multi map regression, +introduced a deadlock during restart when the sss modules is used. + +Looking at the comment above the code which takes the lock it clearly +does this incorrectly. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -34,6 +34,7 @@ xx/xx/2018 autofs-5.1.5 + - add master map pseudo options for mount propagation. + - fix age setting at startup. + - fix use after free in parse_ldap_config(). ++- fix incorrect locking in sss lookup. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/lookup_sss.c ++++ autofs-5.1.4/modules/lookup_sss.c +@@ -786,9 +786,9 @@ int lookup_mount(struct autofs_point *ap + * when we're starting up so just take the readlock in that + */ + if (ap->flags & MOUNT_FLAG_REMOUNT) +- cache_writelock(mc); +- else + cache_readlock(mc); ++ else ++ cache_writelock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { diff --git a/autofs-5.1.4-fix-libresolv-configure-check.patch b/autofs-5.1.4-fix-libresolv-configure-check.patch new file mode 100644 index 0000000..f6a9bb3 --- /dev/null +++ b/autofs-5.1.4-fix-libresolv-configure-check.patch @@ -0,0 +1,94 @@ +autofs-5.1.4 - fix libresolv configure check + +From: Ian Kent + +The libresolv functions are not found by AC_CHECK_LIB() unless +they are prefixed with "__". + +So change the library check to also look for __ during +the check. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + configure | 41 +++++++++++++++++++++++++++++++++++++++++ + configure.in | 2 +- + 3 files changed, 43 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index a7bb89dc..dbfb8389 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -13,6 +13,7 @@ xx/xx/2018 autofs-5.1.5 + - fix monotonic_elapsed. + - Makefiles.rules: remove 'samples' from SUBDIRS. + - dont allow trailing slash in master map mount points. ++- fix libresolv configure check. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/configure b/configure +index 2d517aac..5c8aae30 100755 +--- a/configure ++++ b/configure +@@ -4821,6 +4821,47 @@ fi + $as_echo "$ac_cv_lib_resolv_res_query" >&6; } + if test "x$ac_cv_lib_resolv_res_query" = xyes; then : + LIBRESOLV="-lresolv" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __res_query in -lresolv" >&5 ++$as_echo_n "checking for __res_query in -lresolv... " >&6; } ++if ${ac_cv_lib_resolv___res_query+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lresolv $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* 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 __res_query (); ++int ++main () ++{ ++return __res_query (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_resolv___res_query=yes ++else ++ ac_cv_lib_resolv___res_query=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv___res_query" >&5 ++$as_echo "$ac_cv_lib_resolv___res_query" >&6; } ++if test "x$ac_cv_lib_resolv___res_query" = xyes; then : ++ LIBRESOLV="-lresolv" ++fi ++ + fi + + +diff --git a/configure.in b/configure.in +index d74775cc..4d1208f5 100644 +--- a/configure.in ++++ b/configure.in +@@ -217,7 +217,7 @@ AC_SUBST(NSL_LIBS) + NSL_CFLAGS="" + ]) + +-AC_CHECK_LIB(resolv, res_query, LIBRESOLV="-lresolv") ++AC_CHECK_LIB(resolv, res_query, LIBRESOLV="-lresolv", AC_CHECK_LIB(resolv, __res_query, LIBRESOLV="-lresolv")) + AC_SUBST(LIBRESOLV) + + # diff --git a/autofs-5.1.4-fix-monotonic_elapsed.patch b/autofs-5.1.4-fix-monotonic_elapsed.patch new file mode 100644 index 0000000..17c5a6e --- /dev/null +++ b/autofs-5.1.4-fix-monotonic_elapsed.patch @@ -0,0 +1,49 @@ +autofs-5.1.4 - fix monotonic_elapsed + +From: NeilBrown + +When automount probes multiple hosts to find the one which +responds most quickly, it currently ignores the nanoseconds. +This often makes the cost "0", which makes weights ineffective. + +The cause is that monotonic_elapsed() casts tv_nsec to a +double *after* dividing by 1 billion, rather than before. + +With this change, weights become effective for choosing +between hosts which respond in under one second. + +Signed-off-by: NeilBrown +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 104fca90..313730b1 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ xx/xx/2018 autofs-5.1.5 + - add error handling for ext_mount_add(). + - account for recent libnsl changes. + - use_hostname_for_mounts shouldn't prevent selection among replicas. ++- fix monotonic_elapsed. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 73097c9d..60ede9f8 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -1093,9 +1093,9 @@ double monotonic_elapsed(struct timespec start, struct timespec end) + double t1, t2; + + t1 = (double) start.tv_sec + +- (double) (start.tv_nsec/(1000*1000*1000)); ++ ((double) start.tv_nsec/(1000*1000*1000)); + t2 = (double) end.tv_sec + +- (double) (end.tv_nsec/(1000*1000*1000)); ++ ((double) end.tv_nsec/(1000*1000*1000)); + return t2 - t1; + } + diff --git a/autofs-5.1.4-fix-prefix-option-handling-in-expand_entry.patch b/autofs-5.1.4-fix-prefix-option-handling-in-expand_entry.patch new file mode 100644 index 0000000..4e3996b --- /dev/null +++ b/autofs-5.1.4-fix-prefix-option-handling-in-expand_entry.patch @@ -0,0 +1,55 @@ +autofs-5.1.4 - fix prefix option handling in expand_entry() + +From: Ian Kent + +The changes to fix the defaults handling in the amd map parser caused +the prefix option to not be expanded and also to not be propagated to +submounts in some cases. + +But the prefix should be expanded in modules/parse_amd.c:expand_entry() +along with the reset of the amd map entry fields. + +Just adding this to modules/parse_amd.c:expand_entry() (where it should +be) fixes the amd map entry expansion and also fixes the propagation +of the prefix to submounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 13f01397..19aec2ae 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -4,6 +4,7 @@ xx/xx/2018 autofs-5.1.5 + - fix use after free in do_master_list_reset(). + - fix deadlock in dumpmaps. + - dont use array for path when not necessary. ++- fix prefix option handling in expand_entry(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 2cce5417..1a5a2960 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -725,6 +725,17 @@ static struct substvar *expand_entry(struct autofs_point *ap, + entry->rhost = host; + } + next: ++ if (entry->pref) { ++ if (expand_selectors(ap, entry->pref, &expand, sv)) { ++ debug(logopt, MODPREFIX ++ "pref expand(\"%s\") -> %s", ++ entry->pref, expand); ++ free(entry->pref); ++ entry->pref = expand; ++ } ++ sv = macro_addvar(sv, "pref", 4, entry->pref); ++ } ++ + if (entry->sublink) { + if (expand_selectors(ap, entry->sublink, &expand, sv)) { + debug(logopt, MODPREFIX diff --git a/autofs-5.1.4-fix-program-usage-message.patch b/autofs-5.1.4-fix-program-usage-message.patch new file mode 100644 index 0000000..052dbbd --- /dev/null +++ b/autofs-5.1.4-fix-program-usage-message.patch @@ -0,0 +1,40 @@ +autofs-5.1.4 - fix program usage message + +From: Ian Kent + +There is a discrepancy between the list of options in the usage +message of automount(8) and the options listed in the man page. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -27,6 +27,7 @@ xx/xx/2018 autofs-5.1.5 + - fix fd leak in rpc_do_create_client(). + - add-man page note about extra slashes in paths. + - covarity fixes. ++- fix program usage message. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1893,9 +1893,13 @@ static void usage(void) + " -h --help this text\n" + " -p --pid-file f write process id to file f\n" + " -t --timeout n auto-unmount in n seconds (0-disable)\n" ++ " -M --master-wait n\n" ++ " maximum wait time (seconds) for master\n" ++ " map to become available\n" + " -v --verbose be verbose\n" + " -d --debug log debuging info\n" +- " -D --define define global macro variable\n" ++ " -Dvariable=value, --define variable=value\n" ++ " define global macro variable\n" + " -f --foreground do not fork into background\n" + " -r --random-multimount-selection\n" + " use ramdom replicated server selection\n" diff --git a/autofs-5.1.4-fix-sublink-option-not-set-from-defaults.patch b/autofs-5.1.4-fix-sublink-option-not-set-from-defaults.patch new file mode 100644 index 0000000..cefb27c --- /dev/null +++ b/autofs-5.1.4-fix-sublink-option-not-set-from-defaults.patch @@ -0,0 +1,48 @@ +autofs-5.1.4 - fix sublink option not set from defaults + +From: Ian Kent + +If the amd entry sublink option is given in a defaults entry +it isn't merged into the current entry during parsing. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 12 ++++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 19aec2ae..756ef927 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,7 @@ xx/xx/2018 autofs-5.1.5 + - fix deadlock in dumpmaps. + - dont use array for path when not necessary. + - fix prefix option handling in expand_entry(). ++- fix sublink option not set from defaults. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 1a5a2960..1c962fff 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -645,6 +645,18 @@ static void update_with_defaults(struct amd_entry *defaults, + } + } + ++ if (!entry->sublink) { ++ if (defaults->sublink) { ++ tmp = strdup(defaults->sublink); ++ if (tmp) ++ entry->sublink = tmp; ++ } else { ++ v = macro_findvar(sv, "sublink", 2); ++ if (v) ++ entry->sublink = strdup(v->val); ++ } ++ } ++ + return; + } + diff --git a/autofs-5.1.4-fix-update_negative_cache-map-source-usage.patch b/autofs-5.1.4-fix-update_negative_cache-map-source-usage.patch new file mode 100644 index 0000000..2a822f7 --- /dev/null +++ b/autofs-5.1.4-fix-update_negative_cache-map-source-usage.patch @@ -0,0 +1,98 @@ +autofs-5.1.4 - fix update_negative_cache() map source usage + +From: Ian Kent + +File map sources can be either plain text or executable. + +When the map path is specified without a type (eg. when a +full path is used) an instance map source is used and the +original map is left unchanged. + +But update_negative_cache() fails to take this into account +causing it to update the wrong map cache. + +When a map reload is done the map entry appears to not exist +so the new map entry is added. + +This could go unnoticed except that, after a map read, the +map entry cache cleans stale map entries and the existence +of this negative entry causes the new map entry to be deleted +and map lookups continue to fail. + +In hindsite the use of an instance map source for this is +probably uneccessary but changing it will be risky so, for +now, just make update_negative_cache() use the correct map. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 38 ++++++++++++++++++++++++++++++++++++-- + 2 files changed, 37 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -28,6 +28,7 @@ xx/xx/2018 autofs-5.1.5 + - add-man page note about extra slashes in paths. + - covarity fixes. + - fix program usage message. ++- fix update_negative_cache() map source usage. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -1100,6 +1100,37 @@ static enum nsswitch_status lookup_map_n + return result; + } + ++static struct map_source *lookup_get_map_source(struct master_mapent *entry) ++{ ++ struct map_source *map = entry->maps; ++ struct stat st; ++ char *type; ++ ++ if (map->type || *map->argv[0] != '/') ++ return map; ++ ++ if (*(map->argv[0] + 1) == '/') ++ return map; ++ ++ if (stat(map->argv[0], &st) == -1) ++ return NULL; ++ ++ if (!S_ISREG(st.st_mode)) ++ return NULL; ++ ++ if (st.st_mode & __S_IEXEC) ++ type = "program"; ++ else ++ type = "file"; ++ ++ /* This is a file source with a path starting with "/". ++ * But file maps can be either plain text or executable ++ * so they use a map instance and the actual map source ++ * remains untouched. ++ */ ++ return master_find_source_instance(map, type, map->format, 0, NULL); ++} ++ + static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name) + { + struct master_mapent *entry = ap->entry; +@@ -1133,11 +1164,14 @@ static void update_negative_cache(struct + logmsg("key \"%s\" not found in map source(s).", name); + } + +- /* Doesn't exist in any source, just add it somewhere */ ++ /* Doesn't exist in any source, just add it somewhere. ++ * Also take care to use the same map source used by ++ * map reads and key lookups for the update. ++ */ + if (source) + map = source; + else +- map = entry->maps; ++ map = lookup_get_map_source(entry); + if (map) { + time_t now = monotonic_time(NULL); + int rv = CHE_FAIL; diff --git a/autofs-5.1.4-fix-use-after-free-in-do_master_list_reset.patch b/autofs-5.1.4-fix-use-after-free-in-do_master_list_reset.patch new file mode 100644 index 0000000..ff12fd9 --- /dev/null +++ b/autofs-5.1.4-fix-use-after-free-in-do_master_list_reset.patch @@ -0,0 +1,55 @@ +autofs-5.1.4 - fix use after free in do_master_list_reset() + +From: Ian Kent + +Umm ... list_for_each() can't be used in do_master_list_reset() because +the subject entry of the loop is removed for the list within the loop +body. Therefore it can't be used to calculate the next pointer within a +for (...) loop. + +There is no list_for_each_safe() macro in the list.h of autofs so it +needs to be done manually. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 8 ++++++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 4faab510..2747327b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,6 +1,7 @@ + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. + - fix directory create permission. ++- fix use after free in do_master_list_reset(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/daemon/automount.c b/daemon/automount.c +index dcdc19fb..28b3f2f5 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -2070,14 +2070,18 @@ static void remove_empty_args(char **argv, int *argc) + + static void do_master_list_reset(struct master *master) + { +- struct list_head *head, *p; ++ struct list_head *head, *p, *n; + + master_mutex_lock(); + + head = &master->mounts; +- list_for_each(p, head) { ++ n = head->next; ++ while (n != head) { + struct master_mapent *entry; + ++ p = n; ++ n = p->next; ++ + entry = list_entry(p, struct master_mapent, list); + + if (!list_empty(&entry->list)) diff --git a/autofs-5.1.4-fix-use-after-free-in-parse_ldap_config.patch b/autofs-5.1.4-fix-use-after-free-in-parse_ldap_config.patch new file mode 100644 index 0000000..806d0ab --- /dev/null +++ b/autofs-5.1.4-fix-use-after-free-in-parse_ldap_config.patch @@ -0,0 +1,34 @@ +autofs-5.1.4 - fix use after free in parse_ldap_config() + +From: Ian Kent + +Commit a4a2af5f30 (covarity fixes) incorrecly frees local variable +authtype after assigning it to a lookup context structure member. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -33,6 +33,7 @@ xx/xx/2018 autofs-5.1.5 + - set bind mount as propagation slave. + - add master map pseudo options for mount propagation. + - fix age setting at startup. ++- fix use after free in parse_ldap_config(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/lookup_ldap.c ++++ autofs-5.1.4/modules/lookup_ldap.c +@@ -1383,8 +1383,6 @@ auth_fail: + user, secret ? "specified" : "unspecified", + client_princ, client_cc); + } +- if (authtype) +- free(authtype); + out: + xmlFreeDoc(doc); + if (auth_conf) diff --git a/autofs-5.1.4-improve-hostname-lookup-error-logging.patch b/autofs-5.1.4-improve-hostname-lookup-error-logging.patch new file mode 100644 index 0000000..cfab93e --- /dev/null +++ b/autofs-5.1.4-improve-hostname-lookup-error-logging.patch @@ -0,0 +1,123 @@ +autofs-5.1.4 - improve hostname lookup error logging + +From: Ian Kent + +There's not enough information in name lookup log messages +to determine if the failed lookup is in fact a problem or +is expected. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/parse_subs.c | 3 ++- + lib/rpc_subs.c | 3 ++- + modules/dclist.c | 4 +++- + modules/parse_amd.c | 9 ++++++--- + modules/replicated.c | 5 +++-- + 6 files changed, 17 insertions(+), 8 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f771a433..596590a8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -19,6 +19,7 @@ xx/xx/2018 autofs-5.1.5 + - add fedfs-map-nfs4.c. + - add conditional inclusion of fedfs binaries. + - add an example fedfs master map entry to the installed master map. ++- improve hostname lookup error logging. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index db784a58..841e81fd 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -476,7 +476,8 @@ unsigned int get_network_proximity(const char *name) + + ret = getaddrinfo(name_or_num, NULL, &hints, &ni); + if (ret) { +- logerr("getaddrinfo: %s", gai_strerror(ret)); ++ logerr("hostname lookup for %s failed: %s", ++ name_or_num, gai_strerror(ret)); + return PROXIMITY_ERROR; + } + +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 60ede9f8..cc83e84d 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -693,7 +693,8 @@ static int create_client(struct conn_info *info, CLIENT **client) + ret = getaddrinfo(info->host, NULL, &hints, &ai); + if (ret) { + error(LOGOPT_ANY, +- "hostname lookup failed: %s", gai_strerror(ret)); ++ "hostname lookup for %s failed: %s", ++ info->host, gai_strerror(ret)); + goto out_close; + } + +diff --git a/modules/dclist.c b/modules/dclist.c +index 4daa199b..ba32134d 100644 +--- a/modules/dclist.c ++++ b/modules/dclist.c +@@ -357,7 +357,9 @@ static char *getdnsdomainname(unsigned int logopt) + + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) { +- error(logopt, "hostname lookup failed: %s", gai_strerror(ret)); ++ error(logopt, ++ "hostname lookup for %s failed: %s", ++ name, gai_strerror(ret)); + return NULL; + } + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index e7debc56..9543ced3 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -260,7 +260,8 @@ static int match_my_name(unsigned int logopt, const char *name, struct substvar + ret = getaddrinfo(v->val, NULL, &hints, &cni); + if (ret) { + error(logopt, MODPREFIX +- "hostname lookup failed: %s\n", gai_strerror(ret)); ++ "hostname lookup for %s failed: %s\n", ++ v->val, gai_strerror(ret)); + goto out; + } + +@@ -270,7 +271,8 @@ static int match_my_name(unsigned int logopt, const char *name, struct substvar + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) { + error(logopt, MODPREFIX +- "hostname lookup failed: %s\n", gai_strerror(ret)); ++ "hostname lookup for %s failed: %s\n", ++ name, gai_strerror(ret)); + freeaddrinfo(cni); + goto out; + } +@@ -678,7 +680,8 @@ static char *normalize_hostname(unsigned int logopt, const char *host, + ret = getaddrinfo(host, NULL, &hints, &ni); + if (ret) { + error(logopt, MODPREFIX +- "hostname lookup failed: %s", gai_strerror(ret)); ++ "hostname lookup for %s failed: %s", ++ host, gai_strerror(ret)); + return NULL; + } + name = strdup(ni->ai_canonname); +diff --git a/modules/replicated.c b/modules/replicated.c +index f7b83236..740270ec 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -1007,8 +1007,9 @@ try_name: + + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) { +- error(LOGOPT_ANY, "hostname lookup failed: %s", +- gai_strerror(ret)); ++ error(LOGOPT_ANY, ++ "hostname lookup for %s failed: %s", ++ name, gai_strerror(ret)); + free(name); + return 0; + } diff --git a/autofs-5.1.4-make-umount_ent-recognise-forced-umount.patch b/autofs-5.1.4-make-umount_ent-recognise-forced-umount.patch new file mode 100644 index 0000000..5a3a069 --- /dev/null +++ b/autofs-5.1.4-make-umount_ent-recognise-forced-umount.patch @@ -0,0 +1,41 @@ +autofs-5.1.4 - make umount_ent() recognise forced umount + +From: Ian Kent + +When doing a forced shutdown umount_ent() tries a normal expire +first resulting in a fair amount of unnecessary log noise. + +Change umount_ent() to do a forced expire when a forced shutdown +has been requested to avoid the log noise. + +Signed-off-by: Ian Kent +--- + lib/mounts.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2984,14 +2984,16 @@ int umount_ent(struct autofs_point *ap, + { + 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)) { +- if (ap->state == ST_SHUTDOWN_FORCE) { +- info(ap->logopt, "forcing umount of %s", path); +- rv = spawn_umount(ap->logopt, "-l", path, NULL); +- } ++ if (ap->state != ST_SHUTDOWN_FORCE) ++ rv = spawn_umount(ap->logopt, path, NULL); ++ else { ++ /* We are doing a forced shutdown so unlink busy ++ * mounts */ ++ info(ap->logopt, "forcing umount of %s", path); ++ rv = spawn_umount(ap->logopt, "-l", path, NULL); ++ } + ++ if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { + /* + * Verify that we actually unmounted the thing. This is a + * belt and suspenders approach to not eating user data. diff --git a/autofs-5.1.4-mark-removed-cache-entry-negative.patch b/autofs-5.1.4-mark-removed-cache-entry-negative.patch new file mode 100644 index 0000000..ad2d363 --- /dev/null +++ b/autofs-5.1.4-mark-removed-cache-entry-negative.patch @@ -0,0 +1,64 @@ +autofs-5.1.4 - mark removed cache entry negative + +From: Ian Kent + +When re-reading a map entries that have been removed are detected +and deleted from the map entry cache by lookup_prune_cache(). + +If a removed map entry is mounted at the time lookup_prune_cache() +is called the map entry is skippedi. This is done becuase the next +lookup (following the mount expire, which needs the cache entry to +remain) will detect the stale cache entry and a map update done +resulting in the istale entry being removed. + +But if a map re-read is performed while the cache entry is mounted +the cache will appear to up to date so the removed entry will remain +valid even after it has expired. + +To cover this case it's sufficient to mark the mounted cache entry +negative during the cache prune which prevent further lookups from +using the stale entry. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 12 +++++++++--- + 2 files changed, 10 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -29,6 +29,7 @@ xx/xx/2018 autofs-5.1.5 + - covarity fixes. + - fix program usage message. + - fix update_negative_cache() map source usage. ++- mark removed cache entry negative. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -1417,15 +1417,21 @@ void lookup_prune_one_cache(struct autof + if (valid && valid->mc == mc) { + /* + * We've found a map entry that has been removed from +- * the current cache so it isn't really valid. ++ * the current cache so it isn't really valid. Set the ++ * mapent negative to prevent further mount requests ++ * using the cache entry. + */ ++ debug(ap->logopt, "removed map entry detected, mark negative"); ++ if (valid->mapent) { ++ free(valid->mapent); ++ valid->mapent = NULL; ++ } + cache_unlock(valid->mc); + valid = NULL; + } + if (!valid && + is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { +- debug(ap->logopt, +- "prune check posponed, %s mounted", path); ++ debug(ap->logopt, "prune posponed, %s mounted", path); + free(key); + free(path); + continue; diff --git a/autofs-5.1.4-move-close-stdio-descriptors-to-become_daemon.patch b/autofs-5.1.4-move-close-stdio-descriptors-to-become_daemon.patch new file mode 100644 index 0000000..4a4642e --- /dev/null +++ b/autofs-5.1.4-move-close-stdio-descriptors-to-become_daemon.patch @@ -0,0 +1,117 @@ +autofs-5.1.4 - move close stdio descriptors to become_daemon() + +From: Ian Kent + +Move the stdio file descriptor close to the become_daemon() function +as closing these file descriptors, ie. detaching from ttys, is part +of the preperation for becoming a system daemon. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 27 ++++++++++++++++++++++++++- + include/log.h | 1 - + lib/log.c | 29 ----------------------------- + 4 files changed, 27 insertions(+), 31 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -42,6 +42,7 @@ xx/xx/2018 autofs-5.1.5 + - add NULL check in prepare_attempt_prefix(). + - update build info with systemd. + - use flags for startup boolean options. ++- move close stdio descriptors to become_daemon(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1218,6 +1218,8 @@ static void become_daemon(unsigned int f + } + log_to_stderr(); + } else { ++ int nullfd; ++ + if (open_pipe(start_pipefd) < 0) { + fprintf(stderr, "%s: failed to create start_pipefd.\n", + program); +@@ -1261,7 +1263,30 @@ static void become_daemon(unsigned int f + close(start_pipefd[1]); + exit(*pst_stat); + } +- log_to_syslog(); ++ ++ /* Redirect all our file descriptors to /dev/null */ ++ nullfd = open("/dev/null", O_RDWR); ++ if (nullfd < 0) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ fprintf(stderr, "cannot open /dev/null: %s", estr); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ exit(*pst_stat); ++ } ++ ++ if (dup2(nullfd, STDIN_FILENO) < 0 || ++ dup2(nullfd, STDOUT_FILENO) < 0 || ++ dup2(nullfd, STDERR_FILENO) < 0) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ fprintf(stderr, ++ "redirecting file descriptors failed: %s", estr); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ exit(*pst_stat); ++ } ++ ++ open_log(); ++ close(nullfd); + } + + /* Write pid file if requested */ +--- autofs-5.1.4.orig/include/log.h ++++ autofs-5.1.4/include/log.h +@@ -36,7 +36,6 @@ extern void set_log_debug_ap(struct auto + extern void set_mnt_logging(unsigned global_logopt); + + extern void open_log(void); +-extern void log_to_syslog(void); + extern void log_to_stderr(void); + + extern void log_info(unsigned int, const char* msg, ...); +--- autofs-5.1.4.orig/lib/log.c ++++ autofs-5.1.4/lib/log.c +@@ -314,35 +314,6 @@ void open_log(void) + return; + } + +-void log_to_syslog(void) +-{ +- char buf[MAX_ERR_BUF]; +- int nullfd; +- +- open_log(); +- +- /* Redirect all our file descriptors to /dev/null */ +- nullfd = open("/dev/null", O_RDWR); +- if (nullfd < 0) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- fprintf(stderr, "cannot open /dev/null: %s", estr); +- exit(1); +- } +- +- if (dup2(nullfd, STDIN_FILENO) < 0 || +- dup2(nullfd, STDOUT_FILENO) < 0 || +- dup2(nullfd, STDERR_FILENO) < 0) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- fprintf(stderr, +- "redirecting file descriptors failed: %s", estr); +- exit(1); +- } +- +- close(nullfd); +- +- return; +-} +- + void log_to_stderr(void) + { + if (syslog_open) { diff --git a/autofs-5.1.4-remove-autofs4-module-load-code.patch b/autofs-5.1.4-remove-autofs4-module-load-code.patch new file mode 100644 index 0000000..27c0dfa --- /dev/null +++ b/autofs-5.1.4-remove-autofs4-module-load-code.patch @@ -0,0 +1,222 @@ +autofs-5.1.4 - remove autofs4 module load code + +From: Ian Kent + +The autofs kernel module has finally been renamed from autofs4 to +autofs so autoloading works so there is no need for manual loading. + +The module load function has been commented out in the source for +a long time so there should not be any adverse affects from removing +it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + configure | 61 ---------------------------------------------------- + configure.in | 1 + daemon/automount.c | 8 ------ + daemon/module.c | 35 ----------------------------- + include/automount.h | 7 ----- + include/config.h.in | 6 ----- + 7 files changed, 1 insertion(+), 118 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -38,6 +38,7 @@ xx/xx/2018 autofs-5.1.5 + - fix amd parser opts option handling. + - better handle hesiod support not built in. + - fix hesiod string check in master_parse(). ++- remove autofs4 module load code. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/configure ++++ autofs-5.1.4/configure +@@ -659,8 +659,6 @@ PATH_YACC + YACC + PATH_LEX + LEX +-HAVE_MODPROBE +-MODPROBE + HAVE_E4FSCK + E4FSCK + HAVE_E3FSCK +@@ -4155,65 +4153,6 @@ else + HAVE_E4FSCK=0 + fi + +-for ac_prog in modprobe +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_path_MODPROBE+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- case $MODPROBE in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_MODPROBE="$MODPROBE" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_path_MODPROBE="$as_dir/$ac_word$ac_exec_ext" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-MODPROBE=$ac_cv_path_MODPROBE +-if test -n "$MODPROBE"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MODPROBE" >&5 +-$as_echo "$MODPROBE" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$MODPROBE" && break +-done +- +-if test -n "$MODPROBE"; then +- +-$as_echo "#define HAVE_MODPROBE 1" >>confdefs.h +- +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_MODPROBE "$MODPROBE" +-_ACEOF +- +- HAVE_MODPROBE=1 +-else +- HAVE_MODPROBE=0 +-fi +- + + for ac_prog in flex lex + do +--- autofs-5.1.4.orig/configure.in ++++ autofs-5.1.4/configure.in +@@ -161,7 +161,6 @@ AF_PATH_INCLUDE(UMOUNT, umount, /bin/umo + AF_PATH_INCLUDE(E2FSCK, fsck.ext2 e2fsck, , $searchpath) + AF_PATH_INCLUDE(E3FSCK, fsck.ext3 e3fsck, , $searchpath) + AF_PATH_INCLUDE(E4FSCK, fsck.ext4 e4fsck, , $searchpath) +-AF_PATH_INCLUDE(MODPROBE, modprobe, , $searchpath) + + AF_CHECK_PROG(LEX, flex lex, , $searchpath) + AF_CHECK_PROG(YACC, bison, , $searchpath) +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -2336,14 +2336,6 @@ int main(int argc, char *argv[]) + exit(exit_code); + } + +-#if 0 +- if (!load_autofs4_module()) { +- fprintf(stderr, "%s: can't load %s filesystem module.\n", +- program, FS_MODULE_NAME); +- exit(1); +- } +-#endif +- + /* Don't need the kernel module just to look at the configured maps */ + if (!dumpmaps && (!query_kproto_ver() || get_kver_major() < 5)) { + fprintf(stderr, +--- autofs-5.1.4.orig/daemon/module.c ++++ autofs-5.1.4/daemon/module.c +@@ -19,41 +19,6 @@ + #include "automount.h" + #include "nsswitch.h" + +-int load_autofs4_module(void) +-{ +- FILE *fp; +- char buf[PATH_MAX]; +- int ret; +- +- /* +- * Check if module already loaded or compiled in. +- * If both autofs v3 and v4 are coplied in and +- * the v3 module registers first or the v4 module +- * is an older version we will catch it at mount +- * time. +- */ +- fp = open_fopen_r("/proc/filesystems"); +- if (!fp) { +- logerr("cannot open /proc/filesystems"); +- return 0; +- } +- +- while (fgets(buf, sizeof(buf), fp)) { +- if (strstr(buf, "autofs")) { +- fclose(fp); +- return 1; +- } +- } +- fclose(fp); +- +- ret = spawnl(LOGOPT_NONE, PATH_MODPROBE, PATH_MODPROBE, +- "-q", FS_MODULE_NAME, NULL); +- if (ret) +- return 0; +- +- return 1; +-} +- + int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + int argc, const char *const *argv, struct lookup_mod **lookup) + { +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -52,17 +52,10 @@ + #error Failed to locate umount(8)! + #endif + +-#ifndef HAVE_MODPROBE +-#error Failed to locate modprobe(8)! +-#endif +- + #ifndef HAVE_LINUX_PROCFS + #error Failed to verify existence of procfs filesystem! + #endif + +-#define FS_MODULE_NAME "autofs4" +-int load_autofs4_module(void); +- + /* The -s (sloppy) option to mount is good, if we have it... */ + + #ifdef HAVE_SLOPPY_MOUNT +--- autofs-5.1.4.orig/include/config.h.in ++++ autofs-5.1.4/include/config.h.in +@@ -48,9 +48,6 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_MEMORY_H + +-/* define if you have MODPROBE */ +-#undef HAVE_MODPROBE +- + /* define if you have MOUNT */ + #undef HAVE_MOUNT + +@@ -129,9 +126,6 @@ + /* define if you have LEX */ + #undef PATH_LEX + +-/* define if you have MODPROBE */ +-#undef PATH_MODPROBE +- + /* define if you have MOUNT */ + #undef PATH_MOUNT + diff --git a/autofs-5.1.4-remove-unused-function-dump_master.patch b/autofs-5.1.4-remove-unused-function-dump_master.patch new file mode 100644 index 0000000..17e7c78 --- /dev/null +++ b/autofs-5.1.4-remove-unused-function-dump_master.patch @@ -0,0 +1,37 @@ +autofs-5.1.4 - remove unused function dump_master() + +From: Ian Kent + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/master.c | 11 ----------- + 2 files changed, 1 insertion(+), 11 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -112,6 +112,7 @@ xx/xx/2018 autofs-5.1.5 + - dont prune offset map entries. + - simplify sss source stale check. + - use defines for expire type. ++- remove unused function dump_master(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -1971,14 +1971,3 @@ int master_kill(struct master *master) + + return 1; + } +- +-void dump_master(struct master *master) +-{ +- struct list_head *p, *head; +- +- head = &master->mounts; +- list_for_each(p, head) { +- struct master_mapent *this = list_entry(p, struct master_mapent, list); +- logmsg("path %s", this->path); +- } +-} diff --git a/autofs-5.1.4-set-bind-mount-as-propagation-slave.patch b/autofs-5.1.4-set-bind-mount-as-propagation-slave.patch new file mode 100644 index 0000000..cb8356c --- /dev/null +++ b/autofs-5.1.4-set-bind-mount-as-propagation-slave.patch @@ -0,0 +1,69 @@ +autofs-5.1.4 - set bind mount as propagation slave + +From: Ian Kent + +When using a multi-mount with mount targets that are on the +local machine and resulting bind mounts are made to a file +system that is mount propagation shared (such as the root +file system on systemd managed systems) the autofs offset +mount triggers made within the bind mount will be propagated +back to the target file system. + +When this happens the target of the offset (the unwanted +propagated mount) is itself an autofs trigger mount and +accessing the path results in a deadlock. + +In order for these multi-mounts to function properly in this +case bind mounts that contain mount triggers must be set to +propagation slave or private so the backward propagation +doesn't occur. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_bind.c | 16 +++++++++++++++- + 2 files changed, 16 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -30,6 +30,7 @@ xx/xx/2018 autofs-5.1.5 + - fix program usage message. + - fix update_negative_cache() map source usage. + - mark removed cache entry negative. ++- set bind mount as propagation slave. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/mount_bind.c ++++ autofs-5.1.4/modules/mount_bind.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #define MODULE_MOUNT + #include "automount.h" +@@ -183,8 +184,21 @@ int mount_mount(struct autofs_point *ap, + debug(ap->logopt, + MODPREFIX "mounted %s type %s on %s", + what, fstype, fullpath); +- return 0; + } ++ ++ /* The bind mount has succeeded but if the target ++ * mount is propagation shared propagation of child ++ * mounts (autofs offset mounts for example) back to ++ * the target of the bind mount must be avoided or ++ * autofs trigger mounts will deadlock. ++ */ ++ err = mount(NULL, fullpath, NULL, MS_SLAVE, NULL); ++ if (err) ++ warn(ap->logopt, ++ "failed to set propagation type for %s", ++ fullpath); ++ ++ return 0; + } else { + char *cp; + char basepath[PATH_MAX]; diff --git a/autofs-5.1.4-tiny-patch-for-autofs-typo-and-possible-bug.patch b/autofs-5.1.4-tiny-patch-for-autofs-typo-and-possible-bug.patch new file mode 100644 index 0000000..1f03fff --- /dev/null +++ b/autofs-5.1.4-tiny-patch-for-autofs-typo-and-possible-bug.patch @@ -0,0 +1,48 @@ +autofs-5.1.4 - tiny patch for autofs typo and possible bug + +From: Todd Eigenschink + +(1) The word "to" is doubled in two warnings. + +(2) It prints a warning when it can't open the "old" config file, even +if it was able to open the default one. That's a reasonable warning if +it *couldn't* open the new one, but seems unnecessary if it could. + +The patch removes the unneeded "to"s and only prints warning about the +old config file if it couldn't open the default one. + +Signed-off-by: Todd Eigenschink +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/defaults.c | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -20,6 +20,7 @@ xx/xx/2018 autofs-5.1.5 + - add conditional inclusion of fedfs binaries. + - add an example fedfs master map entry to the installed master map. + - improve hostname lookup error logging. ++- tiny patch for autofs typo and possible bug. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/defaults.c ++++ autofs-5.1.4/lib/defaults.c +@@ -1207,12 +1207,12 @@ unsigned int defaults_read_config(unsign + + conf = open_fopen_r(DEFAULT_CONFIG_FILE); + if (!conf) +- message(to_syslog, "failed to to open config %s", ++ message(to_syslog, "failed to open config %s", + DEFAULT_CONFIG_FILE); + + oldconf = open_fopen_r(OLD_CONFIG_FILE); +- if (!oldconf) +- message(to_syslog, "failed to to open old config %s", ++ if (!oldconf && !conf) ++ message(to_syslog, "failed to open old config %s", + OLD_CONFIG_FILE); + + /* Neither config has been updated */ diff --git a/autofs-5.1.4-update-build-info-with-systemd.patch b/autofs-5.1.4-update-build-info-with-systemd.patch new file mode 100644 index 0000000..7c9f381 --- /dev/null +++ b/autofs-5.1.4-update-build-info-with-systemd.patch @@ -0,0 +1,41 @@ +autofs-5.1.4 - update build info with systemd + +From: Ian Kent + +Update the show_build_info() function to include systemd +build info. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 9 +++++++++ + 2 files changed, 10 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -40,6 +40,7 @@ xx/xx/2018 autofs-5.1.5 + - fix hesiod string check in master_parse(). + - remove autofs4 module load code. + - add NULL check in prepare_attempt_prefix(). ++- update build info with systemd. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1951,6 +1951,15 @@ static void show_build_info(void) + } + #endif + ++#ifdef WITH_SYSTEMD ++ printf("WITH_SYSTEMD "); ++ count = count + 13; ++ ++ if (count > 60) { ++ printf("\n "); ++ count = 0; ++ } ++#endif + + #ifdef WITH_HESIOD + printf("WITH_HESIOD "); diff --git a/autofs-5.1.4-use-defines-for-expire-type.patch b/autofs-5.1.4-use-defines-for-expire-type.patch new file mode 100644 index 0000000..6592ac4 --- /dev/null +++ b/autofs-5.1.4-use-defines-for-expire-type.patch @@ -0,0 +1,100 @@ +autofs-5.1.4 - use defines for expire type + +From: Ian Kent + +The kernel defines for expire type such as an immediate expire +shoule be used to clearify what is being requested. + +AUTOFS_EXP_IMMEDIATE corresponds to a SIGUSR1 prune operation. + +AUTOFS_EXP_FORCE corresponds to an expire type not yet implemented in +the kernel, a SIGUSR2 forced expire. Define it in our internal autofs +kernel include file, the kernel will ignore it if it doesn't support it. + +AUTOFS_EXP_LEAVES is no longer used in autofs version 5. + +Finally add a define AUTOFS_EXP_NORMAL to indicate we're perfoming a +normal expire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 8 ++++---- + include/linux/auto_fs4.h | 6 ++++-- + include/state.h | 2 +- + 4 files changed, 10 insertions(+), 7 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -111,6 +111,7 @@ xx/xx/2018 autofs-5.1.5 + - use a valid timeout in lookup_prune_one_cache(). + - dont prune offset map entries. + - simplify sss source stale check. ++- use defines for expire type. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -634,7 +634,7 @@ static unsigned int st_prepare_shutdown( + ap->state = ST_SHUTDOWN_PENDING; + + /* Unmount everything */ +- exp = expire_proc(ap, 1); ++ exp = expire_proc(ap, AUTOFS_EXP_IMMEDIATE); + switch (exp) { + case EXP_ERROR: + case EXP_PARTIAL: +@@ -660,7 +660,7 @@ static unsigned int st_force_shutdown(st + ap->state = ST_SHUTDOWN_FORCE; + + /* Unmount everything */ +- exp = expire_proc(ap, 1); ++ exp = expire_proc(ap, AUTOFS_EXP_FORCE | AUTOFS_EXP_IMMEDIATE); + switch (exp) { + case EXP_ERROR: + case EXP_PARTIAL: +@@ -695,7 +695,7 @@ static unsigned int st_prune(struct auto + assert(ap->state == ST_READY); + ap->state = ST_PRUNE; + +- switch (expire_proc(ap, 1)) { ++ switch (expire_proc(ap, AUTOFS_EXP_IMMEDIATE)) { + case EXP_ERROR: + case EXP_PARTIAL: + if (!ap->submount) +@@ -716,7 +716,7 @@ static unsigned int st_expire(struct aut + assert(ap->state == ST_READY); + ap->state = ST_EXPIRE; + +- switch (expire_proc(ap, 0)) { ++ switch (expire_proc(ap, AUTOFS_EXP_NORMAL)) { + case EXP_ERROR: + case EXP_PARTIAL: + if (!ap->submount) +--- autofs-5.1.4.orig/include/linux/auto_fs4.h ++++ autofs-5.1.4/include/linux/auto_fs4.h +@@ -27,8 +27,10 @@ + #define AUTOFS_PROTO_SUBVERSION 2 + + /* Mask for expire behaviour */ +-#define AUTOFS_EXP_IMMEDIATE 1 +-#define AUTOFS_EXP_LEAVES 2 ++#define AUTOFS_EXP_NORMAL 0x00 ++#define AUTOFS_EXP_IMMEDIATE 0x01 ++#define AUTOFS_EXP_LEAVES 0x02 ++#define AUTOFS_EXP_FORCE 0x04 + + #define AUTOFS_TYPE_ANY 0U + #define AUTOFS_TYPE_INDIRECT 1U +--- autofs-5.1.4.orig/include/state.h ++++ autofs-5.1.4/include/state.h +@@ -55,7 +55,7 @@ struct expire_args { + unsigned int signaled; + struct autofs_point *ap; /* autofs mount we are working on */ + enum states state; /* State prune or expire */ +- unsigned int how; /* Normal, immediate expire ? */ ++ unsigned int how; /* Normal, immediate, forced expire ? */ + int status; /* Return status */ + }; + diff --git a/autofs-5.1.4-use-flags-for-startup-boolean-options.patch b/autofs-5.1.4-use-flags-for-startup-boolean-options.patch new file mode 100644 index 0000000..b744ce7 --- /dev/null +++ b/autofs-5.1.4-use-flags-for-startup-boolean-options.patch @@ -0,0 +1,217 @@ +autofs-5.1.4 - use flags for startup boolean options + +From: Ian Kent + +The daemon uses a number of boolean flags each stored in unsigned int +variables. But a single bit flag is sufficient storage for most of +these flags. + +So use bit flags for these where possible. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 45 ++++++++++++++++++++++----------------------- + include/automount.h | 6 ++++++ + lib/master.c | 4 ++-- + 4 files changed, 31 insertions(+), 25 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -41,6 +41,7 @@ xx/xx/2018 autofs-5.1.5 + - remove autofs4 module load code. + - add NULL check in prepare_attempt_prefix(). + - update build info with systemd. ++- use flags for startup boolean options. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1195,7 +1195,7 @@ static int handle_packet(struct autofs_p + return -1; + } + +-static void become_daemon(unsigned foreground, unsigned daemon_check) ++static void become_daemon(unsigned int flags) + { + FILE *pidfp; + char buf[MAX_ERR_BUF]; +@@ -1210,8 +1210,8 @@ static void become_daemon(unsigned foreg + } + + /* Detach from foreground process */ +- if (foreground) { +- if (daemon_check && !aquire_flag_file()) { ++ if (flags & DAEMON_FLAGS_FOREGROUND) { ++ if ((flags & DAEMON_FLAGS_CHECK_DAEMON) && !aquire_flag_file()) { + fprintf(stderr, "%s: program is already running.\n", + program); + exit(1); +@@ -1238,7 +1238,7 @@ static void become_daemon(unsigned foreg + } + close(start_pipefd[0]); + +- if (daemon_check && !aquire_flag_file()) { ++ if ((flags & DAEMON_FLAGS_CHECK_DAEMON) && !aquire_flag_file()) { + fprintf(stderr, "%s: program is already running.\n", + program); + /* Return success if already running */ +@@ -2158,8 +2158,8 @@ int main(int argc, char *argv[]) + { + int res, opt, status; + int logpri = -1; +- unsigned ghost, logging, daemon_check; +- unsigned dumpmaps, foreground, have_global_options; ++ unsigned int flags; ++ unsigned int logging; + unsigned master_read; + int master_wait; + time_t timeout; +@@ -2202,17 +2202,15 @@ int main(int argc, char *argv[]) + + nfs_mount_uses_string_options = check_nfs_mount_version(&vers, &check); + ++ flags = defaults_get_browse_mode() ? DAEMON_FLAGS_GHOST : 0; ++ flags |= DAEMON_FLAGS_CHECK_DAEMON; ++ + kpkt_len = get_kpkt_len(); + master_wait = defaults_get_master_wait(); + timeout = defaults_get_timeout(); +- ghost = defaults_get_browse_mode(); + logging = defaults_get_logging(); + global_selection_options = 0; + global_options = NULL; +- have_global_options = 0; +- foreground = 0; +- dumpmaps = 0; +- daemon_check = 1; + + remove_empty_args(argv, &argc); + +@@ -2244,7 +2242,7 @@ int main(int argc, char *argv[]) + break; + + case 'f': +- foreground = 1; ++ flags |= DAEMON_FLAGS_FOREGROUND; + break; + + case 'V': +@@ -2260,7 +2258,7 @@ int main(int argc, char *argv[]) + break; + + case 'm': +- dumpmaps = 1; ++ flags |= DAEMON_FLAGS_DUMP_MAPS; + break; + + case 'M': +@@ -2268,9 +2266,9 @@ int main(int argc, char *argv[]) + break; + + case 'O': +- if (!have_global_options) { ++ if (!(flags & DAEMON_FLAGS_HAVE_GLOBAL_OPTIONS)) { + global_options = strdup(optarg); +- have_global_options = 1; ++ flags |= DAEMON_FLAGS_HAVE_GLOBAL_OPTIONS; + break; + } + printf("%s: global options already specified.\n", +@@ -2295,7 +2293,7 @@ int main(int argc, char *argv[]) + break; + + case 'C': +- daemon_check = 0; ++ flags &= ~DAEMON_FLAGS_CHECK_DAEMON; + break; + + case 'F': +@@ -2346,7 +2344,8 @@ int main(int argc, char *argv[]) + } + + /* Don't need the kernel module just to look at the configured maps */ +- if (!dumpmaps && (!query_kproto_ver() || get_kver_major() < 5)) { ++ if (!(flags & DAEMON_FLAGS_DUMP_MAPS) && ++ (!query_kproto_ver() || get_kver_major() < 5)) { + fprintf(stderr, + "%s: test mount forbidden or " + "incorrect kernel protocol version, " +@@ -2377,7 +2376,7 @@ int main(int argc, char *argv[]) + /* Get processor information for predefined escapes */ + macro_init(); + +- if (dumpmaps) { ++ if (flags & DAEMON_FLAGS_DUMP_MAPS) { + struct master_mapent *entry; + struct list_head *head, *p; + struct mapent_cache *nc; +@@ -2395,9 +2394,9 @@ int main(int argc, char *argv[]) + } + + if (master) +- master_list = master_new(NULL, timeout, ghost); ++ master_list = master_new(NULL, timeout, flags); + else +- master_list = master_new(master, timeout, ghost); ++ master_list = master_new(master, timeout, flags); + if (!master_list) { + printf("%s: can't create master map", program); + macro_free_global_table(); +@@ -2443,9 +2442,9 @@ int main(int argc, char *argv[]) + } + + if (argc == 0) +- master_list = master_new(NULL, timeout, ghost); ++ master_list = master_new(NULL, timeout, flags); + else +- master_list = master_new(argv[0], timeout, ghost); ++ master_list = master_new(argv[0], timeout, flags); + + if (!master_list) { + printf("%s: can't create master map %s", program, argv[0]); +@@ -2453,7 +2452,7 @@ int main(int argc, char *argv[]) + exit(1); + } + +- become_daemon(foreground, daemon_check); ++ become_daemon(flags); + + if (pthread_attr_init(&th_attr)) { + logerr("%s: failed to init thread attribute struct!", +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -66,6 +66,12 @@ + #define SLOPPY + #endif + ++#define DAEMON_FLAGS_FOREGROUND 0x0001 ++#define DAEMON_FLAGS_HAVE_GLOBAL_OPTIONS 0x0004 ++#define DAEMON_FLAGS_GHOST 0x0008 ++#define DAEMON_FLAGS_CHECK_DAEMON 0x0010 ++#define DAEMON_FLAGS_DUMP_MAPS 0x0020 ++ + #define AUTOFS_SUPER_MAGIC 0x00000187L + #define SMB_SUPER_MAGIC 0x0000517BL + #define CIFS_MAGIC_NUMBER 0xFF534D42L +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -922,7 +922,7 @@ void master_free_mapent(struct master_ma + return; + } + +-struct master *master_new(const char *name, unsigned int timeout, unsigned int ghost) ++struct master *master_new(const char *name, unsigned int timeout, unsigned int flags) + { + struct master *master; + char *tmp; +@@ -948,7 +948,7 @@ struct master *master_new(const char *na + master->depth = 0; + master->reading = 0; + master->read_fail = 0; +- master->default_ghost = ghost; ++ master->default_ghost = flags & DAEMON_FLAGS_GHOST; + master->default_timeout = timeout; + master->default_logging = defaults_get_logging(); + master->logopt = master->default_logging; diff --git a/autofs-5.1.4-use-systemd-sd_notify-at-startup.patch b/autofs-5.1.4-use-systemd-sd_notify-at-startup.patch new file mode 100644 index 0000000..410f267 --- /dev/null +++ b/autofs-5.1.4-use-systemd-sd_notify-at-startup.patch @@ -0,0 +1,1357 @@ +autofs-5.1.4 - use systemd sd_notify() at startup + +From: Ian Kent + +autofs needs to ensure statd is started before any NFS mounts +are attempted. + +When starting the statd service with the autofs service the statd +service will trigger a restart of the autofs service during its +start up. Sometimes this can happen during the automount start up +itself. + +When this happens it causes systemd to become confused and remove +the pid file created by automount leaving systemd thinking the +autofs service had failed start up when it was actually running. + +It was recommened that autofs be changed to a "Type=notify" service +to avoid this. Using this a pid file is no longer needed and is now +not used. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + Makefile.conf.in | 3 + aclocal.m4 | 3 + autofs.spec | 1 + configure | 948 +++++++++++++++++++++++++++------------------- + configure.in | 8 + daemon/Makefile | 5 + daemon/automount.c | 83 ++-- + samples/autofs.service.in | 5 + 9 files changed, 635 insertions(+), 422 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -22,6 +22,7 @@ xx/xx/2018 autofs-5.1.5 + - improve hostname lookup error logging. + - tiny patch for autofs typo and possible bug. + - add units After line to include statd service. ++- use systemd sd_notify() at startup. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/Makefile.conf.in ++++ autofs-5.1.4/Makefile.conf.in +@@ -18,6 +18,9 @@ NSLLIB = @NSL_LIBS@ + NSLCFLAGS = @NSL_CFLAGS@ + LIBRESOLV = @LIBRESOLV@ + ++SYSTEMD = @WITH_SYSTEMD@ ++LIBSYSTEMD = @systemd_LIBS@ ++ + # Hesiod support: yes (1) no (0) + HESIOD = @HAVE_HESIOD@ + LIBHESIOD = @LIBHESIOD@ +--- autofs-5.1.4.orig/aclocal.m4 ++++ autofs-5.1.4/aclocal.m4 +@@ -257,14 +257,17 @@ AC_DEFUN([AF_WITH_SYSTEMD], + fi + done + fi ++ WITH_SYSTEMD=0 + if test -n "$systemddir"; then + AC_MSG_RESULT($systemddir) ++ WITH_SYSTEMD=1 + else + AC_MSG_RESULT(not found) + fi + else + if test "$withval" != no; then + systemddir=$withval ++ WITH_SYSTEMD=1 + fi + fi]) + ]) +--- autofs-5.1.4.orig/autofs.spec ++++ autofs-5.1.4/autofs.spec +@@ -32,6 +32,7 @@ Source: https://www.kernel.org/pub/linux + Buildroot: %{_tmppath}/%{name}-tmp + %if %{with_systemd} + BuildRequires: systemd-units ++BuildRequires: systemd-devel + %endif + %if %{with_libtirpc} + BuildRequires: libtirpc-devel +--- autofs-5.1.4.orig/configure ++++ autofs-5.1.4/configure +@@ -674,6 +674,12 @@ MOUNT_NFS + HAVE_MOUNT + MOUNT + DMALLOCLIB ++TIRPC_LIBS ++TIRPC_CFLAGS ++flagdir ++fifodir ++mapdir ++confdir + OBJEXT + EXEEXT + ac_ct_CC +@@ -681,16 +687,13 @@ CPPFLAGS + LDFLAGS + CFLAGS + CC +-TIRPC_LIBS +-TIRPC_CFLAGS ++systemd_LIBS ++systemd_CFLAGS ++WITH_SYSTEMD ++systemddir + PKG_CONFIG_LIBDIR + PKG_CONFIG_PATH + PKG_CONFIG +-flagdir +-fifodir +-mapdir +-confdir +-systemddir + piddir + initdir + target_alias +@@ -760,13 +763,15 @@ target_alias + PKG_CONFIG + PKG_CONFIG_PATH + PKG_CONFIG_LIBDIR +-TIRPC_CFLAGS +-TIRPC_LIBS ++systemd_CFLAGS ++systemd_LIBS + CC + CFLAGS + LDFLAGS + LIBS + CPPFLAGS ++TIRPC_CFLAGS ++TIRPC_LIBS + NSL_CFLAGS + NSL_LIBS + CPP' +@@ -1413,9 +1418,10 @@ Some influential environment variables: + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path +- TIRPC_CFLAGS +- C compiler flags for TIRPC, overriding pkg-config +- TIRPC_LIBS linker flags for TIRPC, overriding pkg-config ++ systemd_CFLAGS ++ C compiler flags for systemd, overriding pkg-config ++ systemd_LIBS ++ linker flags for systemd, overriding pkg-config + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a +@@ -1423,6 +1429,9 @@ Some influential environment variables: + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory ++ TIRPC_CFLAGS ++ C compiler flags for TIRPC, overriding pkg-config ++ TIRPC_LIBS linker flags for TIRPC, overriding pkg-config + NSL_CFLAGS C compiler flags for NSL, overriding pkg-config + NSL_LIBS linker flags for NSL, overriding pkg-config + CPP C preprocessor +@@ -2291,166 +2300,6 @@ if test -z "$piddir"; then + fi + + +-# +-# Check for systemd unit files direectory exists if unit file installation +-# is requested +-# +- +-# Check whether --with-systemd was given. +-if test "${with_systemd+set}" = set; then : +- withval=$with_systemd; if test "$withval" = yes; then +- if test -z "$systemddir"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking location of the systemd unit files directory" >&5 +-$as_echo_n "checking location of the systemd unit files directory... " >&6; } +- for systemd_d in /usr/lib/systemd/system /usr/lib64/systemd/system /lib/systemd/system /lib64/systemd/system; do +- if test -z "$systemddir"; then +- if test -d "$systemd_d"; then +- systemddir="$systemd_d" +- fi +- fi +- done +- fi +- if test -n "$systemddir"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $systemddir" >&5 +-$as_echo "$systemddir" >&6; } +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +-$as_echo "not found" >&6; } +- fi +-else +- if test "$withval" != no; then +- systemddir=$withval +- fi +-fi +-fi +- +- +- +- +-# +-# Location of system config script directory? +-# +-if test -z "$confdir"; then +- for conf_d in /etc/sysconfig /etc/defaults /etc/conf.d /etc/default; do +- if test -z "$confdir"; then +- if test -d "$conf_d"; then +- confdir="$conf_d" +- fi +- fi +- done +-fi +- +-# Check whether --with-confdir was given. +-if test "${with_confdir+set}" = set; then : +- withval=$with_confdir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" +- then +- : +- else +- confdir="${withval}" +- fi +- +-fi +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs configuration file directory" >&5 +-$as_echo_n "checking for autofs configuration file directory... " >&6; } +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $confdir" >&5 +-$as_echo "$confdir" >&6; } +- +- +-# +-# The user can specify --with-mapsdir=PATH to specify autofs maps go +-# +-if test -z "$mapdir"; then +- for map_d in /etc/autofs /etc; do +- if test -z "$mapdir"; then +- if test -d "$map_d"; then +- mapdir="$map_d" +- fi +- fi +- done +-fi +- +-# Check whether --with-mapdir was given. +-if test "${with_mapdir+set}" = set; then : +- withval=$with_mapdir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" +- then +- : +- else +- mapdir="${withval}" +- fi +- +-fi +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs maps directory" >&5 +-$as_echo_n "checking for autofs maps directory... " >&6; } +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mapdir" >&5 +-$as_echo "$mapdir" >&6; } +- +- +-# +-# The user can specify --with-fifodir=PATH to specify where autofs fifos go +-# +-if test -z "$fifodir"; then +- for fifo_d in /run /var/run /tmp; do +- if test -z "$fifodir"; then +- if test -d "$fifo_d"; then +- fifodir="$fifo_d" +- fi +- fi +- done +-fi +- +-# Check whether --with-fifodir was given. +-if test "${with_fifodir+set}" = set; then : +- withval=$with_fifodir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" +- then +- : +- else +- fifodir="${withval}" +- fi +- +-fi +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs fifos directory" >&5 +-$as_echo_n "checking for autofs fifos directory... " >&6; } +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $fifodir" >&5 +-$as_echo "$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 /run /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 +- flagdir="${withval}" +- fi +- +-fi +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs flag file directory" >&5 +-$as_echo_n "checking for autofs flag file directory... " >&6; } +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $flagdir" >&5 +-$as_echo "$flagdir" >&6; } +- +- +-# +-# Use libtirpc +-# +- + + + +@@ -2571,111 +2420,46 @@ $as_echo "no" >&6; } + fi + fi + +-# Check whether --with-libtirpc was given. +-if test "${with_libtirpc+set}" = set; then : +- withval=$with_libtirpc; +-fi +- +-if test "x$with_libtirpc" = "xyes"; then +- +-pkg_failed=no +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIRPC" >&5 +-$as_echo_n "checking for TIRPC... " >&6; } ++# ++# Check for systemd unit files direectory exists if unit file installation ++# is requested ++# + +-if test -n "$TIRPC_CFLAGS"; then +- pkg_cv_TIRPC_CFLAGS="$TIRPC_CFLAGS" +- elif test -n "$PKG_CONFIG"; then +- if test -n "$PKG_CONFIG" && \ +- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 +- ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then +- pkg_cv_TIRPC_CFLAGS=`$PKG_CONFIG --cflags "libtirpc" 2>/dev/null` +- test "x$?" != "x0" && pkg_failed=yes +-else +- pkg_failed=yes +-fi +- else +- pkg_failed=untried +-fi +-if test -n "$TIRPC_LIBS"; then +- pkg_cv_TIRPC_LIBS="$TIRPC_LIBS" +- elif test -n "$PKG_CONFIG"; then +- if test -n "$PKG_CONFIG" && \ +- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 +- ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then +- pkg_cv_TIRPC_LIBS=`$PKG_CONFIG --libs "libtirpc" 2>/dev/null` +- test "x$?" != "x0" && pkg_failed=yes ++# Check whether --with-systemd was given. ++if test "${with_systemd+set}" = set; then : ++ withval=$with_systemd; if test "$withval" = yes; then ++ if test -z "$systemddir"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking location of the systemd unit files directory" >&5 ++$as_echo_n "checking location of the systemd unit files directory... " >&6; } ++ for systemd_d in /usr/lib/systemd/system /usr/lib64/systemd/system /lib/systemd/system /lib64/systemd/system; do ++ if test -z "$systemddir"; then ++ if test -d "$systemd_d"; then ++ systemddir="$systemd_d" ++ fi ++ fi ++ done ++ fi ++ WITH_SYSTEMD=0 ++ if test -n "$systemddir"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $systemddir" >&5 ++$as_echo "$systemddir" >&6; } ++ WITH_SYSTEMD=1 ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 ++$as_echo "not found" >&6; } ++ fi + else +- pkg_failed=yes +-fi +- else +- pkg_failed=untried ++ if test "$withval" != no; then ++ systemddir=$withval ++ WITH_SYSTEMD=1 ++ fi + fi +- +- +- +-if test $pkg_failed = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- +-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then +- _pkg_short_errors_supported=yes +-else +- _pkg_short_errors_supported=no + fi +- if test $_pkg_short_errors_supported = yes; then +- TIRPC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libtirpc" 2>&1` +- else +- TIRPC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libtirpc" 2>&1` +- fi +- # Put the nasty error message in config.log where it belongs +- echo "$TIRPC_PKG_ERRORS" >&5 +- +- as_fn_error $? "Package requirements (libtirpc) were not met: +- +-$TIRPC_PKG_ERRORS +- +-Consider adjusting the PKG_CONFIG_PATH environment variable if you +-installed software in a non-standard prefix. + +-Alternatively, you may set the environment variables TIRPC_CFLAGS +-and TIRPC_LIBS to avoid the need to call pkg-config. +-See the pkg-config man page for more details." "$LINENO" 5 +-elif test $pkg_failed = untried; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +-is in your PATH or set the PKG_CONFIG environment variable to the full +-path to pkg-config. +- +-Alternatively, you may set the environment variables TIRPC_CFLAGS +-and TIRPC_LIBS to avoid the need to call pkg-config. +-See the pkg-config man page for more details. +- +-To get pkg-config, see . +-See \`config.log' for more details" "$LINENO" 5; } +-else +- TIRPC_CFLAGS=$pkg_cv_TIRPC_CFLAGS +- TIRPC_LIBS=$pkg_cv_TIRPC_LIBS +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } + + +-$as_echo "#define WITH_LIBTIRPC 1" >>confdefs.h +- +- +-$as_echo "#define TIRPC_WORKAROUND 1" >>confdefs.h +- + +-fi +- ac_ext=c ++ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' + ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +@@ -3465,7 +3249,511 @@ ac_link='$CC -o conftest$ac_exeext $CFLA + ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +-for ac_func in getrpcbyname getservbyname ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for systemd" >&5 ++$as_echo_n "checking for systemd... " >&6; } ++ ++if test -n "$systemd_CFLAGS"; then ++ pkg_cv_systemd_CFLAGS="$systemd_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_systemd_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$systemd_LIBS"; then ++ pkg_cv_systemd_LIBS="$systemd_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_systemd_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ systemd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1` ++ else ++ systemd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$systemd_PKG_ERRORS" >&5 ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sm_notify in -lsystemd" >&5 ++$as_echo_n "checking for sm_notify in -lsystemd... " >&6; } ++if ${ac_cv_lib_systemd_sm_notify+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lsystemd $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* 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 sm_notify (); ++int ++main () ++{ ++return sm_notify (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_systemd_sm_notify=yes ++else ++ ac_cv_lib_systemd_sm_notify=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_sm_notify" >&5 ++$as_echo "$ac_cv_lib_systemd_sm_notify" >&6; } ++if test "x$ac_cv_lib_systemd_sm_notify" = xyes; then : ++ systemd_LIBS="-lsystemd" ++fi ++ ++ ++ ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sm_notify in -lsystemd" >&5 ++$as_echo_n "checking for sm_notify in -lsystemd... " >&6; } ++if ${ac_cv_lib_systemd_sm_notify+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lsystemd $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* 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 sm_notify (); ++int ++main () ++{ ++return sm_notify (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_systemd_sm_notify=yes ++else ++ ac_cv_lib_systemd_sm_notify=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_sm_notify" >&5 ++$as_echo "$ac_cv_lib_systemd_sm_notify" >&6; } ++if test "x$ac_cv_lib_systemd_sm_notify" = xyes; then : ++ systemd_LIBS="-lsystemd" ++fi ++ ++ ++ ++else ++ systemd_CFLAGS=$pkg_cv_systemd_CFLAGS ++ systemd_LIBS=$pkg_cv_systemd_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++fi ++ ++# ++# Location of system config script directory? ++# ++if test -z "$confdir"; then ++ for conf_d in /etc/sysconfig /etc/defaults /etc/conf.d /etc/default; do ++ if test -z "$confdir"; then ++ if test -d "$conf_d"; then ++ confdir="$conf_d" ++ fi ++ fi ++ done ++fi ++ ++# Check whether --with-confdir was given. ++if test "${with_confdir+set}" = set; then : ++ withval=$with_confdir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" ++ then ++ : ++ else ++ confdir="${withval}" ++ fi ++ ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs configuration file directory" >&5 ++$as_echo_n "checking for autofs configuration file directory... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $confdir" >&5 ++$as_echo "$confdir" >&6; } ++ ++ ++# ++# The user can specify --with-mapsdir=PATH to specify autofs maps go ++# ++if test -z "$mapdir"; then ++ for map_d in /etc/autofs /etc; do ++ if test -z "$mapdir"; then ++ if test -d "$map_d"; then ++ mapdir="$map_d" ++ fi ++ fi ++ done ++fi ++ ++# Check whether --with-mapdir was given. ++if test "${with_mapdir+set}" = set; then : ++ withval=$with_mapdir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" ++ then ++ : ++ else ++ mapdir="${withval}" ++ fi ++ ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs maps directory" >&5 ++$as_echo_n "checking for autofs maps directory... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mapdir" >&5 ++$as_echo "$mapdir" >&6; } ++ ++ ++# ++# The user can specify --with-fifodir=PATH to specify where autofs fifos go ++# ++if test -z "$fifodir"; then ++ for fifo_d in /run /var/run /tmp; do ++ if test -z "$fifodir"; then ++ if test -d "$fifo_d"; then ++ fifodir="$fifo_d" ++ fi ++ fi ++ done ++fi ++ ++# Check whether --with-fifodir was given. ++if test "${with_fifodir+set}" = set; then : ++ withval=$with_fifodir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no" ++ then ++ : ++ else ++ fifodir="${withval}" ++ fi ++ ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs fifos directory" >&5 ++$as_echo_n "checking for autofs fifos directory... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $fifodir" >&5 ++$as_echo "$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 /run /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 ++ flagdir="${withval}" ++ fi ++ ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for autofs flag file directory" >&5 ++$as_echo_n "checking for autofs flag file directory... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $flagdir" >&5 ++$as_echo "$flagdir" >&6; } ++ ++ ++# ++# Use libtirpc ++# ++ ++ ++ ++ ++ ++ ++ ++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. ++set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++PKG_CONFIG=$ac_cv_path_PKG_CONFIG ++if test -n "$PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 ++$as_echo "$PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_path_PKG_CONFIG"; then ++ ac_pt_PKG_CONFIG=$PKG_CONFIG ++ # Extract the first word of "pkg-config", so it can be a program name with args. ++set dummy pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $ac_pt_PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG ++if test -n "$ac_pt_PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 ++$as_echo "$ac_pt_PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_pt_PKG_CONFIG" = x; then ++ PKG_CONFIG="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ PKG_CONFIG=$ac_pt_PKG_CONFIG ++ fi ++else ++ PKG_CONFIG="$ac_cv_path_PKG_CONFIG" ++fi ++ ++fi ++if test -n "$PKG_CONFIG"; then ++ _pkg_min_version=0.9.0 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 ++$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } ++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ PKG_CONFIG="" ++ fi ++fi ++ ++# Check whether --with-libtirpc was given. ++if test "${with_libtirpc+set}" = set; then : ++ withval=$with_libtirpc; ++fi ++ ++if test "x$with_libtirpc" = "xyes"; then ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIRPC" >&5 ++$as_echo_n "checking for TIRPC... " >&6; } ++ ++if test -n "$TIRPC_CFLAGS"; then ++ pkg_cv_TIRPC_CFLAGS="$TIRPC_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_TIRPC_CFLAGS=`$PKG_CONFIG --cflags "libtirpc" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$TIRPC_LIBS"; then ++ pkg_cv_TIRPC_LIBS="$TIRPC_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_TIRPC_LIBS=`$PKG_CONFIG --libs "libtirpc" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ TIRPC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libtirpc" 2>&1` ++ else ++ TIRPC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libtirpc" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$TIRPC_PKG_ERRORS" >&5 ++ ++ as_fn_error $? "Package requirements (libtirpc) were not met: ++ ++$TIRPC_PKG_ERRORS ++ ++Consider adjusting the PKG_CONFIG_PATH environment variable if you ++installed software in a non-standard prefix. ++ ++Alternatively, you may set the environment variables TIRPC_CFLAGS ++and TIRPC_LIBS to avoid the need to call pkg-config. ++See the pkg-config man page for more details." "$LINENO" 5 ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it ++is in your PATH or set the PKG_CONFIG environment variable to the full ++path to pkg-config. ++ ++Alternatively, you may set the environment variables TIRPC_CFLAGS ++and TIRPC_LIBS to avoid the need to call pkg-config. ++See the pkg-config man page for more details. ++ ++To get pkg-config, see . ++See \`config.log' for more details" "$LINENO" 5; } ++else ++ TIRPC_CFLAGS=$pkg_cv_TIRPC_CFLAGS ++ TIRPC_LIBS=$pkg_cv_TIRPC_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++ ++$as_echo "#define WITH_LIBTIRPC 1" >>confdefs.h ++ ++ ++$as_echo "#define TIRPC_WORKAROUND 1" >>confdefs.h ++ ++ ++fi ++ for ac_func in getrpcbyname getservbyname + do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` + ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +@@ -4522,126 +4810,6 @@ fi + + + +- +- +- +- +- +- +-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then +- if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +-set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_path_PKG_CONFIG+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- case $PKG_CONFIG in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-PKG_CONFIG=$ac_cv_path_PKG_CONFIG +-if test -n "$PKG_CONFIG"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +-$as_echo "$PKG_CONFIG" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_path_PKG_CONFIG"; then +- ac_pt_PKG_CONFIG=$PKG_CONFIG +- # Extract the first word of "pkg-config", so it can be a program name with args. +-set dummy pkg-config; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- case $ac_pt_PKG_CONFIG in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +-if test -n "$ac_pt_PKG_CONFIG"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +-$as_echo "$ac_pt_PKG_CONFIG" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_pt_PKG_CONFIG" = x; then +- PKG_CONFIG="" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- PKG_CONFIG=$ac_pt_PKG_CONFIG +- fi +-else +- PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +-fi +- +-fi +-if test -n "$PKG_CONFIG"; then +- _pkg_min_version=0.9.0 +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +-$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } +- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- PKG_CONFIG="" +- fi +-fi +- + pkg_failed=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NSL" >&5 + $as_echo_n "checking for NSL... " >&6; } +--- autofs-5.1.4.orig/configure.in ++++ autofs-5.1.4/configure.in +@@ -48,6 +48,7 @@ AF_INIT_D() + AC_SUBST(initdir) + AF_PID_D() + AC_SUBST(piddir) ++PKG_PROG_PKG_CONFIG() + + # + # Check for systemd unit files direectory exists if unit file installation +@@ -55,6 +56,12 @@ AC_SUBST(piddir) + # + AF_WITH_SYSTEMD() + AC_SUBST(systemddir) ++AC_SUBST(WITH_SYSTEMD) ++PKG_CHECK_MODULES([systemd],[libsystemd],, ++[ ++ AC_CHECK_LIB(systemd, sm_notify, systemd_LIBS="-lsystemd") ++ AC_SUBST(systemd_LIBS) ++]) + + # + # Location of system config script directory? +@@ -218,7 +225,6 @@ fi + AC_CHECK_LIB(rt, clock_gettime, LIBCLOCK_GETTIME="-lrt") + AC_SUBST(LIBCLOCK_GETTIME) + +-PKG_PROG_PKG_CONFIG() + PKG_CHECK_MODULES([NSL],[libnsl],, + [ + AC_CHECK_LIB(nsl, yp_match, NSL_LIBS="-lnsl") +--- autofs-5.1.4.orig/daemon/Makefile ++++ autofs-5.1.4/daemon/Makefile +@@ -22,6 +22,11 @@ CFLAGS += -DVERSION_STRING=\"$(version)\ + LDFLAGS += -rdynamic + LIBS += -ldl -lpthread + ++ifeq ($(SYSTEMD), 1) ++ CFLAGS += -DWITH_SYSTEMD ++ LIBS += $(LIBSYSTEMD) ++endif ++ + ifeq ($(LDAP), 1) + CFLAGS += $(XML_FLAGS) + LIBS += $(XML_LIBS) +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -36,6 +36,9 @@ + #include + #include + #include ++#ifdef WITH_SYSTEMD ++#include ++#endif + + #include "automount.h" + #if defined(LIBXML2_WORKAROUND) || defined(TIRPC_WORKAROUND) +@@ -67,7 +70,7 @@ unsigned int global_selection_options; + long global_negative_timeout = -1; + int do_force_unlink = 0; /* Forceably unlink mount tree at startup */ + +-static int start_pipefd[2]; ++static int start_pipefd[2] = {-1, -1}; + static int st_stat = 1; + static int *pst_stat = &st_stat; + static pthread_t state_mach_thid; +@@ -1206,12 +1209,6 @@ static void become_daemon(unsigned foreg + exit(0); + } + +- if (open_pipe(start_pipefd) < 0) { +- fprintf(stderr, "%s: failed to create start_pipefd.\n", +- program); +- exit(0); +- } +- + /* Detach from foreground process */ + if (foreground) { + if (daemon_check && !aquire_flag_file()) { +@@ -1221,6 +1218,12 @@ static void become_daemon(unsigned foreg + } + log_to_stderr(); + } else { ++ if (open_pipe(start_pipefd) < 0) { ++ fprintf(stderr, "%s: failed to create start_pipefd.\n", ++ program); ++ exit(0); ++ } ++ + pid = fork(); + if (pid > 0) { + close(start_pipefd[1]); +@@ -2450,8 +2453,10 @@ int main(int argc, char *argv[]) + if (pthread_attr_init(&th_attr)) { + logerr("%s: failed to init thread attribute struct!", + program); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2460,8 +2465,10 @@ int main(int argc, char *argv[]) + if (pthread_attr_init(&th_attr_detached)) { + logerr("%s: failed to init thread attribute struct!", + program); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2471,8 +2478,10 @@ int main(int argc, char *argv[]) + &th_attr_detached, PTHREAD_CREATE_DETACHED)) { + logerr("%s: failed to set detached thread attribute!", + program); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2483,8 +2492,10 @@ int main(int argc, char *argv[]) + &th_attr_detached, detached_thread_stack_size)) { + logerr("%s: failed to set stack size thread attribute!", + program); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2495,8 +2506,10 @@ int main(int argc, char *argv[]) + &th_attr_detached, &detached_thread_stack_size)) { + logerr("%s: failed to get detached thread stack size!", + program); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2513,8 +2526,10 @@ int main(int argc, char *argv[]) + logerr("%s: failed to create thread data key for std env vars!", + program); + master_kill(master_list); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2525,8 +2540,10 @@ int main(int argc, char *argv[]) + logerr("%s: failed to create thread data key for attempt ID!", + program); + master_kill(master_list); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2537,8 +2554,10 @@ int main(int argc, char *argv[]) + if (!alarm_start_handler()) { + logerr("%s: failed to create alarm handler thread!", program); + master_kill(master_list); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2547,8 +2566,10 @@ int main(int argc, char *argv[]) + if (!st_start_handler()) { + logerr("%s: failed to create FSM handler thread!", program); + master_kill(master_list); +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + release_flag_file(); + macro_free_global_table(); + exit(1); +@@ -2596,9 +2617,15 @@ int main(int argc, char *argv[]) + */ + do_force_unlink = 0; + +- st_stat = 0; +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); ++ if (start_pipefd[1] != -1) { ++ st_stat = 0; ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } ++ ++#ifdef WITH_SYSTEMD ++ sd_notify(1, "READY=1"); ++#endif + + state_mach_thid = pthread_self(); + statemachine(NULL); +--- autofs-5.1.4.orig/samples/autofs.service.in ++++ autofs-5.1.4/samples/autofs.service.in +@@ -4,10 +4,9 @@ After=network.target ypbind.service sssd + Wants=network-online.target rpc-statd.service rpcbind.service + + [Service] +-Type=forking +-PIDFile=@@autofspiddir@@/autofs.pid ++Type=notify + EnvironmentFile=-@@autofsconfdir@@/autofs +-ExecStart=@@sbindir@@/automount $OPTIONS --pid-file @@autofspiddir@@/autofs.pid ++ExecStart=@@sbindir@@/automount $OPTIONS --foreground --dont-check-daemon + ExecReload=/usr/bin/kill -HUP $MAINPID + KillMode=process + TimeoutSec=180 diff --git a/autofs-5.1.4-use_hostname_for_mounts-shouldnt-prevent-selection-among-replicas.patch b/autofs-5.1.4-use_hostname_for_mounts-shouldnt-prevent-selection-among-replicas.patch new file mode 100644 index 0000000..f398e45 --- /dev/null +++ b/autofs-5.1.4-use_hostname_for_mounts-shouldnt-prevent-selection-among-replicas.patch @@ -0,0 +1,226 @@ +autofs-5.1.4 - use_hostname_for_mounts shouldn't prevent selection among replicas + +From: NeilBrown + +If several replicas have been specified for a mount point, +and use_hostname_for_mount is set to "yes", the selection +between these replicas is currently disabled and the last in +the list is always chosen. + +There is little point selecting between different addresses +for the one host in this case, but it is still worth +selecting between different hosts, particularly if different +weights have been specified. + +This patch restores the "prune_host_list()" functionality +when use_hostname_for_mount is set, and modifies it slightly +so that only on IP address for any host:/path entry in the +config file is willl be successfully probed. After a +success, further addresses from the same entry are skipped. +This is achieved by tracking an entry number ("ent_num") for +each 'struct host'. + +Signed-off-by: NeilBrown +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/replicated.h | 3 ++- + modules/mount_nfs.c | 2 +- + modules/replicated.c | 35 ++++++++++++++++++++--------------- + 4 files changed, 24 insertions(+), 17 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2d5d5b1f..104fca90 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -9,6 +9,7 @@ xx/xx/2018 autofs-5.1.5 + - fix error return in do_nfs_mount(). + - add error handling for ext_mount_add(). + - account for recent libnsl changes. ++- use_hostname_for_mounts shouldn't prevent selection among replicas. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/include/replicated.h b/include/replicated.h +index 69ab7800..0f482d21 100644 +--- a/include/replicated.h ++++ b/include/replicated.h +@@ -57,6 +57,7 @@ + + struct host { + char *name; ++ int ent_num; + struct sockaddr *addr; + size_t addr_len; + unsigned int rr; +@@ -70,7 +71,7 @@ struct host { + }; + + void seed_random(void); +-struct host *new_host(const char *, struct sockaddr *, size_t, ++struct host *new_host(const char *, int, struct sockaddr *, size_t, + unsigned int, unsigned int, unsigned int); + void free_host_list(struct host **); + int parse_location(unsigned, struct host **, const char *, unsigned int); +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 77166544..4cf0cd27 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -236,7 +236,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + (vers & NFS4_VERS_MASK) != 0 && + !(vers & UDP6_REQUESTED)) { + unsigned int v4_probe_ok = 0; +- struct host *tmp = new_host(hosts->name, ++ struct host *tmp = new_host(hosts->name, 0, + hosts->addr, hosts->addr_len, + hosts->proximity, + hosts->weight, hosts->options); +diff --git a/modules/replicated.c b/modules/replicated.c +index 3ac4c70f..f7b83236 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -83,7 +83,7 @@ void seed_random(void) + return; + } + +-struct host *new_host(const char *name, ++struct host *new_host(const char *name, int ent_num, + struct sockaddr *addr, size_t addr_len, + unsigned int proximity, unsigned int weight, + unsigned int options) +@@ -116,6 +116,7 @@ struct host *new_host(const char *name, + memset(new, 0, sizeof(struct host)); + + new->name = tmp1; ++ new->ent_num = ent_num; + new->addr_len = addr_len; + new->addr = tmp2; + new->proximity = proximity; +@@ -714,7 +715,7 @@ done: + int prune_host_list(unsigned logopt, struct host **list, + unsigned int vers, int port) + { +- struct host *this, *last, *first; ++ struct host *this, *last, *first, *prev; + struct host *new = NULL; + unsigned int proximity, selected_version = 0; + unsigned int v2_tcp_count, v3_tcp_count, v4_tcp_count; +@@ -726,12 +727,6 @@ int prune_host_list(unsigned logopt, struct host **list, + if (!*list) + return 0; + +- /* If we're using the host name then there's no point probing +- * avialability and respose time. +- */ +- if (defaults_use_hostname_for_mounts()) +- return 1; +- + /* Use closest hosts to choose NFS version */ + + first = *list; +@@ -877,11 +872,18 @@ int prune_host_list(unsigned logopt, struct host **list, + + first = last; + this = first; ++ prev = NULL; + while (this) { + struct host *next = this->next; + if (!this->name) { + remove_host(list, this); + add_host(&new, this); ++ } else if (defaults_use_hostname_for_mounts() && prev && ++ prev->ent_num == this->ent_num) { ++ /* When we use the hostname to mount, there is no ++ * point in probing every address it has, just one is ++ * enough. Skip the rest. ++ */ + } else { + status = get_supported_ver_and_cost(logopt, this, + selected_version, port); +@@ -889,6 +891,7 @@ int prune_host_list(unsigned logopt, struct host **list, + this->version = selected_version; + remove_host(list, this); + add_host(&new, this); ++ prev = this; + } + } + this = next; +@@ -901,7 +904,7 @@ int prune_host_list(unsigned logopt, struct host **list, + } + + static int add_new_host(struct host **list, +- const char *host, unsigned int weight, ++ const char *host, int ent_num, unsigned int weight, + struct addrinfo *host_addr, + unsigned int rr, unsigned int options) + { +@@ -940,7 +943,7 @@ static int add_new_host(struct host **list, + else + return 0; + +- new = new_host(host, host_addr->ai_addr, addr_len, prx, weight, options); ++ new = new_host(host, ent_num, host_addr->ai_addr, addr_len, prx, weight, options); + if (!new) + return 0; + +@@ -953,7 +956,7 @@ static int add_new_host(struct host **list, + return 1; + } + +-static int add_host_addrs(struct host **list, const char *host, ++static int add_host_addrs(struct host **list, const char *host, int ent_num, + unsigned int weight, unsigned int options) + { + struct addrinfo hints, *ni, *this; +@@ -988,7 +991,7 @@ static int add_host_addrs(struct host **list, const char *host, + + this = ni; + while (this) { +- ret = add_new_host(list, host, weight, this, 0, options); ++ ret = add_new_host(list, host, ent_num, weight, this, 0, options); + if (!ret) + break; + this = this->ai_next; +@@ -1027,7 +1030,7 @@ try_name: + rr++; + this = ni; + while (this) { +- ret = add_new_host(list, host, weight, this, rr, options); ++ ret = add_new_host(list, host, ent_num, weight, this, rr, options); + if (!ret) + break; + this = this->ai_next; +@@ -1120,6 +1123,7 @@ int parse_location(unsigned logopt, struct host **hosts, + { + char *str, *p, *delim; + unsigned int empty = 1; ++ int ent_num = 1; + + if (!list) + return 0; +@@ -1177,7 +1181,7 @@ int parse_location(unsigned logopt, struct host **hosts, + } + + if (p != delim) { +- if (!add_host_addrs(hosts, p, weight, options)) { ++ if (!add_host_addrs(hosts, p, ent_num, weight, options)) { + if (empty) { + p = next; + continue; +@@ -1199,7 +1203,7 @@ int parse_location(unsigned logopt, struct host **hosts, + *delim = '\0'; + next = delim + 1; + +- if (!add_host_addrs(hosts, p, weight, options)) { ++ if (!add_host_addrs(hosts, p, ent_num, weight, options)) { + p = next; + continue; + } +@@ -1213,6 +1217,7 @@ int parse_location(unsigned logopt, struct host **hosts, + return 0; + } + ++ ent_num++; + p = next; + } + diff --git a/autofs-5.1.5-add-NULL-check-for-get_addr_string-return.patch b/autofs-5.1.5-add-NULL-check-for-get_addr_string-return.patch new file mode 100644 index 0000000..be021c3 --- /dev/null +++ b/autofs-5.1.5-add-NULL-check-for-get_addr_string-return.patch @@ -0,0 +1,39 @@ +autofs-5.1.5 - add NULL check for get_addr_string() return + +From: Ian Kent + +When constructing the mount location string in mount_nfs.c:mount_mount() +the return from get_addr_string() is not checked for NULL. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -45,6 +45,7 @@ xx/xx/2018 autofs-5.1.5 + - move close stdio descriptors to become_daemon(). + - add systemd service command line option. + - support strictexpire mount option. ++- add NULL check for get_addr_string() return. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/mount_nfs.c ++++ autofs-5.1.4/modules/mount_nfs.c +@@ -333,7 +333,13 @@ dont_probe: + socklen_t len = INET6_ADDRSTRLEN; + char n_buf[len + 1]; + const char *n_addr; ++ + n_addr = get_addr_string(this->addr, n_buf, len); ++ if (!n_addr) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, "get_addr_string: %s", estr); ++ goto forced_fail; ++ } + loc = malloc(strlen(n_addr) + strlen(this->path) + 4); + if (!loc) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); diff --git a/autofs-5.1.5-add-config-option-for-ignore-mount-option.patch b/autofs-5.1.5-add-config-option-for-ignore-mount-option.patch new file mode 100644 index 0000000..815393c --- /dev/null +++ b/autofs-5.1.5-add-config-option-for-ignore-mount-option.patch @@ -0,0 +1,155 @@ +autofs-5.1.5 - add config option for "ignore" mount option + +From: Ian Kent + +Add a configuration option to control whether the autofs pseudo +mount option is used on autofs mounts. + +The default setting is "no" to avoid unexpected behaviour and +so is an opt-in setting for those who understand that, if user +space utilities and libraries honour this, then autofs mounts +will be ommitted from mount table listings. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/defaults.h | 2 ++ + lib/defaults.c | 17 +++++++++++++++++ + lib/master.c | 3 ++- + man/autofs.conf.5.in | 7 +++++++ + redhat/autofs.conf.default.in | 9 +++++++++ + samples/autofs.conf.default.in | 9 +++++++++ + 7 files changed, 47 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -62,6 +62,7 @@ xx/xx/2018 autofs-5.1.5 + - fix unlink_mount_tree() not umounting mounts. + - add ignore mount option. + - use ignore option for offset mounts as well. ++- add config option for "ignore" mount option + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/defaults.h ++++ autofs-5.1.4/include/defaults.h +@@ -51,6 +51,7 @@ + + #define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" + #define DEFAULT_DISABLE_NOT_FOUND_MESSAGE "0" ++#define DEFAULT_USE_IGNORE_MOUNT_OPTION "0" + + #define DEFAULT_SSS_MASTER_MAP_WAIT "0" + #define DEFAULT_USE_MOUNT_REQUEST_LOG_ID "0" +@@ -174,6 +175,7 @@ const char *defaults_get_auth_conf_file( + unsigned int defaults_get_map_hash_table_size(void); + unsigned int defaults_use_hostname_for_mounts(void); + unsigned int defaults_disable_not_found_message(void); ++unsigned int defaults_get_use_ignore_mount_option(void); + unsigned int defaults_get_sss_master_map_wait(void); + unsigned int defaults_get_use_mount_request_log_id(void); + +--- autofs-5.1.4.orig/lib/defaults.c ++++ autofs-5.1.4/lib/defaults.c +@@ -77,6 +77,7 @@ + + #define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts" + #define NAME_DISABLE_NOT_FOUND_MESSAGE "disable_not_found_message" ++#define NAME_USE_IGNORE_MOUNT_OPTION "use_ignore_mount_option" + + #define NAME_SSS_MASTER_MAP_WAIT "sss_master_map_wait" + #define NAME_USE_MOUNT_REQUEST_LOG_ID "use_mount_request_log_id" +@@ -364,6 +365,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_USE_IGNORE_MOUNT_OPTION, ++ DEFAULT_USE_IGNORE_MOUNT_OPTION, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + ret = conf_update(sec, NAME_SSS_MASTER_MAP_WAIT, + DEFAULT_SSS_MASTER_MAP_WAIT, CONF_ENV); + if (ret == CFG_FAIL) +@@ -1863,6 +1869,17 @@ unsigned int defaults_disable_not_found_ + + return res; + } ++ ++unsigned int defaults_get_use_ignore_mount_option(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_USE_IGNORE_MOUNT_OPTION); ++ if (res < 0) ++ res = atoi(DEFAULT_USE_IGNORE_MOUNT_OPTION); ++ ++ return res; ++} + + unsigned int defaults_get_sss_master_map_wait(void) + { +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -101,7 +101,8 @@ int master_add_autofs_point(struct maste + ap->negative_timeout = global_negative_timeout; + ap->exp_timeout = defaults_get_timeout(); + ap->exp_runfreq = 0; +- ap->flags = MOUNT_FLAG_IGNORE; ++ if (defaults_get_use_ignore_mount_option()) ++ ap->flags = MOUNT_FLAG_IGNORE; + if (ghost) + ap->flags |= MOUNT_FLAG_GHOST; + +--- autofs-5.1.4.orig/man/autofs.conf.5.in ++++ autofs-5.1.4/man/autofs.conf.5.in +@@ -151,6 +151,13 @@ That produces, IMHO, unnecessary noise i + has been added to provide the ability to turn it off. The default is "no" + to maintain the current behaviour. + .TP ++.B use_ignore_mount_option ++.br ++An option to enable the use of autofs pseudo option "disable". This option ++is used as a hint to user space that the mount entry should be ommitted from ++mount table listings. The default is "no" to avoid unexpected changes in ++behaviour and so is an opt-in setting. ++.TP + .B sss_master_map_wait + .br + Set the time to wait and retry if sssd returns "no such entry" when starting +--- autofs-5.1.4.orig/redhat/autofs.conf.default.in ++++ autofs-5.1.4/redhat/autofs.conf.default.in +@@ -183,6 +183,15 @@ mount_nfs_default_protocol = 4 + # + #disable_not_found_message = "no" + # ++# use_ignore_mount_option - This option is used to enable the use of autofs ++# pseudo option "disable". This option is used as a ++# hint to user space that the mount entry should be ++# ommitted from mount table listings. The default is ++# "no" to avoid unexpected changes in behaviour and ++# so is an opt-in setting. ++# ++#use_ignore_mount_option = no ++# + # sss_master_map_wait - When sssd is starting up it can sometimes return + # "no such entry" for a short time until it has read + # in the LDAP map information. Internal default is 0 +--- autofs-5.1.4.orig/samples/autofs.conf.default.in ++++ autofs-5.1.4/samples/autofs.conf.default.in +@@ -182,6 +182,15 @@ browse_mode = no + # + #disable_not_found_message = "no" + # ++# use_ignore_mount_option - This option is used to enable the use of autofs ++# pseudo option "disable". This option is used as a ++# hint to user space that the mount entry should be ++# ommitted from mount table listings. The default is ++# "no" to avoid unexpected changes in behaviour and ++# so is an opt-in setting. ++# ++#use_ignore_mount_option = no ++# + # sss_master_map_wait - When sssd is starting up it can sometimes return + # "no such entry" for a short time until it has read + # in the LDAP map information. Internal default is 0 diff --git a/autofs-5.1.5-add-glibc-getmntent.patch b/autofs-5.1.5-add-glibc-getmntent.patch new file mode 100644 index 0000000..162295d --- /dev/null +++ b/autofs-5.1.5-add-glibc-getmntent.patch @@ -0,0 +1,127 @@ +autofs-5.1.5 - add glibc getmntent_r() + +From: Ian Kent + +Add a slightly modified version of the glibc getmntent_r() function +so autofs can read the proc mount table directly. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 96 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -66,6 +66,7 @@ xx/xx/2018 autofs-5.1.5 + - use bit flags for autofs mount types in mnt_list. + - use mp instead of path in mnt_list entries. + - always use PROC_MOUNTS to make mount lists. ++- add glibc getmntent_r(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -786,6 +786,101 @@ done: + return ret; + } + ++/* From glibc decode_name() */ ++/* Since the values in a line are separated by spaces, a name cannot ++ * contain a space. Therefore some programs encode spaces in names ++ * by the strings "\040". We undo the encoding when reading an entry. ++ * The decoding happens in place. ++ */ ++static char *local_decode_name(char *buf) ++{ ++ char *rp = buf; ++ char *wp = buf; ++ ++ do { ++ if (rp[0] == '\\' && rp[1] == '0' && ++ rp[2] == '4' && rp[3] == '0') { ++ /* \040 is a SPACE. */ ++ *wp++ = ' '; ++ rp += 3; ++ } else if (rp[0] == '\\' && rp[1] == '0' && ++ rp[2] == '1' && rp[3] == '1') { ++ /* \011 is a TAB. */ ++ *wp++ = '\t'; ++ rp += 3; ++ } else if (rp[0] == '\\' && rp[1] == '0' && ++ rp[2] == '1' && rp[3] == '2') { ++ /* \012 is a NEWLINE. */ ++ *wp++ = '\n'; ++ rp += 3; ++ } else if (rp[0] == '\\' && rp[1] == '\\') { ++ /* ++ * We have to escape \\ to be able to represent ++ * all characters. ++ */ ++ *wp++ = '\\'; ++ rp += 1; ++ } else if (rp[0] == '\\' && rp[1] == '1' && ++ rp[2] == '3' && rp[3] == '4') { ++ /* \134 is also \\. */ ++ *wp++ = '\\'; ++ rp += 3; ++ } else ++ *wp++ = *rp; ++ } while (*rp++ != '\0'); ++ ++ return buf; ++} ++ ++/* From glibc getmntent_r() */ ++static struct mntent * ++local_getmntent_r(FILE *tab, struct mntent *mnt, char *buf, int size) ++{ ++ char *cp, *head; ++ ++ do { ++ char *end_ptr; ++ ++ if (fgets(buf, size, tab) == NULL) ++ return 0; ++ ++ end_ptr = strchr(buf, '\n'); ++ if (end_ptr != NULL) { ++ while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t') ++ end_ptr--; ++ *end_ptr = '\0'; ++ } else { ++ /* Whole line was not read. Do it now but forget it. */ ++ char tmp[1024]; ++ while (fgets(tmp, sizeof tmp, tab) != NULL) ++ if (strchr(tmp, '\n') != NULL) ++ break; ++ } ++ ++ head = buf + strspn(buf, " \t"); ++ /* skip empty lines and comment lines */ ++ } while (head[0] == '\0' || head[0] == '#'); ++ ++ cp = strsep(&head, " \t"); ++ mnt->mnt_fsname = cp != NULL ? local_decode_name(cp) : (char *) ""; ++ if (head) ++ head += strspn(head, " \t"); ++ cp = strsep(&head, " \t"); ++ mnt->mnt_dir = cp != NULL ? local_decode_name (cp) : (char *) ""; ++ if (head) ++ head += strspn(head, " \t"); ++ cp = strsep(&head, " \t"); ++ mnt->mnt_type = cp != NULL ? local_decode_name (cp) : (char *) ""; ++ if (head) ++ head += strspn (head, " \t"); ++ cp = strsep (&head, " \t"); ++ mnt->mnt_opts = cp != NULL ? local_decode_name (cp) : (char *) ""; ++ ++ /* autofs doesn't need freq or passno */ ++ ++ return mnt; ++} ++ + /* + * Get list of mounts under path in longest->shortest order + */ diff --git a/autofs-5.1.5-add-ignore-mount-option.patch b/autofs-5.1.5-add-ignore-mount-option.patch new file mode 100644 index 0000000..19b21e4 --- /dev/null +++ b/autofs-5.1.5-add-ignore-mount-option.patch @@ -0,0 +1,90 @@ +autofs-5.1.5 - add ignore mount option + +From: Ian Kent + +Add mount option "ignore", if the kernel supports it, as an +indicator to applications to ignore the mount entry. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 10 ++++++++++ + daemon/indirect.c | 10 ++++++++++ + include/automount.h | 3 +++ + lib/master.c | 4 ++-- + 5 files changed, 26 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -424,6 +424,16 @@ int do_mount_autofs_direct(struct autofs + mp->options = tmp; + } + } ++ ++ if ((ap->flags & MOUNT_FLAG_IGNORE) && ++ ((get_kver_major() == 5 && get_kver_minor() > 4) || ++ (get_kver_major() > 5))) { ++ char *tmp = realloc(mp->options, strlen(mp->options) + 7); ++ if (tmp) { ++ strcat(tmp, ",ignore"); ++ mp->options = tmp; ++ } ++ } + } + + /* In case the directory doesn't exist, try to mkdir it */ +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -133,6 +133,16 @@ static int do_mount_autofs_indirect(stru + } + } + ++ if ((ap->flags & MOUNT_FLAG_IGNORE) && ++ ((get_kver_major() == 5 && get_kver_minor() > 4) || ++ (get_kver_major() > 5))) { ++ char *tmp = realloc(options, strlen(options) + 7); ++ if (tmp) { ++ strcat(tmp, ",ignore"); ++ options = tmp; ++ } ++ } ++ + /* In case the directory doesn't exist, try to mkdir it */ + if (mkdir_path(root, mp_mode) < 0) { + if (errno != EEXIST && errno != EROFS) { +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -556,6 +556,9 @@ struct kernel_mod_version { + /* Use strict expire semantics if requested and kernel supports it */ + #define MOUNT_FLAG_STRICTEXPIRE 0x0400 + ++/* Indicator for applications to ignore the mount entry */ ++#define MOUNT_FLAG_IGNORE 0x0800 ++ + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -101,9 +101,9 @@ int master_add_autofs_point(struct maste + ap->negative_timeout = global_negative_timeout; + ap->exp_timeout = defaults_get_timeout(); + ap->exp_runfreq = 0; +- ap->flags = 0; ++ ap->flags = MOUNT_FLAG_IGNORE; + if (ghost) +- ap->flags = MOUNT_FLAG_GHOST; ++ ap->flags |= MOUNT_FLAG_GHOST; + + if (nobind) + ap->flags |= MOUNT_FLAG_NOBIND; +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -60,6 +60,7 @@ xx/xx/2018 autofs-5.1.5 + - remove a couple of old debug messages. + - fix amd entry memory leak. + - fix unlink_mount_tree() not umounting mounts. ++- add ignore mount option. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. diff --git a/autofs-5.1.5-add-mount_verbose-configuration-option.patch b/autofs-5.1.5-add-mount_verbose-configuration-option.patch new file mode 100644 index 0000000..8521252 --- /dev/null +++ b/autofs-5.1.5-add-mount_verbose-configuration-option.patch @@ -0,0 +1,174 @@ +autofs-5.1.5 - add mount_verbose configuration option + +From: Lars R. Damerow + +This option makes automount pass the -v flag to mount(8). + +Signed-off-by: Lars R. Damerow +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/spawn.c | 20 ++++++++++++-------- + include/defaults.h | 2 ++ + lib/defaults.c | 17 +++++++++++++++++ + man/autofs.conf.5.in | 4 ++++ + redhat/autofs.conf.default.in | 4 ++++ + samples/autofs.conf.default.in | 4 ++++ + 7 files changed, 44 insertions(+), 8 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -47,6 +47,7 @@ xx/xx/2018 autofs-5.1.5 + - support strictexpire mount option. + - add NULL check for get_addr_string() return. + - use malloc(3) in spawn.c. ++- add mount_verbose configuration option. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/spawn.c ++++ autofs-5.1.4/daemon/spawn.c +@@ -558,12 +558,14 @@ int spawn_mount(unsigned logopt, ...) + char prog[] = PATH_MOUNT; + char arg0[] = PATH_MOUNT; + char argn[] = "-n"; ++ char argvr[] = "-v"; + /* 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 update_mtab = 1, ret, printed = 0; + unsigned int wait = defaults_get_mount_wait(); ++ int verbose = defaults_get_mount_verbose(); + char buf[PATH_MAX + 1]; + unsigned int argv_len; + +@@ -590,8 +592,10 @@ int spawn_mount(unsigned logopt, ...) + } + } + +- /* Alloc 1 extra slot in case we need to use the "-f" option */ +- argv_len = sizeof(char *) * (argc + 2); ++ /* Alloc 2 extra slots in case we need to use the "-f" or "-v" options ++ * plus the NULL slot for end of args. ++ */ ++ argv_len = sizeof(char *) * (argc + 3); + argv = malloc(argv_len); + if (!argv) { + char buf[MAX_ERR_BUF]; +@@ -604,12 +608,12 @@ int spawn_mount(unsigned logopt, ...) + argv[0] = arg0; + + va_start(arg, logopt); +- if (update_mtab) +- p = argv + 1; +- else { +- argv[1] = argn; +- p = argv + 2; +- } ++ p = argv + 1; ++ if (!update_mtab) ++ *(p++) = argn; ++ if (verbose) ++ *(p++) = argvr; ++ + while ((*p = va_arg(arg, char *))) { + if (options == SPAWN_OPT_OPEN && !strcmp(*p, "-t")) { + *(++p) = va_arg(arg, char *); +--- autofs-5.1.4.orig/include/defaults.h ++++ autofs-5.1.4/include/defaults.h +@@ -27,6 +27,7 @@ + #define DEFAULT_TIMEOUT "600" + #define DEFAULT_MASTER_WAIT "10" + #define DEFAULT_NEGATIVE_TIMEOUT "60" ++#define DEFAULT_MOUNT_VERBOSE "0" + #define DEFAULT_MOUNT_WAIT "-1" + #define DEFAULT_UMOUNT_WAIT "12" + #define DEFAULT_BROWSE_MODE "1" +@@ -166,6 +167,7 @@ unsigned int defaults_get_ldap_timeout(v + unsigned int defaults_get_ldap_network_timeout(void); + unsigned int defaults_get_mount_nfs_default_proto(void); + unsigned int defaults_get_append_options(void); ++unsigned int defaults_get_mount_verbose(void); + unsigned int defaults_get_mount_wait(void); + unsigned int defaults_get_umount_wait(void); + const char *defaults_get_auth_conf_file(void); +--- autofs-5.1.4.orig/lib/defaults.c ++++ autofs-5.1.4/lib/defaults.c +@@ -68,6 +68,7 @@ + + #define NAME_MOUNT_NFS_DEFAULT_PROTOCOL "mount_nfs_default_protocol" + #define NAME_APPEND_OPTIONS "append_options" ++#define NAME_MOUNT_VERBOSE "mount_verbose" + #define NAME_MOUNT_WAIT "mount_wait" + #define NAME_UMOUNT_WAIT "umount_wait" + #define NAME_AUTH_CONF_FILE "auth_conf_file" +@@ -328,6 +329,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_MOUNT_VERBOSE, ++ DEFAULT_MOUNT_VERBOSE, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + ret = conf_update(sec, NAME_MOUNT_WAIT, + DEFAULT_MOUNT_WAIT, CONF_ENV); + if (ret == CFG_FAIL) +@@ -1780,6 +1786,17 @@ unsigned int defaults_get_append_options + + return res; + } ++ ++unsigned int defaults_get_mount_verbose(void) ++{ ++ long res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_MOUNT_VERBOSE); ++ if (res < 0) ++ res = atoi(DEFAULT_MOUNT_VERBOSE); ++ ++ return res; ++} + + unsigned int defaults_get_mount_wait(void) + { +--- autofs-5.1.4.orig/man/autofs.conf.5.in ++++ autofs-5.1.4/man/autofs.conf.5.in +@@ -41,6 +41,10 @@ Set the default timeout for caching fail + 60). If the equivalent command line option is given it will override this + setting. + .TP ++.B mount_verbose ++.br ++Use the verbose flag when spawning mount(8) (program default "no"). ++.TP + .B mount_wait + .br + Set the default time to wait for a response from a spawned mount(8) +--- autofs-5.1.4.orig/redhat/autofs.conf.default.in ++++ autofs-5.1.4/redhat/autofs.conf.default.in +@@ -26,6 +26,10 @@ timeout = 300 + # + #negative_timeout = 60 + # ++# mount_verbose - use the -v flag when calling mount(8). ++# ++#mount_verbose = no ++# + # mount_wait - time to wait for a response from mount(8). + # Setting this timeout can cause problems when + # mount would otherwise wait for a server that +--- autofs-5.1.4.orig/samples/autofs.conf.default.in ++++ autofs-5.1.4/samples/autofs.conf.default.in +@@ -26,6 +26,10 @@ timeout = 300 + # + #negative_timeout = 60 + # ++# mount_verbose - use the -v flag when calling mount(8). ++# ++#mount_verbose = no ++# + # mount_wait - time to wait for a response from mount(8). + # Setting this timeout can cause problems when + # mount would otherwise wait for a server that diff --git a/autofs-5.1.5-add-strictexpire-mount-option.patch b/autofs-5.1.5-add-strictexpire-mount-option.patch new file mode 100644 index 0000000..3809b9e --- /dev/null +++ b/autofs-5.1.5-add-strictexpire-mount-option.patch @@ -0,0 +1,200 @@ +autofs-5.1.5 - support strictexpire mount option + +From: Ian Kent + +Kernel commit 092a53452b (("autofs: take more care to not update +last_used on path walk") helped to (partially) resolve a problem +where automounts were not expiring due to aggressive accesses from +user space. + +This patch was later reverted because, for very large environments, +it meant more mount requests from clients and when there are a lot +of clients this caused a fairly significant increase in server load. + +But there is a need for both types of expire check, depending on use +case, so a mount option to allow for strict update of last use of +autofs dentrys has been added ito the autofs file system (which just +means not updating the last use on path walk accesses). + +So add support for this master map mount entry option in the user +space code. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 10 ++++++++++ + daemon/indirect.c | 10 ++++++++++ + include/automount.h | 3 +++ + lib/master_parse.y | 8 +++++++- + lib/master_tok.l | 1 + + man/auto.master.5.in | 8 ++++++++ + modules/mount_autofs.c | 5 +++++ + 8 files changed, 45 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -44,6 +44,7 @@ xx/xx/2018 autofs-5.1.5 + - use flags for startup boolean options. + - move close stdio descriptors to become_daemon(). + - add systemd service command line option. ++- support strictexpire mount option. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -421,6 +421,16 @@ int do_mount_autofs_direct(struct autofs + mp->options = make_options_string(ap->path, ap->kpipefd, str_direct); + if (!mp->options) + return 0; ++ ++ if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && ++ ((get_kver_major() == 5 && get_kver_minor() > 3) || ++ (get_kver_major() > 5))) { ++ char *tmp = realloc(mp->options, strlen(mp->options) + 12); ++ if (tmp) { ++ strcat(tmp, ",strictexpire"); ++ mp->options = tmp; ++ } ++ } + } + + /* In case the directory doesn't exist, try to mkdir it */ +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -132,6 +132,16 @@ static int do_mount_autofs_indirect(stru + goto out_err; + } + ++ if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && ++ ((get_kver_major() == 5 && get_kver_minor() > 3) || ++ (get_kver_major() > 5))) { ++ char *tmp = realloc(options, strlen(options) + 12); ++ if (tmp) { ++ strcat(tmp, ",strictexpire"); ++ options = tmp; ++ } ++ } ++ + /* In case the directory doesn't exist, try to mkdir it */ + if (mkdir_path(root, mp_mode) < 0) { + if (errno != EEXIST && errno != EROFS) { +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -553,6 +553,9 @@ struct kernel_mod_version { + #define MOUNT_FLAG_SLAVE 0x0100 + #define MOUNT_FLAG_PRIVATE 0x0200 + ++/* Use strict expire semantics if requested and kernel supports it */ ++#define MOUNT_FLAG_STRICTEXPIRE 0x0400 ++ + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ +--- autofs-5.1.4.orig/lib/master_parse.y ++++ autofs-5.1.4/lib/master_parse.y +@@ -58,6 +58,7 @@ static char *format; + static long timeout; + static long negative_timeout; + static unsigned symlnk; ++static unsigned strictexpire; + static unsigned slave; + static unsigned private; + static unsigned nobind; +@@ -105,7 +106,7 @@ static int master_fprintf(FILE *, char * + %token MAP + %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE + %token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE +-%token OPT_SLAVE OPT_PRIVATE ++%token OPT_STRICTEXPIRE OPT_SLAVE OPT_PRIVATE + %token COLON COMMA NL DDASH + %type map + %type options +@@ -206,6 +207,7 @@ line: + | PATH OPT_DEBUG { master_notify($1); YYABORT; } + | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } + | PATH OPT_SYMLINK { master_notify($1); YYABORT; } ++ | PATH OPT_STRICTEXPIRE { master_notify($1); YYABORT; } + | PATH OPT_SLAVE { master_notify($1); YYABORT; } + | PATH OPT_PRIVATE { master_notify($1); YYABORT; } + | PATH OPT_NOBIND { master_notify($1); YYABORT; } +@@ -619,6 +621,7 @@ option: daemon_option + daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } + | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } + | OPT_SYMLINK { symlnk = 1; } ++ | OPT_STRICTEXPIRE { strictexpire = 1; } + | OPT_SLAVE { slave = 1; } + | OPT_PRIVATE { private = 1; } + | OPT_NOBIND { nobind = 1; } +@@ -693,6 +696,7 @@ static void local_init_vars(void) + timeout = -1; + negative_timeout = 0; + symlnk = 0; ++ strictexpire = 0; + slave = 0; + private = 0; + nobind = 0; +@@ -901,6 +905,8 @@ int master_parse_entry(const char *buffe + entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; + if (symlnk) + entry->ap->flags |= MOUNT_FLAG_SYMLINK; ++ if (strictexpire) ++ entry->ap->flags |= MOUNT_FLAG_STRICTEXPIRE; + if (slave) + entry->ap->flags |= MOUNT_FLAG_SLAVE; + if (private) +--- autofs-5.1.4.orig/lib/master_tok.l ++++ autofs-5.1.4/lib/master_tok.l +@@ -391,6 +391,7 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTW + -?nobrowse { return(OPT_NOGHOST); } + -?slave { return(OPT_SLAVE); } + -?private { return(OPT_PRIVATE); } ++ -?strictexpire { return(OPT_STRICTEXPIRE); } + -g|--ghost|-?browse { return(OPT_GHOST); } + -v|--verbose { return(OPT_VERBOSE); } + -d|--debug { return(OPT_DEBUG); } +--- autofs-5.1.4.orig/man/auto.master.5.in ++++ autofs-5.1.4/man/auto.master.5.in +@@ -199,6 +199,14 @@ entries only, either in the master map ( + or with individual map entries. The option is ignored for direct mounts + and non-root offest mount entries. + .TP ++.I "strictexpire" ++Use a strict expire policy for this automount. Using this option means ++that last use of autofs directory entries will not be updated during ++path walks so that mounts in an automount won't be kept mounted by ++applications scanning the mount tree. Note that this doesn't completely ++resolve the problem of expired automounts being immediately re-mounted ++due to application accesses triggered by the expire itself. ++.TP + .I slave \fPor\fI private + This option allows mount propagation of bind mounts to be set to + either \fIslave\fP or \fIprivate\fP. This option may be needed when using +--- autofs-5.1.4.orig/modules/mount_autofs.c ++++ autofs-5.1.4/modules/mount_autofs.c +@@ -57,6 +57,7 @@ int mount_mount(struct autofs_point *ap, + int nobind = ap->flags & MOUNT_FLAG_NOBIND; + int ghost = ap->flags & MOUNT_FLAG_GHOST; + int symlnk = ap->flags & MOUNT_FLAG_SYMLINK; ++ int strictexpire = ap->flags & MOUNT_FLAG_STRICTEXPIRE; + time_t timeout = get_exp_timeout(ap, ap->entry->maps); + unsigned logopt = ap->logopt; + struct map_type_info *info; +@@ -131,6 +132,8 @@ int mount_mount(struct autofs_point *ap, + ghost = 1; + else if (_strncmp("symlink", cp, 7) == 0) + symlnk = 1; ++ else if (_strncmp("strictexpire", cp, 12) == 0) ++ strictexpire = 1; + else if (_strncmp("hosts", cp, 5) == 0) + hosts = 1; + else if (_strncmp("timeout=", cp, 8) == 0) { +@@ -173,6 +176,8 @@ int mount_mount(struct autofs_point *ap, + nap->parent = ap; + if (symlnk) + nap->flags |= MOUNT_FLAG_SYMLINK; ++ if (strictexpire) ++ nap->flags |= MOUNT_FLAG_STRICTEXPIRE; + + if (hosts) + argc = 0; diff --git a/autofs-5.1.5-allow-period-following-macro-in-selector-value.patch b/autofs-5.1.5-allow-period-following-macro-in-selector-value.patch new file mode 100644 index 0000000..a96c68f --- /dev/null +++ b/autofs-5.1.5-allow-period-following-macro-in-selector-value.patch @@ -0,0 +1,34 @@ +autofs-5.1.5 - allow period following macro in selector value + +From: Ian Kent + +If a ${} macro is used in a selector (such as hostd) the parser doesn't +permit a period to follow it (such as when the value is a host name). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/amd_tok.l | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -51,6 +51,7 @@ xx/xx/2018 autofs-5.1.5 + - optionally log mount requestor process info. + - log mount call arguments if mount_verbose is set. + - make expire remaining log level debug. ++- allow period following macro in selector value. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/amd_tok.l ++++ autofs-5.1.4/modules/amd_tok.l +@@ -95,7 +95,7 @@ V6MASK (12[0-8]|1[0-1][0-9]|[1-9][0-9]| + + FOPT (({QSTR}|{FSTR}|{MACRO})+) + OPTS ({OSTR}(=({VSTR}|{MACRO})+)?) +-SOPT (({SSTR}|{QSTR}|{MACRO})+) ++SOPT ({SSTR}|{QSTR}|{MACRO}(\.|{SSTR}|{QSTR}|{MACRO})+) + NOPT ({SSTR}|(({IP4ADDR}(\/{V4MASK})?)|({IP6ADDR}(\/{V6MASK})?))) + + MAPOPT (fs|type|maptype|pref|sublink|cache) diff --git a/autofs-5.1.5-also-use-strictexpire-for-offsets.patch b/autofs-5.1.5-also-use-strictexpire-for-offsets.patch new file mode 100644 index 0000000..351fa86 --- /dev/null +++ b/autofs-5.1.5-also-use-strictexpire-for-offsets.patch @@ -0,0 +1,42 @@ +autofs-5.1.5 - also use strictexpire for offsets + +From: Ian Kent + +Map entries with offsets should use the "strictexpire" option when +mounting offsets if the option is set for the owner mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -53,6 +53,7 @@ xx/xx/2018 autofs-5.1.5 + - make expire remaining log level debug. + - allow period following macro in selector value. + - fix macro expansion in selector values. ++- also use strictexpire for offsets. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -743,6 +743,16 @@ int mount_autofs_offset(struct autofs_po + mp->options = make_options_string(ap->path, ap->kpipefd, str_offset); + if (!mp->options) + return MOUNT_OFFSET_OK; ++ ++ if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && ++ ((get_kver_major() == 5 && get_kver_minor() > 3) || ++ (get_kver_major() > 5))) { ++ char *tmp = realloc(mp->options, strlen(mp->options) + 12); ++ if (tmp) { ++ strcat(tmp, ",strictexpire"); ++ mp->options = tmp; ++ } ++ } + } + + strcpy(mountpoint, root); diff --git a/autofs-5.1.5-always-use-PROC_MOUNTS-to-make-mount-lists.patch b/autofs-5.1.5-always-use-PROC_MOUNTS-to-make-mount-lists.patch new file mode 100644 index 0000000..1580c15 --- /dev/null +++ b/autofs-5.1.5-always-use-PROC_MOUNTS-to-make-mount-lists.patch @@ -0,0 +1,405 @@ +autofs-5.1.5 - always use PROC_MOUNTS to make mount lists + +From: Ian Kent + +If it's necessary to read a mount table then always use the proc file +system mount table. + +This could be very inefficient for cases where the mtab (_PATH_MOUNTED) +is specified but the mtab has been a symlink to the proc mount tables +for quite a while now so it doesn't make any difference always using +the proc tables. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 6 +++--- + daemon/direct.c | 14 +++++++------- + daemon/indirect.c | 8 ++++---- + daemon/lookup.c | 4 ++-- + daemon/spawn.c | 2 +- + daemon/state.c | 2 +- + include/mounts.h | 6 +++--- + lib/mounts.c | 40 ++++++++++++++++++++-------------------- + modules/parse_amd.c | 4 ++-- + 10 files changed, 44 insertions(+), 43 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -65,6 +65,7 @@ xx/xx/2018 autofs-5.1.5 + - add config option for "ignore" mount option + - use bit flags for autofs mount types in mnt_list. + - use mp instead of path in mnt_list entries. ++- always use PROC_MOUNTS to make mount lists. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -333,7 +333,7 @@ static int walk_tree(const char *base, i + struct stat st, *pst = &st; + int ret; + +- if (!is_mounted(_PATH_MOUNTED, base, MNTS_REAL)) ++ if (!is_mounted(base, MNTS_REAL)) + ret = lstat(base, pst); + else { + pst = NULL; +@@ -593,11 +593,11 @@ static int umount_subtree_mounts(struct + * If this is the root of a multi-mount we've had to umount + * it already to ensure it's ok to remove any offset triggers. + */ +- if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { ++ if (!is_mm_root && is_mounted(path, MNTS_REAL)) { + struct amd_entry *entry; + debug(ap->logopt, "unmounting dir = %s", path); + if (umount_ent(ap, path) && +- is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { ++ is_mounted(path, MNTS_REAL)) { + warn(ap->logopt, "could not umount dir %s", path); + left++; + goto done; +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -207,7 +207,7 @@ int umount_autofs_direct(struct autofs_p + struct mnt_list *mnts; + struct mapent *me, *ne; + +- mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); ++ mnts = tree_make_mnt_tree("/"); + pthread_cleanup_push(mnts_cleanup, mnts); + nc = ap->entry->master->nc; + cache_readlock(nc); +@@ -515,7 +515,7 @@ int mount_autofs_direct(struct autofs_po + return -1; + } + +- mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); ++ mnts = tree_make_mnt_tree("/"); + pthread_cleanup_push(mnts_cleanup, mnts); + pthread_cleanup_push(master_source_lock_cleanup, ap->entry); + master_source_readlock(ap->entry); +@@ -583,7 +583,7 @@ int umount_autofs_offset(struct autofs_p + int opened = 0; + + if (me->ioctlfd != -1) { +- if (is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) { ++ if (is_mounted(me->key, MNTS_REAL)) { + error(ap->logopt, + "attempt to umount busy offset %s", me->key); + return 1; +@@ -591,7 +591,7 @@ int umount_autofs_offset(struct autofs_p + ioctlfd = me->ioctlfd; + } else { + /* offset isn't mounted, return success and try to recover */ +- if (!is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { ++ if (!is_mounted(me->key, MNTS_AUTOFS)) { + debug(ap->logopt, + "offset %s not mounted", + me->key); +@@ -707,7 +707,7 @@ int mount_autofs_offset(struct autofs_po + if (!(ret == -1 && errno == ENOENT)) + return MOUNT_OFFSET_FAIL; + } else { +- if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { ++ if (is_mounted(me->key, MNTS_AUTOFS)) { + if (ap->state != ST_READMAP) + warn(ap->logopt, + "trigger %s already mounted", me->key); +@@ -781,7 +781,7 @@ int mount_autofs_offset(struct autofs_po + * the kernel NFS client. + */ + if (me->multi != me && +- is_mounted(_PROC_MOUNTS, mountpoint, MNTS_REAL)) ++ is_mounted(mountpoint, MNTS_REAL)) + return MOUNT_OFFSET_IGNORE; + + /* +@@ -901,7 +901,7 @@ void *expire_proc_direct(void *arg) + + left = 0; + +- mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); ++ mnts = tree_make_mnt_tree("/"); + pthread_cleanup_push(mnts_cleanup, mnts); + + /* Get a list of mounts select real ones and expire them if possible */ +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -104,7 +104,7 @@ static int do_mount_autofs_indirect(stru + if (ret == 0) + return -1; + } else { +- mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1); ++ mnts = get_mnt_list(ap->path, 1); + if (mnts) { + ret = unlink_mount_tree(ap, mnts); + free_mnt_list(mnts); +@@ -433,7 +433,7 @@ void *expire_proc_indirect(void *arg) + left = 0; + + /* Get a list of real mounts and expire them if possible */ +- mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0); ++ mnts = get_mnt_list(ap->path, 0); + pthread_cleanup_push(mnts_cleanup, mnts); + for (next = mnts; next; next = next->next) { + char *ind_key; +@@ -454,7 +454,7 @@ void *expire_proc_indirect(void *arg) + struct stat st; + + /* It's got a mount, deal with in the outer loop */ +- if (is_mounted(_PATH_MOUNTED, next->mp, MNTS_REAL)) { ++ if (is_mounted(next->mp, MNTS_REAL)) { + pthread_setcancelstate(cur_state, NULL); + continue; + } +@@ -563,7 +563,7 @@ void *expire_proc_indirect(void *arg) + pthread_cleanup_pop(1); + + count = offsets = submnts = 0; +- mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0); ++ mnts = get_mnt_list(ap->path, 0); + pthread_cleanup_push(mnts_cleanup, mnts); + /* Are there any real mounts left */ + for (next = mnts; next; next = next->next) { +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -1425,7 +1425,7 @@ void lookup_prune_one_cache(struct autof + valid = NULL; + } + if (!valid && +- is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { ++ is_mounted(path, MNTS_REAL)) { + debug(ap->logopt, "prune posponed, %s mounted", path); + free(key); + free(path); +@@ -1448,7 +1448,7 @@ void lookup_prune_one_cache(struct autof + + if (valid) + cache_delete(mc, key); +- else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) { ++ else if (!is_mounted(path, MNTS_AUTOFS)) { + dev_t devid = ap->dev; + status = CHE_FAIL; + if (ap->type == LKP_DIRECT) +--- autofs-5.1.4.orig/daemon/spawn.c ++++ autofs-5.1.4/daemon/spawn.c +@@ -427,7 +427,7 @@ static int do_spawn(unsigned logopt, uns + if (!is_bind) + goto done; + +- if (is_mounted(_PROC_MOUNTS, argv[loc], MNTS_AUTOFS)) { ++ if (is_mounted(argv[loc], MNTS_AUTOFS)) { + fprintf(stderr, + "error: can't bind to an autofs mount\n"); + close(STDOUT_FILENO); +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -499,7 +499,7 @@ static void *do_readmap(void *arg) + struct mapent *me; + unsigned int append_alarm = !ap->exp_runfreq; + +- mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); ++ mnts = tree_make_mnt_tree("/"); + pthread_cleanup_push(tree_mnts_cleanup, mnts); + nc = ap->entry->master->nc; + cache_readlock(nc); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -99,11 +99,11 @@ char *make_mnt_name_string(char *path); + int ext_mount_add(struct list_head *, const char *, unsigned int); + int ext_mount_remove(struct list_head *, const char *); + int ext_mount_inuse(const char *); +-struct mnt_list *get_mnt_list(const char *table, const char *path, int include); ++struct mnt_list *get_mnt_list(const char *path, int include); + void free_mnt_list(struct mnt_list *list); +-int is_mounted(const char *table, const char *mp, unsigned int type); ++int is_mounted(const char *mp, unsigned int type); + void tree_free_mnt_tree(struct mnt_list *tree); +-struct mnt_list *tree_make_mnt_tree(const char *table, const char *path); ++struct mnt_list *tree_make_mnt_tree(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); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -789,7 +789,7 @@ done: + /* + * Get list of mounts under path in longest->shortest order + */ +-struct mnt_list *get_mnt_list(const char *table, const char *path, int include) ++struct mnt_list *get_mnt_list(const char *path, int include) + { + FILE *tab; + size_t pathlen = strlen(path); +@@ -803,7 +803,7 @@ struct mnt_list *get_mnt_list(const char + if (!path || !pathlen || pathlen > PATH_MAX) + return NULL; + +- tab = open_setmntent_r(table); ++ tab = open_setmntent_r(_PROC_MOUNTS); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); + logerr("setmntent: %s", estr); +@@ -892,7 +892,7 @@ void free_mnt_list(struct mnt_list *list + } + } + +-static int table_is_mounted(const char *table, const char *mp, unsigned int type) ++static int table_is_mounted(const char *mp, unsigned int type) + { + struct mntent *mnt; + struct mntent mnt_wrk; +@@ -904,7 +904,7 @@ static int table_is_mounted(const char * + if (!mp || !mp_len || mp_len >= PATH_MAX) + return 0; + +- tab = open_setmntent_r(table); ++ tab = open_setmntent_r(_PROC_MOUNTS); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); + logerr("setmntent: %s", estr); +@@ -938,7 +938,7 @@ static int table_is_mounted(const char * + return ret; + } + +-static int ioctl_is_mounted(const char *table, const char *mp, unsigned int type) ++static int ioctl_is_mounted(const char *mp, unsigned int type) + { + struct ioctl_ops *ops = get_ioctl_ops(); + unsigned int mounted; +@@ -949,7 +949,7 @@ static int ioctl_is_mounted(const char * + */ + ret = ops->ismountpoint(LOGOPT_NONE, -1, mp, &mounted); + if (ret == -1) +- return table_is_mounted(table, mp, type); ++ return table_is_mounted(mp, type); + + if (mounted) { + switch (type) { +@@ -964,14 +964,14 @@ static int ioctl_is_mounted(const char * + return 0; + } + +-int is_mounted(const char *table, const char *mp, unsigned int type) ++int is_mounted(const char *mp, unsigned int type) + { + struct ioctl_ops *ops = get_ioctl_ops(); + + if (ops->ismountpoint) +- return ioctl_is_mounted(table, mp, type); ++ return ioctl_is_mounted(mp, type); + else +- return table_is_mounted(table, mp, type); ++ return table_is_mounted(mp, type); + } + + /* +@@ -1018,7 +1018,7 @@ void tree_free_mnt_tree(struct mnt_list + /* + * Make tree of system mounts in /proc/mounts. + */ +-struct mnt_list *tree_make_mnt_tree(const char *table, const char *path) ++struct mnt_list *tree_make_mnt_tree(const char *path) + { + FILE *tab; + struct mntent mnt_wrk; +@@ -1029,7 +1029,7 @@ struct mnt_list *tree_make_mnt_tree(cons + size_t plen; + int eq; + +- tab = open_setmntent_r(table); ++ tab = open_setmntent_r(_PROC_MOUNTS); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); + logerr("setmntent: %s", estr); +@@ -1281,7 +1281,7 @@ int tree_is_mounted(struct mnt_list *mnt + int mounted = 0; + + if (ops->ismountpoint) +- return ioctl_is_mounted(_PROC_MOUNTS, path, type); ++ return ioctl_is_mounted(path, type); + + INIT_LIST_HEAD(&list); + +@@ -1856,7 +1856,7 @@ void set_indirect_mount_tree_catatonic(s + struct mapent_cache *mc; + struct mapent *me; + +- if (!is_mounted(_PROC_MOUNTS, ap->path, MNTS_AUTOFS)) ++ if (!is_mounted(ap->path, MNTS_AUTOFS)) + return; + + map = entry->maps; +@@ -1920,7 +1920,7 @@ int umount_ent(struct autofs_point *ap, + * so that we do not try to call rmdir_path on the + * directory. + */ +- if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { ++ if (!rv && is_mounted(path, MNTS_REAL)) { + crit(ap->logopt, + "the umount binary reported that %s was " + "unmounted, but there is still something " +@@ -2053,7 +2053,7 @@ int mount_multi_triggers(struct autofs_p + */ + if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { + if (oe->ioctlfd != -1 || +- is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { ++ is_mounted(oe->key, MNTS_REAL)) { + char oe_root[PATH_MAX + 1]; + strcpy(oe_root, root); + strcat(oe_root, offset); +@@ -2142,7 +2142,7 @@ int umount_multi_triggers(struct autofs_ + left += umount_multi_triggers(ap, oe, root, oe_base); + + if (oe->ioctlfd != -1 || +- is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { ++ is_mounted(oe->key, MNTS_REAL)) { + left++; + continue; + } +@@ -2185,10 +2185,10 @@ int umount_multi_triggers(struct autofs_ + * delete the offsets from the cache and we need to put + * the offset triggers back. + */ +- if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { ++ if (is_mounted(root, MNTS_REAL)) { + info(ap->logopt, "unmounting dir = %s", root); + if (umount_ent(ap, root) && +- is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { ++ is_mounted(root, MNTS_REAL)) { + if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0) + warn(ap->logopt, + "failed to remount offset triggers"); +@@ -2288,9 +2288,9 @@ int clean_stale_multi_triggers(struct au + * ESTALE errors when attempting list the directory. + */ + if (oe->ioctlfd != -1 || +- is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { ++ is_mounted(oe->key, MNTS_REAL)) { + if (umount_ent(ap, oe->key) && +- is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { ++ is_mounted(oe->key, MNTS_REAL)) { + debug(ap->logopt, + "offset %s has active mount, invalidate", + oe->key); +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1173,7 +1173,7 @@ static int do_generic_mount(struct autof + * multiple times since they are outside of + * the automount filesystem. + */ +- if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) { ++ if (!is_mounted(entry->fs, MNTS_REAL)) { + ret = do_mount(ap, entry->fs, "/", 1, + target, entry->type, opts); + if (ret) +@@ -1223,7 +1223,7 @@ static int do_nfs_mount(struct autofs_po + target, entry->type, opts, + mount_nfs->context); + } else { +- if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) { ++ if (!is_mounted(entry->fs, MNTS_REAL)) { + ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1, + target, entry->type, opts, + mount_nfs->context); diff --git a/autofs-5.1.5-dont-use-tree_is_mounted-for-mounted-checks.patch b/autofs-5.1.5-dont-use-tree_is_mounted-for-mounted-checks.patch new file mode 100644 index 0000000..2eed63a --- /dev/null +++ b/autofs-5.1.5-dont-use-tree_is_mounted-for-mounted-checks.patch @@ -0,0 +1,172 @@ +autofs-5.1.5 - don't use tree_is_mounted() for mounted checks + +From: Ian Kent + +Always use is_mounted() for mounted checks. + +If the proc mount table actually needs to be used this could be +very inefficient but the miscelaneous device ioctl interface +has been available to quite a few years now so it really needs +to be used to avoid the scanning of mount tables. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 12 ++++-------- + daemon/state.c | 4 ++-- + include/automount.h | 2 +- + include/mounts.h | 1 - + lib/mounts.c | 40 ---------------------------------------- + 6 files changed, 8 insertions(+), 52 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -69,6 +69,7 @@ xx/xx/2018 autofs-5.1.5 + - add glibc getmntent_r(). + - use local getmntent_r in table_is_mounted(). + - refactor unlink_active_mounts() in direct.c. ++- don't use tree_is_mounted() for mounted checks. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -82,7 +82,7 @@ static void mnts_cleanup(void *arg) + return; + } + +-int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) ++int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); + char buf[MAX_ERR_BUF]; +@@ -98,7 +98,7 @@ int do_umount_autofs_direct(struct autof + + if (me->ioctlfd != -1) { + if (ap->state == ST_READMAP && +- tree_is_mounted(mnts, me->key, MNTS_REAL)) { ++ is_mounted(me->key, MNTS_REAL)) { + error(ap->logopt, + "attempt to umount busy direct mount %s", + me->key); +@@ -204,11 +204,8 @@ int umount_autofs_direct(struct autofs_p + { + struct map_source *map; + struct mapent_cache *nc, *mc; +- struct mnt_list *mnts; + struct mapent *me, *ne; + +- mnts = tree_make_mnt_tree("/"); +- pthread_cleanup_push(mnts_cleanup, mnts); + nc = ap->entry->master->nc; + cache_readlock(nc); + pthread_cleanup_push(cache_lock_cleanup, nc); +@@ -233,7 +230,7 @@ int umount_autofs_direct(struct autofs_p + * catatonic regardless of the reason for the + * failed umount. + */ +- error = do_umount_autofs_direct(ap, mnts, me); ++ error = do_umount_autofs_direct(ap, me); + if (!error) + goto done; + +@@ -246,7 +243,6 @@ done: + map = map->next; + } + pthread_cleanup_pop(1); +- pthread_cleanup_pop(1); + + close(ap->state_pipe[0]); + close(ap->state_pipe[1]); +@@ -947,7 +943,7 @@ void *expire_proc_direct(void *arg) + } + + /* It's got a mount, deal with in the outer loop */ +- if (tree_is_mounted(mnts, me->key, MNTS_REAL)) { ++ if (is_mounted(me->key, MNTS_REAL)) { + pthread_setcancelstate(cur_state, NULL); + continue; + } +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -438,8 +438,8 @@ static void do_readmap_mount(struct auto + else + ap->exp_runfreq = runfreq; + } +- } else if (!tree_is_mounted(mnts, me->key, MNTS_REAL)) +- do_umount_autofs_direct(ap, mnts, me); ++ } else if (!is_mounted(me->key, MNTS_REAL)) ++ do_umount_autofs_direct(ap, me); + else + debug(ap->logopt, + "%s is mounted", me->key); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -613,7 +613,7 @@ void submount_signal_parent(struct autof + 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 do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me); + int umount_autofs_direct(struct autofs_point *ap); + int umount_autofs_offset(struct autofs_point *ap, struct mapent *me); + int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_indirect_t *pkt); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -107,7 +107,6 @@ struct mnt_list *tree_make_mnt_tree(cons + 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); + const char *mount_type_str(unsigned int); + void set_exp_timeout(struct autofs_point *ap, struct map_source *source, time_t timeout); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1368,46 +1368,6 @@ int tree_find_mnt_ents(struct mnt_list * + return 0; + } + +-int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type) +-{ +- struct ioctl_ops *ops = get_ioctl_ops(); +- struct list_head *p; +- struct list_head list; +- int mounted = 0; +- +- if (ops->ismountpoint) +- return ioctl_is_mounted(path, type); +- +- INIT_LIST_HEAD(&list); +- +- if (!tree_find_mnt_ents(mnts, &list, path)) +- return 0; +- +- list_for_each(p, &list) { +- struct mnt_list *mptr; +- +- mptr = list_entry(p, struct mnt_list, entries); +- +- if (type) { +- if (type & MNTS_REAL) { +- if (mptr->flags & MNTS_AUTOFS) { +- mounted = 1; +- break; +- } +- } else if (type & MNTS_AUTOFS) { +- if (mptr->flags & MNTS_AUTOFS) { +- mounted = 1; +- break; +- } +- } else { +- mounted = 1; +- break; +- } +- } +- } +- return mounted; +-} +- + void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid) + { + struct thread_stdenv_vars *tsv; diff --git a/autofs-5.1.5-fix-additional-typing-errors.patch b/autofs-5.1.5-fix-additional-typing-errors.patch new file mode 100644 index 0000000..c1669c4 --- /dev/null +++ b/autofs-5.1.5-fix-additional-typing-errors.patch @@ -0,0 +1,383 @@ +autofs-5.1.5 - fix additional typing errors + +From: Andreas P + +Fix some more typing errors. +imk: added changes discussed on mailing list. + +Signed-off-by: Andreas P +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + INSTALL | 2 +- + README.replicated-server | 2 +- + man/auto.master.5.in | 14 +++++++------- + man/autofs.5 | 9 ++++----- + man/autofs.conf.5.in | 29 ++++++++++++++--------------- + man/autofs_ldap_auth.conf.5.in | 2 +- + man/automount.8 | 2 +- + modules/lookup_ldap.c | 4 ++-- + modules/replicated.c | 4 ++-- + redhat/autofs.conf.default.in | 14 +++++++------- + redhat/autofs.sysconfig | 2 +- + samples/autofs.conf.default.in | 10 +++++----- + 13 files changed, 47 insertions(+), 48 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -113,6 +113,7 @@ xx/xx/2018 autofs-5.1.5 + - simplify sss source stale check. + - use defines for expire type. + - remove unused function dump_master(). ++- fix additional typing errors. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/INSTALL ++++ autofs-5.1.4/INSTALL +@@ -119,7 +119,7 @@ For example, Fedora Core 4 kernel packag + would use the 2.6.12 patch because it applies the 2.6.12 release + candidate revision 6 patch. But the autofs patch doesn't apply + because the rpm also applies a patch somewhere that changes one +-area the the patch also changes but this change is not present ++area the patch also changes but this change is not present + in the 2.6.12 release kernel. + + On the other hand, Fedora Core 3 kernel 2.6.12-1.1381_FC3 +--- autofs-5.1.4.orig/README.replicated-server ++++ autofs-5.1.4/README.replicated-server +@@ -34,7 +34,7 @@ the following selection rules. + - 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 ++2) NFS version and protocol is selected by calculating 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 +--- autofs-5.1.4.orig/man/auto.master.5.in ++++ autofs-5.1.4/man/auto.master.5.in +@@ -211,12 +211,12 @@ due to application accesses triggered by + This option allows mount propagation of bind mounts to be set to + either \fIslave\fP or \fIprivate\fP. This option may be needed when using + multi-mounts that have bind mounts that bind to a file system that is +-propagation shared. This is becuase the bind mount will have the same ++propagation shared. This is because the bind mount will have the same + properties as its target which causes problems for offset mounts. When + this happens an unwanted offset mount is propagated back to the target + file system resulting in a deadlock when attempting to access the offset. +-This option is a an autofs pseudo mount option that can be used in the +-master map only. By default bind mounts will inherit the mount propagation ++This option is an autofs pseudo mount option that can be used in the ++master map only. By default, bind mounts will inherit the mount propagation + of the target file system. + .TP + .I "\-r, \-\-random-multimount-selection" +@@ -261,7 +261,7 @@ accessing /net/myserver will mount expor + /net/myserver. + .P + NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options +-unless overridden by explicily specifying the "suid", "dev" or "nointr" options in the ++unless overridden by explicitly specifying the "suid", "dev" or "nointr" options in the + master map entry. + .SH LDAP MAPS + If the map type \fBldap\fP is specified the mapname is of the form +@@ -277,7 +277,7 @@ configuration, in which case the map nam + .P + If no schema is set in the autofs configuration then autofs will check + each of the commonly used schema for a valid entry and if one is found +-it will used for subsequent lookups. ++it will be used for subsequent lookups. + .P + There are three common schemas in use: + .TP +@@ -351,7 +351,7 @@ connection is to be used then the client + locations must also be configured within the LDAP client. + .P + In OpenLDAP these may be configured in the \fBldap.conf\fP file or in the +-per-user configuration. For example it may be sensible to use the system ++per-user configuration. For example, it may be sensible to use the system + wide configuration for the location of the Certificate Authority certificate + and set the location of the client certificate and private key + in the per-user configuration. The location of these files and the configuration +@@ -399,5 +399,5 @@ configuration will be used to locate the + .BR autofs_ldap_auth.conf (5). + .SH AUTHOR + This manual page was written by Christoph Lameter , +-for the Debian GNU/Linux system. Edited by and ++for the Debian GNU/Linux system. Edited by and + Ian Kent . +--- autofs-5.1.4.orig/man/autofs.5 ++++ autofs-5.1.4/man/autofs.5 +@@ -64,7 +64,6 @@ can't be mounted. + .br + is used to make the weight the sole factor in selecting a server when multiple + servers are present in a map entry. +-and + .TP + .B \-no-use-weight-only + .br +@@ -192,7 +191,7 @@ SHOST Short hostname (domain part remove + .sp + If a program map is used these standard environment variables will have + a prefix of "AUTOFS_" to prevent interpreted languages like python from +-being able to load and execute arbitray code from a user home directory. ++being able to load and execute arbitrary code from a user home directory. + .RE + .sp + Additional entries can be defined with the \-Dvariable=Value map-option to +@@ -293,10 +292,10 @@ may be negated with the \fB!\fP. + For a \fBlocation\fP to be selected for a mount attempt all of its \fBselectors\fP + must evaluate to true. If a \fBlocation\fP is selected for a mount attempt + and succeeds the lookup is completed and returns success. If the mount +-attempt fails the proceedure continues with the next \fBlocation\fP until ++attempt fails the procedure continues with the next \fBlocation\fP until + they have all been tried. + +-In addition some \fBselectors\fP take no argumenets, some one argument ++In addition, some \fBselectors\fP take no arguments, some one argument + and others optionally take two arguments. + + The \fBselectors\fP that take no arguments are: +@@ -584,7 +583,7 @@ In the first line we have an NFS remote + another nfs mount for the exported directory /work/util from host zeus. + This would be mounted on /test/util. + +-Finally we have an example of the use of the \fBsublink\fP option. In ++Finally, we have an example of the use of the \fBsublink\fP option. In + this case the filesystem bilbo:/shared would be mounted on a path + external the automount directory (under the direcory given by + configuration option auto_dir) and the path /test/local either +--- autofs-5.1.4.orig/man/autofs.conf.5.in ++++ autofs-5.1.4/man/autofs.conf.5.in +@@ -91,7 +91,7 @@ set default log level "none", "verbose" + .B force_standard_program_map_env + .br + override the use of a prefix with standard environment variables when a +-program map is executed. Since program maps are run as the privileded ++program map is executed. Since program maps are run as the privileged + user setting these standard environment variables opens automount(8) to + potential user privilege escalation when the program map is written in a + language that can load components from, for example, a user home directory +@@ -110,16 +110,15 @@ and a direct map with 8000 entries would + containing an average of 8 entries, which should be acceptable. + + However, if excessive CPU usage is observed during automount lookups +-increasing this option can reduce the CPU overhead considerably becuase ++increasing this option can reduce the CPU overhead considerably because + it reduces the length of the search chains. + + Note that the number of entries in a map doesn't necessarily relate + to the number of entries used in the map entry cache. + +-There are three distinct cases, direct maps and indirect maps that +-use the "browse" option must be read in their entirity at program +-start so, in these two cases the map size does retate directly to +-the map entry cache size. ++There are two distinct cases where the map hash table can make a ++significant difference, direct maps and indirect maps that use the ++"browse" option. + + For indirect maps that do not use the "browse" option entries are + added to the map entry cache at lookup so the number of active cache +@@ -174,7 +173,7 @@ by the number of retries that would be u + .B use_mount_request_log_id + .br + Set whether to use a mount request log id so that log entries for specific +-mount requests can be easily identified in logs that have multiple conncurrent ++mount requests can be easily identified in logs that have multiple concurrent + requests. Default is don't use mount request log ids. + .SS LDAP Configuration + .P +@@ -183,7 +182,7 @@ Configuration settings available are: + .B ldap_timeout + .br + Set the network response timeout (default 8). +-Set timeout value for the synchronous API calls. The default is the LDAP ++Set timeout value for the synchronous API calls. The default is the LDAP + library default of an infinite timeout. + .TP + .B ldap_network_timeout +@@ -323,7 +322,7 @@ cleaned on re-load, which is done when m + so these configuration entries are not used by autofs. An + exception to this is the case where the map is large. In this + case it may be necessary to read the whole map at startup even if +-browsing is is not enabled. Adding the cache:=all option to ++browsing is not enabled. Adding the cache:=all option to + map_options can be used to for this. + .TP + .B localhost_address +@@ -390,14 +389,14 @@ and that will be done. + Allow map keys to be shown in directory listings. This option + can have values of "yes" or "no". The default is "no". A variation + of this option, "browsable", can be used as a pseudo mount option +-in type "auto" map entries to provide provide browsing funtionality ++in type "auto" map entries to provide browsing functionality + in sub-mounts. The amd "browsable_dirs = full" option cannot be + implemented within the current autofs framework and is not supported. + .TP + .B exec_map_timeout + .br +-A timeout is not currently used for for program maps, might be +-implemented. ++A timeout is not currently used for program maps but this might be ++implemented in the future. + .TP + .B tag + .br +@@ -473,7 +472,7 @@ its official host name. + .TP + .B domain_strip + .br +-If set to "yes" the domain name part of the host is strippped ++If set to "yes" the domain name part of the host is stripped + when normalizing hostnames. This can be useful when using of + the same maps in a multiple domain environment. + .TP +@@ -497,8 +496,8 @@ that is used for queries if ldap is to b + .B ldap_hostports + .br + This option has no default value set. It must be set to the URI +-of the LDAP server to be used for lookups wheni ldap is used a +-map source. It may contain a comma or space separated list of ++of the LDAP server to be used for lookups when ldap is used as ++a map source. It may contain a comma or space separated list of + LDAP URIs. + .TP + .B hesiod_base +--- autofs-5.1.4.orig/man/autofs_ldap_auth.conf.5.in ++++ autofs-5.1.4/man/autofs_ldap_auth.conf.5.in +@@ -56,7 +56,7 @@ required in order to perform ldap querie + sasl authenticated connections will be allowed. If it is set to no then + authentication is not needed for ldap server connections. If it is set to + autodetect then the ldap server will be queried to establish a suitable sasl +-authentication mechanism. If no suitable mechanism can be found, connections ++authentication mechanism. If no suitable mechanism can be found, connections + to the ldap server are made without authentication. Finally, if it is set to + simple, then simple authentication will be used instead of SASL. + .TP +--- autofs-5.1.4.orig/man/automount.8 ++++ autofs-5.1.4/man/automount.8 +@@ -89,7 +89,7 @@ that would be used by autofs for the who + .TP + .I "\-O, \-\-global-options" + Allows the specification of global mount options used for all master +-map entries. These options will either replace or be appened to options ++map entries. These options will either replace or be appended to options + given in a master map entry depending on the APPEND_OPTIONS configuration + setting. + .TP +--- autofs-5.1.4.orig/modules/lookup_ldap.c ++++ autofs-5.1.4/modules/lookup_ldap.c +@@ -1320,11 +1320,11 @@ auth_fail: + ret |= get_property(logopt, root, "external_key", &extern_key); + /* + * For EXTERNAL auth to function we need a client certificate +- * and and certificate key. The ca certificate used to verify ++ * and certificate key. The ca certificate used to verify + * the server certificate must also be set correctly in the + * global configuration as the connection must be encrypted + * and the server and client certificates must have been +- * verified for the EXTERNAL method to be offerred by the ++ * verified for the EXTERNAL method to be offered by the + * server. If the cert and key have not been set in the autofs + * configuration they must be set in the ldap rc file. + */ +--- autofs-5.1.4.orig/modules/replicated.c ++++ autofs-5.1.4/modules/replicated.c +@@ -24,11 +24,11 @@ + * - 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 ++ * 2) NFS version and protocol is selected by calculating 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 increaes response time and so influences the ++ * which essentially increases response time and so influences the + * host order. + * + * 3) Hosts at further proximity that support the selected NFS version +--- autofs-5.1.4.orig/redhat/autofs.conf.default.in ++++ autofs-5.1.4/redhat/autofs.conf.default.in +@@ -79,7 +79,7 @@ mount_nfs_default_protocol = 4 + # are run as the privileded user this opens + # automount(8) to potential user privilege + # escalation when the program map is written +-# in a language that can load components from, ++# in a language that can load components from, + # for example, a user home directory. + # + # force_standard_program_map_env = no +@@ -87,7 +87,7 @@ mount_nfs_default_protocol = 4 + # use_mount_request_log_id - Set whether to use a mount request log + # id so that log entries for specific mount + # requests can be easily identified in logs +-# that have multiple conncurrent requests. ++# that have multiple concurrent requests. + # + #use_mount_request_log_id = no + # +@@ -419,10 +419,10 @@ dismount_interval = 300 + # appears to work reasonably well most of the time without the + # update). + # +-# autofs_use_lofs = yes ++#autofs_use_lofs = yes + # + # Several configuration options can be set per mount point. +-# In particulr map_type, map_name, map_defaults, search_path, ++# In particular map_type, map_name, map_defaults, search_path, + # browsable_dirs, dismount_interval and selectors_in_defaults + # (not all of which are currently implemented, see above). + # +@@ -431,6 +431,6 @@ dismount_interval = 300 + # master map entry and the format will be inherited for type + # "auto" mounts. + # +-# [ /expamle/mount ] +-# dismount_interval = 60 +-# map_type = nis ++#[ /example/mount ] ++#dismount_interval = 60 ++#map_type = nis +--- autofs-5.1.4.orig/redhat/autofs.sysconfig ++++ autofs-5.1.4/redhat/autofs.sysconfig +@@ -1,5 +1,5 @@ + # +-# Init syatem options ++# Init system options + # + # If the kernel supports using the autofs miscellanous device + # and you wish to use it you must set this configuration option +--- autofs-5.1.4.orig/samples/autofs.conf.default.in ++++ autofs-5.1.4/samples/autofs.conf.default.in +@@ -78,7 +78,7 @@ browse_mode = no + # are run as the privileded user this opens + # automount(8) to potential user privilege + # escalation when the program map is written +-# in a language that can load components from, ++# in a language that can load components from, + # for example, a user home directory. + # + # force_standard_program_map_env = no +@@ -86,7 +86,7 @@ browse_mode = no + # use_mount_request_log_id - Set whether to use a mount request log + # id so that log entries for specific mount + # requests can be easily identified in logs +-# that have multiple conncurrent requests. ++# that have multiple concurrent requests. + # + #use_mount_request_log_id = no + # +@@ -430,6 +430,6 @@ dismount_interval = 300 + # master map entry and the format will be inherited for type + # "auto" mounts. + # +-# [ /expamle/mount ] +-# dismount_interval = 60 +-# map_type = nis ++#[ /example/mount ] ++#dismount_interval = 60 ++#map_type = nis diff --git a/autofs-5.1.5-fix-amd-entry-memory-leak.patch b/autofs-5.1.5-fix-amd-entry-memory-leak.patch new file mode 100644 index 0000000..f45393e --- /dev/null +++ b/autofs-5.1.5-fix-amd-entry-memory-leak.patch @@ -0,0 +1,33 @@ +autofs-5.1.5 - fix amd entry memory leak + +From: Ian Kent + +Fix an incorrect free of an amd_entry structure. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/master.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -58,6 +58,7 @@ xx/xx/2018 autofs-5.1.5 + - remove unused function has_fstab_option(). + - remove unused function reverse_mnt_list(). + - remove a couple of old debug messages. ++- fix amd entry memory leak. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -155,7 +155,7 @@ void master_free_autofs_point(struct aut + ext_mount_remove(&entry->ext_mount, entry->fs); + if (!list_empty(&entry->entries)) + list_del(&entry->entries); +- free(entry); ++ free_amd_entry(entry); + } + mounts_mutex_unlock(ap); + diff --git a/autofs-5.1.5-fix-hesiod-string-check-in-master_parse.patch b/autofs-5.1.5-fix-hesiod-string-check-in-master_parse.patch new file mode 100644 index 0000000..dd389f7 --- /dev/null +++ b/autofs-5.1.5-fix-hesiod-string-check-in-master_parse.patch @@ -0,0 +1,49 @@ +autofs-5.1.5 - fix hesiod string check in master_parse() + +From: Ian Kent + +When map source is specified in a master map entry, checking if +map type is hesiod in master_parse() will generate a SEGV if a +parser type is not also present becuase tmp will be NULL in this +case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/master_parse.y | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -37,6 +37,7 @@ xx/xx/2018 autofs-5.1.5 + - fix incorrect locking in sss lookup. + - fix amd parser opts option handling. + - better handle hesiod support not built in. ++- fix hesiod string check in master_parse(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/master_parse.y ++++ autofs-5.1.4/lib/master_parse.y +@@ -172,8 +172,8 @@ line: + if ((tmp = strchr($2, ','))) + *tmp++ = '\0'; + #ifndef WITH_HESIOD +- /* Map type or or map type parser is hesiod */ +- if (!strcmp($2, "hesiod") || !strcmp(tmp, "hesiod")) { ++ /* Map type or map type parser is hesiod */ ++ if (!strcmp($2, "hesiod") || (tmp && !strcmp(tmp, "hesiod"))) { + master_error("hesiod support not built in"); + local_free_vars(); + YYABORT; +@@ -360,8 +360,8 @@ map: PATH + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; + #ifndef WITH_HESIOD +- /* Map type or or map type parser is hesiod */ +- if (!strcmp($1, "hesiod") || !strcmp(tmp, "hesiod")) { ++ /* Map type or map type parser is hesiod */ ++ if (!strcmp($1, "hesiod") || (tmp && !strcmp(tmp, "hesiod"))) { + master_error("hesiod support not built in"); + local_free_vars(); + YYABORT; diff --git a/autofs-5.1.5-fix-macro-expansion-in-selector-values.patch b/autofs-5.1.5-fix-macro-expansion-in-selector-values.patch new file mode 100644 index 0000000..0b2a5d0 --- /dev/null +++ b/autofs-5.1.5-fix-macro-expansion-in-selector-values.patch @@ -0,0 +1,419 @@ +autofs-5.1.5 - fix macro expansion in selector values + +From: Ian Kent + +Macro expansion is not done in selector values before use, for example +in "hostd==${/key}.." the ${/key} is not expanded before +use leading to an attempt to use an invalid host name. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/parse_amd.c | 286 ++++++++++++++++++++++++++++++++++------------------ + 2 files changed, 193 insertions(+), 94 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -52,6 +52,7 @@ xx/xx/2018 autofs-5.1.5 + - log mount call arguments if mount_verbose is set. + - make expire remaining log level debug. + - allow period following macro in selector value. ++- fix macro expansion in selector values. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -231,17 +231,29 @@ static struct substvar *add_lookup_vars( + return list; + } + +-static int match_my_name(unsigned int logopt, const char *name, struct substvar *sv) ++static int match_my_name(struct autofs_point *ap, const char *name, struct substvar *sv) + { + struct addrinfo hints, *cni, *ni, *haddr; + char host[NI_MAXHOST + 1], numeric[NI_MAXHOST + 1]; ++ unsigned int logopt = ap->logopt; + const struct substvar *v; ++ char *exp_name = NULL; + int rv = 0, ret; + ++ if (!expand_selectors(ap, name, &exp_name, sv)) ++ exp_name = strdup(name); ++ if (!exp_name) { ++ error(logopt, ++ MODPREFIX "error: failed to alloc space for name"); ++ goto out; ++ } ++ + v = macro_findvar(sv, "host", 4); + if (v) { +- if (!strcmp(v->val, name)) +- return 1; ++ if (!strcmp(v->val, exp_name)) { ++ rv = 1; ++ goto out; ++ } + } + + if (!v || !v->val) { +@@ -268,11 +280,11 @@ static int match_my_name(unsigned int lo + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + + /* Resolve comparison name to its names and compare */ +- ret = getaddrinfo(name, NULL, &hints, &ni); ++ ret = getaddrinfo(exp_name, NULL, &hints, &ni); + if (ret) { + error(logopt, MODPREFIX + "hostname lookup for %s failed: %s\n", +- name, gai_strerror(ret)); ++ exp_name, gai_strerror(ret)); + freeaddrinfo(cni); + goto out; + } +@@ -310,18 +322,180 @@ next: + freeaddrinfo(ni); + freeaddrinfo(cni); + out: ++ if (exp_name) ++ free(exp_name); + return rv; + } + +-static int eval_selector(unsigned int logopt, ++static int sel_strcmp(struct autofs_point *ap, ++ const struct substvar *v, struct selector *s, ++ struct substvar *sv) ++{ ++ char *expand = NULL; ++ int ret = 0; ++ int res; ++ ++ res = expand_selectors(ap, s->comp.value, &expand, sv); ++ if (res) ++ res = strcmp(v->val, expand); ++ else ++ res = strcmp(v->val, s->comp.value); ++ ++ if (s->compare & SEL_COMP_EQUAL && !res) { ++ debug(ap->logopt, MODPREFIX ++ "matched selector %s(%s) == %s", ++ v->def, v->val, expand ? expand : s->comp.value); ++ ret = 1; ++ } else if (s->compare & SEL_COMP_NOTEQUAL && res) { ++ debug(ap->logopt, MODPREFIX ++ "matched selector %s(%s) != %s", ++ v->def, v->val, expand ? expand : s->comp.value); ++ ret = 1; ++ } else ++ debug(ap->logopt, MODPREFIX ++ "did not match selector %s(%s) %s %s", ++ v->def, v->val, ++ (s->compare & SEL_COMP_EQUAL ? "==" : "!="), ++ expand ? expand : s->comp.value); ++ ++ if (expand) ++ free(expand); ++ ++ return ret; ++} ++ ++static int sel_lstat(struct autofs_point *ap, ++ struct selector *s, struct substvar *sv) ++{ ++ struct stat st; ++ char *expand = NULL; ++ int res, ret; ++ ++ /* Sould be OK to fail on any error here */ ++ res = expand_selectors(ap, s->func.arg1, &expand, sv); ++ if (res) ++ ret = !lstat(expand, &st); ++ else ++ ret = !lstat(s->func.arg1, &st); ++ ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) ++ debug(ap->logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, expand ? expand : s->func.arg1); ++ else ++ debug(ap->logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, expand ? expand : s->func.arg1); ++ if (expand) ++ free(expand); ++ ++ return ret; ++} ++ ++static int sel_in_network(struct autofs_point *ap, ++ struct selector *s, struct substvar *sv) ++{ ++ char *expand = NULL; ++ int res, ret; ++ ++ res = expand_selectors(ap, s->func.arg1, &expand, sv); ++ if (!res) ++ ret = in_network(s->func.arg1); ++ else ++ ret = in_network(expand); ++ ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) ++ debug(ap->logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, expand ? expand : s->func.arg1); ++ else ++ debug(ap->logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, expand ? expand : s->func.arg1); ++ ++ if (expand) ++ free(expand); ++ ++ return ret; ++} ++ ++static int sel_netgrp(struct autofs_point *ap, ++ struct selector *s, struct substvar *sv) ++{ ++ char *exp_arg1 = NULL, *exp_arg2 = NULL; ++ const struct substvar *v; ++ int res, ret = 0; ++ char *host; ++ ++ if (s->func.arg2) { ++ res = expand_selectors(ap, s->func.arg2, &exp_arg2, sv); ++ if (res) ++ host = exp_arg2; ++ else ++ host = s->func.arg2; ++ } else { ++ if (s->sel->selector == SEL_NETGRP) ++ v = macro_findvar(sv, "host", 4); ++ else ++ v = macro_findvar(sv, "hostd", 5); ++ if (!v || !*v->val) { ++ error(ap->logopt, MODPREFIX ++ "failed to get value of ${host}"); ++ goto out; ++ } ++ host = v->val; ++ } ++ ++ res = expand_selectors(ap, s->func.arg1, &exp_arg1, sv); ++ if (res) ++ ret = innetgr(exp_arg1, host, NULL, NULL); ++ else ++ ret = innetgr(s->func.arg1, host, NULL, NULL); ++ ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) { ++ if (!s->func.arg2) ++ debug(ap->logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, exp_arg1 ? exp_arg1 : s->func.arg1); ++ else ++ debug(ap->logopt, MODPREFIX ++ "matched selector %s(%s,%s)", s->sel->name, ++ exp_arg1 ? exp_arg1 : s->func.arg1, ++ exp_arg2 ? exp_arg2 : s->func.arg2); ++ } else { ++ if (!s->func.arg2) ++ debug(ap->logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, exp_arg1 ? exp_arg1 : s->func.arg1); ++ else ++ debug(ap->logopt, MODPREFIX ++ "did not match selector %s(%s,%s)", s->sel->name, ++ exp_arg1 ? exp_arg1 : s->func.arg1, ++ exp_arg2 ? exp_arg2 : s->func.arg2); ++ } ++out: ++ if (exp_arg1) ++ free(exp_arg1); ++ if (exp_arg2) ++ free(exp_arg2); ++ ++ return ret; ++} ++ ++static int eval_selector(struct autofs_point *ap, + struct amd_entry *this, struct substvar *sv) + { + struct selector *s = this->selector; ++ unsigned int logopt = ap->logopt; + const struct substvar *v; + unsigned int s_type; + unsigned int v_type; +- struct stat st; +- char *host; + int res, val, ret = 0; + + s_type = s->sel->flags & SEL_FLAGS_TYPE_MASK; +@@ -339,26 +513,7 @@ static int eval_selector(unsigned int lo + + switch (v_type) { + case SEL_FLAG_STR: +- res = strcmp(v->val, s->comp.value); +- if (s->compare & SEL_COMP_EQUAL && !res) { +- debug(logopt, MODPREFIX +- "matched selector %s(%s) == %s", +- v->def, v->val, s->comp.value); +- ret = 1; +- break; +- } else if (s->compare & SEL_COMP_NOTEQUAL && res) { +- debug(logopt, MODPREFIX +- "matched selector %s(%s) != %s", +- v->def, v->val, s->comp.value); +- ret = 1; +- break; +- } +- +- debug(logopt, MODPREFIX +- "did not match selector %s(%s) %s %s", +- v->def, v->val, +- (s->compare & SEL_COMP_EQUAL ? "==" : "!="), +- s->comp.value); ++ ret = sel_strcmp(ap, v, s, sv); + break; + + case SEL_FLAG_NUM: +@@ -434,7 +589,7 @@ static int eval_selector(unsigned int lo + break; + + case SEL_XHOST: +- ret = match_my_name(logopt, s->func.arg1, sv); ++ ret = match_my_name(ap, s->func.arg1, sv); + if (s->compare == SEL_COMP_NOT) + ret = !ret; + if (ret) +@@ -448,32 +603,11 @@ static int eval_selector(unsigned int lo + break; + + case SEL_EXISTS: +- /* Sould be OK to fail on any error here */ +- ret = !lstat(s->func.arg1, &st); +- if (s->compare == SEL_COMP_NOT) +- ret = !ret; +- if (ret) +- debug(logopt, MODPREFIX +- "matched selector %s(%s)", +- s->sel->name, s->func.arg1); +- else +- debug(logopt, MODPREFIX +- "did not match selector %s(%s)", +- s->sel->name, s->func.arg1); ++ ret = sel_lstat(ap, s, sv); + break; + + case SEL_IN_NETWORK: +- ret = in_network(s->func.arg1); +- if (s->compare == SEL_COMP_NOT) +- ret = !ret; +- if (ret) +- debug(logopt, MODPREFIX +- "matched selector %s(%s)", +- s->sel->name, s->func.arg1); +- else +- debug(logopt, MODPREFIX +- "did not match selector %s(%s)", +- s->sel->name, s->func.arg1); ++ ret = sel_in_network(ap, s, sv); + break; + + default: +@@ -492,43 +626,7 @@ static int eval_selector(unsigned int lo + switch (s->sel->selector) { + case SEL_NETGRP: + case SEL_NETGRPD: +- if (s->func.arg2) +- host = s->func.arg2; +- else { +- if (s->sel->selector == SEL_NETGRP) +- v = macro_findvar(sv, "host", 4); +- else +- v = macro_findvar(sv, "hostd", 5); +- if (!v || !*v->val) { +- error(logopt, MODPREFIX +- "failed to get value of ${host}"); +- break; +- } +- host = v->val; +- } +- ret = innetgr(s->func.arg1, host, NULL, NULL); +- if (s->compare == SEL_COMP_NOT) +- ret = !ret; +- if (ret) { +- if (!s->func.arg2) +- debug(logopt, MODPREFIX +- "matched selector %s(%s)", +- s->sel->name, s->func.arg1); +- else +- debug(logopt, MODPREFIX +- "matched selector %s(%s,%s)", +- s->sel->name, s->func.arg1, +- s->func.arg2); +- } else { +- if (!s->func.arg2) +- debug(logopt, MODPREFIX +- "did not match selector %s(%s)", +- s->sel->name, s->func.arg1); +- else +- debug(logopt, MODPREFIX +- "did not match selector %s(%s,%s)", +- s->sel->name, s->func.arg1, s->func.arg2); +- } ++ ret = sel_netgrp(ap, s, sv); + break; + + default: +@@ -1753,7 +1851,7 @@ static void update_prefix(struct autofs_ + return; + } + +-static int match_selectors(unsigned int logopt, ++static int match_selectors(struct autofs_point *ap, + struct amd_entry *entry, struct substvar *sv) + { + struct selector *s = entry->selector; +@@ -1761,7 +1859,7 @@ static int match_selectors(unsigned int + + /* No selectors, always match */ + if (!s) { +- debug(logopt, MODPREFIX "no selectors found in location"); ++ debug(ap->logopt, MODPREFIX "no selectors found in location"); + return 1; + } + +@@ -1769,7 +1867,7 @@ static int match_selectors(unsigned int + + /* All selectors must match */ + while (s) { +- ret = eval_selector(logopt, entry, sv); ++ ret = eval_selector(ap, entry, sv); + if (!ret) + break; + s = s->next; +@@ -1939,7 +2037,7 @@ static struct amd_entry *select_default_ + if (!this->selector) + continue; + +- if (match_selectors(ap->logopt, this, sv)) { ++ if (match_selectors(ap, this, sv)) { + if (entry_default) { + /*update_with_defaults(entry_default, this, sv);*/ + free_amd_entry(entry_default); +@@ -2192,7 +2290,7 @@ int parse_mount(struct autofs_point *ap, + break; + } + +- if (!match_selectors(ap->logopt, this, sv)) ++ if (!match_selectors(ap, this, sv)) + continue; + + at_least_one = 1; diff --git a/autofs-5.1.5-fix-missing-initialization-of-autofs_point-flags.patch b/autofs-5.1.5-fix-missing-initialization-of-autofs_point-flags.patch new file mode 100644 index 0000000..e152ce4 --- /dev/null +++ b/autofs-5.1.5-fix-missing-initialization-of-autofs_point-flags.patch @@ -0,0 +1,34 @@ +autofs-5.1.5 - fix missing initialization of autofs_point flags + +From: Ian Kent + +When adding the "use_ignore_mount_option" configuration option I added +a "use without initialization" for ap->flags. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/master.c | 2 ++ + 2 files changed, 3 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -75,6 +75,7 @@ xx/xx/2018 autofs-5.1.5 + - use local_getmntent_r() for unlink_mount_tree(). + - use local getmntent_r() in get_mnt_list(). + - use local getmntent_r() in tree_make_mnt_list(). ++- fix missing initialization of autofs_point flags. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -101,6 +101,8 @@ int master_add_autofs_point(struct maste + ap->negative_timeout = global_negative_timeout; + ap->exp_timeout = defaults_get_timeout(); + ap->exp_runfreq = 0; ++ ap->flags = 0; ++ + if (defaults_get_use_ignore_mount_option()) + ap->flags = MOUNT_FLAG_IGNORE; + if (ghost) diff --git a/autofs-5.1.5-fix-unlink_mount_tree-not-umounting-mounts.patch b/autofs-5.1.5-fix-unlink_mount_tree-not-umounting-mounts.patch new file mode 100644 index 0000000..317de04 --- /dev/null +++ b/autofs-5.1.5-fix-unlink_mount_tree-not-umounting-mounts.patch @@ -0,0 +1,136 @@ +autofs-5.1.5 - fix unlink_mount_tree() not umounting mounts + +From: Ian Kent + +At some point a check matching process group id of mounts was added to +the unlink_mount_tree() function so that mounts not matching the group +id of the calling process would be skipped. + +But unlink_mount_tree() is meant to force a cleanup of mounts from a +previous automount process so the process group of the current process +can never match so all mounts are skipped. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 7 ------- + daemon/indirect.c | 9 --------- + include/mounts.h | 1 - + lib/mounts.c | 20 -------------------- + 5 files changed, 1 insertion(+), 37 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -59,6 +59,7 @@ xx/xx/2018 autofs-5.1.5 + - remove unused function reverse_mnt_list(). + - remove a couple of old debug messages. + - fix amd entry memory leak. ++- fix unlink_mount_tree() not umounting mounts. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -264,10 +264,6 @@ static int unlink_mount_tree(struct auto + { + struct list_head *p; + int rv, ret; +- pid_t pgrp = getpgrp(); +- char spgrp[20]; +- +- sprintf(spgrp, "pgrp=%d", pgrp); + + ret = 1; + list_for_each(p, list) { +@@ -275,9 +271,6 @@ static int unlink_mount_tree(struct auto + + mnt = list_entry(p, struct mnt_list, list); + +- if (strstr(mnt->opts, spgrp)) +- continue; +- + if (strcmp(mnt->fs_type, "autofs")) + rv = spawn_umount(ap->logopt, "-l", mnt->path, NULL); + else +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -44,19 +44,10 @@ static int unlink_mount_tree(struct auto + { + struct mnt_list *this; + int rv, ret; +- pid_t pgrp = getpgrp(); +- char spgrp[20]; +- +- sprintf(spgrp, "pgrp=%d", pgrp); + + ret = 1; + this = mnts; + while (this) { +- if (strstr(this->opts, spgrp)) { +- this = this->next; +- continue; +- } +- + if (strcmp(this->fs_type, "autofs")) + rv = spawn_umount(ap->logopt, "-l", this->path, NULL); + else +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -53,7 +53,6 @@ struct mnt_list { + char *fs_name; + char *fs_type; + char *opts; +- pid_t owner; + /* + * List operations ie. get_mnt_list. + */ +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -798,7 +798,6 @@ struct mnt_list *get_mnt_list(const char + struct mntent *mnt; + struct mnt_list *ent, *mptr, *last; + struct mnt_list *list = NULL; +- char *pgrp; + size_t len; + + if (!path || !pathlen || pathlen > PATH_MAX) +@@ -879,15 +878,6 @@ struct mnt_list *get_mnt_list(const char + return NULL; + } + strcpy(ent->opts, mnt->mnt_opts); +- +- ent->owner = 0; +- pgrp = strstr(mnt->mnt_opts, "pgrp="); +- if (pgrp) { +- char *end = strchr(pgrp, ','); +- if (end) +- *end = '\0'; +- sscanf(pgrp, "pgrp=%d", &ent->owner); +- } + } + endmntent(tab); + +@@ -1068,7 +1058,6 @@ struct mnt_list *tree_make_mnt_tree(cons + struct mntent *mnt; + struct mnt_list *ent, *mptr; + struct mnt_list *tree = NULL; +- char *pgrp; + size_t plen; + int eq; + +@@ -1147,15 +1136,6 @@ struct mnt_list *tree_make_mnt_tree(cons + } + strcpy(ent->opts, mnt->mnt_opts); + +- ent->owner = 0; +- pgrp = strstr(mnt->mnt_opts, "pgrp="); +- if (pgrp) { +- char *end = strchr(pgrp, ','); +- if (end) +- *end = '\0'; +- sscanf(pgrp, "pgrp=%d", &ent->owner); +- } +- + mptr = tree; + while (mptr) { + int elen = strlen(ent->path); diff --git a/autofs-5.1.5-log-mount-call-arguments-if-mount_verbose-is-set.patch b/autofs-5.1.5-log-mount-call-arguments-if-mount_verbose-is-set.patch new file mode 100644 index 0000000..ee3b686 --- /dev/null +++ b/autofs-5.1.5-log-mount-call-arguments-if-mount_verbose-is-set.patch @@ -0,0 +1,222 @@ +autofs-5.1.5 - log mount call arguments if mount_verbose is set + +From: Lars R. Damerow + +Override the debug log only setting if mount_verbose is set so that +mount parameter information is logged on mount. + +Signed-off-by: Lars R. Damerow +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_afs.c | 6 +++++- + modules/mount_bind.c | 10 +++++++--- + modules/mount_ext2.c | 16 ++++++++++------ + modules/mount_generic.c | 14 +++++++++----- + modules/mount_nfs.c | 29 +++++++++++++++++------------ + 6 files changed, 49 insertions(+), 27 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -49,6 +49,7 @@ xx/xx/2018 autofs-5.1.5 + - use malloc(3) in spawn.c. + - add mount_verbose configuration option. + - optionally log mount requestor process info. ++- log mount call arguments if mount_verbose is set. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/mount_afs.c ++++ autofs-5.1.4/modules/mount_afs.c +@@ -37,10 +37,14 @@ int mount_mount(struct autofs_point *ap, + char dest[PATH_MAX + 1]; + size_t r_len = strlen(root); + size_t d_len = r_len + name_len + 2; ++ void (*mountlog)(unsigned int, const char*, ...) = &log_debug; + + if (ap->flags & MOUNT_FLAG_REMOUNT) + return 0; + ++ if (defaults_get_mount_verbose()) ++ mountlog = &log_info; ++ + if (d_len > PATH_MAX) + return 1; + +@@ -53,7 +57,7 @@ int mount_mount(struct autofs_point *ap, + if (dest[strlen(dest)-1] == '/') + dest[strlen(dest)-1] = '\0'; + +- debug(ap->logopt, MODPREFIX "mounting AFS %s -> %s", dest, what); ++ mountlog(ap->logopt, MODPREFIX "mounting AFS %s -> %s", dest, what); + + return symlink(what, dest); /* Try it. If it fails, return the error. */ + } +--- autofs-5.1.4.orig/modules/mount_bind.c ++++ autofs-5.1.4/modules/mount_bind.c +@@ -81,10 +81,14 @@ int mount_mount(struct autofs_point *ap, + int err; + int i, len; + int symlnk = (*name != '/' && (ap->flags & MOUNT_FLAG_SYMLINK)); ++ void (*mountlog)(unsigned int, const char*, ...) = &log_debug; + + if (ap->flags & MOUNT_FLAG_REMOUNT) + return 0; + ++ if (defaults_get_mount_verbose()) ++ mountlog = &log_info; ++ + /* Extract "symlink" pseudo-option which forces local filesystems + * to be symlinked instead of bound. + */ +@@ -164,9 +168,9 @@ int mount_mount(struct autofs_point *ap, + if (!status) + existed = 0; + +- debug(ap->logopt, MODPREFIX +- "calling mount --bind -o %s %s %s", +- options, what, fullpath); ++ mountlog(ap->logopt, MODPREFIX ++ "calling mount --bind -o %s %s %s", ++ options, what, fullpath); + + err = spawn_bind_mount(ap->logopt, "-o", + options, what, fullpath, NULL); +--- autofs-5.1.4.orig/modules/mount_ext2.c ++++ autofs-5.1.4/modules/mount_ext2.c +@@ -47,10 +47,14 @@ int mount_mount(struct autofs_point *ap, + int err, ro = 0; + const char *fsck_prog; + int len, status, existed = 1; ++ void (*mountlog)(unsigned int, const char*, ...) = &log_debug; + + if (ap->flags & MOUNT_FLAG_REMOUNT) + return 0; + ++ if (defaults_get_mount_verbose()) ++ mountlog = &log_info; ++ + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +@@ -121,15 +125,15 @@ int mount_mount(struct autofs_point *ap, + } + + if (options) { +- debug(ap->logopt, MODPREFIX +- "calling mount -t %s -o %s %s %s", +- fstype, options, what, fullpath); ++ mountlog(ap->logopt, MODPREFIX ++ "calling mount -t %s -o %s %s %s", ++ fstype, options, what, fullpath); + err = spawn_mount(ap->logopt, "-t", fstype, + "-o", options, what, fullpath, NULL); + } else { +- debug(ap->logopt, +- MODPREFIX "calling mount -t %s %s %s", +- fstype, what, fullpath); ++ mountlog(ap->logopt, ++ MODPREFIX "calling mount -t %s %s %s", ++ fstype, what, fullpath); + err = spawn_mount(ap->logopt, "-t", fstype, what, fullpath, NULL); + } + +--- autofs-5.1.4.orig/modules/mount_generic.c ++++ autofs-5.1.4/modules/mount_generic.c +@@ -46,10 +46,14 @@ int mount_mount(struct autofs_point *ap, + char buf[MAX_ERR_BUF]; + int err; + int len, status, existed = 1; ++ void (*mountlog)(unsigned int, const char*, ...) = &log_debug; + + if (ap->flags & MOUNT_FLAG_REMOUNT) + return 0; + ++ if (defaults_get_mount_verbose()) ++ mountlog = &log_info; ++ + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +@@ -80,15 +84,15 @@ int mount_mount(struct autofs_point *ap, + existed = 0; + + if (options && options[0]) { +- debug(ap->logopt, +- MODPREFIX "calling mount -t %s -o %s %s %s", +- fstype, options, what, fullpath); ++ mountlog(ap->logopt, ++ MODPREFIX "calling mount -t %s -o %s %s %s", ++ fstype, options, what, fullpath); + + err = spawn_mount(ap->logopt, "-t", fstype, + "-o", options, what, fullpath, NULL); + } else { +- debug(ap->logopt, MODPREFIX "calling mount -t %s %s %s", +- fstype, what, fullpath); ++ mountlog(ap->logopt, MODPREFIX "calling mount -t %s %s %s", ++ fstype, what, fullpath); + err = spawn_mount(ap->logopt, "-t", fstype, what, fullpath, NULL); + } + +--- autofs-5.1.4.orig/modules/mount_nfs.c ++++ autofs-5.1.4/modules/mount_nfs.c +@@ -77,13 +77,17 @@ int mount_mount(struct autofs_point *ap, + int port = -1; + int ro = 0; /* Set if mount bind should be read-only */ + int rdma = 0; ++ void (*mountlog)(unsigned int, const char*, ...) = &log_debug; + + if (ap->flags & MOUNT_FLAG_REMOUNT) + return 0; + +- debug(ap->logopt, +- MODPREFIX "root=%s name=%s what=%s, fstype=%s, options=%s", +- root, name, what, fstype, options); ++ if (defaults_get_mount_verbose()) ++ mountlog = &log_info; ++ ++ mountlog(ap->logopt, ++ MODPREFIX "root=%s name=%s what=%s, fstype=%s, options=%s", ++ root, name, what, fstype, options); + + mount_default_proto = defaults_get_mount_nfs_default_proto(); + vers = NFS_VERS_DEFAULT | NFS_PROTO_DEFAULT; +@@ -203,9 +207,9 @@ int mount_mount(struct autofs_point *ap, + if ((vers & NFS_PROTO_MASK) == 0) + vers |= NFS_PROTO_MASK; + +- debug(ap->logopt, MODPREFIX +- "nfs options=\"%s\", nobind=%d, nosymlink=%d, ro=%d", +- nfsoptions, nobind, nosymlink, ro); ++ mountlog(ap->logopt, MODPREFIX ++ "nfs options=\"%s\", nobind=%d, nosymlink=%d, ro=%d", ++ nfsoptions, nobind, nosymlink, ro); + } + + if (!parse_location(ap->logopt, &hosts, what, flags)) { +@@ -379,17 +383,18 @@ dont_probe: + } + + if (nfsoptions && *nfsoptions) { +- debug(ap->logopt, +- MODPREFIX "calling mount -t %s " SLOPPY +- "-o %s %s %s", fstype, nfsoptions, loc, fullpath); ++ mountlog(ap->logopt, ++ MODPREFIX "calling mount -t %s " SLOPPY ++ "-o %s %s %s", fstype, nfsoptions, loc, ++ fullpath); + + err = spawn_mount(ap->logopt, + "-t", fstype, SLOPPYOPT "-o", + nfsoptions, loc, fullpath, NULL); + } else { +- debug(ap->logopt, +- MODPREFIX "calling mount -t %s %s %s", +- fstype, loc, fullpath); ++ mountlog(ap->logopt, ++ MODPREFIX "calling mount -t %s %s %s", ++ fstype, loc, fullpath); + err = spawn_mount(ap->logopt, + "-t", fstype, loc, fullpath, NULL); + } diff --git a/autofs-5.1.5-make-expire-remaining-log-level-debug.patch b/autofs-5.1.5-make-expire-remaining-log-level-debug.patch new file mode 100644 index 0000000..4d115ea --- /dev/null +++ b/autofs-5.1.5-make-expire-remaining-log-level-debug.patch @@ -0,0 +1,55 @@ +autofs-5.1.5 - make expire remaining log level debug + +From: Ian Kent + +The log message listing the remaining mounts should be log level +debug not info. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 2 +- + daemon/indirect.c | 4 ++-- + 3 files changed, 4 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -50,6 +50,7 @@ xx/xx/2018 autofs-5.1.5 + - add mount_verbose configuration option. + - optionally log mount requestor process info. + - log mount call arguments if mount_verbose is set. ++- make expire remaining log level debug. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -990,7 +990,7 @@ void *expire_proc_direct(void *arg) + pthread_cleanup_pop(1); + + if (left) +- info(ap->logopt, "%d remaining in %s", left, ap->path); ++ debug(ap->logopt, "%d remaining in %s", left, ap->path); + + ec.status = left; + +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -578,7 +578,7 @@ void *expire_proc_indirect(void *arg) + pthread_cleanup_pop(1); + + if (submnts) +- info(ap->logopt, ++ debug(ap->logopt, + "%d submounts remaining in %s", submnts, ap->path); + + /* +@@ -586,7 +586,7 @@ void *expire_proc_indirect(void *arg) + * words) the umounts are done by the time we reach here + */ + if (count) +- info(ap->logopt, "%d remaining in %s", count, ap->path); ++ debug(ap->logopt, "%d remaining in %s", count, ap->path); + + ec.status = left; + diff --git a/autofs-5.1.5-move-unlink_mount_tree-to-lib_mounts_c.patch b/autofs-5.1.5-move-unlink_mount_tree-to-lib_mounts_c.patch new file mode 100644 index 0000000..2773955 --- /dev/null +++ b/autofs-5.1.5-move-unlink_mount_tree-to-lib_mounts_c.patch @@ -0,0 +1,134 @@ +autofs-5.1.5 - move unlink_mount_tree() to lib/mounts.c + +From: Ian Kent + +Both daemon/direct.c and daemon/indirect.c use the same function to +lazy umount a list of mounts, move that function to lib/mounts.c. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 2 -- + daemon/indirect.c | 34 ---------------------------------- + include/mounts.h | 1 + + lib/mounts.c | 35 +++++++++++++++++++++++++++++++++++ + 5 files changed, 37 insertions(+), 36 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -71,6 +71,7 @@ xx/xx/2018 autofs-5.1.5 + - refactor unlink_active_mounts() in direct.c. + - don't use tree_is_mounted() for mounted checks. + - use single unlink_umount_tree() for both direct and indirect mounts. ++- move unlink_mount_tree() to lib/mounts.c. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -49,8 +49,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; + +-int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts); +- + static void key_mnt_params_destroy(void *arg) + { + struct mnt_params *mp; +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -40,40 +40,6 @@ + /* Attribute to create detached thread */ + extern pthread_attr_t th_attr_detached; + +-int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) +-{ +- struct mnt_list *this; +- int rv, ret; +- +- ret = 1; +- this = mnts; +- while (this) { +- if (this->flags & MNTS_AUTOFS) +- rv = umount2(this->mp, MNT_DETACH); +- else +- rv = spawn_umount(ap->logopt, "-l", this->mp, NULL); +- if (rv == -1) { +- debug(ap->logopt, +- "can't unlink %s from mount tree", this->mp); +- +- switch (errno) { +- case EINVAL: +- warn(ap->logopt, +- "bad superblock or not mounted"); +- break; +- +- case ENOENT: +- case EFAULT: +- ret = 0; +- warn(ap->logopt, "bad path for mount"); +- break; +- } +- } +- this = this->next; +- } +- return ret; +-} +- + static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + { + const char *str_indirect = mount_type_str(t_indirect); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -100,6 +100,7 @@ int ext_mount_add(struct list_head *, co + int ext_mount_remove(struct list_head *, const char *); + int ext_mount_inuse(const char *); + struct mnt_list *get_mnt_list(const char *path, int include); ++int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); + void tree_free_mnt_tree(struct mnt_list *tree); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -881,6 +881,41 @@ local_getmntent_r(FILE *tab, struct mnte + return mnt; + } + ++int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) ++{ ++ struct mnt_list *this; ++ int rv, ret; ++ ++ ret = 1; ++ this = mnts; ++ while (this) { ++ if (this->flags & MNTS_AUTOFS) ++ rv = umount2(this->mp, MNT_DETACH); ++ else ++ rv = spawn_umount(ap->logopt, "-l", this->mp, NULL); ++ if (rv == -1) { ++ debug(ap->logopt, ++ "can't unlink %s from mount tree", this->mp); ++ ++ switch (errno) { ++ case EINVAL: ++ warn(ap->logopt, ++ "bad superblock or not mounted"); ++ break; ++ ++ case ENOENT: ++ case EFAULT: ++ ret = 0; ++ warn(ap->logopt, "bad path for mount"); ++ break; ++ } ++ } ++ this = this->next; ++ } ++ ++ return ret; ++} ++ + /* + * Get list of mounts under path in longest->shortest order + */ diff --git a/autofs-5.1.5-optionally-log-mount-requestor-process-info.patch b/autofs-5.1.5-optionally-log-mount-requestor-process-info.patch new file mode 100644 index 0000000..d731970 --- /dev/null +++ b/autofs-5.1.5-optionally-log-mount-requestor-process-info.patch @@ -0,0 +1,155 @@ +autofs-5.1.5 - optionally log mount requestor process info + +From: Lars R. Damerow + +This information can be helpful to determine who or what is making +particular mount requests, especially when used in conjunction with +the use_mount_request_log_id option. + +Signed-off-by: Lars R. Damerow +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 6 ++++++ + daemon/indirect.c | 6 ++++++ + include/log.h | 2 ++ + lib/log.c | 39 +++++++++++++++++++++++++++++++++++++++ + man/autofs.conf.5.in | 3 ++- + redhat/autofs.conf.default.in | 4 +++- + samples/autofs.conf.default.in | 4 +++- + 8 files changed, 62 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -48,6 +48,7 @@ xx/xx/2018 autofs-5.1.5 + - add NULL check for get_addr_string() return. + - use malloc(3) in spawn.c. + - add mount_verbose configuration option. ++- optionally log mount requestor process info. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -1242,6 +1242,12 @@ static void *do_mount_direct(void *arg) + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + ++ if (defaults_get_mount_verbose()) { ++ pid_t ppid = log_pidinfo(ap, mt.pid, "requestor"); ++ if (ppid > 0) ++ log_pidinfo(ap, ppid, "parent"); ++ } ++ + status = fstat(mt.ioctlfd, &st); + if (status == -1) { + error(ap->logopt, +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -758,6 +758,12 @@ static void *do_mount_indirect(void *arg + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + ++ if (defaults_get_mount_verbose()) { ++ pid_t ppid = log_pidinfo(ap, mt.pid, "requestor"); ++ if (ppid > 0) ++ log_pidinfo(ap, ppid, "parent"); ++ } ++ + len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len); + if (!len) { + crit(ap->logopt, "path to be mounted is to long"); +--- autofs-5.1.4.orig/include/log.h ++++ autofs-5.1.4/include/log.h +@@ -46,6 +46,8 @@ extern void log_crit(unsigned, const cha + extern void log_debug(unsigned int, const char* msg, ...); + extern void logmsg(const char* msg, ...); + ++extern pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label); ++ + #define debug(opt, msg, args...) \ + do { log_debug(opt, "%s: " msg, __FUNCTION__, ##args); } while (0) + +--- autofs-5.1.4.orig/lib/log.c ++++ autofs-5.1.4/lib/log.c +@@ -325,3 +325,42 @@ void log_to_stderr(void) + + return; + } ++ ++pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label) { ++ char buf[PATH_MAX + 1] = ""; ++ FILE *statfile; ++ ++ pid_t tgid, ppid; ++ int uid, euid, gid, egid; ++ char comm[64] = ""; ++ ++ sprintf(buf, "/proc/%d/status", pid); ++ statfile = fopen(buf, "r"); ++ if (statfile == NULL) { ++ info(ap->logopt, "pidinfo %s: failed to open %s", label, buf); ++ return -1; ++ } ++ ++ while (fgets(buf, sizeof(buf), statfile) != NULL) { ++ if (strncmp(buf, "Name:", 5) == 0) { ++ sscanf(buf, "Name:\t%s", (char *) &comm); ++ } else if (strncmp(buf, "Tgid:", 5) == 0) { ++ sscanf(buf, "Tgid:\t%d", (int *) &tgid); ++ } else if (strncmp(buf, "PPid:", 5) == 0) { ++ sscanf(buf, "PPid:\t%d", (int *) &ppid); ++ } else if (strncmp(buf, "Uid:", 4) == 0) { ++ sscanf(buf, ++ "Uid:\t%d\t%d", (int *) &uid, (int *) &euid); ++ } else if (strncmp(buf, "Gid:", 4) == 0) { ++ sscanf(buf, ++ "Gid:\t%d\t%d", (int *) &gid, (int *) &egid); ++ } ++ } ++ fclose(statfile); ++ ++ info(ap->logopt, ++ "pidinfo %s: pid:%d comm:%s tgid:%d uid:%d euid:%d gid:%d egid:%d", ++ label, pid, comm, tgid, uid, euid, gid, egid); ++ ++ return ppid; ++} +--- autofs-5.1.4.orig/man/autofs.conf.5.in ++++ autofs-5.1.4/man/autofs.conf.5.in +@@ -43,7 +43,8 @@ setting. + .TP + .B mount_verbose + .br +-Use the verbose flag when spawning mount(8) (program default "no"). ++Use the verbose flag when spawning mount(8), and log some process info ++about the requestor and its parent (program default "no"). + .TP + .B mount_wait + .br +--- autofs-5.1.4.orig/redhat/autofs.conf.default.in ++++ autofs-5.1.4/redhat/autofs.conf.default.in +@@ -26,7 +26,9 @@ timeout = 300 + # + #negative_timeout = 60 + # +-# mount_verbose - use the -v flag when calling mount(8). ++# mount_verbose - use the -v flag when calling mount(8) and log some ++# process information about the requestor and its ++# parent. + # + #mount_verbose = no + # +--- autofs-5.1.4.orig/samples/autofs.conf.default.in ++++ autofs-5.1.4/samples/autofs.conf.default.in +@@ -26,7 +26,9 @@ timeout = 300 + # + #negative_timeout = 60 + # +-# mount_verbose - use the -v flag when calling mount(8). ++# mount_verbose - use the -v flag when calling mount(8) and log some ++# process information about the requestor and its ++# parent. + # + #mount_verbose = no + # diff --git a/autofs-5.1.5-refactor-unlink_active_mounts-in-direct_c.patch b/autofs-5.1.5-refactor-unlink_active_mounts-in-direct_c.patch new file mode 100644 index 0000000..754281e --- /dev/null +++ b/autofs-5.1.5-refactor-unlink_active_mounts-in-direct_c.patch @@ -0,0 +1,116 @@ +autofs-5.1.5 - refactor unlink_active_mounts() in direct_c + +From: Ian Kent + +In daemon/direct.c:unlink_active_mounts() the tree_get_mnt_list() call +returns 1 for a non-empty list which amounts to a mounted check and then +handles the case where the map is being read. + +But the check that's carried out is to distinguish between a readmap +and a mount activity which should be handled by the caller instead of +burying the check away in the unlink_active_mounts() function. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 63 +++++++++++++++++++++++++++----------------------------- + 2 files changed, 32 insertions(+), 32 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -68,6 +68,7 @@ xx/xx/2018 autofs-5.1.5 + - always use PROC_MOUNTS to make mount lists. + - add glibc getmntent_r(). + - use local getmntent_r in table_is_mounted(). ++- refactor unlink_active_mounts() in direct.c. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -298,37 +298,12 @@ static int unlink_mount_tree(struct auto + + static int unlink_active_mounts(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) + { +- struct ioctl_ops *ops = get_ioctl_ops(); + struct list_head list; + + INIT_LIST_HEAD(&list); + +- if (tree_get_mnt_list(mnts, &list, me->key, 1)) { +- if (ap->state == ST_READMAP) { +- time_t tout = get_exp_timeout(ap, me->source); +- int save_ioctlfd, ioctlfd; +- +- save_ioctlfd = ioctlfd = me->ioctlfd; +- +- if (ioctlfd == -1) +- ops->open(ap->logopt, +- &ioctlfd, me->dev, me->key); +- +- if (ioctlfd < 0) { +- error(ap->logopt, +- "failed to create ioctl fd for %s", +- me->key); +- return 0; +- } +- +- ops->timeout(ap->logopt, ioctlfd, tout); +- +- if (save_ioctlfd == -1) +- ops->close(ap->logopt, ioctlfd); +- +- return 0; +- } +- } ++ if (!tree_get_mnt_list(mnts, &list, me->key, 1)) ++ return 1; + + if (!unlink_mount_tree(ap, &list)) { + debug(ap->logopt, +@@ -371,16 +346,40 @@ int do_mount_autofs_direct(struct autofs + if (ret == 0) + return -1; + } else { ++ if (ap->state == ST_READMAP && is_mounted(me->key, MNTS_ALL)) { ++ time_t tout = get_exp_timeout(ap, me->source); ++ int save_ioctlfd, ioctlfd; ++ ++ save_ioctlfd = ioctlfd = me->ioctlfd; ++ ++ if (ioctlfd == -1) ++ ops->open(ap->logopt, ++ &ioctlfd, me->dev, me->key); ++ ++ if (ioctlfd < 0) { ++ error(ap->logopt, ++ "failed to create ioctl fd for %s", ++ me->key); ++ return 0; ++ } ++ ++ ops->timeout(ap->logopt, ioctlfd, tout); ++ ++ if (save_ioctlfd == -1) ++ ops->close(ap->logopt, ioctlfd); ++ ++ return 0; ++ } ++ + /* +- * A return of 0 indicates we're re-reading the map. + * A return of 1 indicates we successfully unlinked +- * the mount tree if there was one. A return of -1 +- * inducates we failed to unlink the mount tree so ++ * the mount tree if there was one. A return of 0 ++ * indicates we failed to unlink the mount tree so + * we have to return a failure. + */ + ret = unlink_active_mounts(ap, mnts, me); +- if (ret == -1 || ret == 0) +- return ret; ++ if (!ret) ++ return -1; + + if (me->ioctlfd != -1) { + error(ap->logopt, "active direct mount %s", me->key); diff --git a/autofs-5.1.5-remove-a-couple-of-old-debug-messages.patch b/autofs-5.1.5-remove-a-couple-of-old-debug-messages.patch new file mode 100644 index 0000000..46b3ae5 --- /dev/null +++ b/autofs-5.1.5-remove-a-couple-of-old-debug-messages.patch @@ -0,0 +1,38 @@ +autofs-5.1.5 - remove a couple of old debug messages + +From: Ian Kent + +Remove a couple of debug log messages from lookup_ghost(). +These messages have not shown a problem here and should be +removed. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 5 ----- + 2 files changed, 1 insertion(+), 5 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -57,6 +57,7 @@ xx/xx/2018 autofs-5.1.5 + - change expire type naming to better reflect usage. + - remove unused function has_fstab_option(). + - remove unused function reverse_mnt_list(). ++- remove a couple of old debug messages. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -793,11 +793,6 @@ int lookup_ghost(struct autofs_point *ap + + /* Directory already exists? */ + if (!ret) { +- /* Shouldn't need this +- me->dev = st.st_dev; +- me->ino = st.st_ino; +- */ +- debug(ap->logopt, "me->dev %d me->ino %d", me->dev, me->ino); + free(fullpath); + goto next; + } diff --git a/autofs-5.1.5-remove-unused-function-has_fstab_option.patch b/autofs-5.1.5-remove-unused-function-has_fstab_option.patch new file mode 100644 index 0000000..33c1274 --- /dev/null +++ b/autofs-5.1.5-remove-unused-function-has_fstab_option.patch @@ -0,0 +1,71 @@ +autofs-5.1.5 - remove unused function has_fstab_option() + +From: Ian Kent + +This function is not used, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 1 - + lib/mounts.c | 29 ----------------------------- + 3 files changed, 1 insertion(+), 30 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -55,6 +55,7 @@ xx/xx/2018 autofs-5.1.5 + - fix macro expansion in selector values. + - also use strictexpire for offsets. + - change expire type naming to better reflect usage. ++- remove unused function has_fstab_option(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -103,7 +103,6 @@ struct mnt_list *get_mnt_list(const char + struct mnt_list *reverse_mnt_list(struct mnt_list *list); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *table, const char *path, unsigned int type); +-int has_fstab_option(const char *opt); + 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); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1026,35 +1026,6 @@ int is_mounted(const char *table, const + return table_is_mounted(table, path, type); + } + +-int has_fstab_option(const char *opt) +-{ +- struct mntent *mnt; +- struct mntent mnt_wrk; +- char buf[PATH_MAX * 3]; +- FILE *tab; +- int ret = 0; +- +- if (!opt) +- return 0; +- +- tab = open_setmntent_r(_PATH_MNTTAB); +- if (!tab) { +- char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("setmntent: %s", estr); +- return 0; +- } +- +- while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { +- if (hasmntopt(mnt, opt)) { +- ret = 1; +- break; +- } +- } +- endmntent(tab); +- +- return ret; +-} +- + /* + * Since we have to look at the entire mount tree for direct + * mounts (all mounts under "/") and we may have a large number diff --git a/autofs-5.1.5-remove-unused-function-reverse_mnt_list.patch b/autofs-5.1.5-remove-unused-function-reverse_mnt_list.patch new file mode 100644 index 0000000..f166c1d --- /dev/null +++ b/autofs-5.1.5-remove-unused-function-reverse_mnt_list.patch @@ -0,0 +1,63 @@ +autofs-5.1.5 - remove unused function reverse_mnt_list() + +From: Ian Kent + +This function is not used, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 1 - + lib/mounts.c | 21 --------------------- + 3 files changed, 1 insertion(+), 22 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -56,6 +56,7 @@ xx/xx/2018 autofs-5.1.5 + - also use strictexpire for offsets. + - change expire type naming to better reflect usage. + - remove unused function has_fstab_option(). ++- remove unused function reverse_mnt_list(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -100,7 +100,6 @@ int ext_mount_add(struct list_head *, co + int ext_mount_remove(struct list_head *, const char *); + int ext_mount_inuse(const char *); + 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 is_mounted(const char *table, const char *path, unsigned int type); + void tree_free_mnt_tree(struct mnt_list *tree); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -894,27 +894,6 @@ struct mnt_list *get_mnt_list(const char + return list; + } + +-/* +- * Reverse a list of mounts +- */ +-struct mnt_list *reverse_mnt_list(struct mnt_list *list) +-{ +- struct mnt_list *next, *last; +- +- if (!list) +- return NULL; +- +- next = list; +- last = NULL; +- while (next) { +- struct mnt_list *this = next; +- next = this->next; +- this->next = last; +- last = this; +- } +- return last; +-} +- + void free_mnt_list(struct mnt_list *list) + { + struct mnt_list *next; diff --git a/autofs-5.1.5-use-bit-flags-for-autofs-mount-types-in-mnt_list.patch b/autofs-5.1.5-use-bit-flags-for-autofs-mount-types-in-mnt_list.patch new file mode 100644 index 0000000..a8733ac --- /dev/null +++ b/autofs-5.1.5-use-bit-flags-for-autofs-mount-types-in-mnt_list.patch @@ -0,0 +1,279 @@ +autofs-5.1.5 - use bit flags for autofs mount types in mnt_list + +From: Ian Kent + +Several fields in struct mnt_list don't need to be saved as strings +so change to using bit flags for them instead. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 10 ++--- + daemon/indirect.c | 16 ++++---- + include/mounts.h | 7 ++- + lib/mounts.c | 97 +++++++++++------------------------------------------- + 5 files changed, 38 insertions(+), 93 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -63,6 +63,7 @@ xx/xx/2018 autofs-5.1.5 + - add ignore mount option. + - use ignore option for offset mounts as well. + - add config option for "ignore" mount option ++- use bit flags for autofs mount types in mnt_list. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -271,10 +271,10 @@ static int unlink_mount_tree(struct auto + + mnt = list_entry(p, struct mnt_list, list); + +- if (strcmp(mnt->fs_type, "autofs")) +- rv = spawn_umount(ap->logopt, "-l", mnt->path, NULL); +- else ++ if (mnt->flags & MNTS_AUTOFS) + rv = umount2(mnt->path, MNT_DETACH); ++ else ++ rv = spawn_umount(ap->logopt, "-l", mnt->path, NULL); + if (rv == -1) { + debug(ap->logopt, + "can't unlink %s from mount tree", mnt->path); +@@ -925,7 +925,7 @@ void *expire_proc_direct(void *arg) + if (!me) + continue; + +- if (!strcmp(next->fs_type, "autofs")) { ++ if (next->flags & MNTS_AUTOFS) { + struct stat st; + int ioctlfd; + +@@ -936,7 +936,7 @@ void *expire_proc_direct(void *arg) + * one of them and pass on state change. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- if (strstr(next->opts, "indirect")) { ++ if (next->flags & MNTS_INDIRECT) { + master_notify_submount(ap, next->path, ap->state); + pthread_setcancelstate(cur_state, NULL); + continue; +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -48,10 +48,10 @@ static int unlink_mount_tree(struct auto + ret = 1; + this = mnts; + while (this) { +- if (strcmp(this->fs_type, "autofs")) +- rv = spawn_umount(ap->logopt, "-l", this->path, NULL); +- else ++ if (this->flags & MNTS_AUTOFS) + rv = umount2(this->path, MNT_DETACH); ++ else ++ rv = spawn_umount(ap->logopt, "-l", this->path, NULL); + if (rv == -1) { + debug(ap->logopt, + "can't unlink %s from mount tree", this->path); +@@ -439,15 +439,15 @@ void *expire_proc_indirect(void *arg) + char *ind_key; + int ret; + +- if (!strcmp(next->fs_type, "autofs")) { ++ if (next->flags & MNTS_AUTOFS) { + /* + * If we have submounts check if this path lives below + * one of them and pass on the state change. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- if (strstr(next->opts, "indirect")) ++ if (next->flags & MNTS_INDIRECT) + master_notify_submount(ap, next->path, ap->state); +- else if (strstr(next->opts, "offset")) { ++ else if (next->flags & MNTS_OFFSET) { + struct map_source *map; + struct mapent_cache *mc = NULL; + struct mapent *me = NULL; +@@ -567,10 +567,10 @@ void *expire_proc_indirect(void *arg) + pthread_cleanup_push(mnts_cleanup, mnts); + /* Are there any real mounts left */ + for (next = mnts; next; next = next->next) { +- if (strcmp(next->fs_type, "autofs")) ++ if (!(next->flags & MNTS_AUTOFS)) + count++; + else { +- if (strstr(next->opts, "indirect")) ++ if (next->flags & MNTS_INDIRECT) + submnts++; + else + offsets++; +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -35,6 +35,9 @@ + #define MNTS_ALL 0x0001 + #define MNTS_REAL 0x0002 + #define MNTS_AUTOFS 0x0004 ++#define MNTS_INDIRECT 0x0008 ++#define MNTS_DIRECT 0x0010 ++#define MNTS_OFFSET 0x0020 + + #define REMOUNT_SUCCESS 0x0000 + #define REMOUNT_FAIL 0x0001 +@@ -50,9 +53,7 @@ struct mapent; + + struct mnt_list { + char *path; +- char *fs_name; +- char *fs_type; +- char *opts; ++ unsigned int flags; + /* + * List operations ie. get_mnt_list. + */ +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -855,29 +855,17 @@ struct mnt_list *get_mnt_list(const char + } + strcpy(ent->path, mnt->mnt_dir); + +- ent->fs_name = malloc(strlen(mnt->mnt_fsname) + 1); +- if (!ent->fs_name) { +- endmntent(tab); +- free_mnt_list(list); +- return NULL; +- } +- strcpy(ent->fs_name, mnt->mnt_fsname); ++ if (!strcmp(mnt->mnt_type, "autofs")) ++ ent->flags |= MNTS_AUTOFS; + +- ent->fs_type = malloc(strlen(mnt->mnt_type) + 1); +- if (!ent->fs_type) { +- endmntent(tab); +- free_mnt_list(list); +- return NULL; +- } +- strcpy(ent->fs_type, mnt->mnt_type); +- +- ent->opts = malloc(strlen(mnt->mnt_opts) + 1); +- if (!ent->opts) { +- endmntent(tab); +- free_mnt_list(list); +- return NULL; ++ if (ent->flags & MNTS_AUTOFS) { ++ if (strstr(mnt->mnt_opts, "indirect")) ++ ent->flags |= MNTS_INDIRECT; ++ else if (strstr(mnt->mnt_opts, "direct")) ++ ent->flags |= MNTS_DIRECT; ++ else if (strstr(mnt->mnt_opts, "offset")) ++ ent->flags |= MNTS_OFFSET; + } +- strcpy(ent->opts, mnt->mnt_opts); + } + endmntent(tab); + +@@ -900,15 +888,6 @@ void free_mnt_list(struct mnt_list *list + if (this->path) + free(this->path); + +- if (this->fs_name) +- free(this->fs_name); +- +- if (this->fs_type) +- free(this->fs_type); +- +- if (this->opts) +- free(this->opts); +- + free(this); + } + } +@@ -1028,22 +1007,11 @@ void tree_free_mnt_tree(struct mnt_list + list_del(&this->self); + + free(this->path); +- free(this->fs_name); +- free(this->fs_type); +- +- if (this->opts) +- free(this->opts); + + free(this); + } + + free(tree->path); +- free(tree->fs_name); +- free(tree->fs_type); +- +- if (tree->opts) +- free(tree->opts); +- + free(tree); + } + +@@ -1103,38 +1071,17 @@ struct mnt_list *tree_make_mnt_tree(cons + } + strcpy(ent->path, mnt->mnt_dir); + +- ent->fs_name = malloc(strlen(mnt->mnt_fsname) + 1); +- if (!ent->fs_name) { +- free(ent->path); +- free(ent); +- endmntent(tab); +- tree_free_mnt_tree(tree); +- return NULL; +- } +- strcpy(ent->fs_name, mnt->mnt_fsname); +- +- ent->fs_type = malloc(strlen(mnt->mnt_type) + 1); +- if (!ent->fs_type) { +- free(ent->fs_name); +- free(ent->path); +- free(ent); +- endmntent(tab); +- tree_free_mnt_tree(tree); +- return NULL; +- } +- strcpy(ent->fs_type, mnt->mnt_type); ++ if (!strcmp(mnt->mnt_type, "autofs")) ++ ent->flags |= MNTS_AUTOFS; + +- ent->opts = malloc(strlen(mnt->mnt_opts) + 1); +- if (!ent->opts) { +- free(ent->fs_type); +- free(ent->fs_name); +- free(ent->path); +- free(ent); +- endmntent(tab); +- tree_free_mnt_tree(tree); +- return NULL; ++ if (ent->flags & MNTS_AUTOFS) { ++ if (strstr(mnt->mnt_opts, "indirect")) ++ ent->flags |= MNTS_INDIRECT; ++ else if (strstr(mnt->mnt_opts, "direct")) ++ ent->flags |= MNTS_DIRECT; ++ else if (strstr(mnt->mnt_opts, "offset")) ++ ent->flags |= MNTS_OFFSET; + } +- strcpy(ent->opts, mnt->mnt_opts); + + mptr = tree; + while (mptr) { +@@ -1347,17 +1294,13 @@ int tree_is_mounted(struct mnt_list *mnt + mptr = list_entry(p, struct mnt_list, entries); + + if (type) { +- unsigned int autofs_fs; +- +- autofs_fs = !strcmp(mptr->fs_type, "autofs"); +- + if (type & MNTS_REAL) { +- if (!autofs_fs) { ++ if (mptr->flags & MNTS_AUTOFS) { + mounted = 1; + break; + } + } else if (type & MNTS_AUTOFS) { +- if (autofs_fs) { ++ if (mptr->flags & MNTS_AUTOFS) { + mounted = 1; + break; + } diff --git a/autofs-5.1.5-use-ignore-option-for-offset-mounts-as-well.patch b/autofs-5.1.5-use-ignore-option-for-offset-mounts-as-well.patch new file mode 100644 index 0000000..797942f --- /dev/null +++ b/autofs-5.1.5-use-ignore-option-for-offset-mounts-as-well.patch @@ -0,0 +1,44 @@ +autofs-5.1.5 - use ignore option for offset mounts as well + +From: Ian Kent + +The pseudo option "ignore" (that's used as a hint that applications +should ignore this mount when reporting a list of mounts) has been +added to direct and indirect mounts but hasn't been added to offset +mounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -61,6 +61,7 @@ xx/xx/2018 autofs-5.1.5 + - fix amd entry memory leak. + - fix unlink_mount_tree() not umounting mounts. + - add ignore mount option. ++- use ignore option for offset mounts as well. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -756,6 +756,16 @@ int mount_autofs_offset(struct autofs_po + mp->options = tmp; + } + } ++ ++ if ((ap->flags & MOUNT_FLAG_IGNORE) && ++ ((get_kver_major() == 5 && get_kver_minor() > 4) || ++ (get_kver_major() > 5))) { ++ char *tmp = realloc(mp->options, strlen(mp->options) + 7); ++ if (tmp) { ++ strcat(tmp, ",ignore"); ++ mp->options = tmp; ++ } ++ } + } + + strcpy(mountpoint, root); diff --git a/autofs-5.1.5-use-local-getmntent_r-in-get_mnt_list.patch b/autofs-5.1.5-use-local-getmntent_r-in-get_mnt_list.patch new file mode 100644 index 0000000..d788772 --- /dev/null +++ b/autofs-5.1.5-use-local-getmntent_r-in-get_mnt_list.patch @@ -0,0 +1,53 @@ +autofs-5.1.5 - use local getmntent_r() in get_mnt_list() + +From: Ian Kent + +Change get_mnt_list() to use the local getmntent_r() instead of +the glibc version so that if glibc is changed to support the +autofs "ignore" hint automount(8) won't be affected. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -73,6 +73,7 @@ xx/xx/2018 autofs-5.1.5 + - use single unlink_umount_tree() for both direct and indirect mounts. + - move unlink_mount_tree() to lib/mounts.c. + - use local_getmntent_r() for unlink_mount_tree(). ++- use local getmntent_r() in get_mnt_list(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -956,14 +956,14 @@ struct mnt_list *get_mnt_list(const char + if (!path || !pathlen || pathlen > PATH_MAX) + return NULL; + +- tab = open_setmntent_r(_PROC_MOUNTS); ++ tab = open_fopen_r(_PROC_MOUNTS); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("setmntent: %s", estr); ++ logerr("fopen: %s", estr); + return NULL; + } + +- while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { ++ while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { + len = strlen(mnt->mnt_dir); + + if ((!include && len <= pathlen) || +@@ -1020,7 +1020,7 @@ struct mnt_list *get_mnt_list(const char + ent->flags |= MNTS_OFFSET; + } + } +- endmntent(tab); ++ fclose(tab); + + return list; + } diff --git a/autofs-5.1.5-use-local-getmntent_r-in-table_is_mounted.patch b/autofs-5.1.5-use-local-getmntent_r-in-table_is_mounted.patch new file mode 100644 index 0000000..d22303e --- /dev/null +++ b/autofs-5.1.5-use-local-getmntent_r-in-table_is_mounted.patch @@ -0,0 +1,53 @@ +autofs-5.1.5 - use local getmntent_r in table_is_mounted() + +From: Ian Kent + +Use the local_getmntent_r() funtion copied from glibc in the function +table_is_mounted() so that if glibc is changed to support the autofs +"ignore" hint automount(8) won't be affected. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -67,6 +67,7 @@ xx/xx/2018 autofs-5.1.5 + - use mp instead of path in mnt_list entries. + - always use PROC_MOUNTS to make mount lists. + - add glibc getmntent_r(). ++- use local getmntent_r in table_is_mounted(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -999,14 +999,14 @@ static int table_is_mounted(const char * + if (!mp || !mp_len || mp_len >= PATH_MAX) + return 0; + +- tab = open_setmntent_r(_PROC_MOUNTS); ++ tab = open_fopen_r(_PROC_MOUNTS); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("setmntent: %s", estr); ++ logerr("fopen: %s", estr); + return 0; + } + +- while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { ++ while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { + size_t len = strlen(mnt->mnt_dir); + + if (type) { +@@ -1028,7 +1028,7 @@ static int table_is_mounted(const char * + break; + } + } +- endmntent(tab); ++ fclose(tab); + + return ret; + } diff --git a/autofs-5.1.5-use-local-getmntent_r-in-tree_get_mnt_list.patch b/autofs-5.1.5-use-local-getmntent_r-in-tree_get_mnt_list.patch new file mode 100644 index 0000000..e4ca35a --- /dev/null +++ b/autofs-5.1.5-use-local-getmntent_r-in-tree_get_mnt_list.patch @@ -0,0 +1,55 @@ +autofs-5.1.5 - use local getmntent_r() in tree_make_mnt_list() + +From: Ian Kent + +Change tree_make_mnt_list() to use the local getmntent_r() instead of +the glibc version so that if glibc is changed to support the autofs +"ignore" hint automount(8) won't be affected. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -74,6 +74,7 @@ xx/xx/2018 autofs-5.1.5 + - move unlink_mount_tree() to lib/mounts.c. + - use local_getmntent_r() for unlink_mount_tree(). + - use local getmntent_r() in get_mnt_list(). ++- use local getmntent_r() in tree_make_mnt_list(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1182,16 +1182,16 @@ struct mnt_list *tree_make_mnt_tree(cons + size_t plen; + int eq; + +- tab = open_setmntent_r(_PROC_MOUNTS); ++ tab = open_fopen_r(_PROC_MOUNTS); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("setmntent: %s", estr); ++ logerr("fopen: %s", estr); + return NULL; + } + + plen = strlen(path); + +- while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { ++ while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { + size_t len = strlen(mnt->mnt_dir); + + /* Not matching path */ +@@ -1283,7 +1283,7 @@ struct mnt_list *tree_make_mnt_tree(cons + if (!tree) + tree = ent; + } +- endmntent(tab); ++ fclose(tab); + + return tree; + } diff --git a/autofs-5.1.5-use-local_getmntent_r-for-unlink_mount_tree.patch b/autofs-5.1.5-use-local_getmntent_r-for-unlink_mount_tree.patch new file mode 100644 index 0000000..a774539 --- /dev/null +++ b/autofs-5.1.5-use-local_getmntent_r-for-unlink_mount_tree.patch @@ -0,0 +1,179 @@ +autofs-5.1.5 - use local_getmntent_r() for unlink_mount_tree() + +From: Ian Kent + +Now that unlink_mount_tree() is located in a single location and +only one function is used for this, change it to use our local +getmntent_r() function so that if glibc is changed to support the +autofs "ignore" hint automount(8) won't be affected. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 24 ++++++------------------ + daemon/indirect.c | 17 ++++++----------- + include/mounts.h | 2 +- + lib/mounts.c | 45 ++++++++++++++++++++++++++++++++++----------- + 5 files changed, 48 insertions(+), 41 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -72,6 +72,7 @@ xx/xx/2018 autofs-5.1.5 + - don't use tree_is_mounted() for mounted checks. + - use single unlink_umount_tree() for both direct and indirect mounts. + - move unlink_mount_tree() to lib/mounts.c. ++- use local_getmntent_r() for unlink_mount_tree(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -286,8 +286,6 @@ int do_mount_autofs_direct(struct autofs + if (ret == 0) + return -1; + } else { +- struct mnt_list *mnts; +- + if (ap->state == ST_READMAP && is_mounted(me->key, MNTS_ALL)) { + time_t tout = get_exp_timeout(ap, me->source); + int save_ioctlfd, ioctlfd; +@@ -313,22 +311,12 @@ int do_mount_autofs_direct(struct autofs + return 0; + } + +- mnts = get_mnt_list(me->key, 1); +- if (mnts) { +- /* +- * A return of 1 indicates we successfully unlinked +- * the mount tree if there was one. A return of 0 +- * indicates we failed to unlink the mount tree so +- * we have to return a failure. +- */ +- ret = unlink_mount_tree(ap, mnts); +- free_mnt_list(mnts); +- if (!ret) { +- error(ap->logopt, +- "already mounted as other than autofs " +- "or failed to unlink entry in tree"); +- return -1; +- } ++ ret = unlink_mount_tree(ap, ap->path); ++ if (!ret) { ++ error(ap->logopt, ++ "already mounted as other than autofs " ++ "or failed to unlink entry in tree"); ++ goto out_err; + } + + if (me->ioctlfd != -1) { +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -50,7 +50,6 @@ static int do_mount_autofs_indirect(stru + const char *map_name = hosts_map_name; + const char *type; + struct stat st; +- struct mnt_list *mnts; + int ret; + int err; + +@@ -70,16 +69,12 @@ static int do_mount_autofs_indirect(stru + if (ret == 0) + return -1; + } else { +- mnts = get_mnt_list(ap->path, 1); +- if (mnts) { +- ret = unlink_mount_tree(ap, mnts); +- free_mnt_list(mnts); +- if (!ret) { +- error(ap->logopt, +- "already mounted as other than autofs " +- "or failed to unlink entry in tree"); +- goto out_err; +- } ++ ret = unlink_mount_tree(ap, ap->path); ++ if (!ret) { ++ error(ap->logopt, ++ "already mounted as other than autofs " ++ "or failed to unlink entry in tree"); ++ goto out_err; + } + } + +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -100,7 +100,7 @@ int ext_mount_add(struct list_head *, co + int ext_mount_remove(struct list_head *, const char *); + int ext_mount_inuse(const char *); + struct mnt_list *get_mnt_list(const char *path, int include); +-int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts); ++int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); + void tree_free_mnt_tree(struct mnt_list *tree); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -881,21 +881,44 @@ local_getmntent_r(FILE *tab, struct mnte + return mnt; + } + +-int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) ++int unlink_mount_tree(struct autofs_point *ap, const char *mp) + { +- struct mnt_list *this; +- int rv, ret; ++ FILE *tab; ++ struct mntent *mnt; ++ struct mntent mnt_wrk; ++ char buf[PATH_MAX * 3]; ++ unsigned int mp_len = strlen(mp); ++ int rv, ret = 1; + +- ret = 1; +- this = mnts; +- while (this) { +- if (this->flags & MNTS_AUTOFS) +- rv = umount2(this->mp, MNT_DETACH); ++ tab = open_fopen_r(_PROC_MOUNTS); ++ if (!tab) { ++ char *estr = strerror_r(errno, buf, PATH_MAX - 1); ++ logerr("fopen: %s", estr); ++ return 0; ++ } ++ ++ while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { ++ unsigned int mnt_dir_len; ++ int is_autofs; ++ ++ if (strncmp(mnt->mnt_dir, mp, mp_len)) ++ continue; ++ ++ mnt_dir_len = strlen(mnt->mnt_dir); ++ is_autofs = !strcmp(mnt->mnt_type, "autofs"); ++ ++ if (mnt_dir_len == mp_len && !is_autofs) { ++ ret = 0; ++ break; ++ } ++ ++ if (is_autofs) ++ rv = umount2(mnt->mnt_dir, MNT_DETACH); + else +- rv = spawn_umount(ap->logopt, "-l", this->mp, NULL); ++ rv = spawn_umount(ap->logopt, "-l", mnt->mnt_dir, NULL); + if (rv == -1) { + debug(ap->logopt, +- "can't unlink %s from mount tree", this->mp); ++ "can't unlink %s from mount tree", mnt->mnt_dir); + + switch (errno) { + case EINVAL: +@@ -910,8 +933,8 @@ int unlink_mount_tree(struct autofs_poin + break; + } + } +- this = this->next; + } ++ fclose(tab); + + return ret; + } diff --git a/autofs-5.1.5-use-malloc-in-spawn_c.patch b/autofs-5.1.5-use-malloc-in-spawn_c.patch new file mode 100644 index 0000000..72634af --- /dev/null +++ b/autofs-5.1.5-use-malloc-in-spawn_c.patch @@ -0,0 +1,161 @@ +autofs-5.1.5 - use malloc(3) in spawn.c + +From: Ian Kent + +Use malloc(3) in spawn.c functions instead of alloca(3) as a failure +return for this function is undefined. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/spawn.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 45 insertions(+), 6 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -46,6 +46,7 @@ xx/xx/2018 autofs-5.1.5 + - add systemd service command line option. + - support strictexpire mount option. + - add NULL check for get_addr_string() return. ++- use malloc(3) in spawn.c. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/spawn.c ++++ autofs-5.1.4/daemon/spawn.c +@@ -521,22 +521,33 @@ int spawnv(unsigned logopt, const char * + int spawnl(unsigned logopt, const char *prog, ...) + { + va_list arg; +- int argc; ++ int argc, ret; + char **argv, **p; ++ unsigned int argv_len; + + va_start(arg, prog); + for (argc = 1; va_arg(arg, char *); argc++); + va_end(arg); + +- if (!(argv = alloca(sizeof(char *) * argc))) ++ argv_len = sizeof(char *) * (argc + 1); ++ argv = malloc(argv_len); ++ if (!argv) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ crit(logopt, "malloc: %s", estr); + return -1; ++ } ++ memset(argv, 0, argv_len); + + va_start(arg, prog); + p = argv; + while ((*p++ = va_arg(arg, char *))); + va_end(arg); + +- return do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, (const char **) argv); ++ ret = do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, (const char **) argv); ++ free(argv); ++ ++ return ret; + } + + int spawn_mount(unsigned logopt, ...) +@@ -554,6 +565,7 @@ int spawn_mount(unsigned logopt, ...) + int update_mtab = 1, ret, printed = 0; + unsigned int wait = defaults_get_mount_wait(); + char buf[PATH_MAX + 1]; ++ unsigned int argv_len; + + /* If we use mount locking we can't validate the location */ + #ifdef ENABLE_MOUNT_LOCKING +@@ -579,8 +591,15 @@ int spawn_mount(unsigned logopt, ...) + } + + /* Alloc 1 extra slot in case we need to use the "-f" option */ +- if (!(argv = alloca(sizeof(char *) * (argc + 2)))) ++ argv_len = sizeof(char *) * (argc + 2); ++ argv = malloc(argv_len); ++ if (!argv) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ crit(logopt, "malloc: %s", estr); + return -1; ++ } ++ memset(argv, 0, argv_len); + + argv[0] = arg0; + +@@ -655,6 +674,7 @@ int spawn_mount(unsigned logopt, ...) + umount(argv[argc]); + ret = MNT_FORCE_FAIL; + } ++ free(argv); + + return ret; + } +@@ -683,6 +703,7 @@ int spawn_bind_mount(unsigned logopt, .. + int update_mtab = 1, ret, printed = 0; + unsigned int wait = defaults_get_mount_wait(); + char buf[PATH_MAX + 1]; ++ unsigned int argv_len; + + /* If we use mount locking we can't validate the location */ + #ifdef ENABLE_MOUNT_LOCKING +@@ -711,8 +732,15 @@ int spawn_bind_mount(unsigned logopt, .. + } + } + +- if (!(argv = alloca(sizeof(char *) * (argc + 2)))) ++ argv_len = sizeof(char *) * (argc + 2); ++ argv = malloc(argv_len); ++ if (!argv) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ crit(logopt, "malloc: %s", estr); + return -1; ++ } ++ memset(argv, 0, argv_len); + + argv[0] = arg0; + argv[1] = bind; +@@ -774,6 +802,7 @@ int spawn_bind_mount(unsigned logopt, .. + umount(argv[argc]); + ret = MNT_FORCE_FAIL; + } ++ free(argv); + + return ret; + } +@@ -796,6 +825,7 @@ int spawn_umount(unsigned logopt, ...) + int update_mtab = 1, ret, printed = 0; + unsigned int wait = defaults_get_umount_wait(); + char buf[PATH_MAX + 1]; ++ unsigned int argv_len; + + #ifdef ENABLE_MOUNT_LOCKING + options = SPAWN_OPT_LOCK; +@@ -821,8 +851,15 @@ int spawn_umount(unsigned logopt, ...) + if (arg_c) + argc++;; + +- if (!(argv = alloca(sizeof(char *) * (argc + 1)))) ++ argv_len = sizeof(char *) * (argc + 1); ++ argv = malloc(argv_len); ++ if (!argv) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ crit(logopt, "malloc: %s", estr); + return -1; ++ } ++ memset(argv, 0, argv_len); + + p = argv; + *p++ = arg0; +@@ -870,6 +907,7 @@ int spawn_umount(unsigned logopt, ...) + "and /etc/mtab will differ"); + ret = 0; + } ++ free(argv); + + return ret; + } diff --git a/autofs-5.1.5-use-mp-instead-of-path-in-mnt_list-entries.patch b/autofs-5.1.5-use-mp-instead-of-path-in-mnt_list-entries.patch new file mode 100644 index 0000000..19d722b --- /dev/null +++ b/autofs-5.1.5-use-mp-instead-of-path-in-mnt_list-entries.patch @@ -0,0 +1,436 @@ +autofs-5.1.5 - use mp instead of path in mnt_list entries + +From: Ian Kent + +Use the simpler, more instructive mp instead of path in the +mnt_list structure. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 18 ++++++------- + daemon/indirect.c | 22 ++++++++-------- + include/mounts.h | 4 +-- + lib/mounts.c | 70 +++++++++++++++++++++++++++--------------------------- + 5 files changed, 58 insertions(+), 57 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -64,6 +64,7 @@ xx/xx/2018 autofs-5.1.5 + - use ignore option for offset mounts as well. + - add config option for "ignore" mount option + - use bit flags for autofs mount types in mnt_list. ++- use mp instead of path in mnt_list entries. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -272,12 +272,12 @@ static int unlink_mount_tree(struct auto + mnt = list_entry(p, struct mnt_list, list); + + if (mnt->flags & MNTS_AUTOFS) +- rv = umount2(mnt->path, MNT_DETACH); ++ rv = umount2(mnt->mp, MNT_DETACH); + else +- rv = spawn_umount(ap->logopt, "-l", mnt->path, NULL); ++ rv = spawn_umount(ap->logopt, "-l", mnt->mp, NULL); + if (rv == -1) { + debug(ap->logopt, +- "can't unlink %s from mount tree", mnt->path); ++ "can't unlink %s from mount tree", mnt->mp); + + switch (errno) { + case EINVAL: +@@ -920,7 +920,7 @@ void *expire_proc_direct(void *arg) + */ + pthread_cleanup_push(master_source_lock_cleanup, ap->entry); + master_source_readlock(ap->entry); +- me = lookup_source_mapent(ap, next->path, LKP_DISTINCT); ++ me = lookup_source_mapent(ap, next->mp, LKP_DISTINCT); + pthread_cleanup_pop(1); + if (!me) + continue; +@@ -937,7 +937,7 @@ void *expire_proc_direct(void *arg) + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + if (next->flags & MNTS_INDIRECT) { +- master_notify_submount(ap, next->path, ap->state); ++ master_notify_submount(ap, next->mp, ap->state); + pthread_setcancelstate(cur_state, NULL); + continue; + } +@@ -968,7 +968,7 @@ void *expire_proc_direct(void *arg) + cache_writelock(me->mc); + if (me->ioctlfd != -1 && + fstat(me->ioctlfd, &st) != -1 && +- !count_mounts(ap, next->path, st.st_dev)) { ++ !count_mounts(ap, next->mp, st.st_dev)) { + ops->close(ap->logopt, me->ioctlfd); + me->ioctlfd = -1; + cache_unlock(me->mc); +@@ -979,7 +979,7 @@ void *expire_proc_direct(void *arg) + + ioctlfd = me->ioctlfd; + +- ret = ops->expire(ap->logopt, ioctlfd, next->path, how); ++ ret = ops->expire(ap->logopt, ioctlfd, next->mp, how); + if (ret) { + left++; + pthread_setcancelstate(cur_state, NULL); +@@ -1002,10 +1002,10 @@ void *expire_proc_direct(void *arg) + if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE) + pthread_testcancel(); + +- debug(ap->logopt, "send expire to trigger %s", next->path); ++ debug(ap->logopt, "send expire to trigger %s", next->mp); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = ops->expire(ap->logopt, ioctlfd, next->path, how); ++ ret = ops->expire(ap->logopt, ioctlfd, next->mp, how); + if (ret) + left++; + pthread_setcancelstate(cur_state, NULL); +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -49,12 +49,12 @@ static int unlink_mount_tree(struct auto + this = mnts; + while (this) { + if (this->flags & MNTS_AUTOFS) +- rv = umount2(this->path, MNT_DETACH); ++ rv = umount2(this->mp, MNT_DETACH); + else +- rv = spawn_umount(ap->logopt, "-l", this->path, NULL); ++ rv = spawn_umount(ap->logopt, "-l", this->mp, NULL); + if (rv == -1) { + debug(ap->logopt, +- "can't unlink %s from mount tree", this->path); ++ "can't unlink %s from mount tree", this->mp); + + switch (errno) { + case EINVAL: +@@ -446,7 +446,7 @@ void *expire_proc_indirect(void *arg) + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + if (next->flags & MNTS_INDIRECT) +- master_notify_submount(ap, next->path, ap->state); ++ master_notify_submount(ap, next->mp, ap->state); + else if (next->flags & MNTS_OFFSET) { + struct map_source *map; + struct mapent_cache *mc = NULL; +@@ -454,13 +454,13 @@ void *expire_proc_indirect(void *arg) + struct stat st; + + /* It's got a mount, deal with in the outer loop */ +- if (is_mounted(_PATH_MOUNTED, next->path, MNTS_REAL)) { ++ if (is_mounted(_PATH_MOUNTED, next->mp, MNTS_REAL)) { + pthread_setcancelstate(cur_state, NULL); + continue; + } + + /* Don't touch submounts */ +- if (master_find_submount(ap, next->path)) { ++ if (master_find_submount(ap, next->mp)) { + pthread_setcancelstate(cur_state, NULL); + continue; + } +@@ -471,7 +471,7 @@ void *expire_proc_indirect(void *arg) + while (map) { + mc = map->mc; + cache_writelock(mc); +- me = cache_lookup_distinct(mc, next->path); ++ me = cache_lookup_distinct(mc, next->mp); + if (me) + break; + cache_unlock(mc); +@@ -513,7 +513,7 @@ void *expire_proc_indirect(void *arg) + * If the mount corresponds to an offset trigger then + * the key is the path, otherwise it's the last component. + */ +- ind_key = strrchr(next->path, '/'); ++ ind_key = strrchr(next->mp, '/'); + if (ind_key) + ind_key++; + +@@ -526,7 +526,7 @@ void *expire_proc_indirect(void *arg) + */ + pthread_cleanup_push(master_source_lock_cleanup, ap->entry); + master_source_readlock(ap->entry); +- me = lookup_source_mapent(ap, next->path, LKP_DISTINCT); ++ me = lookup_source_mapent(ap, next->mp, LKP_DISTINCT); + if (!me && ind_key) + me = lookup_source_mapent(ap, ind_key, LKP_NORMAL); + pthread_cleanup_pop(1); +@@ -538,10 +538,10 @@ void *expire_proc_indirect(void *arg) + cache_unlock(me->mc); + } + +- debug(ap->logopt, "expire %s", next->path); ++ debug(ap->logopt, "expire %s", next->mp); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = ops->expire(ap->logopt, ioctlfd, next->path, how); ++ ret = ops->expire(ap->logopt, ioctlfd, next->mp, how); + if (ret) + left++; + pthread_setcancelstate(cur_state, NULL); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -52,7 +52,7 @@ extern const unsigned int t_offset; + struct mapent; + + struct mnt_list { +- char *path; ++ char *mp; + unsigned int flags; + /* + * List operations ie. get_mnt_list. +@@ -101,7 +101,7 @@ int ext_mount_remove(struct list_head *, + int ext_mount_inuse(const char *); + struct mnt_list *get_mnt_list(const char *table, const char *path, int include); + void free_mnt_list(struct mnt_list *list); +-int is_mounted(const char *table, const char *path, unsigned int type); ++int is_mounted(const char *table, const char *mp, unsigned int type); + 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); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -817,8 +817,8 @@ struct mnt_list *get_mnt_list(const char + strncmp(mnt->mnt_dir, path, pathlen) != 0) + continue; + +- /* Not a subdirectory of requested path ? */ +- /* pathlen == 1 => everything is subdir */ ++ /* Not a subdirectory of requested mp? */ ++ /* mp_len == 1 => everything is subdir */ + if (pathlen > 1 && len > pathlen && + mnt->mnt_dir[pathlen] != '/') + continue; +@@ -834,7 +834,7 @@ struct mnt_list *get_mnt_list(const char + mptr = list; + last = NULL; + while (mptr) { +- if (len >= strlen(mptr->path)) ++ if (len >= strlen(mptr->mp)) + break; + last = mptr; + mptr = mptr->next; +@@ -847,13 +847,13 @@ struct mnt_list *get_mnt_list(const char + + ent->next = mptr; + +- ent->path = malloc(len + 1); +- if (!ent->path) { ++ ent->mp = malloc(len + 1); ++ if (!ent->mp) { + endmntent(tab); + free_mnt_list(list); + return NULL; + } +- strcpy(ent->path, mnt->mnt_dir); ++ strcpy(ent->mp, mnt->mnt_dir); + + if (!strcmp(mnt->mnt_type, "autofs")) + ent->flags |= MNTS_AUTOFS; +@@ -885,23 +885,23 @@ void free_mnt_list(struct mnt_list *list + + next = this->next; + +- if (this->path) +- free(this->path); ++ if (this->mp) ++ free(this->mp); + + free(this); + } + } + +-static int table_is_mounted(const char *table, const char *path, unsigned int type) ++static int table_is_mounted(const char *table, const char *mp, unsigned int type) + { + struct mntent *mnt; + struct mntent mnt_wrk; + char buf[PATH_MAX * 3]; +- size_t pathlen = strlen(path); ++ size_t mp_len = strlen(mp); + FILE *tab; + int ret = 0; + +- if (!path || !pathlen || pathlen >= PATH_MAX) ++ if (!mp || !mp_len || mp_len >= PATH_MAX) + return 0; + + tab = open_setmntent_r(table); +@@ -928,7 +928,7 @@ static int table_is_mounted(const char * + continue; + } + +- if (pathlen == len && !strncmp(path, mnt->mnt_dir, pathlen)) { ++ if (mp_len == len && !strncmp(mp, mnt->mnt_dir, mp_len)) { + ret = 1; + break; + } +@@ -938,7 +938,7 @@ static int table_is_mounted(const char * + return ret; + } + +-static int ioctl_is_mounted(const char *table, const char *path, unsigned int type) ++static int ioctl_is_mounted(const char *table, const char *mp, unsigned int type) + { + struct ioctl_ops *ops = get_ioctl_ops(); + unsigned int mounted; +@@ -947,9 +947,9 @@ static int ioctl_is_mounted(const char * + /* If the ioctl fails fall back to the potentially resource + * intensive mount table check. + */ +- ret = ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted); ++ ret = ops->ismountpoint(LOGOPT_NONE, -1, mp, &mounted); + if (ret == -1) +- return table_is_mounted(table, path, type); ++ return table_is_mounted(table, mp, type); + + if (mounted) { + switch (type) { +@@ -964,14 +964,14 @@ static int ioctl_is_mounted(const char * + return 0; + } + +-int is_mounted(const char *table, const char *path, unsigned int type) ++int is_mounted(const char *table, const char *mp, unsigned int type) + { + struct ioctl_ops *ops = get_ioctl_ops(); + + if (ops->ismountpoint) +- return ioctl_is_mounted(table, path, type); ++ return ioctl_is_mounted(table, mp, type); + else +- return table_is_mounted(table, path, type); ++ return table_is_mounted(table, mp, type); + } + + /* +@@ -1006,12 +1006,12 @@ void tree_free_mnt_tree(struct mnt_list + + list_del(&this->self); + +- free(this->path); ++ free(this->mp); + + free(this); + } + +- free(tree->path); ++ free(tree->mp); + free(tree); + } + +@@ -1062,14 +1062,14 @@ struct mnt_list *tree_make_mnt_tree(cons + INIT_LIST_HEAD(&ent->entries); + INIT_LIST_HEAD(&ent->sublist); + +- ent->path = malloc(len + 1); +- if (!ent->path) { ++ ent->mp = malloc(len + 1); ++ if (!ent->mp) { + endmntent(tab); + free(ent); + tree_free_mnt_tree(tree); + return NULL; + } +- strcpy(ent->path, mnt->mnt_dir); ++ strcpy(ent->mp, mnt->mnt_dir); + + if (!strcmp(mnt->mnt_type, "autofs")) + ent->flags |= MNTS_AUTOFS; +@@ -1085,8 +1085,8 @@ struct mnt_list *tree_make_mnt_tree(cons + + mptr = tree; + while (mptr) { +- int elen = strlen(ent->path); +- int mlen = strlen(mptr->path); ++ int elen = strlen(ent->mp); ++ int mlen = strlen(mptr->mp); + + if (elen < mlen) { + if (mptr->left) { +@@ -1106,7 +1106,7 @@ struct mnt_list *tree_make_mnt_tree(cons + } + } + +- eq = strcmp(ent->path, mptr->path); ++ eq = strcmp(ent->mp, mptr->mp); + if (eq < 0) { + if (mptr->left) + mptr = mptr->left; +@@ -1146,7 +1146,7 @@ int tree_get_mnt_list(struct mnt_list *m + return 0; + + plen = strlen(path); +- mlen = strlen(mnts->path); ++ mlen = strlen(mnts->mp); + if (mlen < plen) + return tree_get_mnt_list(mnts->right, list, path, include); + else { +@@ -1155,10 +1155,10 @@ int tree_get_mnt_list(struct mnt_list *m + tree_get_mnt_list(mnts->left, list, path, include); + + if ((!include && mlen <= plen) || +- strncmp(mnts->path, path, plen)) ++ strncmp(mnts->mp, path, plen)) + goto skip; + +- if (plen > 1 && mlen > plen && mnts->path[plen] != '/') ++ if (plen > 1 && mlen > plen && mnts->mp[plen] != '/') + goto skip; + + INIT_LIST_HEAD(&mnts->list); +@@ -1193,7 +1193,7 @@ int tree_get_mnt_sublist(struct mnt_list + return 0; + + plen = strlen(path); +- mlen = strlen(mnts->path); ++ mlen = strlen(mnts->mp); + if (mlen < plen) + return tree_get_mnt_sublist(mnts->right, list, path, include); + else { +@@ -1202,10 +1202,10 @@ int tree_get_mnt_sublist(struct mnt_list + tree_get_mnt_sublist(mnts->left, list, path, include); + + if ((!include && mlen <= plen) || +- strncmp(mnts->path, path, plen)) ++ strncmp(mnts->mp, path, plen)) + goto skip; + +- if (plen > 1 && mlen > plen && mnts->path[plen] != '/') ++ if (plen > 1 && mlen > plen && mnts->mp[plen] != '/') + goto skip; + + INIT_LIST_HEAD(&mnts->sublist); +@@ -1237,7 +1237,7 @@ int tree_find_mnt_ents(struct mnt_list * + return 0; + + plen = strlen(path); +- mlen = strlen(mnts->path); ++ mlen = strlen(mnts->mp); + if (mlen < plen) + return tree_find_mnt_ents(mnts->right, list, path); + else if (mlen > plen) +@@ -1247,7 +1247,7 @@ int tree_find_mnt_ents(struct mnt_list * + + tree_find_mnt_ents(mnts->left, list, path); + +- if (!strcmp(mnts->path, path)) { ++ if (!strcmp(mnts->mp, path)) { + INIT_LIST_HEAD(&mnts->entries); + list_add(&mnts->entries, list); + } +@@ -1258,7 +1258,7 @@ int tree_find_mnt_ents(struct mnt_list * + + this = list_entry(p, struct mnt_list, self); + +- if (!strcmp(this->path, path)) { ++ if (!strcmp(this->mp, path)) { + INIT_LIST_HEAD(&this->entries); + list_add(&this->entries, list); + } diff --git a/autofs-5.1.5-use-single-unlink_umount_tree-for-both-direct-and-indirect-mounts.patch b/autofs-5.1.5-use-single-unlink_umount_tree-for-both-direct-and-indirect-mounts.patch new file mode 100644 index 0000000..ede2e23 --- /dev/null +++ b/autofs-5.1.5-use-single-unlink_umount_tree-for-both-direct-and-indirect-mounts.patch @@ -0,0 +1,271 @@ +autofs-5.1.5 - use single unlink_umount_tree() for both direct and indirect mounts + +From: Ian Kent + +Use the same function, unlink_umount_tree(), for forced unlink of mounts +for both indirect and direct mounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 96 +++++++++++++--------------------------------------- + daemon/indirect.c | 2 - + daemon/state.c | 17 +-------- + include/automount.h | 2 - + 5 files changed, 30 insertions(+), 88 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -70,6 +70,7 @@ xx/xx/2018 autofs-5.1.5 + - use local getmntent_r in table_is_mounted(). + - refactor unlink_active_mounts() in direct.c. + - don't use tree_is_mounted() for mounted checks. ++- use single unlink_umount_tree() for both direct and indirect mounts. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -49,6 +49,8 @@ pthread_key_t key_mnt_direct_params; + pthread_key_t key_mnt_offset_params; + pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT; + ++int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts); ++ + static void key_mnt_params_destroy(void *arg) + { + struct mnt_params *mp; +@@ -256,64 +258,8 @@ done: + return 0; + } + +-static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list) +-{ +- struct list_head *p; +- int rv, ret; +- +- ret = 1; +- list_for_each(p, list) { +- struct mnt_list *mnt; +- +- mnt = list_entry(p, struct mnt_list, list); +- +- if (mnt->flags & MNTS_AUTOFS) +- rv = umount2(mnt->mp, MNT_DETACH); +- else +- rv = spawn_umount(ap->logopt, "-l", mnt->mp, NULL); +- if (rv == -1) { +- debug(ap->logopt, +- "can't unlink %s from mount tree", mnt->mp); +- +- switch (errno) { +- case EINVAL: +- warn(ap->logopt, +- "bad superblock or not mounted"); +- break; +- +- case ENOENT: +- case EFAULT: +- ret = 0; +- warn(ap->logopt, "bad path for mount"); +- break; +- } +- } +- } +- return ret; +-} +- +-static int unlink_active_mounts(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) +-{ +- struct list_head list; +- +- INIT_LIST_HEAD(&list); +- +- if (!tree_get_mnt_list(mnts, &list, me->key, 1)) +- 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 0; +- } +- +- return 1; +-} +- + int do_mount_autofs_direct(struct autofs_point *ap, +- struct mnt_list *mnts, struct mapent *me, +- time_t timeout) ++ struct mapent *me, time_t timeout) + { + const char *str_direct = mount_type_str(t_direct); + struct ioctl_ops *ops = get_ioctl_ops(); +@@ -342,6 +288,8 @@ int do_mount_autofs_direct(struct autofs + if (ret == 0) + return -1; + } else { ++ struct mnt_list *mnts; ++ + if (ap->state == ST_READMAP && is_mounted(me->key, MNTS_ALL)) { + time_t tout = get_exp_timeout(ap, me->source); + int save_ioctlfd, ioctlfd; +@@ -367,15 +315,23 @@ int do_mount_autofs_direct(struct autofs + return 0; + } + +- /* +- * A return of 1 indicates we successfully unlinked +- * the mount tree if there was one. A return of 0 +- * indicates we failed to unlink the mount tree so +- * we have to return a failure. +- */ +- ret = unlink_active_mounts(ap, mnts, me); +- if (!ret) +- return -1; ++ mnts = get_mnt_list(me->key, 1); ++ if (mnts) { ++ /* ++ * A return of 1 indicates we successfully unlinked ++ * the mount tree if there was one. A return of 0 ++ * indicates we failed to unlink the mount tree so ++ * we have to return a failure. ++ */ ++ ret = unlink_mount_tree(ap, mnts); ++ free_mnt_list(mnts); ++ if (!ret) { ++ error(ap->logopt, ++ "already mounted as other than autofs " ++ "or failed to unlink entry in tree"); ++ return -1; ++ } ++ } + + if (me->ioctlfd != -1) { + error(ap->logopt, "active direct mount %s", me->key); +@@ -494,7 +450,6 @@ int mount_autofs_direct(struct autofs_po + struct map_source *map; + struct mapent_cache *nc, *mc; + struct mapent *me, *ne, *nested; +- struct mnt_list *mnts; + time_t now = monotonic_time(NULL); + + if (strcmp(ap->path, "/-")) { +@@ -510,8 +465,6 @@ int mount_autofs_direct(struct autofs_po + return -1; + } + +- mnts = tree_make_mnt_tree("/"); +- 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; +@@ -539,7 +492,7 @@ int mount_autofs_direct(struct autofs_po + if (ne) { + if (map->master_line < ne->age) { + /* TODO: check return, locking me */ +- do_mount_autofs_direct(ap, mnts, me, timeout); ++ do_mount_autofs_direct(ap, me, timeout); + } + me = cache_enumerate(mc, me); + continue; +@@ -556,7 +509,7 @@ int mount_autofs_direct(struct autofs_po + } + + /* TODO: check return, locking me */ +- do_mount_autofs_direct(ap, mnts, me, timeout); ++ do_mount_autofs_direct(ap, me, timeout); + + me = cache_enumerate(mc, me); + } +@@ -565,7 +518,6 @@ int mount_autofs_direct(struct autofs_po + } + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); +- pthread_cleanup_pop(1); + + return 0; + } +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -40,7 +40,7 @@ + /* Attribute to create detached thread */ + extern pthread_attr_t th_attr_detached; + +-static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) ++int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts) + { + struct mnt_list *this; + int rv, ret; +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -350,14 +350,7 @@ static void do_readmap_cleanup(void *arg + return; + } + +-static void tree_mnts_cleanup(void *arg) +-{ +- struct mnt_list *mnts = (struct mnt_list *) arg; +- tree_free_mnt_tree(mnts); +- return; +-} +- +-static void do_readmap_mount(struct autofs_point *ap, struct mnt_list *mnts, ++static void do_readmap_mount(struct autofs_point *ap, + struct map_source *map, struct mapent *me, time_t now) + { + struct mapent_cache *nc; +@@ -444,7 +437,7 @@ static void do_readmap_mount(struct auto + debug(ap->logopt, + "%s is mounted", me->key); + } else +- do_mount_autofs_direct(ap, mnts, me, get_exp_timeout(ap, map)); ++ do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map)); + + return; + } +@@ -455,7 +448,6 @@ static void *do_readmap(void *arg) + struct map_source *map; + struct mapent_cache *nc, *mc; + struct readmap_args *ra; +- struct mnt_list *mnts; + int status; + time_t now; + +@@ -499,8 +491,6 @@ static void *do_readmap(void *arg) + struct mapent *me; + unsigned int append_alarm = !ap->exp_runfreq; + +- mnts = tree_make_mnt_tree("/"); +- pthread_cleanup_push(tree_mnts_cleanup, mnts); + nc = ap->entry->master->nc; + cache_readlock(nc); + pthread_cleanup_push(cache_lock_cleanup, nc); +@@ -518,7 +508,7 @@ static void *do_readmap(void *arg) + cache_readlock(mc); + me = cache_enumerate(mc, NULL); + while (me) { +- do_readmap_mount(ap, mnts, map, me, now); ++ do_readmap_mount(ap, map, me, now); + me = cache_enumerate(mc, me); + } + lookup_prune_one_cache(ap, map->mc, now); +@@ -538,7 +528,6 @@ static void *do_readmap(void *arg) + + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); +- pthread_cleanup_pop(1); + } + + pthread_cleanup_pop(1); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -606,7 +606,7 @@ 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, const char *root); +-int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me, time_t timeout); ++int do_mount_autofs_direct(struct autofs_point *ap, struct mapent *me, time_t timeout); + int mount_autofs_direct(struct autofs_point *ap); + 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); diff --git a/autofs-5.1.6-add-a-hash-index-to-mnt_list.patch b/autofs-5.1.6-add-a-hash-index-to-mnt_list.patch new file mode 100644 index 0000000..3291813 --- /dev/null +++ b/autofs-5.1.6-add-a-hash-index-to-mnt_list.patch @@ -0,0 +1,202 @@ +autofs-5.1.6 - add a hash index to mnt_list + +From: Ian Kent + +Add a hash index (and utility functions) to struct mnt_list. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/mounts.h | 8 +++ + lib/mounts.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 144 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -121,6 +121,7 @@ xx/xx/2018 autofs-5.1.5 + - change mountpoint to mp in struct ext_mount. + - make external mounts independent of amd_entry. + - make external mounts use simpler hashtable. ++- add a hash index to mnt_list. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -54,10 +54,16 @@ struct mapent; + struct mnt_list { + char *mp; + unsigned int flags; ++ ++ /* Hash of all mounts */ ++ struct hlist_node hash; ++ unsigned int ref; ++ + /* + * List operations ie. get_mnt_list. + */ + struct mnt_list *next; ++ + /* + * Tree operations ie. tree_make_tree, + * tree_get_mnt_list etc. +@@ -100,6 +106,8 @@ char *make_mnt_name_string(char *path); + int ext_mount_add(const char *, const char *); + int ext_mount_remove(const char *); + int ext_mount_inuse(const char *); ++struct mnt_list *mnts_lookup_mount(const char *mp); ++void mnts_put_mount(struct mnt_list *mnt); + struct mnt_list *get_mnt_list(const char *path, int include); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -63,6 +63,11 @@ struct ext_mount { + static DEFINE_HASHTABLE(ext_mounts_hash, EXT_MOUNTS_HASH_BITS); + static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER; + ++#define MNTS_HASH_BITS 7 ++ ++static DEFINE_HASHTABLE(mnts_hash, MNTS_HASH_BITS); ++static pthread_mutex_t mnts_hash_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + unsigned int linux_version_code(void) + { + struct utsname my_utsname; +@@ -832,6 +837,136 @@ done: + return ret; + } + ++static void mnts_hash_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&mnts_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static void mnts_hash_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&mnts_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static struct mnt_list *mnts_lookup(const char *mp) ++{ ++ uint32_t hval = hash(mp, HASH_SIZE(mnts_hash)); ++ struct mnt_list *this; ++ ++ if (hlist_empty(&mnts_hash[hval])) ++ return NULL; ++ ++ hlist_for_each_entry(this, &mnts_hash[hval], hash) { ++ if (!strcmp(this->mp, mp) && this->ref) ++ return this; ++ } ++ ++ return NULL; ++} ++ ++static struct mnt_list *mnts_alloc_mount(const char *mp) ++{ ++ struct mnt_list *this; ++ ++ this = malloc(sizeof(*this)); ++ if (!this) ++ goto done; ++ memset(this, 0, sizeof(*this)); ++ ++ this->mp = strdup(mp); ++ if (!this->mp) { ++ free(this); ++ this = NULL; ++ goto done; ++ } ++ ++ this->ref = 1; ++ INIT_HLIST_NODE(&this->hash); ++done: ++ return this; ++} ++ ++static void __mnts_get_mount(struct mnt_list *mnt) ++{ ++ mnt->ref++; ++} ++ ++static void __mnts_put_mount(struct mnt_list *mnt) ++{ ++ mnt->ref--; ++ if (!mnt->ref) { ++ hash_del(&mnt->hash); ++ free(mnt->mp); ++ free(mnt); ++ } ++} ++ ++static struct mnt_list *mnts_new_mount(const char *mp) ++{ ++ struct mnt_list *this; ++ ++ this = mnts_lookup(mp); ++ if (this) { ++ __mnts_get_mount(this); ++ goto done; ++ } ++ ++ this = mnts_alloc_mount(mp); ++ if (!this) ++ goto done; ++ ++ hash_add_str(mnts_hash, &this->hash, this->mp); ++done: ++ return this; ++} ++ ++static struct mnt_list *mnts_get_mount(const char *mp) ++{ ++ struct mnt_list *this; ++ ++ this = mnts_lookup(mp); ++ if (this) { ++ __mnts_get_mount(this); ++ return this; ++ } ++ ++ return mnts_new_mount(mp); ++} ++ ++static struct mnt_list *__mnts_lookup_mount(const char *mp) ++{ ++ struct mnt_list *this; ++ ++ this = mnts_lookup(mp); ++ if (this) ++ __mnts_get_mount(this); ++ ++ return this; ++} ++ ++struct mnt_list *mnts_lookup_mount(const char *mp) ++{ ++ struct mnt_list *this; ++ ++ mnts_hash_mutex_lock(); ++ this = __mnts_lookup_mount(mp); ++ mnts_hash_mutex_unlock(); ++ ++ return this; ++} ++ ++void mnts_put_mount(struct mnt_list *mnt) ++{ ++ if (!mnt) ++ return; ++ mnts_hash_mutex_lock(); ++ __mnts_put_mount(mnt); ++ mnts_hash_mutex_unlock(); ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/autofs-5.1.6-add-force-unlink-mounts-and-exit-option.patch b/autofs-5.1.6-add-force-unlink-mounts-and-exit-option.patch new file mode 100644 index 0000000..cdd2553 --- /dev/null +++ b/autofs-5.1.6-add-force-unlink-mounts-and-exit-option.patch @@ -0,0 +1,248 @@ +autofs-5.1.6 - add force unlink mounts and exit option + +From: Ian Kent + +Add a automount program option to force an unlink umount of all +existing mounts under configured autofs mount points then exit. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 51 +++++++++++++++++++++++++++++++++------------------ + daemon/direct.c | 12 +++++++++++- + daemon/indirect.c | 21 ++++++++++++++++----- + include/automount.h | 1 + + lib/master.c | 6 ++++-- + man/automount.8 | 6 ++++++ + 7 files changed, 72 insertions(+), 26 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -89,6 +89,7 @@ xx/xx/2018 autofs-5.1.5 + - use bit flag for force unlink mounts. + - improve force unlink option description. + - remove command fifo on autofs mount fail. ++- add force unlink mounts and exit option. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1153,8 +1153,13 @@ static int mount_autofs(struct autofs_po + { + int status = 0; + +- if (autofs_init_ap(ap) != 0) +- return -1; ++ /* No need to create comms fds and command fifo if ++ * unlinking mounts and exiting. ++ */ ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) { ++ if (autofs_init_ap(ap) != 0) ++ return -1; ++ } + + if (ap->type == LKP_DIRECT) + status = mount_autofs_direct(ap); +@@ -1859,7 +1864,8 @@ void *handle_mounts(void *arg) + } + + if (mount_autofs(ap, root) < 0) { +- crit(ap->logopt, "mount of %s failed!", ap->path); ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) ++ crit(ap->logopt, "mount of %s failed!", ap->path); + suc->status = 1; + umount_autofs(ap, root, 1); + free(root); +@@ -1951,6 +1957,7 @@ static void usage(void) + " -C --dont-check-daemon\n" + " don't check if daemon is already running\n" + " -F --force forceably clean up known automounts at start\n" ++ " -U --force-exit forceably clean up known automounts and exit\n" + " -V --version print version, build config and exit\n" + , program); + } +@@ -2202,7 +2209,7 @@ int main(int argc, char *argv[]) + time_t timeout; + time_t age = monotonic_time(NULL); + struct rlimit rlim; +- const char *options = "+hp:t:vmdD:SfVrO:l:n:CFM"; ++ const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM"; + static const struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"pid-file", 1, 0, 'p'}, +@@ -2220,6 +2227,7 @@ int main(int argc, char *argv[]) + {"set-log-priority", 1, 0, 'l'}, + {"dont-check-daemon", 0, 0, 'C'}, + {"force", 0, 0, 'F'}, ++ {"force-exit", 0, 0, 'U'}, + {"master-wait", 1, 0, 'M'}, + {0, 0, 0, 0} + }; +@@ -2342,6 +2350,11 @@ int main(int argc, char *argv[]) + do_force_unlink = UNLINK_AND_CONT; + break; + ++ case 'U': ++ flags |= DAEMON_FLAGS_FOREGROUND; ++ do_force_unlink = UNLINK_AND_EXIT; ++ break; ++ + case '?': + case ':': + printf("%s: Ambiguous or unknown options\n", program); +@@ -2657,25 +2670,27 @@ int main(int argc, char *argv[]) + } + } + +- /* +- * Mmm ... reset force unlink umount so we don't also do this +- * in future when we receive a HUP signal. +- */ +- do_force_unlink = 0; ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) { ++ /* ++ * Mmm ... reset force unlink umount so we don't also do ++ * this in future when we receive a HUP signal. ++ */ ++ do_force_unlink = 0; + +- if (start_pipefd[1] != -1) { +- st_stat = 0; +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); +- } ++ if (start_pipefd[1] != -1) { ++ st_stat = 0; ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } + + #ifdef WITH_SYSTEMD +- if (flags & DAEMON_FLAGS_SYSTEMD_SERVICE) +- sd_notify(1, "READY=1"); ++ if (flags & DAEMON_FLAGS_SYSTEMD_SERVICE) ++ sd_notify(1, "READY=1"); + #endif + +- state_mach_thid = pthread_self(); +- statemachine(NULL); ++ state_mach_thid = pthread_self(); ++ statemachine(NULL); ++ } + + master_kill(master_list); + +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -286,7 +286,14 @@ int do_mount_autofs_direct(struct autofs + if (ret == 0) + return -1; + } else { +- if (ap->state == ST_READMAP && is_mounted(me->key, MNTS_ALL)) { ++ /* I don't remember why this is here for the force ++ * unlink case. I don't think it should be but I may ++ * have done it for a reason so keep it for the unlink ++ * and continue case but not for the unlink and exit ++ * case. ++ */ ++ if (!(do_force_unlink & UNLINK_AND_EXIT) && ++ ap->state == ST_READMAP && is_mounted(me->key, MNTS_ALL)) { + time_t tout = get_exp_timeout(ap, me->source); + int save_ioctlfd, ioctlfd; + +@@ -319,6 +326,9 @@ int do_mount_autofs_direct(struct autofs + goto out_err; + } + ++ if (do_force_unlink & UNLINK_AND_EXIT) ++ return -1; ++ + if (me->ioctlfd != -1) { + error(ap->logopt, "active direct mount %s", me->key); + return -1; +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -76,6 +76,9 @@ static int do_mount_autofs_indirect(stru + "or failed to unlink entry in tree"); + goto out_err; + } ++ ++ if (do_force_unlink & UNLINK_AND_EXIT) ++ return -1; + } + + options = make_options_string(ap->path, +@@ -163,12 +166,20 @@ int mount_autofs_indirect(struct autofs_ + int status; + int map; + ++ /* Don't read the map if the unlink and exit option has been ++ * given. do_mount_autofs_indirect() will return -1 if this ++ * option has been given so there's no need to do anything ++ * else. ++ */ ++ + /* TODO: read map, determine map type is OK */ +- if (lookup_nss_read_map(ap, NULL, now)) +- lookup_prune_cache(ap, now); +- else { +- error(ap->logopt, "failed to read map for %s", ap->path); +- return -1; ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) { ++ if (lookup_nss_read_map(ap, NULL, now)) ++ lookup_prune_cache(ap, now); ++ else { ++ error(ap->logopt, "failed to read map for %s", ap->path); ++ return -1; ++ } + } + + status = do_mount_autofs_indirect(ap, root); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -591,6 +591,7 @@ struct autofs_point { + }; + + #define UNLINK_AND_CONT 0x01 ++#define UNLINK_AND_EXIT 0x02 + + /* Foreably unlink existing mounts at startup. */ + extern int do_force_unlink; +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -1358,7 +1358,8 @@ static int master_do_mount(struct master + suc.done = 0; + suc.status = 0; + +- debug(ap->logopt, "mounting %s", entry->path); ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) ++ debug(ap->logopt, "mounting %s", entry->path); + + status = pthread_create(&thid, &th_attr, handle_mounts, &suc); + if (status) { +@@ -1376,7 +1377,8 @@ static int master_do_mount(struct master + } + + if (suc.status) { +- error(ap->logopt, "failed to startup mount"); ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) ++ error(ap->logopt, "failed to startup mount"); + handle_mounts_startup_cond_destroy(&suc); + return 0; + } +--- autofs-5.1.4.orig/man/automount.8 ++++ autofs-5.1.4/man/automount.8 +@@ -121,6 +121,12 @@ Don't check if the daemon is currently r + Force an unlink umount of existing mounts under configured autofs managed + mount points during startup. This can cause problems for processes with + working directories within these mounts (see NOTES). ++.TP ++.I "\-U, \-\-force-exit" ++Force an unlink umount of existing mounts under configured autofs managed ++mount points and exit rather than continuing the startup. This can cause ++problems for processes with working directories within these mounts (see ++NOTES). + .SH ARGUMENTS + \fBautomount\fP takes one optional argument, the name of the master map to + use. diff --git a/autofs-5.1.6-add-hashtable-implementation.patch b/autofs-5.1.6-add-hashtable-implementation.patch new file mode 100644 index 0000000..23e3c9a --- /dev/null +++ b/autofs-5.1.6-add-hashtable-implementation.patch @@ -0,0 +1,334 @@ +autofs-5.1.6 - add hashtable implementation + +From: Ian Kent + +Include the (slightly modified) Linux kernel hashtable implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 19 ----- + include/hash.h | 101 +++++++++++++++++++++++++++++++ + include/hashtable.h | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 269 insertions(+), 18 deletions(-) + create mode 100644 include/hash.h + create mode 100644 include/hashtable.h + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -117,6 +117,7 @@ xx/xx/2018 autofs-5.1.5 + - make bind mounts propagation slave by default. + - fix browse dir not re-created on symlink expire. + - update list.h. ++- add hashtable implementation. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -22,6 +22,7 @@ + #include + #include "config.h" + #include "list.h" ++#include "hash.h" + + #include + +@@ -143,24 +144,6 @@ struct autofs_point; + #define UMOUNT_RETRIES 8 + #define EXPIRE_RETRIES 3 + +-static u_int32_t inline hash(const char *key, unsigned int size) +-{ +- u_int32_t hashval; +- char *s = (char *) key; +- +- for (hashval = 0; *s != '\0';) { +- hashval += (unsigned char) *s++; +- hashval += (hashval << 10); +- hashval ^= (hashval >> 6); +- } +- +- hashval += (hashval << 3); +- hashval ^= (hashval >> 11); +- hashval += (hashval << 15); +- +- return hashval % size; +-} +- + struct mapent_cache { + pthread_rwlock_t rwlock; + unsigned int size; +--- /dev/null ++++ autofs-5.1.4/include/hash.h +@@ -0,0 +1,101 @@ ++#ifndef _LINUX_HASH_H ++#define _LINUX_HASH_H ++/* Fast hashing routine for ints, longs and pointers. ++ (C) 2002 Nadia Yvette Chambers, IBM */ ++ ++#include ++#include ++ ++/* ++ * The "GOLDEN_RATIO_PRIME" is used in ifs/btrfs/brtfs_inode.h and ++ * fs/inode.c. It's not actually prime any more (the previous primes ++ * were actively bad for hashing), but the name remains. ++ */ ++#if __WORDSIZE == 32 ++#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32 ++#define hash_long(val, bits) hash_32(val, bits) ++#elif __WORDSIZE == 64 ++#define hash_long(val, bits) hash_64(val, bits) ++#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64 ++#else ++#error Wordsize not 32 or 64 ++#endif ++ ++/* String based hash function */ ++static uint32_t inline hash(const char *key, unsigned int size) ++{ ++ u_int32_t hashval; ++ char *s = (char *) key; ++ ++ for (hashval = 0; *s != '\0';) { ++ hashval += (unsigned char) *s++; ++ hashval += (hashval << 10); ++ hashval ^= (hashval >> 6); ++ } ++ ++ hashval += (hashval << 3); ++ hashval ^= (hashval >> 11); ++ hashval += (hashval << 15); ++ ++ return hashval % size; ++} ++ ++/* ++ * This hash multiplies the input by a large odd number and takes the ++ * high bits. Since multiplication propagates changes to the most ++ * significant end only, it is essential that the high bits of the ++ * product be used for the hash value. ++ * ++ * Chuck Lever verified the effectiveness of this technique: ++ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf ++ * ++ * Although a random odd number will do, it turns out that the golden ++ * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice ++ * properties. (See Knuth vol 3, section 6.4, exercise 9.) ++ * ++ * These are the negative, (1 - phi) = phi**2 = (3 - sqrt(5))/2, ++ * which is very slightly easier to multiply by and makes no ++ * difference to the hash distribution. ++ */ ++#define GOLDEN_RATIO_32 0x61C88647 ++#define GOLDEN_RATIO_64 0x61C8864680B583EBull ++ ++static inline uint32_t __hash_32(uint32_t val) ++{ ++ return val * GOLDEN_RATIO_32; ++} ++ ++static inline uint32_t hash_32(uint32_t val, unsigned int bits) ++{ ++ /* High bits are more random, so use them. */ ++ return __hash_32(val) >> (32 - bits); ++} ++ ++static __always_inline uint32_t hash_64(uint64_t val, unsigned int bits) ++{ ++#if __WORDSIZE == 64 ++ /* 64x64-bit multiply is efficient on all 64-bit processors */ ++ return val * GOLDEN_RATIO_64 >> (64 - bits); ++#else ++ /* Hash 64 bits using only 32x32-bit multiply. */ ++ return hash_32((uint32_t) val ^ __hash_32(val >> 32), bits); ++#endif ++} ++ ++static inline uint32_t hash_ptr(const void *ptr, unsigned int bits) ++{ ++ return hash_long((unsigned long) ptr, bits); ++} ++ ++/* This really should be called fold32_ptr; it does no hashing to speak of. */ ++static inline uint32_t hash32_ptr(const void *ptr) ++{ ++ unsigned long val = (unsigned long) ptr; ++ ++#if __WORDSIZE == 64 ++ val ^= (val >> 32); ++#endif ++ return (uint32_t) val; ++} ++ ++#endif /* _LINUX_HASH_H */ +--- /dev/null ++++ autofs-5.1.4/include/hashtable.h +@@ -0,0 +1,166 @@ ++/* ++ * Statically sized hash table implementation ++ * (C) 2012 Sasha Levin ++ */ ++ ++#ifndef _LINUX_HASHTABLE_H ++#define _LINUX_HASHTABLE_H ++ ++#include "list.h" ++#include "hash.h" ++ ++#ifndef ARRAY_SIZE ++#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) ++#endif ++ ++static inline unsigned int ilog2(unsigned long val) { ++ unsigned int ret = -1; ++ ++ while (val != 0) { ++ val >>= 1; ++ ret++; ++ } ++ return ret; ++} ++ ++#define DEFINE_HASHTABLE(name, bits) \ ++ struct hlist_head name[1 << (bits)] = \ ++ { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } ++ ++#define DECLARE_HASHTABLE(name, bits) \ ++ struct hlist_head name[1 << (bits)] ++ ++#define HASH_SIZE(name) (ARRAY_SIZE(name)) ++#define HASH_BITS(name) ilog2(HASH_SIZE(name)) ++ ++/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ ++#define hash_min(val, bits) \ ++ (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) ++ ++static inline void __hash_init(struct hlist_head *ht, unsigned int sz) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < sz; i++) ++ INIT_HLIST_HEAD(&ht[i]); ++} ++ ++/** ++ * hash_init - initialize a hash table ++ * @hashtable: hashtable to be initialized ++ * ++ * Calculates the size of the hashtable from the given parameter, otherwise ++ * same as hash_init_size. ++ * ++ * This has to be a macro since HASH_BITS() will not work on pointers since ++ * it calculates the size during preprocessing. ++ */ ++#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable)) ++ ++/** ++ * hash_add - add an object to a hashtable ++ * @hashtable: hashtable to add to ++ * @node: the &struct hlist_node of the object to be added ++ * @key: the key of the object to be added ++ */ ++#define hash_add(hashtable, node, key) \ ++ hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) ++ ++/** ++ * hash_add_str - add a string object to a hashtable ++ * @hashtable: hashtable to add to ++ * @node: the &struct hlist_node of the object to be added ++ * @key: the string key of the object to be added ++ */ ++#define hash_add_str(hashtable, node, key) \ ++ hlist_add_head(node, &hashtable[hash(key, HASH_SIZE(hashtable))]) ++ ++/** ++ * hash_hashed - check whether an object is in any hashtable ++ * @node: the &struct hlist_node of the object to be checked ++ */ ++static inline int hash_hashed(struct hlist_node *node) ++{ ++ return !hlist_unhashed(node); ++} ++ ++static inline int __hash_empty(struct hlist_head *ht, unsigned int sz) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < sz; i++) ++ if (!hlist_empty(&ht[i])) ++ return 0; ++ ++ return 1; ++} ++ ++/** ++ * hash_empty - check whether a hashtable is empty ++ * @hashtable: hashtable to check ++ * ++ * This has to be a macro since HASH_BITS() will not work on pointers since ++ * it calculates the size during preprocessing. ++ */ ++#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable)) ++ ++/** ++ * hash_del - remove an object from a hashtable ++ * @node: &struct hlist_node of the object to remove ++ */ ++static inline void hash_del(struct hlist_node *node) ++{ ++ hlist_del_init(node); ++} ++ ++/** ++ * hash_for_each - iterate over a hashtable ++ * @name: hashtable to iterate ++ * @bkt: integer to use as bucket loop cursor ++ * @obj: the type * to use as a loop cursor for each entry ++ * @member: the name of the hlist_node within the struct ++ */ ++#define hash_for_each(name, bkt, obj, member) \ ++ for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ ++ (bkt)++)\ ++ hlist_for_each_entry(obj, &name[bkt], member) ++ ++/** ++ * hash_for_each_safe - iterate over a hashtable safe against removal of ++ * hash entry ++ * @name: hashtable to iterate ++ * @bkt: integer to use as bucket loop cursor ++ * @tmp: a &struct used for temporary storage ++ * @obj: the type * to use as a loop cursor for each entry ++ * @member: the name of the hlist_node within the struct ++ */ ++#define hash_for_each_safe(name, bkt, tmp, obj, member) \ ++ for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ ++ (bkt)++)\ ++ hlist_for_each_entry_safe(obj, tmp, &name[bkt], member) ++ ++/** ++ * hash_for_each_possible - iterate over all possible objects hashing to the ++ * same bucket ++ * @name: hashtable to iterate ++ * @obj: the type * to use as a loop cursor for each entry ++ * @member: the name of the hlist_node within the struct ++ * @key: the key of the objects to iterate over ++ */ ++#define hash_for_each_possible(name, obj, member, key) \ ++ hlist_for_each_entry(obj, &name[hash_min(key, HASH_BITS(name))], member) ++ ++/** ++ * hash_for_each_possible_safe - iterate over all possible objects hashing to the ++ * same bucket safe against removals ++ * @name: hashtable to iterate ++ * @obj: the type * to use as a loop cursor for each entry ++ * @tmp: a &struct used for temporary storage ++ * @member: the name of the hlist_node within the struct ++ * @key: the key of the objects to iterate over ++ */ ++#define hash_for_each_possible_safe(name, obj, tmp, member, key) \ ++ hlist_for_each_entry_safe(obj, tmp,\ ++ &name[hash_min(key, HASH_BITS(name))], member) ++ ++#endif diff --git a/autofs-5.1.6-add-helper-to-construct-mount-point-path.patch b/autofs-5.1.6-add-helper-to-construct-mount-point-path.patch new file mode 100644 index 0000000..1cb15cf --- /dev/null +++ b/autofs-5.1.6-add-helper-to-construct-mount-point-path.patch @@ -0,0 +1,225 @@ +autofs-5.1.6 - add helper to construct mount point path + +From: Ian Kent + +Add convenience helper to construct mount point path. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 3 +++ + lib/mounts.c | 23 +++++++++++++++++++++++ + modules/mount_bind.c | 19 +++++-------------- + modules/mount_changer.c | 19 +++++-------------- + modules/mount_ext2.c | 19 +++++-------------- + modules/mount_generic.c | 19 +++++-------------- + modules/mount_nfs.c | 21 ++++++++------------- + 8 files changed, 55 insertions(+), 69 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -135,6 +135,7 @@ xx/xx/2018 autofs-5.1.5 + - move submount check into conditional_alarm_add(). + - move lib/master.c to daemon/master.c. + - use master_list_empty() for list empty check. ++- add helper to construct mount point path. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -94,6 +94,9 @@ unsigned int linux_version_code(void); + int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *); + extern unsigned int nfs_mount_uses_string_options; + ++int mount_fullpath(char *fullpath, size_t max_len, ++ const char *root, const char *name); ++ + struct amd_entry; + + struct substvar *addstdenv(struct substvar *sv, const char *prefix); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -339,6 +339,29 @@ int check_nfs_mount_version(struct nfs_m + } + #endif + ++int mount_fullpath(char *fullpath, size_t max_len, ++ const char *root, const char *name) ++{ ++ int last, len; ++ ++ last = strlen(root) - 1; ++ ++ /* Root offset of multi-mount or direct or offset mount. ++ * Direct or offset mount, name (or root) is absolute path. ++ */ ++ if (root[last] == '/' || *name == '/') ++ len = snprintf(fullpath, max_len, "%s", root); ++ else ++ len = snprintf(fullpath, max_len, "%s/%s", root, name); ++ ++ if (len >= max_len) ++ return 0; ++ ++ fullpath[len] = '\0'; ++ ++ return len; ++} ++ + static char *set_env_name(const char *prefix, const char *name, char *buf) + { + size_t len; +--- autofs-5.1.4.orig/modules/mount_bind.c ++++ autofs-5.1.4/modules/mount_bind.c +@@ -122,21 +122,12 @@ int mount_mount(struct autofs_point *ap, + } + } + +- /* Root offset of multi-mount */ +- len = strlen(root); +- if (root[len - 1] == '/') { +- len = snprintf(fullpath, len, "%s", root); +- } else if (*name == '/') { +- /* +- * Direct or offset mount, name is absolute path so +- * don't use root (but with move mount changes root +- * is now the same as name). +- */ +- len = sprintf(fullpath, "%s", root); +- } else { +- len = sprintf(fullpath, "%s/%s", root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ if (!len) { ++ error(ap->logopt, ++ MODPREFIX "mount point path too long"); ++ return 1; + } +- fullpath[len] = '\0'; + + i = len; + while (--i > 0 && fullpath[i] == '/') +--- autofs-5.1.4.orig/modules/mount_changer.c ++++ autofs-5.1.4/modules/mount_changer.c +@@ -59,21 +59,12 @@ int mount_mount(struct autofs_point *ap, + + fstype = "iso9660"; + +- /* Root offset of multi-mount */ +- len = strlen(root); +- if (root[len - 1] == '/') { +- len = snprintf(fullpath, len, "%s", root); +- } else if (*name == '/') { +- /* +- * Direct or offset mount, name is absolute path so +- * don't use root (but with move mount changes root +- * is now the same as name). +- */ +- len = sprintf(fullpath, "%s", root); +- } else { +- len = sprintf(fullpath, "%s/%s", root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ if (!len) { ++ error(ap->logopt, ++ MODPREFIX "mount point path too long"); ++ return 1; + } +- fullpath[len] = '\0'; + + debug(ap->logopt, MODPREFIX "calling umount %s", what); + +--- autofs-5.1.4.orig/modules/mount_ext2.c ++++ autofs-5.1.4/modules/mount_ext2.c +@@ -55,21 +55,12 @@ int mount_mount(struct autofs_point *ap, + if (defaults_get_mount_verbose()) + mountlog = &log_info; + +- /* Root offset of multi-mount */ +- len = strlen(root); +- if (root[len - 1] == '/') { +- len = snprintf(fullpath, len, "%s", root); +- } else if (*name == '/') { +- /* +- * Direct or offset mount, name is absolute path so +- * don't use root (but with move mount changes root +- * is now the same as name). +- */ +- len = sprintf(fullpath, "%s", root); +- } else { +- len = sprintf(fullpath, "%s/%s", root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ if (!len) { ++ error(ap->logopt, ++ MODPREFIX "mount point path too long"); ++ return 1; + } +- fullpath[len] = '\0'; + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +--- autofs-5.1.4.orig/modules/mount_generic.c ++++ autofs-5.1.4/modules/mount_generic.c +@@ -54,21 +54,12 @@ int mount_mount(struct autofs_point *ap, + if (defaults_get_mount_verbose()) + mountlog = &log_info; + +- /* Root offset of multi-mount */ +- len = strlen(root); +- if (root[len - 1] == '/') { +- len = snprintf(fullpath, len, "%s", root); +- } else if (*name == '/') { +- /* +- * Direct or offset mount, name is absolute path so +- * don't use root (but with move mount changes root +- * is now the same as name). +- */ +- len = sprintf(fullpath, "%s", root); +- } else { +- len = sprintf(fullpath, "%s/%s", root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ if (!len) { ++ error(ap->logopt, ++ MODPREFIX "mount point path too long"); ++ return 1; + } +- fullpath[len] = '\0'; + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +--- autofs-5.1.4.orig/modules/mount_nfs.c ++++ autofs-5.1.4/modules/mount_nfs.c +@@ -212,6 +212,14 @@ int mount_mount(struct autofs_point *ap, + nfsoptions, nobind, nosymlink, ro); + } + ++ /* Construct mount point directory */ ++ len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ if (!len) { ++ error(ap->logopt, ++ MODPREFIX "mount point path too long"); ++ return 1; ++ } ++ + if (!parse_location(ap->logopt, &hosts, what, flags)) { + info(ap->logopt, MODPREFIX "no hosts available"); + return 1; +@@ -266,19 +274,6 @@ dont_probe: + return 1; + } + +- /* Construct and perhaps create mount point directory */ +- +- /* Root offset of multi-mount */ +- len = strlen(root); +- if (root[len - 1] == '/') { +- len = snprintf(fullpath, len, "%s", root); +- } else if (*name == '/') { +- len = sprintf(fullpath, "%s", root); +- } else { +- len = sprintf(fullpath, "%s/%s", root, name); +- } +- fullpath[len] = '\0'; +- + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + + status = mkdir_path(fullpath, mp_mode); diff --git a/autofs-5.1.6-add-sss-ECONREFUSED-return-handling.patch b/autofs-5.1.6-add-sss-ECONREFUSED-return-handling.patch new file mode 100644 index 0000000..5430c64 --- /dev/null +++ b/autofs-5.1.6-add-sss-ECONREFUSED-return-handling.patch @@ -0,0 +1,66 @@ +autofs-5.1.6 - add sss ECONREFUSED return handling + +From: Ian Kent + +The sss library has returned ECONNREFUSED for the case of sssd not +running for a long time now but autofs doesn't catch it, fix that. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 9 +++++++++ + 2 files changed, 10 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 5a3d785..2a45829 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -94,6 +94,7 @@ xx/xx/2018 autofs-5.1.5 + - fix lookup_nss_read_master() nsswicth check return. + - fix typo in open_sss_lib(). + - fix sss_master_map_wait timing. ++- add sss ECONREFUSED return handling. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index fbb6193..c393296 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -297,6 +297,9 @@ int lookup_read_master(struct master *master, time_t age, void *context) + if (ret) { + unsigned int retries; + ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; ++ + if (ret != ENOENT) + return NSS_STATUS_UNAVAIL; + +@@ -308,6 +311,8 @@ int lookup_read_master(struct master *master, time_t age, void *context) + ctxt, ctxt->mapname, &sss_ctxt, + retries); + if (ret) { ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; + if (ret == ENOENT) + return NSS_STATUS_NOTFOUND; + return NSS_STATUS_UNAVAIL; +@@ -415,6 +420,8 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + + ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt); + if (ret) { ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; + if (ret == ENOENT) + return NSS_STATUS_NOTFOUND; + return NSS_STATUS_UNAVAIL; +@@ -525,6 +532,8 @@ static int lookup_one(struct autofs_point *ap, + + ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt); + if (ret) { ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; + if (ret == ENOENT) + return NSS_STATUS_NOTFOUND; + return NSS_STATUS_UNAVAIL; diff --git a/autofs-5.1.6-add-support-for-new-sss-autofs-proto-version-call.patch b/autofs-5.1.6-add-support-for-new-sss-autofs-proto-version-call.patch new file mode 100644 index 0000000..1cea8cd --- /dev/null +++ b/autofs-5.1.6-add-support-for-new-sss-autofs-proto-version-call.patch @@ -0,0 +1,120 @@ +autofs-5.1.6 - add support for new sss autofs proto version call + +From: Ian Kent + +Add sss protocol feature version function existence check and local get +function. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 45 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 1830730..7c22aa1 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -96,6 +96,7 @@ xx/xx/2018 autofs-5.1.5 + - fix sss_master_map_wait timing. + - add sss ECONREFUSED return handling. + - use mapname in sss context for setautomntent(). ++- add support for new sss autofs proto version call. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index c44c55d..3819981 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -37,11 +37,29 @@ + + #define SSS_SO_NAME "libsss_autofs" + ++/* If the sss library protocol version is greater than 0 there are ++ * more possibile error returns from the sss autofs library calls. ++ * ++ * If ECONNREFUSED is returned then sssd is not running or not ++ * configured on the system, immediately return an unavailable ++ * status. ++ * ++ * A return of EHOSTDOWN means sss backend server is down so we ++ * should retry. ++ * ++ * With older sss ilibrary we can get a return of ENOENT for the ++ * above cases so also wait in that case since we can't be sure ++ * the map doesn't exist. ++ */ ++#define SSS_PROTO_VERSION 1 ++ ++unsigned int _sss_auto_protocol_version(unsigned int); + int _sss_setautomntent(const char *, void **); + int _sss_getautomntent_r(char **, char **, void *); + int _sss_getautomntbyname_r(char *, char **, void *); + int _sss_endautomntent(void **); + ++typedef unsigned int (*protocol_version_t) (unsigned int); + typedef int (*setautomntent_t) (const char *, void **); + typedef int (*getautomntent_t) (char **, char **, void *); + typedef int (*getautomntbyname_t) (char *, char **, void *); +@@ -50,6 +68,7 @@ typedef int (*endautomntent_t) (void **); + struct lookup_context { + const char *mapname; + void *dlhandle; ++ protocol_version_t protocol_version; + setautomntent_t setautomntent; + getautomntent_t getautomntent_r; + getautomntbyname_t getautomntbyname_r; +@@ -58,6 +77,8 @@ struct lookup_context { + }; + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ ++int sss_proto_version = SSS_PROTO_VERSION; /* 0 => initial version, ++ * >= 1 => new error handling. */ + + static int open_sss_lib(struct lookup_context *ctxt) + { +@@ -78,6 +99,11 @@ static int open_sss_lib(struct lookup_context *ctxt) + return 1; + ctxt->dlhandle = dh; + ++ /* Don't fail on NULL, it's simply not present in this version of the ++ * sss autofs library. ++ */ ++ ctxt->protocol_version = (protocol_version_t) dlsym(dh, "_sss_auto_protocol_version"); ++ + ctxt->setautomntent = (setautomntent_t) dlsym(dh, "_sss_setautomntent"); + if (!ctxt->setautomntent) + goto lib_names_fail; +@@ -193,6 +219,7 @@ int lookup_reinit(const char *mapfmt, + } + + new->dlhandle = ctxt->dlhandle; ++ new->protocol_version = ctxt->protocol_version; + new->setautomntent = ctxt->setautomntent; + new->getautomntent_r = ctxt->getautomntent_r; + new->getautomntbyname_r = ctxt->getautomntbyname_r; +@@ -219,6 +246,23 @@ static int setautomntent(unsigned int logopt, + return ret; + } + ++static unsigned int proto_version(struct lookup_context *ctxt) ++{ ++ unsigned int proto_version = 0; ++ ++ if (ctxt->protocol_version) { ++ /* If ctxt->protocol_version() is defined it's assumed ++ * that for sss_proto_version <= sss autofs library ++ * protocol version ctxt->protocol_version() will ++ * return the version requested by autofs to indicate ++ * it userstands what the autofs module is capable of ++ * handling. ++ */ ++ proto_version = ctxt->protocol_version(sss_proto_version); ++ } ++ return proto_version; ++} ++ + static int setautomntent_wait(unsigned int logopt, + struct lookup_context *ctxt, + void **sss_ctxt, unsigned int retries) diff --git a/autofs-5.1.6-change-mountpoint-to-mp-in-struct-ext_mount.patch b/autofs-5.1.6-change-mountpoint-to-mp-in-struct-ext_mount.patch new file mode 100644 index 0000000..65e2800 --- /dev/null +++ b/autofs-5.1.6-change-mountpoint-to-mp-in-struct-ext_mount.patch @@ -0,0 +1,74 @@ +autofs-5.1.6 - change mountpoint to mp in struct ext_mount + +From: Ian Kent + +Use simple name mp instead of mountpoint in struct ext_mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 14 +++++++------- + 2 files changed, 8 insertions(+), 7 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -118,6 +118,7 @@ xx/xx/2018 autofs-5.1.5 + - fix browse dir not re-created on symlink expire. + - update list.h. + - add hashtable implementation. ++- change mountpoint to mp in struct ext_mount. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -54,7 +54,7 @@ static size_t maxgrpbuf = 0; + #define EXT_MOUNTS_HASH_SIZE 50 + + struct ext_mount { +- char *mountpoint; ++ char *mp; + unsigned int umount; + struct list_head mount; + struct list_head mounts; +@@ -743,9 +743,9 @@ static void ext_mounts_hash_init(void) + ext_mounts_hash_init_done = 1; + } + +-static struct ext_mount *ext_mount_lookup(const char *mountpoint) ++static struct ext_mount *ext_mount_lookup(const char *mp) + { +- u_int32_t hval = hash(mountpoint, EXT_MOUNTS_HASH_SIZE); ++ u_int32_t hval = hash(mp, EXT_MOUNTS_HASH_SIZE); + struct list_head *p, *head; + + if (!ext_mounts_hash_init_done) +@@ -757,7 +757,7 @@ static struct ext_mount *ext_mount_looku + head = &ext_mounts_hash[hval]; + list_for_each(p, head) { + struct ext_mount *this = list_entry(p, struct ext_mount, mount); +- if (!strcmp(this->mountpoint, mountpoint)) ++ if (!strcmp(this->mp, mp)) + return this; + } + return NULL; +@@ -788,8 +788,8 @@ int ext_mount_add(struct list_head *entr + if (!em) + goto done; + +- em->mountpoint = strdup(path); +- if (!em->mountpoint) { ++ em->mp = strdup(path); ++ if (!em->mp) { + free(em); + goto done; + } +@@ -828,7 +828,7 @@ int ext_mount_remove(struct list_head *e + if (em->umount) + ret = 1; + if (list_empty(&em->mount)) { +- free(em->mountpoint); ++ free(em->mp); + free(em); + } + } diff --git a/autofs-5.1.6-cleanup-stale-logpri-fifo-pipes-on-unlink-and-exit.patch b/autofs-5.1.6-cleanup-stale-logpri-fifo-pipes-on-unlink-and-exit.patch new file mode 100644 index 0000000..5236ac1 --- /dev/null +++ b/autofs-5.1.6-cleanup-stale-logpri-fifo-pipes-on-unlink-and-exit.patch @@ -0,0 +1,101 @@ +autofs-5.1.6 - cleanup stale logpri fifo pipes on unlink and exit + +From: Ian Kent + +If the unlink and exit option is given then stale fifo pipe files +need to be cleaned up since the entire tree of mounts below autofs +managed directories will be unlinked as well as the autofs mounts +themselves. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 52 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -90,6 +90,7 @@ xx/xx/2018 autofs-5.1.5 + - improve force unlink option description. + - remove command fifo on autofs mount fail. + - add force unlink mounts and exit option. ++- cleanup stale logpri fifo pipes on unlink and exit. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -60,7 +60,8 @@ unsigned int nfs_mount_uses_string_optio + static struct nfs_mount_vers vers, check = {1, 1, 1}; + + /* autofs fifo name prefix */ +-const char *fifodir = AUTOFS_FIFO_DIR "/autofs.fifo"; ++#define FIFO_NAME_PREFIX "autofs.fifo" ++const char *fifodir = AUTOFS_FIFO_DIR "/" FIFO_NAME_PREFIX; + + const char *global_options; /* Global option, from command line */ + +@@ -887,6 +888,48 @@ out_free: + return ret; + } + ++static void cleanup_stale_logpri_fifo_pipes(void) ++{ ++ size_t prefix_len = strlen(FIFO_NAME_PREFIX); ++ char *dir = AUTOFS_FIFO_DIR; ++ size_t dir_len = strlen(dir); ++ struct dirent *dent; ++ DIR *dfd; ++ int ret; ++ ++ dfd = opendir(dir); ++ if (!dfd) { ++ warn(LOGOPT_ANY, "failed to open fifo dir %s", dir); ++ return; ++ } ++ ++ while ((dent = readdir(dfd))) { ++ char fifo_path[PATH_MAX]; ++ ++ if (!(dent->d_type & DT_FIFO)) ++ continue; ++ if (strncmp(FIFO_NAME_PREFIX, dent->d_name, prefix_len)) ++ continue; ++ if ((dir_len + 1 + strlen(dent->d_name)) >= PATH_MAX) { ++ warn(LOGOPT_ANY, "fifo path too long for buffer"); ++ continue; ++ } ++ ++ strcpy(fifo_path, dir); ++ strcat(fifo_path, "/"); ++ strcat(fifo_path, dent->d_name); ++ ++ ret = unlink(fifo_path); ++ if (ret == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ warn(LOGOPT_ANY, "unlink of fifo failed: %s", estr); ++ } ++ } ++ ++ closedir(dfd); ++} ++ + static void handle_fifo_message(struct autofs_point *ap, int fd) + { + int ret; +@@ -2670,7 +2713,13 @@ int main(int argc, char *argv[]) + } + } + +- if (!(do_force_unlink & UNLINK_AND_EXIT)) { ++ /* If the option to unlink all autofs mounts and exit has ++ * been given remove logpri fifo files as all the mounts ++ * will be detached leaving them stale. ++ */ ++ if (do_force_unlink & UNLINK_AND_EXIT) ++ cleanup_stale_logpri_fifo_pipes(); ++ else { + /* + * Mmm ... reset force unlink umount so we don't also do + * this in future when we receive a HUP signal. diff --git a/autofs-5.1.6-dont-prune-offset-map-entries.patch b/autofs-5.1.6-dont-prune-offset-map-entries.patch new file mode 100644 index 0000000..2a4a1c9 --- /dev/null +++ b/autofs-5.1.6-dont-prune-offset-map-entries.patch @@ -0,0 +1,49 @@ +autofs-5.1.6 - dont prune offset map entries + +From: Ian Kent + +Indirect maps create offset map entries for multi-mount map entries on +deamnd and remove them when they expire. + +Since they are created based on an owning map entry they don't correspond +to an actual map entry so they, and their owning map entry, should never +be pruned. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 9 +++++++++ + 2 files changed, 10 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 3608345..34b160e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -109,6 +109,7 @@ xx/xx/2018 autofs-5.1.5 + - refactor sss getautomntbyname(). + - improve sss getautomntbyname() error handling. + - use a valid timeout in lookup_prune_one_cache(). ++- dont prune offset map entries. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 8bf1335..2de622e 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1355,6 +1355,15 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + } + + if (ap->type == LKP_INDIRECT) { ++ /* Don't prune offset map entries since they are ++ * created on demand and managed by expire and don't ++ * prune the multi-map owner map entry. ++ */ ++ if (*me->key == '/' || me->multi == me) { ++ me = cache_enumerate(mc, me); ++ continue; ++ } ++ + /* If the map hasn't been read (nobrowse + * indirect mounts) then keep cached entries + * for POSITIVE_TIMEOUT. diff --git a/autofs-5.1.6-fix-a-regression-with-map-instance-lookup.patch b/autofs-5.1.6-fix-a-regression-with-map-instance-lookup.patch new file mode 100644 index 0000000..6400aa7 --- /dev/null +++ b/autofs-5.1.6-fix-a-regression-with-map-instance-lookup.patch @@ -0,0 +1,310 @@ +autofs-5.1.6 - fix a regression with map instance lookup + +From: Ian Kent + +Commit b66deff4241d ("autofs-5.1.3 - fix possible map instance memory +leak") introduced a regression. + +The change didn't fix the memory leak and also failed to fix the race +updating the map instance list that caused it. + +To fix this get rid of the horible temporary map usage and update the +instance list in place. Doing this causes some additional allocations +and frees but is somewhat simpler overall and avoids the race. + +Fixes: b66deff4241d ("autofs-5.1.3 - fix possible map instance memory leak") +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/lookup.c | 180 +++++++++++++++++++++++--------------------------------- + 2 files changed, 76 insertions(+), 105 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -76,6 +76,7 @@ xx/xx/2018 autofs-5.1.5 + - use local getmntent_r() in get_mnt_list(). + - use local getmntent_r() in tree_make_mnt_list(). + - fix missing initialization of autofs_point flags. ++- fix a regression with map instance lookup. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -64,6 +64,10 @@ static char *find_map_path(struct autofs + char *search_path; + struct stat st; + ++ /* Absolute path, just return a copy */ ++ if (mname[0] == '/') ++ return strdup(mname); ++ + /* + * This is different to the way it is in amd. + * autofs will always try to locate maps in AUTOFS_MAP_DIR +@@ -373,14 +377,27 @@ static int read_file_source_instance(str + char src_prog[] = "program"; + struct stat st; + char *type, *format; ++ char *path; ++ ++ if (map->argc < 1) { ++ error(ap->logopt, "invalid arguments for autofs_point"); ++ return NSS_STATUS_UNKNOWN; ++ } + +- if (stat(map->argv[0], &st) == -1) { +- warn(ap->logopt, "file map %s not found", map->argv[0]); ++ path = find_map_path(ap, map); ++ if (!path) ++ return NSS_STATUS_UNKNOWN; ++ ++ if (stat(path, &st) == -1) { ++ warn(ap->logopt, "file map %s not found", path); ++ free(path); + return NSS_STATUS_NOTFOUND; + } + +- if (!S_ISREG(st.st_mode)) ++ if (!S_ISREG(st.st_mode)) { ++ free(path); + return NSS_STATUS_NOTFOUND; ++ } + + if (st.st_mode & __S_IEXEC) + type = src_prog; +@@ -391,9 +408,23 @@ static int read_file_source_instance(str + + instance = master_find_source_instance(map, type, format, 0, NULL); + if (!instance) { +- int argc = map->argc; +- const char **argv = map->argv; ++ const char **argv; ++ int argc; ++ ++ argc = map->argc; ++ argv = copy_argv(map->argc, map->argv); ++ if (!argv) { ++ error(ap->logopt, "failed to copy args"); ++ free(path); ++ return NSS_STATUS_UNKNOWN; ++ } ++ if (argv[0]) ++ free((char *) argv[0]); ++ argv[0] = path; ++ path = NULL; ++ + instance = master_add_source_instance(map, type, format, age, argc, argv); ++ free_argv(argc, argv); + if (!instance) + return NSS_STATUS_UNAVAIL; + instance->recurse = map->recurse; +@@ -401,6 +432,9 @@ static int read_file_source_instance(str + } + instance->stale = map->stale; + ++ if (path) ++ free(path); ++ + return do_read_map(ap, instance, age); + } + +@@ -476,16 +510,11 @@ static int lookup_map_read_map(struct au + static enum nsswitch_status read_map_source(struct nss_source *this, + struct autofs_point *ap, struct map_source *map, time_t age) + { +- enum nsswitch_status result; +- struct map_source tmap; +- char *path; +- + if (strcasecmp(this->source, "files")) { + return read_source_instance(ap, map, this->source, age); + } + + /* +- * autofs built-in map for nsswitch "files" is "file". + * This is a special case as we need to append the + * normal location to the map name. + * note: It's invalid to specify a relative path. +@@ -496,50 +525,7 @@ static enum nsswitch_status read_map_sou + return NSS_STATUS_NOTFOUND; + } + +- this->source[4] = '\0'; +- tmap.flags = map->flags; +- tmap.type = this->source; +- tmap.format = map->format; +- tmap.name = map->name; +- tmap.lookup = map->lookup; +- tmap.mc = map->mc; +- tmap.instance = map->instance; +- tmap.exp_timeout = map->exp_timeout; +- tmap.recurse = map->recurse; +- tmap.depth = map->depth; +- tmap.stale = map->stale; +- tmap.argc = 0; +- tmap.argv = NULL; +- +- path = find_map_path(ap, map); +- if (!path) +- return NSS_STATUS_UNKNOWN; +- +- if (map->argc >= 1) { +- tmap.argc = map->argc; +- tmap.argv = copy_argv(map->argc, map->argv); +- if (!tmap.argv) { +- error(ap->logopt, "failed to copy args"); +- free(path); +- return NSS_STATUS_UNKNOWN; +- } +- if (tmap.argv[0]) +- free((char *) tmap.argv[0]); +- tmap.argv[0] = path; +- } else { +- error(ap->logopt, "invalid arguments for autofs_point"); +- free(path); +- return NSS_STATUS_UNKNOWN; +- } +- +- pthread_cleanup_push(argv_cleanup, &tmap); +- result = read_file_source_instance(ap, &tmap, age); +- pthread_cleanup_pop(1); +- +- if (!map->instance) +- map->instance = tmap.instance; +- +- return result; ++ return read_file_source_instance(ap, map, age); + } + + int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age) +@@ -925,17 +911,30 @@ static int lookup_name_file_source_insta + time_t age = monotonic_time(NULL); + struct stat st; + char *type, *format; ++ char *path; + + if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD) + return lookup_amd_instance(ap, map, name, name_len); + +- if (stat(map->argv[0], &st) == -1) { ++ if (map->argc < 1) { ++ error(ap->logopt, "invalid arguments for autofs_point"); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ path = find_map_path(ap, map); ++ if (!path) ++ return NSS_STATUS_UNKNOWN; ++ ++ if (stat(path, &st) == -1) { + debug(ap->logopt, "file map not found"); ++ free(path); + return NSS_STATUS_NOTFOUND; + } + +- if (!S_ISREG(st.st_mode)) ++ if (!S_ISREG(st.st_mode)) { ++ free(path); + return NSS_STATUS_NOTFOUND; ++ } + + if (st.st_mode & __S_IEXEC) + type = src_prog; +@@ -946,15 +945,32 @@ static int lookup_name_file_source_insta + + instance = master_find_source_instance(map, type, format, 0, NULL); + if (!instance) { +- int argc = map->argc; +- const char **argv = map->argv; ++ const char **argv; ++ int argc; ++ ++ argc = map->argc; ++ argv = copy_argv(map->argc, map->argv); ++ if (!argv) { ++ error(ap->logopt, "failed to copy args"); ++ free(path); ++ return NSS_STATUS_UNKNOWN; ++ } ++ if (argv[0]) ++ free((char *) argv[0]); ++ argv[0] = path; ++ path = NULL; ++ + instance = master_add_source_instance(map, type, format, age, argc, argv); ++ free_argv(argc, argv); + if (!instance) + return NSS_STATUS_NOTFOUND; + instance->recurse = map->recurse; + instance->depth = map->depth; + } + ++ if (path) ++ free(path); ++ + return do_lookup_mount(ap, instance, name, name_len); + } + +@@ -1030,10 +1046,6 @@ static enum nsswitch_status lookup_map_n + struct autofs_point *ap, struct map_source *map, + const char *name, int name_len) + { +- enum nsswitch_status result; +- struct map_source tmap; +- char *path; +- + if (strcasecmp(this->source, "files")) + return lookup_name_source_instance(ap, map, + this->source, name, name_len); +@@ -1050,49 +1062,7 @@ static enum nsswitch_status lookup_map_n + return NSS_STATUS_NOTFOUND; + } + +- this->source[4] = '\0'; +- tmap.flags = map->flags; +- tmap.type = this->source; +- tmap.format = map->format; +- tmap.name = map->name; +- tmap.mc = map->mc; +- tmap.instance = map->instance; +- tmap.exp_timeout = map->exp_timeout; +- tmap.recurse = map->recurse; +- tmap.depth = map->depth; +- tmap.argc = 0; +- tmap.argv = NULL; +- +- path = find_map_path(ap, map); +- if (!path) +- return NSS_STATUS_UNKNOWN; +- +- if (map->argc >= 1) { +- tmap.argc = map->argc; +- tmap.argv = copy_argv(map->argc, map->argv); +- if (!tmap.argv) { +- error(ap->logopt, "failed to copy args"); +- free(path); +- return NSS_STATUS_UNKNOWN; +- } +- if (tmap.argv[0]) +- free((char *) tmap.argv[0]); +- tmap.argv[0] = path; +- } else { +- error(ap->logopt, "invalid arguments for autofs_point"); +- free(path); +- return NSS_STATUS_UNKNOWN; +- } +- +- result = lookup_name_file_source_instance(ap, &tmap, name, name_len); +- +- if (!map->instance) +- map->instance = tmap.instance; +- +- /* path is freed in free_argv */ +- free_argv(tmap.argc, tmap.argv); +- +- return result; ++ return lookup_name_file_source_instance(ap, map, name, name_len); + } + + static struct map_source *lookup_get_map_source(struct master_mapent *entry) diff --git a/autofs-5.1.6-fix-autofs-mount-options-construction.patch b/autofs-5.1.6-fix-autofs-mount-options-construction.patch new file mode 100644 index 0000000..e02f640 --- /dev/null +++ b/autofs-5.1.6-fix-autofs-mount-options-construction.patch @@ -0,0 +1,273 @@ +autofs-5.1.6 - fix autofs mount options construction + +From: Ian Kent + +There's an off by one length error in the autofs mount options +construction. + +Consolidate the options construction into make_options_string() and +use snprintf() to verify the options length calculation is correct. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 46 ++----------------------- + daemon/indirect.c | 23 +----------- + include/mounts.h | 3 + + lib/mounts.c | 98 +++++++++++++++++++++++++++++++++++++++++++++--------- + 5 files changed, 92 insertions(+), 79 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -80,6 +80,7 @@ xx/xx/2018 autofs-5.1.5 + - fix trailing dollar sun entry expansion. + - initialize struct addrinfo for getaddrinfo() calls. + - fix quoted string length calc in expandsunent(). ++- fix autofs mount options construction. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -348,29 +348,10 @@ int do_mount_autofs_direct(struct autofs + } + + if (!mp->options) { +- mp->options = make_options_string(ap->path, ap->kpipefd, str_direct); ++ mp->options = make_options_string(ap->path, ++ ap->kpipefd, str_direct, ap->flags); + if (!mp->options) + return 0; +- +- if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && +- ((get_kver_major() == 5 && get_kver_minor() > 3) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 12); +- if (tmp) { +- strcat(tmp, ",strictexpire"); +- mp->options = tmp; +- } +- } +- +- if ((ap->flags & MOUNT_FLAG_IGNORE) && +- ((get_kver_major() == 5 && get_kver_minor() > 4) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 7); +- if (tmp) { +- strcat(tmp, ",ignore"); +- mp->options = tmp; +- } +- } + } + + /* In case the directory doesn't exist, try to mkdir it */ +@@ -676,29 +657,10 @@ int mount_autofs_offset(struct autofs_po + } + + if (!mp->options) { +- mp->options = make_options_string(ap->path, ap->kpipefd, str_offset); ++ mp->options = make_options_string(ap->path, ++ ap->kpipefd, str_offset, ap->flags); + if (!mp->options) + return MOUNT_OFFSET_OK; +- +- if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && +- ((get_kver_major() == 5 && get_kver_minor() > 3) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 12); +- if (tmp) { +- strcat(tmp, ",strictexpire"); +- mp->options = tmp; +- } +- } +- +- if ((ap->flags & MOUNT_FLAG_IGNORE) && +- ((get_kver_major() == 5 && get_kver_minor() > 4) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 7); +- if (tmp) { +- strcat(tmp, ",ignore"); +- mp->options = tmp; +- } +- } + } + + strcpy(mountpoint, root); +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -78,32 +78,13 @@ static int do_mount_autofs_indirect(stru + } + } + +- options = make_options_string(ap->path, ap->kpipefd, str_indirect); ++ options = make_options_string(ap->path, ++ ap->kpipefd, str_indirect, ap->flags); + if (!options) { + error(ap->logopt, "options string error"); + goto out_err; + } + +- if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && +- ((get_kver_major() == 5 && get_kver_minor() > 3) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(options, strlen(options) + 12); +- if (tmp) { +- strcat(tmp, ",strictexpire"); +- options = tmp; +- } +- } +- +- if ((ap->flags & MOUNT_FLAG_IGNORE) && +- ((get_kver_major() == 5 && get_kver_minor() > 4) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(options, strlen(options) + 7); +- if (tmp) { +- strcat(tmp, ",ignore"); +- options = tmp; +- } +- } +- + /* In case the directory doesn't exist, try to mkdir it */ + if (mkdir_path(root, mp_mode) < 0) { + if (errno != EEXIST && errno != EROFS) { +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -94,7 +94,8 @@ void free_amd_entry_list(struct list_hea + 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_options_string(char *path, int pipefd, ++ const char *type, unsigned int flags); + char *make_mnt_name_string(char *path); + int ext_mount_add(struct list_head *, const char *, unsigned int); + int ext_mount_remove(struct list_head *, const char *); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -599,43 +599,111 @@ void free_amd_entry_list(struct list_hea + } + } + ++static int cacl_max_options_len(unsigned int flags) ++{ ++ unsigned int kver_major = get_kver_major(); ++ unsigned int kver_minor = get_kver_minor(); ++ int max_len; ++ ++ /* %d and %u are maximum lenght of 10 and mount type is maximum ++ * length of 9 (e. ",indirect"). ++ * The base temaplate is "fd=%d,pgrp=%u,minproto=5,maxproto=%d" ++ * plus the length of mount type plus 1 for the NULL. ++ */ ++ max_len = 79 + 1; ++ ++ if (kver_major < 5 || (kver_major == 5 && kver_minor < 4)) ++ goto out; ++ ++ /* maybe add ",strictexpire" */ ++ if (flags & MOUNT_FLAG_STRICTEXPIRE) ++ max_len += 13; ++ ++ if (kver_major == 5 && kver_minor < 5) ++ goto out; ++ ++ /* maybe add ",ignore" */ ++ if (flags & MOUNT_FLAG_IGNORE) ++ max_len += 7; ++out: ++ return max_len; ++} ++ + /* + * Make common autofs mount options string + */ +-char *make_options_string(char *path, int pipefd, const char *extra) ++char *make_options_string(char *path, int pipefd, ++ const char *type, unsigned int flags) + { ++ unsigned int kver_major = get_kver_major(); ++ unsigned int kver_minor = get_kver_minor(); + char *options; +- int len; ++ int max_len, len, new; + +- options = malloc(MAX_OPTIONS_LEN + 1); ++ max_len = cacl_max_options_len(flags); ++ ++ options = malloc(max_len); + if (!options) { + logerr("can't malloc options string"); + return NULL; + } + +- if (extra) +- len = snprintf(options, MAX_OPTIONS_LEN, ++ if (type) ++ len = snprintf(options, max_len, + options_template_extra, + pipefd, (unsigned) getpgrp(), +- AUTOFS_MAX_PROTO_VERSION, extra); ++ AUTOFS_MAX_PROTO_VERSION, type); + else +- len = snprintf(options, MAX_OPTIONS_LEN, options_template, ++ len = snprintf(options, max_len, options_template, + pipefd, (unsigned) getpgrp(), + AUTOFS_MAX_PROTO_VERSION); + +- if (len >= MAX_OPTIONS_LEN) { +- logerr("buffer to small for options - truncated"); +- len = MAX_OPTIONS_LEN - 1; ++ if (len < 0) ++ goto error_out; ++ ++ if (len >= max_len) ++ goto truncated; ++ ++ if (kver_major < 5 || (kver_major == 5 && kver_minor < 4)) ++ goto out; ++ ++ /* maybe add ",strictexpire" */ ++ if (flags & MOUNT_FLAG_STRICTEXPIRE) { ++ new = snprintf(options + len, ++ max_len, "%s", ",strictexpire"); ++ if (new < 0) ++ goto error_out; ++ len += new; ++ if (len >= max_len) ++ goto truncated; + } + +- if (len < 0) { +- logerr("failed to malloc autofs mount options for %s", path); +- free(options); +- return NULL; ++ if (kver_major == 5 && kver_minor < 5) ++ goto out; ++ ++ /* maybe add ",ignore" */ ++ if (flags & MOUNT_FLAG_IGNORE) { ++ new = snprintf(options + len, ++ max_len, "%s", ",ignore"); ++ if (new < 0) ++ goto error_out; ++ len += new; ++ if (len >= max_len) ++ goto truncated; + } ++out: + options[len] = '\0'; +- + return options; ++ ++truncated: ++ logerr("buffer to small for options - truncated"); ++ len = max_len -1; ++ goto out; ++ ++error_out: ++ logerr("error constructing mount options string for %s", path); ++ free(options); ++ return NULL; + } + + char *make_mnt_name_string(char *path) diff --git a/autofs-5.1.6-fix-browse-dir-not-re-created-on-symlink-expire.patch b/autofs-5.1.6-fix-browse-dir-not-re-created-on-symlink-expire.patch new file mode 100644 index 0000000..aafc5c4 --- /dev/null +++ b/autofs-5.1.6-fix-browse-dir-not-re-created-on-symlink-expire.patch @@ -0,0 +1,52 @@ +autofs-5.1.6 - fix browse dir not re-created on symlink expire + +From: Ian Kent + +If symlinks are being used for mounts and the autofs mount has browse mode +enabled when a symlink is removed at expire the browse mode directory needs +to be re-created. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 19 +++++++++++++++++++ + 2 files changed, 20 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -115,6 +115,7 @@ xx/xx/2018 autofs-5.1.5 + - remove unused function dump_master(). + - fix additional typing errors. + - make bind mounts propagation slave by default. ++- fix browse dir not re-created on symlink expire. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -651,6 +651,25 @@ int umount_multi(struct autofs_point *ap + "failed to remove symlink %s", path); + return 1; + } ++ /* Check if the autofs mount has browse mode enabled. ++ * If so re-create the directory entry. ++ */ ++ if (ap->flags | MOUNT_FLAG_GHOST) { ++ int ret; ++ ++ /* If the browse directory create fails log an ++ * error and continue anyway since the expire ++ * has succeeded. ++ */ ++ ret = mkdir_path(path, mp_mode); ++ if (ret && errno != EEXIST) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ warn(ap->logopt, ++ "mkdir_path %s failed: %s", path, estr); ++ } ++ } + /* Check for an external mount and attempt umount if needed */ + mounts_mutex_lock(ap); + entry = __master_find_amdmount(ap, path); diff --git a/autofs-5.1.6-fix-direct-mount-unlink_mount_tree-path.patch b/autofs-5.1.6-fix-direct-mount-unlink_mount_tree-path.patch new file mode 100644 index 0000000..51b4b5e --- /dev/null +++ b/autofs-5.1.6-fix-direct-mount-unlink_mount_tree-path.patch @@ -0,0 +1,40 @@ +autofs-5.1.6 - fix direct mount unlink_mount_tree() path + +From: Ian Kent + +Oops! + +The path used if unlink_mount_tree() is called for direct mount entries +is not correct, fix it. + +Note: the mount table handling has changed and using the --force option +with automount when direct mount maps are large will result in somewhat +larger overhead. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -83,6 +83,7 @@ xx/xx/2018 autofs-5.1.5 + - fix autofs mount options construction. + - mount_nfs.c fix local rdma share not mounting. + - fix incorrect systemctl command syntax in autofs(8). ++- fix direct mount unlink_mount_tree() path. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -311,7 +311,7 @@ int do_mount_autofs_direct(struct autofs + return 0; + } + +- ret = unlink_mount_tree(ap, ap->path); ++ ret = unlink_mount_tree(ap, me->key); + if (!ret) { + error(ap->logopt, + "already mounted as other than autofs " diff --git a/autofs-5.1.6-fix-double-quoting-in-auto.smb.patch b/autofs-5.1.6-fix-double-quoting-in-auto.smb.patch new file mode 100644 index 0000000..44e655a --- /dev/null +++ b/autofs-5.1.6-fix-double-quoting-in-auto.smb.patch @@ -0,0 +1,36 @@ +autofs-5.1.6 - fix double quoting in auto.smb + +From: Ian Kent + +The example program mount script installed to /etc/auto.smb incorrectly +adds a quote for the trailing dollar of special Windows mounts. But they +are already surrounded by double quotes. This may have been handled by +mount.cifs at some point but it's failing now. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + samples/auto.smb | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +--- autofs-5.1.4.orig/samples/auto.smb ++++ autofs-5.1.4/samples/auto.smb +@@ -75,8 +75,6 @@ $SMBCLIENT $smbopts -gL "$key" 2>/dev/nu + dir = $2 + loc = $2 + # Enclose mount dir and location in quotes +- # Double quote "$" in location as it is special +- gsub(/\$$/, "\\$", loc); + gsub(/\&/,"\\\\&",loc) + print " \\\n\t \"/" dir "\"", "\"://" key "/" loc "\"" + } +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -81,6 +81,7 @@ + - fix kernel mount status notification. + - fix set open file limit. + - improve descriptor open error reporting. ++- fix double quoting in auto.smb. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. diff --git a/autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch b/autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch new file mode 100644 index 0000000..f76ccbe --- /dev/null +++ b/autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch @@ -0,0 +1,35 @@ +autofs-5.1.6 - fix double quoting of ampersand in auto.smb as well + +From: Ian Kent + +The example program mount script installed to /etc/auto.smb incorrectly +adds a quote for the & character that causes mount failures. But the +produced map entry is already surrounded by double quotes. This may have +been handled by mount.cifs at some point but it's failing now. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + samples/auto.smb | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- autofs-5.1.4.orig/samples/auto.smb ++++ autofs-5.1.4/samples/auto.smb +@@ -75,7 +75,6 @@ $SMBCLIENT $smbopts -gL "$key" 2>/dev/nu + dir = $2 + loc = $2 + # Enclose mount dir and location in quotes +- gsub(/\&/,"\\\\&",loc) + print " \\\n\t \"/" dir "\"", "\"://" key "/" loc "\"" + } + END { if (!first) print "\n"; else exit 1 } +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -82,6 +82,7 @@ + - fix set open file limit. + - improve descriptor open error reporting. + - fix double quoting in auto.smb. ++- fix double quoting of ampersand in auto.smb as well. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. diff --git a/autofs-5.1.6-fix-empty-mounts-list-return-from-unlink_mount_tree.patch b/autofs-5.1.6-fix-empty-mounts-list-return-from-unlink_mount_tree.patch new file mode 100644 index 0000000..8ab0516 --- /dev/null +++ b/autofs-5.1.6-fix-empty-mounts-list-return-from-unlink_mount_tree.patch @@ -0,0 +1,47 @@ +autofs-5.1.6 - fix empty mounts list return from unlink_mount_tree() + +From: Ian Kent + +If there are no appropriate mounts found by get_mnt_list() then +unlink_mount_tree() should return 1 not 0 since if there are no +mounts to umount this shouldn't cause a failure return. + +Also, if a real error occurs in get_mnt_list() we should check for +it and return a failure from unlink_mount_tree() since that would +be mount table not found or out of memory. If that's ignored things +would only get worse from that point. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++++++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -75,6 +75,7 @@ + - fix direct mount deadlock. + - fix lookup_prune_one_cache() refactoring change. + - add missing description of null map option. ++- fix empty mounts list return from unlink_mount_tree(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2115,9 +2115,13 @@ int unlink_mount_tree(struct autofs_poin + struct mnt_list *mnts, *mnt; + int rv, ret = 1; + ++ errno = 0; + mnts = get_mnt_list(mp, 1); +- if (!mnts) +- return 0; ++ if (!mnts) { ++ if (errno) ++ return 0; ++ return 1; ++ } + + for (mnt = mnts; mnt; mnt = mnt->next) { + if (mnt->flags & MNTS_AUTOFS) diff --git a/autofs-5.1.6-fix-incorrect-logical-compare-in-unlink_mount_tree.patch b/autofs-5.1.6-fix-incorrect-logical-compare-in-unlink_mount_tree.patch new file mode 100644 index 0000000..4556683 --- /dev/null +++ b/autofs-5.1.6-fix-incorrect-logical-compare-in-unlink_mount_tree.patch @@ -0,0 +1,33 @@ +autofs-5.1.6 - fix incorrect logical compare in unlink_mount_tree() + +From: Ian Kent + +Fix silly mistake using or instead of and in unlink_mount_tree(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -85,6 +85,7 @@ xx/xx/2018 autofs-5.1.5 + - fix incorrect systemctl command syntax in autofs(8). + - fix direct mount unlink_mount_tree() path. + - fix unlink mounts umount order. ++- fix incorrect logical compare in unlink_mount_tree(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -959,7 +959,7 @@ int unlink_mount_tree(struct autofs_poin + return 0; + + for (mnt = mnts; mnt; mnt = mnt->next) { +- if (mnt->flags | MNTS_AUTOFS) ++ if (mnt->flags & MNTS_AUTOFS) + rv = umount2(mnt->mp, MNT_DETACH); + else + rv = spawn_umount(ap->logopt, "-l", mnt->mp, NULL); diff --git a/autofs-5.1.6-fix-incorrect-systemctl-command-syntax-in-autofs-8.patch b/autofs-5.1.6-fix-incorrect-systemctl-command-syntax-in-autofs-8.patch new file mode 100644 index 0000000..b25e644 --- /dev/null +++ b/autofs-5.1.6-fix-incorrect-systemctl-command-syntax-in-autofs-8.patch @@ -0,0 +1,34 @@ +autofs-5.1.6 - fix incorrect systemctl command syntax in autofs(8) + +From: Ian Kent + +In the body of the OPERATION section "systemctl autofs.service status" +is used when it should be "systemctl status autofs.service". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/autofs.8.in | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -82,6 +82,7 @@ xx/xx/2018 autofs-5.1.5 + - fix quoted string length calc in expandsunent(). + - fix autofs mount options construction. + - mount_nfs.c fix local rdma share not mounting. ++- fix incorrect systemctl command syntax in autofs(8). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/man/autofs.8.in ++++ autofs-5.1.4/man/autofs.8.in +@@ -58,7 +58,7 @@ service control reload action must be re + .P + .B @@initdir@@/autofs status + or +-.B systemctl autofs.service status ++.B systemctl status autofs.service + will display the status of, + .BR automount (8), + running or not. When using the systemd init system the status output includes diff --git a/autofs-5.1.6-fix-lookup_nss_read_master-nsswicth-check-return.patch b/autofs-5.1.6-fix-lookup_nss_read_master-nsswicth-check-return.patch new file mode 100644 index 0000000..15909c5 --- /dev/null +++ b/autofs-5.1.6-fix-lookup_nss_read_master-nsswicth-check-return.patch @@ -0,0 +1,42 @@ +autofs-5.1.6 - fix lookup_nss_read_master() nsswicth check return + +From: Ian Kent + +When reading master map nsswicth sources the result of reading the master +map should be returned rather than the result of the nsswitch check. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 6 ++---- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 52fc100..3c00184 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -91,6 +91,7 @@ xx/xx/2018 autofs-5.1.5 + - remove command fifo on autofs mount fail. + - add force unlink mounts and exit option. + - cleanup stale logpri fifo pipes on unlink and exit. ++- fix lookup_nss_read_master() nsswicth check return. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/daemon/lookup.c b/daemon/lookup.c +index d9d3a4e..2b9c7e8 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -303,10 +303,8 @@ int lookup_nss_read_master(struct master *master, time_t age) + master->read_fail = 1; + + status = check_nss_result(this, result); +- if (status >= 0) { +- free_sources(&nsslist); +- return status; +- } ++ if (status >= 0) ++ break; + } + + if (!list_empty(&nsslist)) diff --git a/autofs-5.1.6-fix-program-map-multi-mount-lookup-after-mount-fail.patch b/autofs-5.1.6-fix-program-map-multi-mount-lookup-after-mount-fail.patch new file mode 100644 index 0000000..2fed0c8 --- /dev/null +++ b/autofs-5.1.6-fix-program-map-multi-mount-lookup-after-mount-fail.patch @@ -0,0 +1,60 @@ +autofs-5.1.6 - fix program map multi-mount lookup after mount fail + +From: Ian Kent + +For the case of a singleton multi-mount program map lookup following +a mount fail (and the negative timeout has passed) the lookup key is +what's expected for an indirect map key but the the root offset map +entry already exists. This causes autofs to think it has an incorrect +lookup key and it fails the lookup when it should take the opptunity +to delete and update the cache entry since it's not actually in use +yet. + +If a check is done to see if the lookup is for the root offset, +deleting the entry fails because it contains an offset. Later when +parsing is done the offset will get updated and can get out of sync +with the entry of the multi-mount owner. That's not a problem as the +offsets would be deleted on eventual expire but it's best to clean +out the entry and start a fresh so the most up to date map entry +is being used. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_program.c | 7 +++++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -27,6 +27,7 @@ + - rename path to m_offset in update_offset_entry(). + - don't pass root to do_mount_autofs_offset(). + - rename tree implementation functions. ++- fix program map multi-mount lookup after mount fail. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/lookup_program.c ++++ autofs-5.1.4/modules/lookup_program.c +@@ -664,7 +664,7 @@ int lookup_mount(struct autofs_point *ap + name_len, ent, ctxt->parse->context); + goto out_free; + } else { +- if (me->multi) { ++ if (me->multi && me->multi != me) { + cache_unlock(mc); + warn(ap->logopt, MODPREFIX + "unexpected lookup for active multi-mount" +@@ -674,8 +674,11 @@ int lookup_mount(struct autofs_point *ap + cache_unlock(mc); + cache_writelock(mc); + me = cache_lookup_distinct(mc, name); +- if (me) ++ if (me) { ++ if (me->multi) ++ cache_delete_offset_list(mc, name); + cache_delete(mc, name); ++ } + cache_unlock(mc); + } + } diff --git a/autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch b/autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch new file mode 100644 index 0000000..d1bcde8 --- /dev/null +++ b/autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch @@ -0,0 +1,44 @@ +autofs-5.1.6 - fix quoted string length calc in expandsunent() + +From: Ian Kent + +The expandsunent() function in modules/parse_sun.c fails to properly +handle the ending " in a quoted string causing the length calculation +to not account for the ending quote and also doesn't properly account +for the remainder of the string being expanded. + +Also, when called again (after being called to get the length) the +allocated buffer is too small leading to out of bounds accesses. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -79,6 +79,7 @@ xx/xx/2018 autofs-5.1.5 + - fix a regression with map instance lookup. + - fix trailing dollar sun entry expansion. + - initialize struct addrinfo for getaddrinfo() calls. ++- fix quoted string length calc in expandsunent(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -213,9 +213,11 @@ int expandsunent(const char *src, char * + *dst++ = *src; + src++; + } +- if (*src && dst) { ++ if (*src) { + len++; +- *dst++ = *src++; ++ if (dst) ++ *dst++ = *src; ++ src++; + } + break; + diff --git a/autofs-5.1.6-fix-remount-expire.patch b/autofs-5.1.6-fix-remount-expire.patch new file mode 100644 index 0000000..fd9c75f --- /dev/null +++ b/autofs-5.1.6-fix-remount-expire.patch @@ -0,0 +1,48 @@ +autofs-5.1.6 - fix remount expire + +From: Ian Kent + +When starting autofs when there are active mounts due to in use +mounts from a previous shutdown, and a mount entry has offsets, +and an offset doesn't have a real mount due to a non-strict fail +returning success for the remount a file handle is incorrectly +left open. + +The file handle gets assingned to the offset entry for expires +but since there is no mount to expire it never gets closed which +prevents the multi-mount owner itself from expiring. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -126,6 +126,7 @@ xx/xx/2018 autofs-5.1.5 + - use mnt_list for amdmounts. + - make umount_autofs() static. + - remove force parameter from umount_all(). ++- fix remount expire. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2205,8 +2205,14 @@ int try_remount(struct autofs_point *ap, + if (fd != -1) { + if (type == t_indirect) + ap->ioctlfd = fd; +- else ++ else { ++ if (type == t_offset && ++ !is_mounted(me->key, MNTS_REAL)) { ++ ops->close(ap->logopt, fd); ++ fd = -1; ++ } + me->ioctlfd = fd; ++ } + return 1; + } + diff --git a/autofs-5.1.6-fix-retries-check-in-setautomntent_wait.patch b/autofs-5.1.6-fix-retries-check-in-setautomntent_wait.patch new file mode 100644 index 0000000..2c3625a --- /dev/null +++ b/autofs-5.1.6-fix-retries-check-in-setautomntent_wait.patch @@ -0,0 +1,38 @@ +autofs-5.1.6 - fix retries check in setautomntent_wait() + +From: Ian Kent + +In setautomntent_wait() on exit from the retry loop retry will always +be greater than retries if the retry limit is reached. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 7c22aa1..b3ffbb6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -97,6 +97,7 @@ xx/xx/2018 autofs-5.1.5 + - add sss ECONREFUSED return handling. + - use mapname in sss context for setautomntent(). + - add support for new sss autofs proto version call. ++- fix retries check in setautomntent_wait(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 3819981..d65e71c 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -299,7 +299,7 @@ static int setautomntent_wait(unsigned int logopt, + *sss_ctxt = NULL; + } + +- if (retry == retries) ++ if (retry > retries) + ret = ETIMEDOUT; + + estr = strerror_r(ret, buf, MAX_ERR_BUF); diff --git a/autofs-5.1.6-fix-sss-master-map-wait-timing.patch b/autofs-5.1.6-fix-sss-master-map-wait-timing.patch new file mode 100644 index 0000000..95d1d09 --- /dev/null +++ b/autofs-5.1.6-fix-sss-master-map-wait-timing.patch @@ -0,0 +1,60 @@ +autofs-5.1.6 - fix sss_master_map_wait timing + +From: Ian Kent + +The sss lookup retry delay is half a second but the sss daemon timeouts +are fairly long so change the retry delay to one second. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 10 +++++----- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 63c6d41..5a3d785 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -93,6 +93,7 @@ xx/xx/2018 autofs-5.1.5 + - cleanup stale logpri fifo pipes on unlink and exit. + - fix lookup_nss_read_master() nsswicth check return. + - fix typo in open_sss_lib(). ++- fix sss_master_map_wait timing. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index cc18e62..fbb6193 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -30,8 +30,8 @@ + + #define MAPFMT_DEFAULT "sun" + +-/* Half a second between retries */ +-#define SETAUTOMOUNTENT_MASTER_INTERVAL 500000000 ++/* One second between retries */ ++#define SSS_WAIT_INTERVAL 1 + + #define MODPREFIX "lookup(sss): " + +@@ -230,8 +230,8 @@ static int setautomntent_wait(unsigned int logopt, + + *sss_ctxt = NULL; + +- while (++retry < retries) { +- struct timespec t = { 0, SETAUTOMOUNTENT_MASTER_INTERVAL }; ++ while (++retry <= retries) { ++ struct timespec t = { SSS_WAIT_INTERVAL, 0 }; + struct timespec r; + + ret = ctxt->setautomntent(mapname, sss_ctxt); +@@ -300,7 +300,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + if (ret != ENOENT) + return NSS_STATUS_UNAVAIL; + +- retries = defaults_get_sss_master_map_wait() * 2; ++ retries = defaults_get_sss_master_map_wait(); + if (retries <= 0) + return NSS_STATUS_NOTFOUND; + diff --git a/autofs-5.1.6-fix-stale-offset-directories-disable-mount.patch b/autofs-5.1.6-fix-stale-offset-directories-disable-mount.patch new file mode 100644 index 0000000..1b1b74f --- /dev/null +++ b/autofs-5.1.6-fix-stale-offset-directories-disable-mount.patch @@ -0,0 +1,57 @@ +autofs-5.1.6 - fix stale offset directories disable mount + +From: Ian Kent + +When starting autofs when there are active mounts due to in use +mounts from a previous shutdown, and a mount entry has offsets +that are within an autofs mount, the mount point directories are +incorrectly marked as not created by us when re-connecting to the +mount so they are not removed at expire. + +Since the base autofs mount directory needs to be empty for mounts +to be triggered these directories disable automounting for the mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 12 ++++++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -127,6 +127,7 @@ xx/xx/2018 autofs-5.1.5 + - make umount_autofs() static. + - remove force parameter from umount_all(). + - fix remount expire. ++- fix stale offset directories disable mount. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2182,15 +2182,23 @@ int try_remount(struct autofs_point *ap, + * number for the mount but we can't know if we created + * it or not. However, if this is an indirect mount with + * the nobrowse option we need to remove the mount point +- * directory at umount anyway. ++ * directory at umount anyway. Also, if this is an offset ++ * mount that's not within a real mount then we know we ++ * created it so we must remove it on expire for the mount ++ * to function. + */ + if (type == t_indirect) { + if (ap->flags & MOUNT_FLAG_GHOST) + ap->flags &= ~MOUNT_FLAG_DIR_CREATED; + else + ap->flags |= MOUNT_FLAG_DIR_CREATED; +- } else ++ } else { + me->flags &= ~MOUNT_FLAG_DIR_CREATED; ++ if (type == t_offset) { ++ if (!is_mounted(me->parent->key, MNTS_REAL)) ++ me->flags |= MOUNT_FLAG_DIR_CREATED; ++ } ++ } + + /* + * Either we opened the mount or we're re-reading the map. diff --git a/autofs-5.1.6-fix-trailing-dollar-sun-entry-expansion.patch b/autofs-5.1.6-fix-trailing-dollar-sun-entry-expansion.patch new file mode 100644 index 0000000..1225c1e --- /dev/null +++ b/autofs-5.1.6-fix-trailing-dollar-sun-entry-expansion.patch @@ -0,0 +1,46 @@ +autofs-5.1.6 - fix trailing dollar sun entry expansion + +From: Ian Kent + +In modules/parse_sun.c:expandsunent() if we see "$ " or "$" in a +the entry it can't be a macro, and the value can't be quoted since '\' +and '"' cases are handled seperately in the swicth, so treat the +character as a valid entry character. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 12 ++++++++++++ + 2 files changed, 13 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -77,6 +77,7 @@ xx/xx/2018 autofs-5.1.5 + - use local getmntent_r() in tree_make_mnt_list(). + - fix missing initialization of autofs_point flags. + - fix a regression with map instance lookup. ++- fix trailing dollar sun entry expansion. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -161,6 +161,18 @@ int expandsunent(const char *src, char * + } + src = p + 1; + } else { ++ /* If the '$' is folloed by a space or NULL it ++ * can't be a macro, and the value can't be ++ * quoted since '\' and '"' cases are handled ++ * in other cases, so treat the $ as a valid ++ * map entry character. ++ */ ++ if (isblank(*src) || !*src) { ++ if (dst) ++ *dst++ = ch; ++ len++; ++ break; ++ } + p = src; + while (isalnum(*p) || *p == '_') + p++; diff --git a/autofs-5.1.6-fix-typo-in-open_sss_lib.patch b/autofs-5.1.6-fix-typo-in-open_sss_lib.patch new file mode 100644 index 0000000..13f568d --- /dev/null +++ b/autofs-5.1.6-fix-typo-in-open_sss_lib.patch @@ -0,0 +1,37 @@ +autofs-5.1.6 - fix typo in open_sss_lib() + +From: Ian Kent + +Fix obvious typo in modules/lookup_sss.c:open_sss_lib(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 3c00184..63c6d41 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -92,6 +92,7 @@ xx/xx/2018 autofs-5.1.5 + - add force unlink mounts and exit option. + - cleanup stale logpri fifo pipes on unlink and exit. + - fix lookup_nss_read_master() nsswicth check return. ++- fix typo in open_sss_lib(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 7859830..cc18e62 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -91,7 +91,7 @@ static int open_sss_lib(struct lookup_context *ctxt) + goto lib_names_fail; + + ctxt->endautomntent = (endautomntent_t) dlsym(dh, "_sss_endautomntent"); +- if (!ctxt->setautomntent) ++ if (!ctxt->endautomntent) + goto lib_names_fail; + + return 0; diff --git a/autofs-5.1.6-fix-unlink-mounts-umount-order.patch b/autofs-5.1.6-fix-unlink-mounts-umount-order.patch new file mode 100644 index 0000000..ab45e1d --- /dev/null +++ b/autofs-5.1.6-fix-unlink-mounts-umount-order.patch @@ -0,0 +1,89 @@ +autofs-5.1.6 - fix unlink mounts umount order + +From: Ian Kent + +The recent changes to mount table handling to support the "ignore" +autofs pseudo option resulted in the incorrect umount order being used +in the unlink_mount_tree() function. + +To fix this change unlink_mount_tree() to use the existing get_mnt_list() +function to construct a correctly ordered list for the umounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 39 +++++++++------------------------------ + 2 files changed, 10 insertions(+), 30 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -84,6 +84,7 @@ xx/xx/2018 autofs-5.1.5 + - mount_nfs.c fix local rdma share not mounting. + - fix incorrect systemctl command syntax in autofs(8). + - fix direct mount unlink_mount_tree() path. ++- fix unlink mounts umount order. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -951,42 +951,21 @@ local_getmntent_r(FILE *tab, struct mnte + + int unlink_mount_tree(struct autofs_point *ap, const char *mp) + { +- FILE *tab; +- struct mntent *mnt; +- struct mntent mnt_wrk; +- char buf[PATH_MAX * 3]; +- unsigned int mp_len = strlen(mp); ++ struct mnt_list *mnts, *mnt; + int rv, ret = 1; + +- tab = open_fopen_r(_PROC_MOUNTS); +- if (!tab) { +- char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("fopen: %s", estr); ++ mnts = get_mnt_list(mp, 1); ++ if (!mnts) + return 0; +- } +- +- while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { +- unsigned int mnt_dir_len; +- int is_autofs; +- +- if (strncmp(mnt->mnt_dir, mp, mp_len)) +- continue; +- +- mnt_dir_len = strlen(mnt->mnt_dir); +- is_autofs = !strcmp(mnt->mnt_type, "autofs"); +- +- if (mnt_dir_len == mp_len && !is_autofs) { +- ret = 0; +- break; +- } + +- if (is_autofs) +- rv = umount2(mnt->mnt_dir, MNT_DETACH); ++ for (mnt = mnts; mnt; mnt = mnt->next) { ++ if (mnt->flags | MNTS_AUTOFS) ++ rv = umount2(mnt->mp, MNT_DETACH); + else +- rv = spawn_umount(ap->logopt, "-l", mnt->mnt_dir, NULL); ++ rv = spawn_umount(ap->logopt, "-l", mnt->mp, NULL); + if (rv == -1) { + debug(ap->logopt, +- "can't unlink %s from mount tree", mnt->mnt_dir); ++ "can't unlink %s from mount tree", mnt->mp); + + switch (errno) { + case EINVAL: +@@ -1002,7 +981,7 @@ int unlink_mount_tree(struct autofs_poin + } + } + } +- fclose(tab); ++ free_mnt_list(mnts); + + return ret; + } diff --git a/autofs-5.1.6-improve-force-unlink-mounts-option-description.patch b/autofs-5.1.6-improve-force-unlink-mounts-option-description.patch new file mode 100644 index 0000000..ee414ce --- /dev/null +++ b/autofs-5.1.6-improve-force-unlink-mounts-option-description.patch @@ -0,0 +1,39 @@ +autofs-5.1.6 - improve force unlink mounts option description + +From: Ian Kent + +Update the automount(8) man page description of the force unlink mounts +option to indicate it operates on configured autofs mounts and mounts +under them. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/automount.8 | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -87,6 +87,7 @@ xx/xx/2018 autofs-5.1.5 + - fix unlink mounts umount order. + - fix incorrect logical compare in unlink_mount_tree(). + - use bit flag for force unlink mounts. ++- improve force unlink option description. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/man/automount.8 ++++ autofs-5.1.4/man/automount.8 +@@ -118,9 +118,9 @@ path name as specified in the master map + Don't check if the daemon is currently running (see NOTES). + .TP + .I "\-F, \-\-force" +-Force an unlink umount of existing mounts under autofs managed mount points +-during startup. This can cause problems for processes with working directories +-within these mounts (see NOTES). ++Force an unlink umount of existing mounts under configured autofs managed ++mount points during startup. This can cause problems for processes with ++working directories within these mounts (see NOTES). + .SH ARGUMENTS + \fBautomount\fP takes one optional argument, the name of the master map to + use. diff --git a/autofs-5.1.6-improve-sss-getautomntbyname-error-handling.patch b/autofs-5.1.6-improve-sss-getautomntbyname-error-handling.patch new file mode 100644 index 0000000..43d81e0 --- /dev/null +++ b/autofs-5.1.6-improve-sss-getautomntbyname-error-handling.patch @@ -0,0 +1,189 @@ +autofs-5.1.6 - improve sss getautomntbyname() error handling + +From: Ian Kent + +Recent versions of the sss autofs access library will return EHOSTDOWN +if the backend server is down. + +The presence of this improvement in error handling is determined by an +added function to get the sss autofs protocol version. + +Update the getautomntbyname() function to use this. + +Also introduce a wait function so we can wait (for a while) for the host +to come back up. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/lookup_sss.c | 106 ++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 95 insertions(+), 12 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 8b662d7..309def2 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -107,6 +107,7 @@ xx/xx/2018 autofs-5.1.5 + - sss introduce a flag to indicate map being read. + - update sss timeout documentation. + - refactor sss getautomntbyname(). ++- improve sss getautomntbyname() error handling. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 1a56ea1..70efc11 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -566,27 +566,106 @@ free: + return err; + } + ++static int getautomntbyname_wait(unsigned int logopt, ++ struct lookup_context *ctxt, ++ char *key, char **value, void *sss_ctxt, ++ unsigned int flags) ++{ ++ unsigned int retries; ++ unsigned int retry = 0; ++ int ret = 0; ++ ++ retries = calculate_retry_count(ctxt, flags); ++ if (retries == 0) { ++ if (proto_version(ctxt) == 0) ++ return EINVAL; ++ return ENOENT; ++ } ++ ++ warn(logopt, ++ "can't contact sssd to to lookup key value, retry for %d seconds", ++ retries); ++ ++ while (++retry <= retries) { ++ struct timespec t = { SSS_WAIT_INTERVAL, 0 }; ++ struct timespec r; ++ ++ ret = ctxt->getautomntbyname_r(key, value, sss_ctxt); ++ if (proto_version(ctxt) == 0) { ++ if (ret != ENOENT) ++ break; ++ } else { ++ if (ret != EHOSTDOWN) ++ break; ++ } ++ ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ } ++ ++ if (!ret) ++ info(logopt, ++ "successfully contacted sssd to lookup key value"); ++ else { ++ if (proto_version(ctxt) == 0 && retry > retries) ++ ret = ETIMEDOUT; ++ } ++ return ret; ++} ++ + static int getautomntbyname(unsigned int logopt, + struct lookup_context *ctxt, +- char *key, char **value, void *sss_ctxt) ++ char *key, char **value, void *sss_ctxt, ++ unsigned int flags) + { + char buf[MAX_ERR_BUF]; + char *estr; +- int ret = NSS_STATUS_UNAVAIL; ++ int err = NSS_STATUS_UNAVAIL; ++ int ret; + + ret = ctxt->getautomntbyname_r(key, value, sss_ctxt); + if (ret) { + /* Host has gone down */ + if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- +- if (ret != ENOENT) + goto error; + +- ret = NSS_STATUS_NOTFOUND; +- goto free; ++ if (proto_version(ctxt) == 0) { ++ if (ret != ENOENT) ++ goto error; ++ /* For prorocol version 0 ENOENT can only be ++ * used to indicate no entry was found. So it ++ * can't be used to determine if we need to wait ++ * on sss. ++ */ ++ err = NSS_STATUS_NOTFOUND; ++ goto free; ++ } else { ++ if (ret == ENOENT) { ++ err = NSS_STATUS_NOTFOUND; ++ goto free; ++ } ++ if (ret != EHOSTDOWN) ++ goto error; ++ } ++ ++ ret = getautomntbyname_wait(logopt, ctxt, ++ key, value, sss_ctxt, flags); ++ if (ret) { ++ if (ret == ECONNREFUSED) ++ goto free; ++ if (ret == ETIMEDOUT) ++ goto error; ++ /* sss proto version 0 and sss timeout not set */ ++ if (ret == EINVAL) ++ goto free; ++ if (ret == ENOENT) { ++ err = NSS_STATUS_NOTFOUND; ++ goto free; ++ } ++ goto error; ++ } + } +- return ret; ++ return NSS_STATUS_SUCCESS; + + error: + estr = strerror_r(ret, buf, MAX_ERR_BUF); +@@ -596,7 +675,7 @@ free: + free(*value); + *value = NULL; + } +- return ret; ++ return err; + } + + int lookup_read_master(struct master *master, time_t age, void *context) +@@ -802,7 +881,8 @@ static int lookup_one(struct autofs_point *ap, + if (ret) + return ret; + +- ret = getautomntbyname(ap->logopt, ctxt, qKey, &value, sss_ctxt); ++ ret = getautomntbyname(ap->logopt, ctxt, ++ qKey, &value, sss_ctxt, SSS_LOOKUP_KEY); + if (ret == NSS_STATUS_NOTFOUND) + goto wild; + if (ret) { +@@ -829,13 +909,15 @@ static int lookup_one(struct autofs_point *ap, + return NSS_STATUS_SUCCESS; + + wild: +- ret = getautomntbyname(ap->logopt, ctxt, "/", &value, sss_ctxt); ++ ret = getautomntbyname(ap->logopt, ctxt, ++ "/", &value, sss_ctxt, SSS_LOOKUP_KEY); + if (ret) { + if (ret != NSS_STATUS_NOTFOUND) { + endautomntent(ap->logopt, ctxt, &sss_ctxt); + return ret; + } +- ret = getautomntbyname(ap->logopt, ctxt, "*", &value, sss_ctxt); ++ ret = getautomntbyname(ap->logopt, ctxt, ++ "*", &value, sss_ctxt, SSS_LOOKUP_KEY); + if (ret && ret != NSS_STATUS_NOTFOUND) { + endautomntent(ap->logopt, ctxt, &sss_ctxt); + return ret; diff --git a/autofs-5.1.6-improve-sss-getautomntent-error-handling.patch b/autofs-5.1.6-improve-sss-getautomntent-error-handling.patch new file mode 100644 index 0000000..b548efd --- /dev/null +++ b/autofs-5.1.6-improve-sss-getautomntent-error-handling.patch @@ -0,0 +1,205 @@ +autofs-5.1.6 - improve sss getautomntent() error handling + +From: Ian Kent + +Recent versions of the sss autofs access library will return EHOSTDOWN +if the backend server is down. + +The presence of this improvement in error handling is determined by an +added function to get the sss autofs protocol version. + +Update the getautomntent() function to use this. + +Also introduce a wait function so we can wait (for a while) for the host +to come back up. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/lookup_sss.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 116 insertions(+), 11 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index ecd54e9..434e23d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -101,6 +101,7 @@ xx/xx/2018 autofs-5.1.5 + - refactor sss setautomntent(). + - improve sss setautomntent() error handling. + - refactor sss getautomntent(). ++- improve sss getautomntent() error handling. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 5addd87..f366b48 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -377,38 +377,136 @@ static int endautomntent(unsigned int logopt, + return ret; + } + ++static int getautomntent_wait(unsigned int logopt, ++ struct lookup_context *ctxt, ++ char **key, char **value, void *sss_ctxt) ++{ ++ unsigned int retries; ++ unsigned int retry = 0; ++ int ret = 0; ++ ++ retries = defaults_get_sss_master_map_wait(); ++ ++ /* Use the sss_master_map_wait configuration option ++ * for the time to wait when reading a map too. If ++ * it isn't set in the antofs configuration give it ++ * a sensible value since we want to wait for a host ++ * that's down in case it comes back up. ++ */ ++ if (retries <= 0) { ++ /* Protocol version 0 cant't tell us about ++ * a host being down, return not found. ++ */ ++ if (proto_version(ctxt) == 0) ++ return ENOENT; ++ retries = 10; ++ } ++ ++ warn(logopt, ++ "can't contact sssd to to get map entry, retry for %d seconds", ++ retries); ++ ++ while (++retry <= retries) { ++ struct timespec t = { SSS_WAIT_INTERVAL, 0 }; ++ struct timespec r; ++ ++ ret = ctxt->getautomntent_r(key, value, sss_ctxt); ++ if (proto_version(ctxt) == 0) { ++ if (ret != ENOENT) ++ break; ++ } else { ++ if (ret != EHOSTDOWN) ++ break; ++ } ++ ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ } ++ ++ if (!ret) ++ info(logopt, ++ "successfully contacted sssd to get map entry"); ++ else { ++ if (retry == retries) ++ ret = ETIMEDOUT; ++ } ++ return ret; ++} ++ + static int getautomntent(unsigned int logopt, + struct lookup_context *ctxt, + char **key, char **value, int count, void *sss_ctxt) + { + char buf[MAX_ERR_BUF]; + char *estr; +- int ret = NSS_STATUS_UNAVAIL; ++ int err = NSS_STATUS_UNAVAIL; ++ int ret; + + ret = ctxt->getautomntent_r(key, value, sss_ctxt); + if (ret) { + /* Host has gone down */ +- if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- if (ret != ENOENT) ++ if (ret == ECONNREFUSED) { ++ err = NSS_STATUS_UNKNOWN; + goto error; +- if (!count) { +- ret = NSS_STATUS_NOTFOUND; ++ } ++ ++ if (proto_version(ctxt) == 0) { ++ if (ret != ENOENT) ++ goto error; ++ /* For prorocol version 0 ENOENT can only be ++ * used to indicate we've read all entries. ++ * So even if we haven't got any values yet we ++ * can't use it to determine if we need to wait ++ * on sss. ++ */ ++ err = NSS_STATUS_NOTFOUND; ++ if (count) ++ err = NSS_STATUS_SUCCESS; + goto free; ++ } else { ++ if (ret == ENOENT) { ++ err = NSS_STATUS_NOTFOUND; ++ if (count) ++ err = NSS_STATUS_SUCCESS; ++ goto free; ++ } ++ if (ret != EHOSTDOWN) ++ goto error; ++ } ++ ++ ret = getautomntent_wait(logopt, ctxt, ++ key, value, sss_ctxt); ++ if (ret) { ++ if (ret == ECONNREFUSED) { ++ err = NSS_STATUS_UNKNOWN; ++ goto free; ++ } ++ if (ret == ETIMEDOUT) ++ goto error; ++ if (ret == ENOENT) { ++ err = NSS_STATUS_NOTFOUND; ++ if (count) ++ err = NSS_STATUS_SUCCESS; ++ goto free; ++ } ++ goto error; + } +- goto error; + } +- return ret; ++ return NSS_STATUS_SUCCESS; + + error: + estr = strerror_r(ret, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX "getautomntent: %s", estr); + free: +- if (*key) ++ if (*key) { + free(*key); +- if (*value) ++ *key = NULL; ++ } ++ if (*value) { + free(*value); +- return ret; ++ *value = NULL; ++ } ++ return err; + } + + int lookup_read_master(struct master *master, time_t age, void *context) +@@ -439,6 +537,9 @@ int lookup_read_master(struct master *master, time_t age, void *context) + return ret; + } + ++ if (!key || !value) ++ break; ++ + count++; + + buffer_len = strlen(key) + 1 + strlen(value) + 2; +@@ -523,6 +624,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return ret; + } + ++ if (!key || !value) ++ break; ++ + /* + * Ignore keys beginning with '+' as plus map + * inclusion is only valid in file maps. diff --git a/autofs-5.1.6-improve-sss-setautomntent-error-handling.patch b/autofs-5.1.6-improve-sss-setautomntent-error-handling.patch new file mode 100644 index 0000000..f3eda36 --- /dev/null +++ b/autofs-5.1.6-improve-sss-setautomntent-error-handling.patch @@ -0,0 +1,159 @@ +autofs-5.1.6 - improve sss setautomntent() error handling + +From: Ian Kent + +Recent versions of the sss autofs access library will return EHOSTDOWN +if the backend server is down. + +The presence of this improvement in error handling is determined by an +added function to get the sss autofs protocol version. + +Update the setautomntent() function to use this. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 72 ++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 55 insertions(+), 18 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 141658d..5ccd787 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -99,6 +99,7 @@ xx/xx/2018 autofs-5.1.5 + - add support for new sss autofs proto version call. + - fix retries check in setautomntent_wait(). + - refactor sss setautomntent(). ++- improve sss setautomntent() error handling. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 011b232..e1ed83c 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -259,16 +259,37 @@ static int setautomntent_wait(unsigned int logopt, + *sss_ctxt = NULL; + + retries = defaults_get_sss_master_map_wait(); +- if (retries <= 0) +- return ENOENT; ++ ++ /* If sss_master_map_wait is not set in the autofs ++ * configuration give it a sensible value since we ++ * want to wait for a host that's down in case it ++ * comes back up. ++ */ ++ if (retries <= 0) { ++ /* Protocol version 0 cant't tell us about ++ * a host being down, return not found. ++ */ ++ if (proto_version(ctxt) == 0) ++ return ENOENT; ++ retries = 10; ++ } ++ ++ warn(logopt, ++ "can't connect to sssd, retry for %d seconds", ++ retries); + + while (++retry <= retries) { + struct timespec t = { SSS_WAIT_INTERVAL, 0 }; + struct timespec r; + + ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); +- if (ret != ENOENT) +- break; ++ if (proto_version(ctxt) == 0) { ++ if (ret != ENOENT) ++ break; ++ } else { ++ if (ret != EHOSTDOWN) ++ break; ++ } + + if (*sss_ctxt) { + free(*sss_ctxt); +@@ -279,17 +300,17 @@ static int setautomntent_wait(unsigned int logopt, + memcpy(&t, &r, sizeof(struct timespec)); + } + +- +- if (ret) { ++ if (!ret) ++ info(logopt, "successfully connected to sssd"); ++ else { + if (*sss_ctxt) { + free(*sss_ctxt); + *sss_ctxt = NULL; + } + +- if (retry > retries) ++ if (proto_version(ctxt) == 0 && retry > retries) + ret = ETIMEDOUT; + } +- + return ret; + } + +@@ -298,35 +319,50 @@ static int setautomntent(unsigned int logopt, + { + char buf[MAX_ERR_BUF]; + char *estr; ++ int err = NSS_STATUS_UNAVAIL; + int ret; + + ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); + if (ret) { +- if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- +- if (ret != ENOENT) ++ if (ret == ECONNREFUSED) { ++ err = NSS_STATUS_UNKNOWN; + goto error; ++ } ++ ++ if (proto_version(ctxt) == 0) { ++ if (ret != ENOENT) ++ goto error; ++ } else { ++ if (ret != ENOENT && ret != EHOSTDOWN) ++ goto error; ++ } + + ret = setautomntent_wait(logopt, ctxt, sss_ctxt); + if (ret) { +- if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- if (ret == ENOENT) +- return NSS_STATUS_NOTFOUND; ++ if (ret == ECONNREFUSED) { ++ err = NSS_STATUS_UNKNOWN; ++ goto error; ++ } ++ if (ret == ETIMEDOUT) ++ goto error; ++ if (ret == ENOENT) { ++ err = NSS_STATUS_NOTFOUND; ++ goto free; ++ } + goto error; + } + } +- return ret; ++ return NSS_STATUS_SUCCESS; + + error: + estr = strerror_r(ret, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX "setautomntent: %s", estr); ++free: + if (*sss_ctxt) { + free(*sss_ctxt); + *sss_ctxt = NULL; + } +- return NSS_STATUS_UNAVAIL; ++ return err; + } + + static int endautomntent(unsigned int logopt, diff --git a/autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch b/autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch new file mode 100644 index 0000000..a96054f --- /dev/null +++ b/autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch @@ -0,0 +1,104 @@ +autofs-5.1.6 - initialize struct addrinfo for getaddrinfo() calls + +From: Ian Kent + +The getaddrinfo() call may have become more fussy about initialization +of the passed in struct addrinfo that receives the results. + +It's good practice to initialize it prior to the gataddrinfo() call just +in case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/parse_subs.c | 1 + + lib/rpc_subs.c | 1 + + modules/dclist.c | 1 + + modules/parse_amd.c | 3 +++ + modules/replicated.c | 2 ++ + 6 files changed, 9 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -78,6 +78,7 @@ xx/xx/2018 autofs-5.1.5 + - fix missing initialization of autofs_point flags. + - fix a regression with map instance lookup. + - fix trailing dollar sun entry expansion. ++- initialize struct addrinfo for getaddrinfo() calls. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/parse_subs.c ++++ autofs-5.1.4/lib/parse_subs.c +@@ -475,6 +475,7 @@ unsigned int get_network_proximity(const + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + ++ ni = NULL; + ret = getaddrinfo(name_or_num, NULL, &hints, &ni); + if (ret) { + logerr("hostname lookup for %s failed: %s", +--- autofs-5.1.4.orig/lib/rpc_subs.c ++++ autofs-5.1.4/lib/rpc_subs.c +@@ -691,6 +691,7 @@ static int create_client(struct conn_inf + else + hints.ai_socktype = SOCK_STREAM; + ++ ai = NULL; + ret = getaddrinfo(info->host, NULL, &hints, &ai); + if (ret) { + error(LOGOPT_ANY, +--- autofs-5.1.4.orig/modules/dclist.c ++++ autofs-5.1.4/modules/dclist.c +@@ -355,6 +355,7 @@ static char *getdnsdomainname(unsigned i + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) { + error(logopt, +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -269,6 +269,7 @@ static int match_my_name(struct autofs_p + hints.ai_socktype = SOCK_DGRAM; + + /* Get host canonical name */ ++ cni = NULL; + ret = getaddrinfo(v->val, NULL, &hints, &cni); + if (ret) { + error(logopt, MODPREFIX +@@ -280,6 +281,7 @@ static int match_my_name(struct autofs_p + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + + /* Resolve comparison name to its names and compare */ ++ ni = NULL; + ret = getaddrinfo(exp_name, NULL, &hints, &ni); + if (ret) { + error(logopt, MODPREFIX +@@ -775,6 +777,7 @@ static char *normalize_hostname(unsigned + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(host, NULL, &hints, &ni); + if (ret) { + error(logopt, MODPREFIX +--- autofs-5.1.4.orig/modules/replicated.c ++++ autofs-5.1.4/modules/replicated.c +@@ -985,6 +985,7 @@ static int add_host_addrs(struct host ** + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) + goto try_name; +@@ -1005,6 +1006,7 @@ try_name: + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) { + error(LOGOPT_ANY, diff --git a/autofs-5.1.6-make-bind-mounts-propagation-slave-by-default.patch b/autofs-5.1.6-make-bind-mounts-propagation-slave-by-default.patch new file mode 100644 index 0000000..ece835a --- /dev/null +++ b/autofs-5.1.6-make-bind-mounts-propagation-slave-by-default.patch @@ -0,0 +1,220 @@ +autofs-5.1.6 - make bind mounts propagation slave by default + +From: Ian Kent + +Make setting mount propagation on bind mounts mandatory with a default +of propagation slave. + +When using multi-mounts that have bind mounts the bind mount will have +the same properties as its parent which is commonly propagation shared. +And if the mount target is also propagation shared this can lead to a +deadlock when attempting to access the offset mounts. When this happens +an unwanted offset mount is propagated back to the target file system +resulting in a deadlock since the automount target is itself an +(unwanted) automount trigger. + +This problem has been present much longer than I originally thought, +perhaps since mount propagation was introduced into the kernel, so +explicitly setting bind mount propagation is the sensible thing to do. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 9 +++++---- + lib/master_parse.y | 29 +++++++++++++++++------------ + lib/master_tok.l | 1 + + modules/mount_bind.c | 40 ++++++++++++++++++++++------------------ + 5 files changed, 46 insertions(+), 34 deletions(-) + +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -551,14 +551,15 @@ struct kernel_mod_version { + #define MOUNT_FLAG_AMD_CACHE_ALL 0x0080 + + /* Set mount propagation for bind mounts */ +-#define MOUNT_FLAG_SLAVE 0x0100 +-#define MOUNT_FLAG_PRIVATE 0x0200 ++#define MOUNT_FLAG_SHARED 0x0100 ++#define MOUNT_FLAG_SLAVE 0x0200 ++#define MOUNT_FLAG_PRIVATE 0x0400 + + /* Use strict expire semantics if requested and kernel supports it */ +-#define MOUNT_FLAG_STRICTEXPIRE 0x0400 ++#define MOUNT_FLAG_STRICTEXPIRE 0x0800 + + /* Indicator for applications to ignore the mount entry */ +-#define MOUNT_FLAG_IGNORE 0x0800 ++#define MOUNT_FLAG_IGNORE 0x1000 + + struct autofs_point { + pthread_t thid; +--- autofs-5.1.4.orig/lib/master_parse.y ++++ autofs-5.1.4/lib/master_parse.y +@@ -59,8 +59,6 @@ static long timeout; + static long negative_timeout; + static unsigned symlnk; + static unsigned strictexpire; +-static unsigned slave; +-static unsigned private; + static unsigned nobind; + static unsigned ghost; + extern unsigned global_selection_options; +@@ -72,6 +70,14 @@ static int tmp_argc; + static char **local_argv; + static int local_argc; + ++#define PROPAGATION_SHARED MOUNT_FLAG_SHARED ++#define PROPAGATION_SLAVE MOUNT_FLAG_SLAVE ++#define PROPAGATION_PRIVATE MOUNT_FLAG_PRIVATE ++#define PROPAGATION_MASK (MOUNT_FLAG_SHARED | \ ++ MOUNT_FLAG_SLAVE | \ ++ MOUNT_FLAG_PRIVATE) ++static unsigned int propagation; ++ + static char errstr[MAX_ERR_LEN]; + + static unsigned int verbose; +@@ -106,7 +112,7 @@ static int master_fprintf(FILE *, char * + %token MAP + %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE + %token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE +-%token OPT_STRICTEXPIRE OPT_SLAVE OPT_PRIVATE ++%token OPT_STRICTEXPIRE OPT_SHARED OPT_SLAVE OPT_PRIVATE + %token COLON COMMA NL DDASH + %type map + %type options +@@ -208,6 +214,7 @@ line: + | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } + | PATH OPT_SYMLINK { master_notify($1); YYABORT; } + | PATH OPT_STRICTEXPIRE { master_notify($1); YYABORT; } ++ | PATH OPT_SHARED { master_notify($1); YYABORT; } + | PATH OPT_SLAVE { master_notify($1); YYABORT; } + | PATH OPT_PRIVATE { master_notify($1); YYABORT; } + | PATH OPT_NOBIND { master_notify($1); YYABORT; } +@@ -622,8 +629,9 @@ daemon_option: OPT_TIMEOUT NUMBER { time + | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } + | OPT_SYMLINK { symlnk = 1; } + | OPT_STRICTEXPIRE { strictexpire = 1; } +- | OPT_SLAVE { slave = 1; } +- | OPT_PRIVATE { private = 1; } ++ | OPT_SHARED { propagation = PROPAGATION_SHARED; } ++ | OPT_SLAVE { propagation = PROPAGATION_SLAVE; } ++ | OPT_PRIVATE { propagation = PROPAGATION_PRIVATE; } + | OPT_NOBIND { nobind = 1; } + | OPT_NOGHOST { ghost = 0; } + | OPT_GHOST { ghost = 1; } +@@ -697,8 +705,7 @@ static void local_init_vars(void) + negative_timeout = 0; + symlnk = 0; + strictexpire = 0; +- slave = 0; +- private = 0; ++ propagation = PROPAGATION_SLAVE; + nobind = 0; + ghost = defaults_get_browse_mode(); + random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; +@@ -888,7 +895,6 @@ int master_parse_entry(const char *buffe + ghost = 1; + } + +- + if (!entry->ap) { + ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0); + if (!ret) { +@@ -899,6 +905,9 @@ int master_parse_entry(const char *buffe + return 0; + } + } ++ entry->ap->flags &= ~(PROPAGATION_MASK); ++ entry->ap->flags |= propagation; ++ + if (random_selection) + entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT; + if (use_weight) +@@ -907,10 +916,6 @@ int master_parse_entry(const char *buffe + entry->ap->flags |= MOUNT_FLAG_SYMLINK; + if (strictexpire) + entry->ap->flags |= MOUNT_FLAG_STRICTEXPIRE; +- if (slave) +- entry->ap->flags |= MOUNT_FLAG_SLAVE; +- if (private) +- entry->ap->flags |= MOUNT_FLAG_PRIVATE; + if (negative_timeout) + entry->ap->negative_timeout = negative_timeout; + if (mode && mode < LONG_MAX) +--- autofs-5.1.4.orig/lib/master_tok.l ++++ autofs-5.1.4/lib/master_tok.l +@@ -389,6 +389,7 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTW + -?symlink { return(OPT_SYMLINK); } + -?nobind { return(OPT_NOBIND); } + -?nobrowse { return(OPT_NOGHOST); } ++ -?shared { return(OPT_SHARED); } + -?slave { return(OPT_SLAVE); } + -?private { return(OPT_PRIVATE); } + -?strictexpire { return(OPT_STRICTEXPIRE); } +--- autofs-5.1.4.orig/modules/mount_bind.c ++++ autofs-5.1.4/modules/mount_bind.c +@@ -153,6 +153,7 @@ int mount_mount(struct autofs_point *ap, + + if (!symlnk && bind_works) { + int status, existed = 1; ++ int flags; + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); + +@@ -190,24 +191,27 @@ int mount_mount(struct autofs_point *ap, + what, fstype, fullpath); + } + +- if (ap->flags & (MOUNT_FLAG_SLAVE | MOUNT_FLAG_PRIVATE)) { +- int flags = MS_SLAVE; +- +- if (ap->flags & MOUNT_FLAG_PRIVATE) +- flags = MS_PRIVATE; +- +- /* The bind mount has succeeded but if the target +- * mount is propagation shared propagation of child +- * mounts (autofs offset mounts for example) back to +- * the target of the bind mount must be avoided or +- * autofs trigger mounts will deadlock. +- */ +- err = mount(NULL, fullpath, NULL, flags, NULL); +- if (err) { +- warn(ap->logopt, +- "failed to set propagation for %s", +- fullpath, root); +- } ++ /* The bind mount has succeeded, now set the mount propagation. ++ * ++ * The default is propagation shared, change it if the master ++ * map entry has a different option specified. ++ */ ++ flags = MS_SLAVE; ++ if (ap->flags & MOUNT_FLAG_PRIVATE) ++ flags = MS_PRIVATE; ++ else if (ap->flags & MOUNT_FLAG_SHARED) ++ flags = MS_SHARED; ++ ++ /* Note: If the parent mount is propagation shared propagation ++ * of child mounts (autofs offset mounts for example) back to ++ * the target of the bind mount can happen in some cases and ++ * must be avoided or autofs trigger mounts will deadlock. ++ */ ++ err = mount(NULL, fullpath, NULL, flags, NULL); ++ if (err) { ++ warn(ap->logopt, ++ "failed to set propagation for %s", ++ fullpath, root); + } + + return 0; +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -114,6 +114,7 @@ xx/xx/2018 autofs-5.1.5 + - use defines for expire type. + - remove unused function dump_master(). + - fix additional typing errors. ++- make bind mounts propagation slave by default. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. diff --git a/autofs-5.1.6-make-external-mounts-independent-of-amd_entry.patch b/autofs-5.1.6-make-external-mounts-independent-of-amd_entry.patch new file mode 100644 index 0000000..a4e9482 --- /dev/null +++ b/autofs-5.1.6-make-external-mounts-independent-of-amd_entry.patch @@ -0,0 +1,382 @@ +autofs-5.1.6 - make external mounts independent of amd_entry + +From: Ian Kent + +The external mounts used by amd map entries should not depend +on the amd map entry. + +The external mounts list is keyed by the external mount path +and this should be what's used to locate them. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 4 - + include/mounts.h | 6 +- + include/parse_amd.h | 1 + lib/master.c | 3 - + lib/mounts.c | 114 ++++++++++++++++++++++++++++++---------------------- + modules/parse_amd.c | 14 +++--- + 7 files changed, 80 insertions(+), 63 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -119,6 +119,7 @@ xx/xx/2018 autofs-5.1.5 + - update list.h. + - add hashtable implementation. + - change mountpoint to mp in struct ext_mount. ++- make external mounts independent of amd_entry. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -613,7 +613,7 @@ static int umount_subtree_mounts(struct + } + list_del(&entry->entries); + mounts_mutex_unlock(ap); +- umount_amd_ext_mount(ap, entry); ++ umount_amd_ext_mount(ap, entry->fs); + free_amd_entry(entry); + } + done: +@@ -679,7 +679,7 @@ int umount_multi(struct autofs_point *ap + } + list_del(&entry->entries); + mounts_mutex_unlock(ap); +- umount_amd_ext_mount(ap, entry); ++ umount_amd_ext_mount(ap, entry->fs); + free_amd_entry(entry); + return 0; + } +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -97,8 +97,8 @@ unsigned int get_kver_minor(void); + char *make_options_string(char *path, int pipefd, + const char *type, unsigned int flags); + char *make_mnt_name_string(char *path); +-int ext_mount_add(struct list_head *, const char *, unsigned int); +-int ext_mount_remove(struct list_head *, const char *); ++int ext_mount_add(const char *, const char *); ++int ext_mount_remove(const char *); + int ext_mount_inuse(const char *); + struct mnt_list *get_mnt_list(const char *path, int include); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); +@@ -118,7 +118,7 @@ int try_remount(struct autofs_point *, s + void set_indirect_mount_tree_catatonic(struct autofs_point *); + void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); + int umount_ent(struct autofs_point *, const char *); +-int umount_amd_ext_mount(struct autofs_point *, struct amd_entry *); ++int umount_amd_ext_mount(struct autofs_point *, 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 *); + int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); +--- autofs-5.1.4.orig/include/parse_amd.h ++++ autofs-5.1.4/include/parse_amd.h +@@ -66,7 +66,6 @@ struct amd_entry { + struct selector *selector; + struct list_head list; + struct list_head entries; +- struct list_head ext_mount; + }; + + int amd_parse_list(struct autofs_point *, +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -154,10 +154,9 @@ void master_free_autofs_point(struct aut + while (p != head) { + struct amd_entry *entry = list_entry(p, struct amd_entry, entries); + p = p->next; +- if (!list_empty(&entry->ext_mount)) +- ext_mount_remove(&entry->ext_mount, entry->fs); + if (!list_empty(&entry->entries)) + list_del(&entry->entries); ++ ext_mount_remove(entry->fs); + free_amd_entry(entry); + } + mounts_mutex_unlock(ap); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -54,10 +54,10 @@ static size_t maxgrpbuf = 0; + #define EXT_MOUNTS_HASH_SIZE 50 + + struct ext_mount { ++ unsigned int ref; + char *mp; +- unsigned int umount; ++ char *umount; + struct list_head mount; +- struct list_head mounts; + }; + static struct list_head ext_mounts_hash[EXT_MOUNTS_HASH_SIZE]; + static unsigned int ext_mounts_hash_init_done = 0; +@@ -542,7 +542,6 @@ struct amd_entry *new_amd_entry(const st + new->path = path; + INIT_LIST_HEAD(&new->list); + INIT_LIST_HEAD(&new->entries); +- INIT_LIST_HEAD(&new->ext_mount); + + return new; + } +@@ -763,7 +762,7 @@ static struct ext_mount *ext_mount_looku + return NULL; + } + +-int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount) ++int ext_mount_add(const char *path, const char *umount) + { + struct ext_mount *em; + u_int32_t hval; +@@ -773,13 +772,7 @@ int ext_mount_add(struct list_head *entr + + em = ext_mount_lookup(path); + if (em) { +- struct list_head *p, *head; +- head = &em->mounts; +- list_for_each(p, head) { +- if (p == entry) +- goto done; +- } +- list_add_tail(entry, &em->mounts); ++ em->ref++; + ret = 1; + goto done; + } +@@ -787,28 +780,34 @@ int ext_mount_add(struct list_head *entr + em = malloc(sizeof(struct ext_mount)); + if (!em) + goto done; ++ memset(em, 0, sizeof(*em)); + + em->mp = strdup(path); + if (!em->mp) { + free(em); + goto done; + } +- em->umount = umount; ++ if (umount) { ++ em->umount = strdup(umount); ++ if (!em->umount) { ++ free(em->mp); ++ free(em); ++ goto done; ++ } ++ } ++ em->ref = 1; + INIT_LIST_HEAD(&em->mount); +- INIT_LIST_HEAD(&em->mounts); + + hval = hash(path, EXT_MOUNTS_HASH_SIZE); + list_add_tail(&em->mount, &ext_mounts_hash[hval]); + +- list_add_tail(entry, &em->mounts); +- + ret = 1; + done: + pthread_mutex_unlock(&ext_mount_hash_mutex); + return ret; + } + +-int ext_mount_remove(struct list_head *entry, const char *path) ++int ext_mount_remove(const char *path) + { + struct ext_mount *em; + int ret = 0; +@@ -819,18 +818,18 @@ int ext_mount_remove(struct list_head *e + if (!em) + goto done; + +- list_del_init(entry); +- +- if (!list_empty(&em->mounts)) ++ em->ref--; ++ if (em->ref) + goto done; + else { + list_del_init(&em->mount); +- if (em->umount) +- ret = 1; + if (list_empty(&em->mount)) { + free(em->mp); ++ if (em->umount) ++ free(em->umount); + free(em); + } ++ ret = 1; + } + done: + pthread_mutex_unlock(&ext_mount_hash_mutex); +@@ -846,9 +845,7 @@ int ext_mount_inuse(const char *path) + em = ext_mount_lookup(path); + if (!em) + goto done; +- +- if (!list_empty(&em->mounts)) +- ret = 1; ++ ret = em->ref; + done: + pthread_mutex_unlock(&ext_mount_hash_mutex); + return ret; +@@ -2092,29 +2089,49 @@ int umount_ent(struct autofs_point *ap, + return rv; + } + +-int umount_amd_ext_mount(struct autofs_point *ap, struct amd_entry *entry) ++int umount_amd_ext_mount(struct autofs_point *ap, const char *path) + { ++ struct ext_mount *em; ++ char *umount = NULL; ++ char *mp; + int rv = 1; + +- if (entry->umount) { +- char *prog, *str; +- char **argv; +- int argc = -1; ++ pthread_mutex_lock(&ext_mount_hash_mutex); + +- str = strdup(entry->umount); +- if (!str) ++ em = ext_mount_lookup(path); ++ if (!em) { ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ goto out; ++ } ++ mp = strdup(em->mp); ++ if (!mp) { ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ goto out; ++ } ++ if (em->umount) { ++ umount = strdup(em->umount); ++ if (!umount) { ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ free(mp); + goto out; ++ } ++ } ++ ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ++ if (umount) { ++ char *prog; ++ char **argv; ++ int argc = -1; + + prog = NULL; + argv = NULL; + +- argc = construct_argv(str, &prog, &argv); +- if (argc == -1) { +- free(str); +- goto out; +- } ++ argc = construct_argv(umount, &prog, &argv); ++ if (argc == -1) ++ goto done; + +- if (!ext_mount_remove(&entry->ext_mount, entry->fs)) { ++ if (!ext_mount_remove(mp)) { + rv =0; + goto out_free; + } +@@ -2122,29 +2139,30 @@ int umount_amd_ext_mount(struct autofs_p + rv = spawnv(ap->logopt, prog, (const char * const *) argv); + if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv))) + error(ap->logopt, +- "failed to umount program mount at %s", entry->fs); ++ "failed to umount program mount at %s", mp); + else { + rv = 0; +- debug(ap->logopt, +- "umounted program mount at %s", entry->fs); +- rmdir_path(ap, entry->fs, ap->dev); ++ debug(ap->logopt, "umounted program mount at %s", mp); ++ rmdir_path(ap, mp, ap->dev); + } + out_free: + free_argv(argc, (const char **) argv); +- free(str); + +- goto out; ++ goto done; + } + +- if (ext_mount_remove(&entry->ext_mount, entry->fs)) { +- rv = umount_ent(ap, entry->fs); ++ if (ext_mount_remove(mp)) { ++ rv = umount_ent(ap, mp); + if (rv) + error(ap->logopt, +- "failed to umount external mount %s", entry->fs); ++ "failed to umount external mount %s", mp); + else +- debug(ap->logopt, +- "umounted external mount %s", entry->fs); ++ debug(ap->logopt, "umounted external mount %s", mp); + } ++done: ++ if (umount) ++ free(umount); ++ free(mp); + out: + return rv; + } +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1136,7 +1136,7 @@ symlink: + + if (entry->sublink) { + /* failed to complete sublink mount */ +- umount_amd_ext_mount(ap, entry); ++ umount_amd_ext_mount(ap, entry->fs); + } + out: + return ret; +@@ -1183,8 +1183,8 @@ static int do_generic_mount(struct autof + goto out; + umount = 1; + } +- /* We have an external mount */ +- if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) { ++ /* If we have an external mount add it to the list */ ++ if (umount && !ext_mount_add(entry->fs, entry->umount)) { + umount_ent(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", +@@ -1235,7 +1235,7 @@ static int do_nfs_mount(struct autofs_po + umount = 1; + } + /* We might be using an external mount */ +- if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) { ++ if (umount && !ext_mount_add(entry->fs, entry->umount)) { + umount_ent(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", entry->fs); +@@ -1429,7 +1429,7 @@ static int do_program_mount(struct autof + /* An external mount with path entry->fs exists + * so ext_mount_add() won't fail. + */ +- ext_mount_add(&entry->ext_mount, entry->fs, 1); ++ ext_mount_add(entry->fs, entry->umount); + } else { + rv = mkdir_path(entry->fs, mp_mode); + if (rv && errno != EEXIST) { +@@ -1445,7 +1445,7 @@ static int do_program_mount(struct autof + + rv = spawnv(ap->logopt, prog, (const char * const *) argv); + if (WIFEXITED(rv) && !WEXITSTATUS(rv)) { +- if (ext_mount_add(&entry->ext_mount, entry->fs, 1)) { ++ if (ext_mount_add(entry->fs, entry->umount)) { + rv = 0; + debug(ap->logopt, MODPREFIX + "%s: mounted %s", entry->type, entry->fs); +@@ -1470,7 +1470,7 @@ do_free: + if (!rv) + goto out; + +- if (umount_amd_ext_mount(ap, entry)) { ++ if (umount_amd_ext_mount(ap, entry->fs)) { + if (!ext_mount_inuse(entry->fs)) + rmdir_path(ap, entry->fs, ap->dev); + debug(ap->logopt, MODPREFIX diff --git a/autofs-5.1.6-make-external-mounts-use-simpler-hashtable.patch b/autofs-5.1.6-make-external-mounts-use-simpler-hashtable.patch new file mode 100644 index 0000000..044f74a --- /dev/null +++ b/autofs-5.1.6-make-external-mounts-use-simpler-hashtable.patch @@ -0,0 +1,128 @@ +autofs-5.1.6 - make external mounts use simpler hashtable + +From: Ian Kent + +Use the added hashtable implementation for the external mounts +hashtable. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 49 +++++++++++++++---------------------------------- + 2 files changed, 16 insertions(+), 34 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -120,6 +120,7 @@ xx/xx/2018 autofs-5.1.5 + - add hashtable implementation. + - change mountpoint to mp in struct ext_mount. + - make external mounts independent of amd_entry. ++- make external mounts use simpler hashtable. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -29,6 +29,7 @@ + #include + + #include "automount.h" ++#include "hashtable.h" + + #define MAX_OPTIONS_LEN 80 + #define MAX_MNT_NAME_LEN 30 +@@ -51,16 +52,15 @@ static const char kver_options_template[ + extern size_t detached_thread_stack_size; + static size_t maxgrpbuf = 0; + +-#define EXT_MOUNTS_HASH_SIZE 50 ++#define EXT_MOUNTS_HASH_BITS 6 + + struct ext_mount { + unsigned int ref; + char *mp; + char *umount; +- struct list_head mount; ++ struct hlist_node mount; + }; +-static struct list_head ext_mounts_hash[EXT_MOUNTS_HASH_SIZE]; +-static unsigned int ext_mounts_hash_init_done = 0; ++static DEFINE_HASHTABLE(ext_mounts_hash, EXT_MOUNTS_HASH_BITS); + static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER; + + unsigned int linux_version_code(void) +@@ -734,38 +734,22 @@ char *make_mnt_name_string(char *path) + return mnt_name; + } + +-static void ext_mounts_hash_init(void) +-{ +- int i; +- for (i = 0; i < EXT_MOUNTS_HASH_SIZE; i++) +- INIT_LIST_HEAD(&ext_mounts_hash[i]); +- ext_mounts_hash_init_done = 1; +-} +- + static struct ext_mount *ext_mount_lookup(const char *mp) + { +- u_int32_t hval = hash(mp, EXT_MOUNTS_HASH_SIZE); +- struct list_head *p, *head; +- +- if (!ext_mounts_hash_init_done) +- ext_mounts_hash_init(); +- +- if (list_empty(&ext_mounts_hash[hval])) +- return NULL; ++ uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash)); ++ struct ext_mount *this; + +- head = &ext_mounts_hash[hval]; +- list_for_each(p, head) { +- struct ext_mount *this = list_entry(p, struct ext_mount, mount); ++ hlist_for_each_entry(this, &ext_mounts_hash[hval], mount) { + if (!strcmp(this->mp, mp)) + return this; + } ++ + return NULL; + } + + int ext_mount_add(const char *path, const char *umount) + { + struct ext_mount *em; +- u_int32_t hval; + int ret = 0; + + pthread_mutex_lock(&ext_mount_hash_mutex); +@@ -796,10 +780,9 @@ int ext_mount_add(const char *path, cons + } + } + em->ref = 1; +- INIT_LIST_HEAD(&em->mount); ++ INIT_HLIST_NODE(&em->mount); + +- hval = hash(path, EXT_MOUNTS_HASH_SIZE); +- list_add_tail(&em->mount, &ext_mounts_hash[hval]); ++ hash_add_str(ext_mounts_hash, &em->mount, em->mp); + + ret = 1; + done: +@@ -822,13 +805,11 @@ int ext_mount_remove(const char *path) + if (em->ref) + goto done; + else { +- list_del_init(&em->mount); +- if (list_empty(&em->mount)) { +- free(em->mp); +- if (em->umount) +- free(em->umount); +- free(em); +- } ++ hlist_del_init(&em->mount); ++ free(em->mp); ++ if (em->umount) ++ free(em->umount); ++ free(em); + ret = 1; + } + done: diff --git a/autofs-5.1.6-make-umount_autofs-static.patch b/autofs-5.1.6-make-umount_autofs-static.patch new file mode 100644 index 0000000..94352b9 --- /dev/null +++ b/autofs-5.1.6-make-umount_autofs-static.patch @@ -0,0 +1,86 @@ +autofs-5.1.6 - make umount_autofs() static + +From: Ian Kent + +The function umount_autofs() is only called within daemon/automount.c +so make it static. + +Also it's only ever called with it's force parameter true so remove +it as well and because this parameter is always true the failure case +when calling umount_all() never happens. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 11 +++++------ + include/automount.h | 1 - + 3 files changed, 6 insertions(+), 7 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -124,6 +124,7 @@ xx/xx/2018 autofs-5.1.5 + - add a hash index to mnt_list. + - use mnt_list for submounts. + - use mnt_list for amdmounts. ++- make umount_autofs() static. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -722,7 +722,7 @@ static int umount_all(struct autofs_poin + return left; + } + +-int umount_autofs(struct autofs_point *ap, const char *root, int force) ++static int umount_autofs(struct autofs_point *ap, const char *root) + { + int ret = 0; + +@@ -737,8 +737,7 @@ int umount_autofs(struct autofs_point *a + lookup_close_lookup(ap); + + if (ap->type == LKP_INDIRECT) { +- if (umount_all(ap, force) && !force) +- return -1; ++ umount_all(ap, 1); + ret = umount_autofs_indirect(ap, root); + } else + ret = umount_autofs_direct(ap); +@@ -1867,7 +1866,7 @@ int handle_mounts_exit(struct autofs_poi + * to check for possible recovery. + */ + if (ap->type == LKP_DIRECT) { +- umount_autofs(ap, NULL, 1); ++ umount_autofs(ap, NULL); + handle_mounts_cleanup(ap); + return 1; + } +@@ -1878,7 +1877,7 @@ int handle_mounts_exit(struct autofs_poi + * so we can continue. This can happen if a lookup + * occurs while we're trying to umount. + */ +- ret = umount_autofs(ap, NULL, 1); ++ ret = umount_autofs(ap, NULL); + if (!ret) { + set_indirect_mount_tree_catatonic(ap); + handle_mounts_cleanup(ap); +@@ -1934,7 +1933,7 @@ void *handle_mounts(void *arg) + if (!(do_force_unlink & UNLINK_AND_EXIT)) + crit(ap->logopt, "mount of %s failed!", ap->path); + suc->status = 1; +- umount_autofs(ap, root, 1); ++ umount_autofs(ap, root); + free(root); + pthread_setcancelstate(cancel_state, NULL); + pthread_exit(NULL); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -599,7 +599,6 @@ int mount_autofs_direct(struct autofs_po + 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); + 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 mapent *me); + int umount_autofs_direct(struct autofs_point *ap); diff --git a/autofs-5.1.6-mount_nfs_c-fix-local-rdma-share-not-mounting.patch b/autofs-5.1.6-mount_nfs_c-fix-local-rdma-share-not-mounting.patch new file mode 100644 index 0000000..9f90ae6 --- /dev/null +++ b/autofs-5.1.6-mount_nfs_c-fix-local-rdma-share-not-mounting.patch @@ -0,0 +1,49 @@ +autofs-5.1.6 - mount_nfs.c fix local rdma share not mounting + +From: Achilles Gaikwad + +When using the same system as nfs-server and nfs-client, and +using `nobind` option for autofs we would fall to the code where +we let `mount.nfs(8)` to handle the mount. However, when the +nfs-server and the nfs-client is the same system we end up calling +`rpc_ping` which gives negative return code. Due to this we fall to +the label next: and never attempt a mount of nfs share. +This patch fixes this BUG by not probing rpc_ping if we're +using rdma. + +Signed-off-by: Achilles Gaikwad +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 9 +++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -81,6 +81,7 @@ xx/xx/2018 autofs-5.1.5 + - initialize struct addrinfo for getaddrinfo() calls. + - fix quoted string length calc in expandsunent(). + - fix autofs mount options construction. ++- mount_nfs.c fix local rdma share not mounting. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/modules/mount_nfs.c ++++ autofs-5.1.4/modules/mount_nfs.c +@@ -375,9 +375,14 @@ dont_probe: + */ + if (this->proximity == PROXIMITY_LOCAL) { + char *host = this->name ? this->name : "localhost"; +- int ret; ++ int ret = 1; + +- ret = rpc_ping(host, port, vers, 2, 0, RPC_CLOSE_DEFAULT); ++ /* If we're using RDMA, rpc_ping will fail when ++ * nfs-server is local. Therefore, don't probe ++ * when we're using RDMA. ++ */ ++ if(!rdma) ++ ret = rpc_ping(host, port, vers, 2, 0, RPC_CLOSE_DEFAULT); + if (ret <= 0) + goto next; + } diff --git a/autofs-5.1.6-move-lib_master_c-to-daemon_master_c.patch b/autofs-5.1.6-move-lib_master_c-to-daemon_master_c.patch new file mode 100644 index 0000000..090a661 --- /dev/null +++ b/autofs-5.1.6-move-lib_master_c-to-daemon_master_c.patch @@ -0,0 +1,6877 @@ +autofs-5.1.6 - move lib/master.c to daemon/master.c + +From: Ian Kent + +The lib subdirectory isn't really the right place for master.c, move +it to the deamon subdirectory. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/Makefile | 19 + daemon/master.c | 1885 ++++++++++++++++++++++++++++++++++++++++++++++++++ + daemon/master_parse.y | 983 ++++++++++++++++++++++++++ + daemon/master_tok.l | 504 +++++++++++++ + lib/Makefile | 23 + lib/master.c | 1885 -------------------------------------------------- + lib/master_parse.y | 983 -------------------------- + lib/master_tok.l | 504 ------------- + 9 files changed, 3394 insertions(+), 3393 deletions(-) + create mode 100644 daemon/master.c + create mode 100644 daemon/master_parse.y + create mode 100644 daemon/master_tok.l + delete mode 100644 lib/master.c + delete mode 100644 lib/master_parse.y + delete mode 100644 lib/master_tok.l + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -133,6 +133,7 @@ xx/xx/2018 autofs-5.1.5 + - remove unused function tree_get_mnt_list(). + - only add expre alarm for active mounts. + - move submount check into conditional_alarm_add(). ++- move lib/master.c to daemon/master.c. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/Makefile ++++ autofs-5.1.4/daemon/Makefile +@@ -6,9 +6,12 @@ + include ../Makefile.rules + + SRCS = automount.c indirect.c direct.c spawn.c module.c mount.c \ +- lookup.c state.c flag.c ++ master.c master_tok.l master_parse.y lookup.c state.c flag.c + OBJS = automount.o indirect.o direct.o spawn.o module.o mount.o \ +- lookup.o state.o flag.o ++ master.o master_tok.o master_parse.tab.o lookup.o state.o \ ++ flag.o ++ ++YACCSRC = master_tok.c master_parse.tab.c master_parse.tab.h + + version := $(shell cat ../.version) + +@@ -38,8 +41,18 @@ automount: $(OBJS) $(AUTOFS_LIB) + $(CC) $(DAEMON_LDFLAGS) -o automount $(OBJS) $(LDFLAGS) $(AUTOFS_LIB) $(LIBS) + $(STRIP) automount + ++master_tok.c: master_tok.l ++ $(LEX) -o$@ -Pmaster_ $? ++ ++master_parse.tab.c master_parse.tab.h: master_parse.y ++ $(YACC) -v -d -p master_ -b master_parse $? ++ ++master_tok.o: master_tok.c master_parse.tab.h ++ ++master_parse.tab.o: master_parse.tab.c master_parse.tab.h ++ + clean: +- rm -f *.o *.s *~ automount ++ rm -f *.o *.s *~ $(YACCSRC) *.output *~ automount + + install: all + install -d -m 755 $(INSTALLROOT)$(sbindir) +--- /dev/null ++++ autofs-5.1.4/daemon/master.c +@@ -0,0 +1,1885 @@ ++/* ----------------------------------------------------------------------- * ++ * ++ * master.c - master map utility routines. ++ * ++ * Copyright 2006 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 "automount.h" ++ ++/* The root of the map entry tree */ ++struct master *master_list = NULL; ++ ++extern const char *global_options; ++extern long global_negative_timeout; ++ ++/* Attribute to create a joinable thread */ ++extern pthread_attr_t th_attr; ++ ++extern struct startup_cond suc; ++ ++static struct map_source * ++__master_find_map_source(struct master_mapent *, ++ const char *, const char *, int, const char **); ++ ++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, unsigned logopt, ++ unsigned nobind, unsigned ghost, int submount) ++{ ++ struct autofs_point *ap; ++ int status; ++ ++ ap = malloc(sizeof(struct autofs_point)); ++ if (!ap) ++ return 0; ++ ++ ap->state = ST_INIT; ++ ++ ap->state_pipe[0] = -1; ++ ap->state_pipe[1] = -1; ++ ap->logpri_fifo = -1; ++ ++ ap->path = strdup(entry->path); ++ if (!ap->path) { ++ free(ap); ++ return 0; ++ } ++ ap->pref = NULL; ++ ++ ap->entry = entry; ++ ap->exp_thread = 0; ++ ap->readmap_thread = 0; ++ /* ++ * Program command line option overrides config. ++ * We can't use 0 negative timeout so use default. ++ */ ++ if (global_negative_timeout <= 0) ++ ap->negative_timeout = defaults_get_negative_timeout(); ++ else ++ ap->negative_timeout = global_negative_timeout; ++ ap->exp_timeout = defaults_get_timeout(); ++ ap->exp_runfreq = 0; ++ ap->flags = 0; ++ ++ if (defaults_get_use_ignore_mount_option()) ++ ap->flags = MOUNT_FLAG_IGNORE; ++ if (ghost) ++ ap->flags |= MOUNT_FLAG_GHOST; ++ ++ if (nobind) ++ ap->flags |= MOUNT_FLAG_NOBIND; ++ ++ if (ap->path[1] == '-') ++ ap->type = LKP_DIRECT; ++ else ++ ap->type = LKP_INDIRECT; ++ ++ 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); ++ INIT_LIST_HEAD(&ap->amdmounts); ++ ap->shutdown = 0; ++ ++ status = pthread_mutex_init(&ap->mounts_mutex, NULL); ++ if (status) { ++ free(ap->path); ++ free(ap); ++ return 0; ++ } ++ ap->mode = 0; ++ ++ entry->ap = ap; ++ ++ return 1; ++} ++ ++void master_free_autofs_point(struct autofs_point *ap) ++{ ++ struct list_head *p, *head; ++ int status; ++ ++ if (!ap) ++ return; ++ ++ mounts_mutex_lock(ap); ++ head = &ap->amdmounts; ++ p = head->next; ++ while (p != head) { ++ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount); ++ p = p->next; ++ ext_mount_remove(mnt->ext_mp); ++ mnts_remove_amdmount(mnt->mp); ++ } ++ mounts_mutex_unlock(ap); ++ ++ status = pthread_mutex_destroy(&ap->mounts_mutex); ++ if (status) ++ fatal(status); ++ ++ if (ap->pref) ++ free(ap->pref); ++ free(ap->path); ++ free(ap); ++} ++ ++struct map_source * ++master_add_map_source(struct master_mapent *entry, ++ char *type, char *format, time_t age, ++ int argc, const char **argv) ++{ ++ struct map_source *source; ++ char *ntype, *nformat; ++ const char **tmpargv; ++ ++ source = malloc(sizeof(struct map_source)); ++ if (!source) ++ return NULL; ++ memset(source, 0, sizeof(struct map_source)); ++ source->ref = 1; ++ ++ if (type) { ++ ntype = strdup(type); ++ if (!ntype) { ++ master_free_map_source(source, 0); ++ return NULL; ++ } ++ source->type = ntype; ++ } ++ ++ if (format) { ++ nformat = strdup(format); ++ if (!nformat) { ++ master_free_map_source(source, 0); ++ return NULL; ++ } ++ source->format = nformat; ++ if (!strcmp(nformat, "amd")) ++ source->flags |= MAP_FLAG_FORMAT_AMD; ++ } ++ ++ source->age = age; ++ source->stale = 1; ++ ++ tmpargv = copy_argv(argc, argv); ++ if (!tmpargv) { ++ master_free_map_source(source, 0); ++ return NULL; ++ } ++ source->argc = argc; ++ source->argv = tmpargv; ++ if (source->argv[0]) ++ source->name = strdup(source->argv[0]); ++ ++ master_source_writelock(entry); ++ ++ if (!entry->maps) { ++ source->mc = cache_init(entry->ap, source); ++ if (!source->mc) { ++ master_free_map_source(source, 0); ++ master_source_unlock(entry); ++ return NULL; ++ } ++ entry->maps = source; ++ } else { ++ struct map_source *this, *last, *next; ++ ++ /* Typically there only a few map sources */ ++ ++ this = __master_find_map_source(entry, type, format, argc, tmpargv); ++ if (this) { ++ debug(entry->ap->logopt, ++ "map source used without taking reference"); ++ this->age = age; ++ master_free_map_source(source, 0); ++ master_source_unlock(entry); ++ return this; ++ } ++ ++ source->mc = cache_init(entry->ap, source); ++ if (!source->mc) { ++ master_free_map_source(source, 0); ++ master_source_unlock(entry); ++ return NULL; ++ } ++ ++ last = NULL; ++ next = entry->maps; ++ while (next) { ++ last = next; ++ next = next->next; ++ } ++ if (last) ++ last->next = source; ++ else ++ entry->maps = source; ++ } ++ ++ master_source_unlock(entry); ++ ++ return source; ++} ++ ++static int compare_source_type_and_format(struct map_source *map, const char *type, const char *format) ++{ ++ int res = 0; ++ ++ if (type) { ++ if (!map->type) ++ goto done; ++ ++ if (strcmp(map->type, type)) ++ goto done; ++ } else if (map->type) ++ goto done; ++ ++ if (format) { ++ if (!map->format) ++ goto done; ++ ++ if (strcmp(map->format, format)) ++ goto done; ++ } else if (map->format) ++ goto done; ++ ++ res = 1; ++done: ++ return res; ++} ++ ++static struct map_source * ++__master_find_map_source(struct master_mapent *entry, ++ const char *type, const char *format, ++ int argc, const char **argv) ++{ ++ struct map_source *map; ++ struct map_source *source = NULL; ++ int res; ++ ++ map = entry->maps; ++ while (map) { ++ res = compare_source_type_and_format(map, type, format); ++ if (!res) ++ goto next; ++ ++ res = compare_argv(map->argc, map->argv, argc, argv); ++ if (!res) ++ goto next; ++ ++ source = map; ++ break; ++next: ++ map = map->next; ++ } ++ ++ return source; ++} ++ ++struct map_source *master_find_map_source(struct master_mapent *entry, ++ const char *type, const char *format, ++ int argc, const char **argv) ++{ ++ struct map_source *source = NULL; ++ ++ master_source_readlock(entry); ++ source = __master_find_map_source(entry, type, format, argc, argv); ++ master_source_unlock(entry); ++ ++ return source; ++} ++ ++struct map_source * ++master_get_map_source(struct master_mapent *entry, ++ const char *type, const char *format, ++ int argc, const char **argv) ++{ ++ struct map_source *source = NULL; ++ ++ master_source_readlock(entry); ++ source = __master_find_map_source(entry, type, format, argc, argv); ++ if (source) ++ source->ref++; ++ master_source_unlock(entry); ++ ++ return source; ++} ++ ++static void __master_free_map_source(struct map_source *source, unsigned int free_cache) ++{ ++ /* instance map sources are not ref counted */ ++ if (source->ref && --source->ref) ++ return; ++ if (source->type) ++ free(source->type); ++ if (source->format) ++ free(source->format); ++ if (source->name) ++ free(source->name); ++ if (free_cache && source->mc) ++ cache_release(source); ++ if (source->lookup) { ++ struct map_source *instance; ++ ++ instance = source->instance; ++ while (instance) { ++ if (instance->lookup) ++ close_lookup(instance->lookup); ++ instance = instance->next; ++ } ++ close_lookup(source->lookup); ++ } ++ if (source->argv) ++ free_argv(source->argc, source->argv); ++ if (source->instance) { ++ struct map_source *instance, *next; ++ ++ instance = source->instance; ++ while (instance) { ++ next = instance->next; ++ __master_free_map_source(instance, 0); ++ instance = next; ++ } ++ } ++ ++ free(source); ++ ++ return; ++} ++ ++void master_free_map_source(struct map_source *source, unsigned int free_cache) ++{ ++ int status; ++ ++ status = pthread_mutex_lock(&instance_mutex); ++ if (status) ++ fatal(status); ++ ++ __master_free_map_source(source, free_cache); ++ ++ status = pthread_mutex_unlock(&instance_mutex); ++ if (status) ++ fatal(status); ++} ++ ++struct map_source *master_find_source_instance(struct map_source *source, const char *type, const char *format, int argc, const char **argv) ++{ ++ struct map_source *map; ++ struct map_source *instance = NULL; ++ int status, res; ++ ++ status = pthread_mutex_lock(&instance_mutex); ++ if (status) ++ fatal(status); ++ ++ map = source->instance; ++ while (map) { ++ res = compare_source_type_and_format(map, type, format); ++ if (!res) ++ goto next; ++ ++ if (!argv) { ++ instance = map; ++ break; ++ } ++ ++ res = compare_argv(map->argc, map->argv, argc, argv); ++ if (!res) ++ goto next; ++ ++ instance = map; ++ break; ++next: ++ map = map->next; ++ } ++ ++ status = pthread_mutex_unlock(&instance_mutex); ++ if (status) ++ fatal(status); ++ ++ return instance; ++} ++ ++struct map_source * ++master_add_source_instance(struct map_source *source, const char *type, const char *format, time_t age, int argc, const char **argv) ++{ ++ struct map_source *instance; ++ struct map_source *new; ++ char *ntype, *nformat; ++ const char **tmpargv; ++ int status; ++ ++ instance = master_find_source_instance(source, type, format, argc, argv); ++ if (instance) ++ return instance; ++ ++ new = malloc(sizeof(struct map_source)); ++ if (!new) ++ return NULL; ++ memset(new, 0, sizeof(struct map_source)); ++ ++ if (type) { ++ ntype = strdup(type); ++ if (!ntype) { ++ master_free_map_source(new, 0); ++ return NULL; ++ } ++ new->type = ntype; ++ } ++ ++ if (format) { ++ nformat = strdup(format); ++ if (!nformat) { ++ master_free_map_source(new, 0); ++ return NULL; ++ } ++ new->format = nformat; ++ if (!strcmp(nformat, "amd")) ++ new->flags |= MAP_FLAG_FORMAT_AMD; ++ } ++ ++ new->age = age; ++ new->master_line = 0; ++ new->mc = source->mc; ++ new->exp_timeout = source->exp_timeout; ++ new->stale = 1; ++ ++ tmpargv = copy_argv(argc, argv); ++ if (!tmpargv) { ++ master_free_map_source(new, 0); ++ return NULL; ++ } ++ new->argc = argc; ++ new->argv = tmpargv; ++ if (source->name) ++ new->name = strdup(source->name); ++ ++ status = pthread_mutex_lock(&instance_mutex); ++ if (status) ++ fatal(status); ++ ++ if (!source->instance) ++ source->instance = new; ++ else { ++ /* ++ * We know there's no other instance of this ++ * type so just add to head of list ++ */ ++ new->next = source->instance; ++ source->instance = new; ++ } ++ ++ status = pthread_mutex_unlock(&instance_mutex); ++ if (status) ++ fatal(status); ++ ++ return new; ++} ++ ++int check_stale_instances(struct map_source *source) ++{ ++ struct map_source *map; ++ ++ if (!source) ++ return 0; ++ ++ map = source->instance; ++ while (map) { ++ if (map->stale) ++ return 1; ++ if (check_stale_instances(map)) ++ return 1; ++ map = map->next; ++ } ++ ++ return 0; ++} ++ ++void clear_stale_instances(struct map_source *source) ++{ ++ struct map_source *map; ++ ++ if (!source) ++ return; ++ ++ map = source->instance; ++ while (map) { ++ clear_stale_instances(map); ++ if (map->stale) ++ map->stale = 0; ++ map = map->next; ++ } ++ ++ return; ++} ++ ++void send_map_update_request(struct autofs_point *ap) ++{ ++ struct map_source *map; ++ int status, need_update = 0; ++ ++ status = pthread_mutex_lock(&instance_mutex); ++ if (status) ++ fatal(status); ++ ++ map = ap->entry->maps; ++ while (map) { ++ if (check_stale_instances(map)) ++ map->stale = 1; ++ if (map->stale) { ++ need_update = 1; ++ break; ++ } ++ map = map->next; ++ } ++ ++ status = pthread_mutex_unlock(&instance_mutex); ++ if (status) ++ fatal(status); ++ ++ if (!need_update) ++ return; ++ ++ st_add_task(ap, ST_READMAP); ++ ++ return; ++} ++ ++void master_source_writelock(struct master_mapent *entry) ++{ ++ int status; ++ ++ status = pthread_rwlock_wrlock(&entry->source_lock); ++ if (status) { ++ logmsg("master_mapent source write lock failed"); ++ fatal(status); ++ } ++ return; ++} ++ ++void master_source_readlock(struct master_mapent *entry) ++{ ++ int retries = 25; ++ int status; ++ ++ while (retries--) { ++ status = pthread_rwlock_rdlock(&entry->source_lock); ++ if (status != EAGAIN && status != EBUSY) ++ break; ++ else { ++ struct timespec t = { 0, 200000000 }; ++ struct timespec r; ++ ++ if (status == EAGAIN) ++ logmsg("master_mapent source too many readers"); ++ else ++ logmsg("master_mapent source write lock held"); ++ ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ } ++ } ++ ++ if (status) { ++ logmsg("master_mapent source read lock failed"); ++ fatal(status); ++ } ++ ++ return; ++} ++ ++void master_source_unlock(struct master_mapent *entry) ++{ ++ int status; ++ ++ status = pthread_rwlock_unlock(&entry->source_lock); ++ if (status) { ++ logmsg("master_mapent source unlock failed"); ++ fatal(status); ++ } ++ return; ++} ++ ++void master_source_lock_cleanup(void *arg) ++{ ++ struct master_mapent *entry = (struct master_mapent *) arg; ++ ++ master_source_unlock(entry); ++ ++ return; ++} ++ ++void master_source_current_wait(struct master_mapent *entry) ++{ ++ int status; ++ ++ status = pthread_mutex_lock(&entry->current_mutex); ++ if (status) { ++ logmsg("entry current source lock failed"); ++ fatal(status); ++ } ++ ++ while (entry->current != NULL) { ++ status = pthread_cond_wait( ++ &entry->current_cond, &entry->current_mutex); ++ if (status) { ++ logmsg("entry current source condition wait failed"); ++ fatal(status); ++ } ++ } ++ ++ return; ++} ++ ++void master_source_current_signal(struct master_mapent *entry) ++{ ++ int status; ++ ++ status = pthread_cond_signal(&entry->current_cond); ++ if (status) { ++ logmsg("entry current source condition signal failed"); ++ fatal(status); ++ } ++ ++ status = pthread_mutex_unlock(&entry->current_mutex); ++ if (status) { ++ logmsg("entry current source unlock failed"); ++ fatal(status); ++ } ++ ++ return; ++} ++ ++struct master_mapent *master_find_mapent(struct master *master, const char *path) ++{ ++ struct list_head *head, *p; ++ ++ head = &master->mounts; ++ list_for_each(p, head) { ++ struct master_mapent *entry; ++ ++ entry = list_entry(p, struct master_mapent, list); ++ ++ if (!strcmp(entry->path, path)) ++ return entry; ++ } ++ ++ return NULL; ++} ++ ++unsigned int master_partial_match_mapent(struct master *master, const char *path) ++{ ++ struct list_head *head, *p; ++ size_t path_len = strlen(path); ++ int ret = 0; ++ ++ head = &master->mounts; ++ list_for_each(p, head) { ++ struct master_mapent *entry; ++ size_t entry_len; ++ size_t cmp_len; ++ ++ entry = list_entry(p, struct master_mapent, list); ++ ++ entry_len = strlen(entry->path); ++ cmp_len = min(entry_len, path_len); ++ ++ if (!strncmp(entry->path, path, cmp_len)) { ++ /* paths are equal, matching master map entry ? */ ++ if (entry_len == path_len) { ++ if (entry->maps && ++ entry->maps->flags & MAP_FLAG_FORMAT_AMD) ++ ret = 1; ++ else ++ ret = -1; ++ break; ++ } ++ ++ /* amd mount conflicts with entry mount */ ++ if (entry_len > path_len && ++ *(entry->path + path_len) == '/') { ++ ret = -1; ++ break; ++ } ++ ++ /* entry mount conflicts with amd mount */ ++ if (entry_len < path_len && ++ *(path + entry_len) == '/') { ++ ret = -1; ++ break; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age) ++{ ++ struct master_mapent *entry; ++ int status; ++ char *tmp; ++ ++ entry = malloc(sizeof(struct master_mapent)); ++ if (!entry) ++ return NULL; ++ ++ memset(entry, 0, sizeof(struct master_mapent)); ++ ++ tmp = strdup(path); ++ if (!tmp) { ++ free(entry); ++ return NULL; ++ } ++ entry->path = tmp; ++ ++ entry->thid = 0; ++ entry->age = age; ++ entry->master = master; ++ entry->current = NULL; ++ entry->maps = NULL; ++ entry->ap = NULL; ++ ++ status = pthread_rwlock_init(&entry->source_lock, NULL); ++ if (status) ++ fatal(status); ++ ++ status = pthread_mutex_init(&entry->current_mutex, NULL); ++ if (status) ++ fatal(status); ++ ++ status = pthread_cond_init(&entry->current_cond, NULL); ++ if (status) ++ fatal(status); ++ ++ INIT_LIST_HEAD(&entry->list); ++ ++ return entry; ++} ++ ++void master_add_mapent(struct master *master, struct master_mapent *entry) ++{ ++ list_add_tail(&entry->list, &master->mounts); ++ return; ++} ++ ++void master_remove_mapent(struct master_mapent *entry) ++{ ++ struct master *master = entry->master; ++ ++ if (entry->ap->submount) ++ return; ++ ++ if (!list_empty(&entry->list)) { ++ list_del_init(&entry->list); ++ list_add(&entry->join, &master->completed); ++ } ++ ++ return; ++} ++ ++void master_free_mapent_sources(struct master_mapent *entry, unsigned int free_cache) ++{ ++ if (entry->maps) { ++ struct map_source *m, *n; ++ ++ m = entry->maps; ++ while (m) { ++ n = m->next; ++ master_free_map_source(m, free_cache); ++ m = n; ++ } ++ entry->maps = NULL; ++ } ++ ++ return; ++} ++ ++void master_free_mapent(struct master_mapent *entry) ++{ ++ int status; ++ ++ if (entry->path) ++ free(entry->path); ++ ++ master_free_autofs_point(entry->ap); ++ ++ status = pthread_rwlock_destroy(&entry->source_lock); ++ if (status) ++ fatal(status); ++ ++ status = pthread_mutex_destroy(&entry->current_mutex); ++ if (status) ++ fatal(status); ++ ++ status = pthread_cond_destroy(&entry->current_cond); ++ if (status) ++ fatal(status); ++ ++ free(entry); ++ ++ return; ++} ++ ++struct master *master_new(const char *name, unsigned int timeout, unsigned int flags) ++{ ++ struct master *master; ++ char *tmp; ++ ++ master = malloc(sizeof(struct master)); ++ if (!master) ++ return NULL; ++ ++ if (!name) ++ tmp = (char *) defaults_get_master_map(); ++ else ++ tmp = strdup(name); ++ ++ if (!tmp) { ++ free(master); ++ return NULL; ++ } ++ ++ master->name = tmp; ++ master->nc = NULL; ++ ++ master->recurse = 0; ++ master->depth = 0; ++ master->reading = 0; ++ master->read_fail = 0; ++ master->readall = 0; ++ master->default_ghost = flags & DAEMON_FLAGS_GHOST; ++ master->default_timeout = timeout; ++ master->default_logging = defaults_get_logging(); ++ master->logopt = master->default_logging; ++ ++ INIT_LIST_HEAD(&master->mounts); ++ INIT_LIST_HEAD(&master->completed); ++ ++ return master; ++} ++ ++static void master_add_amd_mount_section_mounts(struct master *master, time_t age) ++{ ++ unsigned int m_logopt = master->logopt; ++ struct master_mapent *entry; ++ struct map_source *source; ++ unsigned int loglevel; ++ unsigned int logopt; ++ unsigned int flags; ++ char *argv[2]; ++ char **paths; ++ int ret; ++ int i; ++ ++ loglevel = conf_amd_get_log_options(); ++ ++ paths = conf_amd_get_mount_paths(); ++ if (!paths) ++ return; ++ ++ i = 0; ++ while (paths[i]) { ++ const char *path = paths[i]; ++ unsigned int ghost = 0; ++ time_t timeout; ++ char *type = NULL; ++ char *map = NULL; ++ char *opts; ++ ++ ret = master_partial_match_mapent(master, path); ++ if (ret) { ++ /* If this amd entry is already present in the ++ * master map it's not a duplicate, don't issue ++ * an error message. ++ */ ++ if (ret == 1) ++ goto next; ++ info(m_logopt, ++ "amd section mount path conflict, %s ignored", ++ path); ++ goto next; ++ } ++ ++ map = conf_amd_get_map_name(path); ++ if (!map) { ++ error(m_logopt, ++ "failed to get map name for amd section mount %s", ++ path); ++ goto next; ++ } ++ ++ entry = master_new_mapent(master, path, age); ++ if (!entry) { ++ error(m_logopt, ++ "failed to allocate new amd section mount %s", ++ path); ++ goto next; ++ } ++ ++ logopt = m_logopt; ++ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) ++ logopt = LOGOPT_DEBUG; ++ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) ++ logopt = LOGOPT_VERBOSE; ++ ++ /* It isn't possible to provide the fullybrowsable amd ++ * browsing functionality within the autofs framework. ++ * This flag will not be set if browsable_dirs = full ++ * in the configuration or fullybrowsable is present as ++ * an option. ++ */ ++ flags = conf_amd_get_flags(path); ++ if (flags & CONF_BROWSABLE_DIRS) ++ ghost = 1; ++ ++ ret = master_add_autofs_point(entry, logopt, 0, ghost, 0); ++ if (!ret) { ++ error(m_logopt, "failed to add autofs_point"); ++ master_free_mapent(entry); ++ goto next; ++ } ++ ++ opts = conf_amd_get_map_options(path); ++ if (opts) { ++ /* autofs uses the equivalent of cache:=inc,sync ++ * (except for file maps which use cache:=all,sync) ++ * but if the map is large then it may be necessary ++ * to read the whole map at startup even if browsing ++ * is is not enabled, so look for cache:=all in the ++ * map_options configuration entry. ++ */ ++ if (strstr(opts, "cache:=all")) ++ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ free(opts); ++ } ++ ++ type = conf_amd_get_map_type(path); ++ argv[0] = map; ++ argv[1] = NULL; ++ ++ source = master_add_map_source(entry, type, "amd", ++ age, 1, (const char **) argv); ++ if (!source) { ++ error(m_logopt, ++ "failed to add source for amd section mount %s", ++ path); ++ master_free_mapent(entry); ++ goto next; ++ } ++ ++ timeout = conf_amd_get_dismount_interval(path); ++ set_exp_timeout(entry->ap, source, timeout); ++ source->master_line = 0; ++ ++ entry->age = age; ++ entry->current = NULL; ++ ++ master_add_mapent(master, entry); ++next: ++ if (type) ++ free(type); ++ if (map) ++ free(map); ++ i++; ++ } ++ ++ i = 0; ++ while (paths[i]) ++ free(paths[i++]); ++ free(paths); ++} ++ ++static void wait_for_lookups_and_lock(struct master *master) ++{ ++ struct list_head *p, *head; ++ int status; ++ ++again: ++ master_mutex_lock(); ++ ++ head = &master->mounts; ++ p = head->next; ++ while (p != head) { ++ struct master_mapent *this; ++ ++ this = list_entry(p, struct master_mapent, list); ++ ++ status = pthread_rwlock_trywrlock(&this->source_lock); ++ if (status) { ++ struct timespec t = { 0, 200000000 }; ++ struct timespec r; ++ ++ master_mutex_unlock(); ++ ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ ++ goto again; ++ } ++ master_source_unlock(this); ++ ++ p = p->next; ++ } ++} ++ ++int master_read_master(struct master *master, time_t age) ++{ ++ unsigned int logopt = master->logopt; ++ struct mapent_cache *nc; ++ ++ /* ++ * We need to clear and re-populate the null map entry cache ++ * before alowing anyone else to use it. ++ */ ++ wait_for_lookups_and_lock(master); ++ if (master->nc) { ++ cache_writelock(master->nc); ++ nc = master->nc; ++ cache_clean_null_cache(nc); ++ } else { ++ nc = cache_init_null_cache(master); ++ if (!nc) { ++ error(logopt, ++ "failed to init null map cache for %s", ++ master->name); ++ return 0; ++ } ++ cache_writelock(nc); ++ master->nc = nc; ++ } ++ master_init_scan(); ++ lookup_nss_read_master(master, age); ++ cache_unlock(nc); ++ master_add_amd_mount_section_mounts(master, age); ++ ++ if (!master->read_fail) ++ master_mount_mounts(master, age); ++ else { ++ master->read_fail = 0; ++ /* HUP signal sets master->readall == 1 only */ ++ if (!master->readall) { ++ master_mutex_unlock(); ++ return 0; ++ } else ++ master_mount_mounts(master, age); ++ } ++ ++ if (list_empty(&master->mounts)) ++ warn(logopt, "no mounts in table"); ++ ++ master_mutex_unlock(); ++ ++ return 1; ++} ++ ++int master_submount_list_empty(struct autofs_point *ap) ++{ ++ int res = 0; ++ ++ mounts_mutex_lock(ap); ++ if (list_empty(&ap->submounts)) ++ res = 1; ++ mounts_mutex_unlock(ap); ++ ++ return res; ++} ++ ++int master_notify_submount(struct autofs_point *ap, const char *path, enum states state) ++{ ++ struct mnt_list *this, *sbmnt; ++ int ret = 1; ++ ++ this = mnts_find_submount(path); ++ if (this) { ++ /* We have found a submount to expire */ ++ st_mutex_lock(); ++ ++ if (this->ap->state == ST_SHUTDOWN) { ++ this = NULL; ++ st_mutex_unlock(); ++ goto done; ++ } ++ ++ this->ap->shutdown = ap->shutdown; ++ ++ __st_add_task(this->ap, state); ++ ++ st_mutex_unlock(); ++ ++ st_wait_task(this->ap, state, 0); ++ ++ /* ++ * If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or ++ * ST_SHUTDOWN_FORCE we need to wait until it goes away or changes ++ * to ST_READY. ++ */ ++ st_mutex_lock(); ++ while ((sbmnt = mnts_find_submount(path))) { ++ struct timespec t = { 0, 300000000 }; ++ struct timespec r; ++ ++ if (sbmnt->ap->state != ST_SHUTDOWN && ++ sbmnt->ap->state != ST_SHUTDOWN_PENDING && ++ sbmnt->ap->state != ST_SHUTDOWN_FORCE) { ++ ret = 0; ++ mnts_put_mount(sbmnt); ++ break; ++ } ++ mnts_put_mount(sbmnt); ++ ++ st_mutex_unlock(); ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ st_mutex_lock(); ++ } ++ st_mutex_unlock(); ++done: ++ mnts_put_mount(this); ++ } ++ ++ return ret; ++} ++ ++void master_notify_state_change(struct master *master, int sig) ++{ ++ struct master_mapent *entry; ++ struct autofs_point *ap; ++ struct list_head *p; ++ int cur_state; ++ unsigned int logopt; ++ ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ master_mutex_lock(); ++ ++ list_for_each(p, &master->mounts) { ++ enum states next = ST_INVAL; ++ ++ entry = list_entry(p, struct master_mapent, list); ++ ++ ap = entry->ap; ++ logopt = ap->logopt; ++ ++ st_mutex_lock(); ++ ++ if (ap->state == ST_SHUTDOWN) ++ goto next; ++ ++ switch (sig) { ++ case SIGTERM: ++ case SIGINT: ++ if (ap->state != ST_SHUTDOWN_PENDING && ++ ap->state != ST_SHUTDOWN_FORCE) { ++ next = ST_SHUTDOWN_PENDING; ++ ap->shutdown = 1; ++ __st_add_task(ap, next); ++ } ++ break; ++#ifdef ENABLE_FORCED_SHUTDOWN ++ case SIGUSR2: ++ if (ap->state != ST_SHUTDOWN_FORCE && ++ ap->state != ST_SHUTDOWN_PENDING) { ++ next = ST_SHUTDOWN_FORCE; ++ ap->shutdown = 1; ++ __st_add_task(ap, next); ++ } ++ break; ++#endif ++ case SIGUSR1: ++ assert(ap->state == ST_READY); ++ next = ST_PRUNE; ++ __st_add_task(ap, next); ++ break; ++ } ++next: ++ if (next != ST_INVAL) ++ debug(logopt, ++ "sig %d switching %s from %d to %d", ++ sig, ap->path, ap->state, next); ++ ++ st_mutex_unlock(); ++ } ++ ++ master_mutex_unlock(); ++ pthread_setcancelstate(cur_state, NULL); ++ ++ return; ++} ++ ++static int master_do_mount(struct master_mapent *entry) ++{ ++ struct startup_cond suc; ++ struct autofs_point *ap; ++ pthread_t thid; ++ int 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.root = ap->path; ++ suc.done = 0; ++ suc.status = 0; ++ ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) ++ debug(ap->logopt, "mounting %s", entry->path); ++ ++ status = pthread_create(&thid, &th_attr, handle_mounts, &suc); ++ if (status) { ++ crit(ap->logopt, ++ "failed to create mount handler thread for %s", ++ entry->path); ++ handle_mounts_startup_cond_destroy(&suc); ++ return 0; ++ } ++ ++ while (!suc.done) { ++ status = pthread_cond_wait(&suc.cond, &suc.mutex); ++ if (status) ++ fatal(status); ++ } ++ ++ if (suc.status) { ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) ++ error(ap->logopt, "failed to startup mount"); ++ handle_mounts_startup_cond_destroy(&suc); ++ return 0; ++ } ++ entry->thid = thid; ++ ++ handle_mounts_startup_cond_destroy(&suc); ++ ++ return 1; ++} ++ ++static void check_update_map_sources(struct master_mapent *entry, int readall) ++{ ++ struct map_source *source, *last; ++ struct autofs_point *ap; ++ int map_stale = 0; ++ ++ if (readall) ++ map_stale = 1; ++ ++ ap = entry->ap; ++ ++ master_source_writelock(entry); ++ ++ last = NULL; ++ source = entry->maps; ++ while (source) { ++ if (readall) ++ source->stale = 1; ++ ++ /* ++ * If a map source is no longer valid and all it's ++ * entries have expired away we can get rid of it. ++ */ ++ if (entry->age > source->age) { ++ struct mapent *me; ++ cache_readlock(source->mc); ++ me = cache_lookup_first(source->mc); ++ if (!me) { ++ struct map_source *next = source->next; ++ ++ cache_unlock(source->mc); ++ ++ if (!last) ++ entry->maps = next; ++ else ++ last->next = next; ++ ++ if (entry->maps == source) ++ entry->maps = next; ++ ++ master_free_map_source(source, 1); ++ ++ source = next; ++ continue; ++ } else { ++ source->stale = 1; ++ map_stale = 1; ++ } ++ cache_unlock(source->mc); ++ } ++ last = source; ++ source = source->next; ++ } ++ ++ master_source_unlock(entry); ++ ++ /* The map sources have changed */ ++ if (map_stale) ++ st_add_task(ap, ST_READMAP); ++ ++ return; ++} ++ ++int master_mount_mounts(struct master *master, time_t age) ++{ ++ struct mapent_cache *nc = master->nc; ++ struct list_head *p, *head; ++ int cur_state; ++ ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ ++ head = &master->mounts; ++ p = head->next; ++ while (p != head) { ++ struct master_mapent *this; ++ struct autofs_point *ap; ++ struct mapent *ne, *nested; ++ struct stat st; ++ int state_pipe, save_errno; ++ int ret; ++ ++ this = list_entry(p, struct master_mapent, list); ++ p = p->next; ++ ++ ap = this->ap; ++ ++ /* A master map entry has gone away */ ++ if (this->age < age) { ++ st_add_task(ap, ST_SHUTDOWN_PENDING); ++ continue; ++ } ++ ++ cache_readlock(nc); ++ ne = cache_lookup_distinct(nc, this->path); ++ /* ++ * If this path matched a nulled entry the master map entry ++ * must be an indirect mount so the master map entry line ++ * number may be obtained from this->maps. ++ */ ++ if (ne) { ++ int lineno = ne->age; ++ cache_unlock(nc); ++ ++ /* null entry appears after map entry */ ++ if (this->maps->master_line < lineno) { ++ warn(ap->logopt, ++ "ignoring null entry that appears after " ++ "existing entry for %s", this->path); ++ goto cont; ++ } ++ if (ap->state != ST_INIT) { ++ st_add_task(ap, ST_SHUTDOWN_PENDING); ++ continue; ++ } ++ /* ++ * The map entry hasn't been started yet and we've ++ * seen a preceeding null map entry for it so just ++ * delete it from the master map entry list so it ++ * doesn't get in the road. ++ */ ++ list_del_init(&this->list); ++ master_free_mapent_sources(ap->entry, 1); ++ master_free_mapent(ap->entry); ++ continue; ++ } ++ nested = cache_partial_match(nc, this->path); ++ if (nested) { ++ error(ap->logopt, ++ "removing invalid nested null entry %s", ++ nested->key); ++ nested = cache_partial_match(nc, this->path); ++ if (nested) ++ cache_delete(nc, nested->key); ++ } ++ cache_unlock(nc); ++cont: ++ st_mutex_lock(); ++ ++ state_pipe = this->ap->state_pipe[1]; ++ ++ /* No pipe so mount is needed */ ++ ret = fstat(state_pipe, &st); ++ save_errno = errno; ++ ++ st_mutex_unlock(); ++ ++ if (!ret) ++ check_update_map_sources(this, master->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); ++ } ++ } ++ } ++ ++ pthread_setcancelstate(cur_state, NULL); ++ ++ return 1; ++} ++ ++/* The nss source instances end up in reverse order. */ ++static void list_source_instances(struct map_source *source, struct map_source *instance) ++{ ++ if (!source || !instance) { ++ printf("none"); ++ return; ++ } ++ ++ if (instance->next) ++ list_source_instances(source, instance->next); ++ ++ /* ++ * For convienience we map nss instance type "files" to "file". ++ * Check for that and report corrected instance type. ++ */ ++ if (strcmp(instance->type, "file")) ++ printf("%s ", instance->type); ++ else { ++ if (source->argv && *(source->argv[0]) != '/') ++ printf("files "); ++ else ++ printf("%s ", instance->type); ++ } ++ ++ return; ++} ++ ++static void print_map_info(struct map_source *source) ++{ ++ int argc = source->argc; ++ int i, multi, map_num; ++ ++ multi = (source->type && !strcmp(source->type, "multi")); ++ map_num = 1; ++ for (i = 0; i < argc; i++) { ++ if (source->argv[i] && *source->argv[i] != '-') { ++ if (!multi) ++ printf(" map: %s\n", source->argv[i]); ++ else ++ printf(" map[%i]: %s\n", map_num, source->argv[i]); ++ i++; ++ } ++ ++ if (i >= argc) ++ return; ++ ++ if (!strcmp(source->argv[i], "--")) ++ continue; ++ ++ if (source->argv[i]) { ++ int need_newline = 0; ++ int j; ++ ++ if (!multi) ++ printf(" arguments:"); ++ else ++ printf(" arguments[%i]:", map_num); ++ ++ for (j = i; j < source->argc; j++) { ++ if (!strcmp(source->argv[j], "--")) ++ break; ++ printf(" %s", source->argv[j]); ++ i++; ++ need_newline = 1; ++ } ++ if (need_newline) ++ printf("\n"); ++ } ++ if (multi) ++ map_num++; ++ } ++ ++ return; ++} ++ ++static int match_type(const char *source, const char *type) ++{ ++ if (!strcmp(source, type)) ++ return 1; ++ /* Sources file and files are synonymous */ ++ if (!strncmp(source, type, 4) && (strlen(source) <= 5)) ++ return 1; ++ return 0; ++} ++ ++static char *get_map_name(const char *string) ++{ ++ char *name, *tmp; ++ char *start, *end, *base; ++ ++ tmp = strdup(string); ++ if (!tmp) { ++ printf("error: allocation failure: %s\n", strerror(errno)); ++ return NULL; ++ } ++ ++ base = basename(tmp); ++ end = strchr(base, ','); ++ if (end) ++ *end = '\0'; ++ start = strchr(tmp, '='); ++ if (start) ++ start++; ++ else { ++ char *colon = strrchr(base, ':'); ++ if (colon) ++ start = ++colon; ++ else ++ start = base; ++ } ++ ++ name = strdup(start); ++ if (!name) ++ printf("error: allocation failure: %s\n", strerror(errno)); ++ free(tmp); ++ ++ return name; ++} ++ ++static int match_name(struct map_source *source, const char *name) ++{ ++ int argc = source->argc; ++ int ret = 0; ++ int i; ++ ++ /* ++ * This can't work for old style "multi" type sources since ++ * there's no way to know from which map the cache entry came ++ * from and duplicate entries are ignored at map read time. ++ * All we can really do is list all the entries for the given ++ * multi map if one of its map names matches. ++ */ ++ for (i = 0; i < argc; i++) { ++ if (i == 0 || !strcmp(source->argv[i], "--")) { ++ if (i != 0) { ++ i++; ++ if (i >= argc) ++ break; ++ } ++ ++ if (source->argv[i] && *source->argv[i] != '-') { ++ char *map = get_map_name(source->argv[i]); ++ if (!map) ++ break; ++ if (!strcmp(map, name)) { ++ ret = 1; ++ free(map); ++ break; ++ } ++ free(map); ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++int dump_map(struct master *master, const char *type, const char *name) ++{ ++ struct list_head *p, *head; ++ ++ if (list_empty(&master->mounts)) { ++ printf("no master map entries found\n"); ++ return 1; ++ } ++ ++ head = &master->mounts; ++ p = head->next; ++ while (p != head) { ++ struct map_source *source; ++ struct master_mapent *this; ++ struct autofs_point *ap; ++ time_t now = monotonic_time(NULL); ++ ++ this = list_entry(p, struct master_mapent, list); ++ p = p->next; ++ ++ ap = this->ap; ++ ++ /* ++ * Ensure we actually read indirect map entries so we can ++ * list them. The map reads won't read any indirect map ++ * entries (other than those in a file map) unless the ++ * browse option is set. ++ */ ++ if (ap->type == LKP_INDIRECT) ++ ap->flags |= MOUNT_FLAG_GHOST; ++ ++ /* Read the map content into the cache */ ++ if (lookup_nss_read_map(ap, NULL, now)) ++ lookup_prune_cache(ap, now); ++ else { ++ printf("failed to read map\n"); ++ lookup_close_lookup(ap); ++ continue; ++ } ++ ++ if (!this->maps) { ++ printf("no map sources found for %s\n", ap->path); ++ lookup_close_lookup(ap); ++ continue; ++ } ++ ++ source = this->maps; ++ while (source) { ++ struct map_source *instance; ++ struct mapent *me; ++ ++ instance = NULL; ++ if (source->type) { ++ if (!match_type(source->type, type)) { ++ source = source->next; ++ continue; ++ } ++ if (!match_name(source, name)) { ++ source = source->next; ++ continue; ++ } ++ instance = source; ++ } else { ++ struct map_source *map; ++ ++ map = source->instance; ++ while (map) { ++ if (!match_type(map->type, type)) { ++ map = map->next; ++ continue; ++ } ++ if (!match_name(map, name)) { ++ map = map->next; ++ continue; ++ } ++ instance = map; ++ break; ++ } ++ } ++ ++ if (!instance) { ++ source = source->next; ++ lookup_close_lookup(ap); ++ continue; ++ } ++ ++ me = cache_lookup_first(source->mc); ++ if (!me) ++ printf("no keys found in map\n"); ++ else { ++ do { ++ if (me->source == instance) ++ printf("%s\t%s\n", me->key, me->mapent); ++ } while ((me = cache_lookup_next(source->mc, me))); ++ } ++ ++ lookup_close_lookup(ap); ++ return 1; ++ } ++ lookup_close_lookup(ap); ++ } ++ ++ return 0; ++} ++ ++int master_show_mounts(struct master *master) ++{ ++ struct list_head *p, *head; ++ ++ printf("\nautofs dump map information\n" ++ "===========================\n\n"); ++ ++ printf("global options: "); ++ if (!global_options) ++ printf("none configured\n"); ++ else { ++ printf("%s\n", global_options); ++ unsigned int append_options = defaults_get_append_options(); ++ const char *append = append_options ? "will" : "will not"; ++ printf("global options %s be appended to map entries\n", append); ++ } ++ ++ if (list_empty(&master->mounts)) { ++ printf("no master map entries found\n\n"); ++ return 1; ++ } ++ ++ head = &master->mounts; ++ p = head->next; ++ while (p != head) { ++ struct map_source *source; ++ struct master_mapent *this; ++ struct autofs_point *ap; ++ time_t now = monotonic_time(NULL); ++ unsigned int count = 0; ++ ++ this = list_entry(p, struct master_mapent, list); ++ p = p->next; ++ ++ ap = this->ap; ++ ++ printf("\nMount point: %s\n", ap->path); ++ ++ printf("\nsource(s):\n"); ++ ++ /* ++ * Ensure we actually read indirect map entries so we can ++ * list them. The map reads won't read any indirect map ++ * entries (other than those in a file map) unless the ++ * browse option is set. ++ */ ++ if (ap->type == LKP_INDIRECT) ++ ap->flags |= MOUNT_FLAG_GHOST; ++ ++ /* Read the map content into the cache */ ++ if (lookup_nss_read_map(ap, NULL, now)) ++ lookup_prune_cache(ap, now); ++ else { ++ printf(" failed to read map\n\n"); ++ continue; ++ } ++ ++ if (!this->maps) { ++ printf(" no map sources found\n\n"); ++ continue; ++ } ++ ++ source = this->maps; ++ while (source) { ++ struct mapent *me; ++ ++ if (source->type) ++ printf("\n type: %s\n", source->type); ++ else { ++ printf("\n instance type(s): "); ++ list_source_instances(source, source->instance); ++ printf("\n"); ++ } ++ ++ if (source->argc >= 1) { ++ print_map_info(source); ++ if (count && ap->type == LKP_INDIRECT) ++ printf(" duplicate indirect map entry" ++ " will be ignored at run time\n"); ++ } ++ ++ printf("\n"); ++ ++ me = cache_lookup_first(source->mc); ++ if (!me) ++ printf(" no keys found in map\n"); ++ else { ++ do { ++ printf(" %s | %s\n", me->key, me->mapent); ++ } while ((me = cache_lookup_next(source->mc, me))); ++ } ++ ++ count++; ++ ++ source = source->next; ++ } ++ ++ lookup_close_lookup(ap); ++ ++ printf("\n"); ++ } ++ ++ return 1; ++} ++ ++int master_list_empty(struct master *master) ++{ ++ int res = 0; ++ ++ master_mutex_lock(); ++ if (list_empty(&master->mounts)) ++ res = 1; ++ master_mutex_unlock(); ++ ++ return res; ++} ++ ++int master_done(struct master *master) ++{ ++ struct list_head *head, *p; ++ struct master_mapent *entry; ++ int res = 0; ++ ++ head = &master->completed; ++ p = head->next; ++ while (p != head) { ++ entry = list_entry(p, struct master_mapent, join); ++ p = p->next; ++ list_del(&entry->join); ++ pthread_join(entry->thid, NULL); ++ master_free_mapent_sources(entry, 1); ++ master_free_mapent(entry); ++ } ++ if (list_empty(&master->mounts)) ++ res = 1; ++ ++ return res; ++} ++ ++unsigned int master_get_logopt(void) ++{ ++ return master_list ? master_list->logopt : LOGOPT_NONE; ++} ++ ++int master_kill(struct master *master) ++{ ++ if (!list_empty(&master->mounts)) ++ return 0; ++ ++ if (master->name) ++ free(master->name); ++ ++ cache_release_null_cache(master); ++ free(master); ++ ++ return 1; ++} +--- /dev/null ++++ autofs-5.1.4/daemon/master_parse.y +@@ -0,0 +1,983 @@ ++%{ ++/* ----------------------------------------------------------------------- * ++ * ++ * master_parser.y - master map buffer parser. ++ * ++ * Copyright 2006 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 "automount.h" ++#include "master.h" ++ ++#define MAX_ERR_LEN 512 ++ ++extern struct master *master_list; ++ ++char **add_argv(int, char **, char *); ++const char **copy_argv(int, const char **); ++int free_argv(int, const char **); ++ ++extern FILE *master_in; ++extern char *master_text; ++extern int master_lex(void); ++extern int master_lineno; ++extern void master_set_scan_buffer(const char *); ++ ++static char *master_strdup(char *); ++static void local_init_vars(void); ++static void local_free_vars(void); ++static void trim_maptype(char *); ++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; ++static char *format; ++static long timeout; ++static long negative_timeout; ++static unsigned symlnk; ++static unsigned strictexpire; ++static unsigned nobind; ++static unsigned ghost; ++extern unsigned global_selection_options; ++static unsigned random_selection; ++static unsigned use_weight; ++static unsigned long mode; ++static char **tmp_argv; ++static int tmp_argc; ++static char **local_argv; ++static int local_argc; ++ ++#define PROPAGATION_SHARED MOUNT_FLAG_SHARED ++#define PROPAGATION_SLAVE MOUNT_FLAG_SLAVE ++#define PROPAGATION_PRIVATE MOUNT_FLAG_PRIVATE ++#define PROPAGATION_MASK (MOUNT_FLAG_SHARED | \ ++ MOUNT_FLAG_SLAVE | \ ++ MOUNT_FLAG_PRIVATE) ++static unsigned int propagation; ++ ++static char errstr[MAX_ERR_LEN]; ++ ++static unsigned int verbose; ++static unsigned int debug; ++ ++static int lineno; ++ ++#define YYDEBUG 0 ++ ++#ifndef YYENABLE_NLS ++#define YYENABLE_NLS 0 ++#endif ++#ifndef YYLTYPE_IS_TRIVIAL ++#define YYLTYPE_IS_TRIVIAL 0 ++#endif ++ ++#if YYDEBUG ++static int master_fprintf(FILE *, char *, ...); ++#undef YYFPRINTF ++#define YYFPRINTF master_fprintf ++#endif ++ ++%} ++ ++%union { ++ char strtype[2048]; ++ int inttype; ++ long longtype; ++} ++ ++%token COMMENT ++%token MAP ++%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE ++%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE ++%token OPT_STRICTEXPIRE OPT_SHARED OPT_SLAVE OPT_PRIVATE ++%token COLON COMMA NL DDASH ++%type map ++%type options ++%type dn ++%type dnattrs ++%type dnattr ++%type option ++%type daemon_option ++%type mount_option ++%token PATH ++%token QUOTE ++%token NILL ++%token SPACE ++%token EQUAL ++%token MULTITYPE ++%token MAPTYPE ++%token DNSERVER ++%token DNATTR ++%token DNNAME ++%token MAPHOSTS ++%token MAPNULL ++%token MAPXFN ++%token MAPNAME ++%token NUMBER ++%token OCTALNUMBER ++%token OPTION ++ ++%start file ++ ++%% ++ ++file: { ++ master_lineno = 0; ++#if YYDEBUG != 0 ++ master_debug = YYDEBUG; ++#endif ++ } line ++ ; ++ ++line: ++ | PATH mapspec ++ { ++ path = master_strdup($1); ++ if (!path) { ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | PATH MULTITYPE maplist ++ { ++ char *tmp = NULL; ++ ++ trim_maptype($2); ++ ++ if (path) ++ free(path); ++ path = master_strdup($1); ++ if (!path) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ ++ if ((tmp = strchr($2, ','))) ++ *tmp++ = '\0'; ++#ifndef WITH_HESIOD ++ /* Map type or map type parser is hesiod */ ++ if (!strcmp($2, "hesiod") || (tmp && !strcmp(tmp, "hesiod"))) { ++ master_error("hesiod support not built in"); ++ local_free_vars(); ++ YYABORT; ++ } ++#endif ++ if (type) ++ free(type); ++ type = master_strdup($2); ++ if (!type) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ if (tmp) { ++ if (format) ++ free(format); ++ format = master_strdup(tmp); ++ if (!format) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ } ++ | PATH COLON { master_notify($1); YYABORT; } ++ | PATH OPTION { master_notify($2); YYABORT; } ++ | PATH NILL { master_notify($2); YYABORT; } ++ | PATH OPT_RANDOM { master_notify($1); YYABORT; } ++ | PATH OPT_USE_WEIGHT { master_notify($1); YYABORT; } ++ | PATH OPT_DEBUG { master_notify($1); YYABORT; } ++ | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } ++ | PATH OPT_SYMLINK { master_notify($1); YYABORT; } ++ | PATH OPT_STRICTEXPIRE { master_notify($1); YYABORT; } ++ | PATH OPT_SHARED { master_notify($1); YYABORT; } ++ | PATH OPT_SLAVE { master_notify($1); YYABORT; } ++ | PATH OPT_PRIVATE { master_notify($1); YYABORT; } ++ | PATH OPT_NOBIND { master_notify($1); YYABORT; } ++ | PATH OPT_GHOST { master_notify($1); YYABORT; } ++ | PATH OPT_NOGHOST { master_notify($1); YYABORT; } ++ | PATH OPT_VERBOSE { master_notify($1); YYABORT; } ++ | PATH OPT_MODE { master_notify($1); YYABORT; } ++ | PATH { master_notify($1); YYABORT; } ++ | QUOTE { master_notify($1); YYABORT; } ++ | OPTION { master_notify($1); YYABORT; } ++ | NILL { master_notify($1); YYABORT; } ++ | COMMENT { YYABORT; } ++ ; ++ ++mapspec: map ++ { ++ if (local_argv) ++ free_argv(local_argc, (const char **) local_argv); ++ local_argc = tmp_argc; ++ local_argv = tmp_argv; ++ tmp_argc = 0; ++ tmp_argv = NULL; ++ } ++ | map options ++ { ++ if (local_argv) ++ free_argv(local_argc, (const char **) local_argv); ++ local_argc = tmp_argc; ++ local_argv = tmp_argv; ++ tmp_argc = 0; ++ tmp_argv = NULL; ++ } ++ ; ++ ++maplist: map ++ { ++ if (!add_multi_mapstr()) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | map options ++ { ++ if (!add_multi_mapstr()) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | maplist DDASH map ++ { ++ local_argc++; ++ local_argv = add_argv(local_argc, local_argv, "--"); ++ if (!local_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ if (!add_multi_mapstr()) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | maplist DDASH map options ++ { ++ local_argc++; ++ local_argv = add_argv(local_argc, local_argv, "--"); ++ if (!local_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ if (!add_multi_mapstr()) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ ; ++ ++map: PATH ++ { ++ tmp_argc++; ++ tmp_argv = add_argv(tmp_argc, tmp_argv, $1); ++ if (!tmp_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | MAPNAME ++ { ++ tmp_argc++; ++ tmp_argv = add_argv(tmp_argc, tmp_argv, $1); ++ if (!tmp_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | MAPHOSTS ++ { ++ if (type) ++ free(type); ++ type = master_strdup($1 + 1); ++ if (!type) { ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | MAPXFN ++ { ++ master_notify($1); ++ master_msg("X/Open Federated Naming service not supported"); ++ YYABORT; ++ } ++ | MAPNULL ++ { ++ if (type) ++ free(type); ++ type = master_strdup($1 + 1); ++ if (!type) { ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | dnattrs ++ { ++ if (type) ++ free(type); ++ type = master_strdup("ldap"); ++ if (!type) { ++ local_free_vars(); ++ YYABORT; ++ } ++ tmp_argc++; ++ tmp_argv = add_argv(tmp_argc, tmp_argv, $1); ++ if (!tmp_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | MAPTYPE PATH ++ { ++ char *tmp = NULL; ++ ++ trim_maptype($1); ++ ++ if ((tmp = strchr($1, ','))) ++ *tmp++ = '\0'; ++#ifndef WITH_HESIOD ++ /* Map type or map type parser is hesiod */ ++ if (!strcmp($1, "hesiod") || (tmp && !strcmp(tmp, "hesiod"))) { ++ master_error("hesiod support not built in"); ++ local_free_vars(); ++ YYABORT; ++ } ++#endif ++ if (type) ++ free(type); ++ if (strcmp($1, "exec")) ++ type = master_strdup($1); ++ else ++ type = master_strdup("program"); ++ if (!type) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ if (tmp) { ++ if (format) ++ free(format); ++ format = master_strdup(tmp); ++ if (!format) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ tmp_argc++; ++ tmp_argv = add_argv(tmp_argc, tmp_argv, $2); ++ if (!tmp_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | MAPTYPE MAPNAME ++ { ++ char *tmp = NULL; ++ ++ trim_maptype($1); ++ ++ if ((tmp = strchr($1, ','))) ++ *tmp++ = '\0'; ++ ++ if (type) ++ free(type); ++ if (strcmp($1, "exec")) ++ type = master_strdup($1); ++ else ++ type = master_strdup("program"); ++ if (!type) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ if (tmp) { ++ if (format) ++ free(format); ++ format = master_strdup(tmp); ++ if (!format) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ tmp_argc++; ++ tmp_argv = add_argv(tmp_argc, tmp_argv, $2); ++ if (!tmp_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ | MAPTYPE dn ++ { ++ char *tmp = NULL; ++ ++ trim_maptype($1); ++ ++ if ((tmp = strchr($1, ','))) ++ *tmp++ = '\0'; ++ ++ if (type) ++ free(type); ++ if (strcmp($1, "exec")) ++ type = master_strdup($1); ++ else ++ type = master_strdup("program"); ++ if (!type) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ if (tmp) { ++ if (format) ++ free(format); ++ format = master_strdup(tmp); ++ if (!format) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ tmp_argc++; ++ tmp_argv = add_argv(tmp_argc, tmp_argv, $2); ++ if (!tmp_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ /* Add back the type for lookup_ldap.c to handle ldaps */ ++ if (*tmp_argv[0]) { ++ tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2); ++ if (!tmp) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ strcpy(tmp, type); ++ strcat(tmp, ":"); ++ strcat(tmp, tmp_argv[0]); ++ free(tmp_argv[0]); ++ tmp_argv[0] = tmp; ++ } ++ } ++ ; ++ ++dn: DNSERVER dnattrs ++ { ++ strcpy($$, $1); ++ strcat($$, $2); ++ } ++ | dnattrs ++ { ++ strcpy($$, $1); ++ } ++ | ++ { ++ master_notify("syntax error in dn"); ++ YYABORT; ++ } ++ ; ++ ++dnattrs: DNATTR EQUAL DNNAME ++ { ++ if (strcasecmp($1, "cn") && ++ strcasecmp($1, "ou") && ++ strcasecmp($1, "automountMapName") && ++ strcasecmp($1, "nisMapName")) { ++ strcpy(errstr, $1); ++ strcat(errstr, "="); ++ strcat(errstr, $3); ++ master_notify(errstr); ++ YYABORT; ++ } ++ strcpy($$, $1); ++ strcat($$, "="); ++ strcat($$, $3); ++ } ++ | DNATTR EQUAL DNNAME COMMA dnattr ++ { ++ if (strcasecmp($1, "cn") && ++ strcasecmp($1, "ou") && ++ strcasecmp($1, "automountMapName") && ++ strcasecmp($1, "nisMapName")) { ++ strcpy(errstr, $1); ++ strcat(errstr, "="); ++ strcat(errstr, $3); ++ master_notify(errstr); ++ YYABORT; ++ } ++ strcpy($$, $1); ++ strcat($$, "="); ++ strcat($$, $3); ++ strcat($$, ","); ++ strcat($$, $5); ++ } ++ | DNNAME ++ { ++ /* Matches map in old style syntax ldap:server:map */ ++ strcpy($$, $1); ++ } ++ | DNATTR ++ { ++ master_notify($1); ++ YYABORT; ++ } ++ ; ++ ++dnattr: DNATTR EQUAL DNNAME ++ { ++ if (!strcasecmp($1, "automountMapName") || ++ !strcasecmp($1, "nisMapName")) { ++ strcpy(errstr, $1); ++ strcat(errstr, "="); ++ strcat(errstr, $3); ++ master_notify(errstr); ++ YYABORT; ++ } ++ strcpy($$, $1); ++ strcat($$, "="); ++ strcat($$, $3); ++ } ++ | DNATTR EQUAL DNNAME COMMA dnattr ++ { ++ if (!strcasecmp($1, "automountMapName") || ++ !strcasecmp($1, "nisMapName")) { ++ strcpy(errstr, $1); ++ strcat(errstr, "="); ++ strcat(errstr, $3); ++ master_notify(errstr); ++ YYABORT; ++ } ++ strcpy($$, $1); ++ strcat($$, "="); ++ strcat($$, $3); ++ strcat($$, ","); ++ strcat($$, $5); ++ } ++ | DNATTR ++ { ++ master_notify($1); ++ YYABORT; ++ } ++ | DNNAME ++ { ++ master_notify($1); ++ YYABORT; ++ } ++ ; ++ ++options: option {} ++ | options COMMA option {} ++ | options option {} ++ | options COMMA COMMA option ++ { ++ master_notify($1); ++ YYABORT; ++ } ++ | options EQUAL ++ { ++ master_notify($1); ++ YYABORT; ++ } ++ ; ++ ++option: daemon_option ++ | mount_option {} ++ | error ++ { ++ master_notify("bogus option"); ++ YYABORT; ++ } ++ ; ++ ++daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } ++ | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } ++ | OPT_SYMLINK { symlnk = 1; } ++ | OPT_STRICTEXPIRE { strictexpire = 1; } ++ | OPT_SHARED { propagation = PROPAGATION_SHARED; } ++ | OPT_SLAVE { propagation = PROPAGATION_SLAVE; } ++ | OPT_PRIVATE { propagation = PROPAGATION_PRIVATE; } ++ | OPT_NOBIND { nobind = 1; } ++ | OPT_NOGHOST { ghost = 0; } ++ | OPT_GHOST { ghost = 1; } ++ | OPT_VERBOSE { verbose = 1; } ++ | OPT_DEBUG { debug = 1; } ++ | OPT_RANDOM { random_selection = 1; } ++ | OPT_USE_WEIGHT { use_weight = 1; } ++ | OPT_MODE OCTALNUMBER { mode = $2; } ++ ; ++ ++mount_option: OPTION ++ { ++ tmp_argc++; ++ tmp_argv = add_argv(tmp_argc, tmp_argv, $1); ++ if (!tmp_argv) { ++ master_error("memory allocation error"); ++ local_free_vars(); ++ YYABORT; ++ } ++ } ++ ; ++%% ++ ++#if YYDEBUG ++static int master_fprintf(FILE *f, char *msg, ...) ++{ ++ va_list ap; ++ va_start(ap, msg); ++ vsyslog(LOG_DEBUG, msg, ap); ++ va_end(ap); ++ return 1; ++} ++#endif ++ ++static char *master_strdup(char *str) ++{ ++ char *tmp; ++ ++ tmp = strdup(str); ++ if (!tmp) ++ master_error("memory allocation error"); ++ return tmp; ++} ++ ++static int master_error(const char *s) ++{ ++ logmsg("%s while parsing map.", s); ++ return 0; ++} ++ ++static int master_notify(const char *s) ++{ ++ logmsg("syntax error in map near [ %s ]", s); ++ return(0); ++} ++ ++static int master_msg(const char *s) ++{ ++ logmsg("%s", s); ++ return 0; ++} ++ ++static void local_init_vars(void) ++{ ++ path = NULL; ++ type = NULL; ++ format = NULL; ++ verbose = 0; ++ debug = 0; ++ timeout = -1; ++ negative_timeout = 0; ++ symlnk = 0; ++ strictexpire = 0; ++ propagation = PROPAGATION_SLAVE; ++ nobind = 0; ++ ghost = defaults_get_browse_mode(); ++ random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; ++ use_weight = 0; ++ mode = 0; ++ tmp_argv = NULL; ++ tmp_argc = 0; ++ local_argv = NULL; ++ local_argc = 0; ++} ++ ++static void local_free_vars(void) ++{ ++ if (path) ++ free(path); ++ ++ if (type) ++ free(type); ++ ++ if (format) ++ free(format); ++ ++ if (local_argv) { ++ free_argv(local_argc, (const char **) local_argv); ++ local_argv = NULL; ++ local_argc = 0; ++ } ++ ++ if (tmp_argv) { ++ free_argv(tmp_argc, (const char **) tmp_argv); ++ tmp_argv = NULL; ++ tmp_argc = 0; ++ } ++} ++ ++static void trim_maptype(char *type) ++{ ++ char *tmp; ++ ++ tmp = strchr(type, ':'); ++ if (tmp) ++ *tmp = '\0'; ++ else { ++ int len = strlen(type); ++ while (len-- && isblank(type[len])) ++ type[len] = '\0'; ++ } ++ return; ++} ++ ++static int add_multi_mapstr(void) ++{ ++ if (type) { ++ /* If type given and format is non-null add it back */ ++ if (format) { ++ int len = strlen(type) + strlen(format) + 2; ++ char *tmp = realloc(type, len); ++ if (!tmp) ++ return 0; ++ type = tmp; ++ strcat(type, ","); ++ strcat(type, format); ++ free(format); ++ format = NULL; ++ } ++ ++ local_argc++; ++ local_argv = add_argv(local_argc, local_argv, type); ++ if (!local_argv) { ++ free(type); ++ type = NULL; ++ return 0; ++ } ++ ++ free(type); ++ type = NULL; ++ } ++ ++ local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv); ++ if (!local_argv) { ++ free(type); ++ type = NULL; ++ return 0; ++ } ++ local_argc += tmp_argc; ++ ++ tmp_argc = 0; ++ tmp_argv = NULL; ++ ++ return 1; ++} ++ ++void master_init_scan(void) ++{ ++ lineno = 0; ++} ++ ++int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigned int logging, time_t age) ++{ ++ struct master *master = master_list; ++ struct mapent_cache *nc; ++ struct master_mapent *entry, *new; ++ struct map_source *source; ++ unsigned int logopt = logging; ++ unsigned int m_logopt = master->logopt; ++ size_t mp_len; ++ int ret; ++ ++ local_init_vars(); ++ ++ lineno++; ++ ++ master_set_scan_buffer(buffer); ++ ++ ret = master_parse(); ++ if (ret != 0) { ++ local_free_vars(); ++ return 0; ++ } ++ ++ mp_len = strlen(path); ++ while (mp_len && path[--mp_len] == '/') ++ path[mp_len] = 0; ++ ++ nc = master->nc; ++ ++ /* Add null map entries to the null map cache */ ++ if (type && !strcmp(type, "null")) { ++ cache_update(nc, NULL, path, NULL, lineno); ++ local_free_vars(); ++ return 1; ++ } ++ ++ /* Ignore all subsequent matching nulled entries */ ++ if (cache_lookup_distinct(nc, path)) { ++ local_free_vars(); ++ return 1; ++ } ++ ++ if (debug || verbose) { ++ logopt = (debug ? LOGOPT_DEBUG : 0); ++ logopt |= (verbose ? LOGOPT_VERBOSE : 0); ++ } ++ ++ new = NULL; ++ entry = master_find_mapent(master, path); ++ if (!entry) { ++ new = master_new_mapent(master, path, age); ++ if (!new) { ++ local_free_vars(); ++ return 0; ++ } ++ entry = new; ++ } else { ++ if (entry->age && entry->age == age) { ++ if (strcmp(path, "/-")) { ++ info(m_logopt, ++ "ignoring duplicate indirect mount %s", ++ path); ++ local_free_vars(); ++ return 0; ++ } ++ } ++ } ++ ++ if (!format) { ++ if (conf_amd_mount_section_exists(path)) ++ format = strdup("amd"); ++ } ++ ++ if (format && !strcmp(format, "amd")) { ++ unsigned int loglevel = conf_amd_get_log_options(); ++ unsigned int flags = conf_amd_get_flags(path); ++ ++ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) ++ logopt = LOGOPT_DEBUG; ++ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) ++ logopt = LOGOPT_VERBOSE; ++ ++ /* It isn't possible to provide the fullybrowsable amd ++ * browsing functionality within the autofs framework. ++ * This flag will not be set if browsable_dirs = full ++ * in the configuration or fullybrowsable is present as ++ * an option. ++ */ ++ if (flags & CONF_BROWSABLE_DIRS) ++ ghost = 1; ++ } ++ ++ if (!entry->ap) { ++ ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0); ++ if (!ret) { ++ error(m_logopt, "failed to add autofs_point"); ++ if (new) ++ master_free_mapent(new); ++ local_free_vars(); ++ return 0; ++ } ++ } ++ entry->ap->flags &= ~(PROPAGATION_MASK); ++ entry->ap->flags |= propagation; ++ ++ if (random_selection) ++ entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT; ++ if (use_weight) ++ entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; ++ if (symlnk) ++ entry->ap->flags |= MOUNT_FLAG_SYMLINK; ++ if (strictexpire) ++ entry->ap->flags |= MOUNT_FLAG_STRICTEXPIRE; ++ if (negative_timeout) ++ entry->ap->negative_timeout = negative_timeout; ++ if (mode && mode < LONG_MAX) ++ entry->ap->mode = mode; ++ ++ if (timeout < 0) { ++ /* ++ * If no timeout is given get the timout from the ++ * autofs point, or the first map, or the config ++ * for amd maps. ++ */ ++ if (format && !strcmp(format, "amd")) ++ timeout = conf_amd_get_dismount_interval(path); ++ else ++ timeout = get_exp_timeout(entry->ap, entry->maps); ++ } ++ ++ if (format && !strcmp(format, "amd")) { ++ char *opts = conf_amd_get_map_options(path); ++ if (opts) { ++ /* autofs uses the equivalent of cache:=inc,sync ++ * (except for file maps which use cache:=all,sync) ++ * but if the map is large then it may be necessary ++ * to read the whole map at startup even if browsing ++ * is is not enabled, so look for cache:=all in the ++ * map_options configuration entry. ++ */ ++ if (strstr(opts, "cache:=all")) ++ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ free(opts); ++ } ++ } ++ ++/* ++ source = master_find_map_source(entry, type, format, ++ local_argc, (const char **) local_argv); ++ if (!source) ++ source = master_add_map_source(entry, type, format, age, ++ local_argc, (const char **) local_argv); ++ else ++ source->age = age; ++*/ ++ source = master_add_map_source(entry, type, format, age, ++ local_argc, (const char **) local_argv); ++ if (!source) { ++ error(m_logopt, "failed to add source"); ++ if (new) ++ master_free_mapent(new); ++ local_free_vars(); ++ return 0; ++ } ++ set_exp_timeout(entry->ap, source, timeout); ++ source->master_line = lineno; ++ ++ entry->age = age; ++ entry->current = NULL; ++ ++ if (new) ++ master_add_mapent(master, entry); ++ ++ local_free_vars(); ++ ++ return 1; ++} ++ +--- /dev/null ++++ autofs-5.1.4/daemon/master_tok.l +@@ -0,0 +1,504 @@ ++%{ ++/* ----------------------------------------------------------------------- * ++ * ++ * master_tok.l - master map tokenizer. ++ * ++ * Copyright 2006 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. ++ * ++ * ----------------------------------------------------------------------- */ ++ ++#ifdef ECHO ++# undef ECHO ++#endif /* ECHO */ ++static void master_echo(void); /* forward definition */ ++#define ECHO master_echo() ++ ++#include ++#include ++#include ++#include ++#include "master_parse.tab.h" ++ ++/* ++ * There are some things that need to be defined only if useing GNU flex. ++ * These must not be defined if using standard lex ++ */ ++#ifdef FLEX_SCANNER ++int master_lineno; ++#endif ++ ++int master_lex(void); ++int master_wrap(void); ++ ++/* no need for yywrap() */ ++#define YY_SKIP_YYWRAP ++ ++#ifndef YY_STACK_USED ++#define YY_STACK_USED 0 ++#endif ++#ifndef YY_ALWAYS_INTERACTIVE ++#define YY_ALWAYS_INTERACTIVE 0 ++#endif ++#ifndef YY_NEVER_INTERACTIVE ++#define YY_NEVER_INTERACTIVE 0 ++#endif ++#ifndef YY_MAIN ++#define YY_MAIN 0 ++#endif ++ ++void master_set_scan_buffer(const char *); ++const char *line = NULL; ++ ++#ifdef FLEX_SCANNER ++const char *line_pos = NULL; ++const char *line_lim = NULL; ++int my_yyinput(char *, int); ++ ++#undef YY_INPUT ++#define YY_INPUT(b, r, ms) (r = my_yyinput(b, ms)) ++#else ++#undef input ++#undef unput ++#define input() (*(char *) line++) ++#define unput(c) (*(char *) --line = c) ++#endif ++ ++#define BUFF_LEN 1024 ++char buff[BUFF_LEN]; ++char *bptr; ++char *optr = buff; ++unsigned int tlen; ++ ++%} ++ ++%option nounput ++ ++%x PATHSTR MAPSTR DNSTR OPTSTR OCTAL ++ ++WS [[:blank:]]+ ++OPTWS [[:blank:]]* ++NL \r?\n ++CONT \\\n{OPTWS} ++ ++OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=(\"?([[:alnum:]_\-\:\.])+\"?))?)+) ++MACROSTR (-D{OPTWS}([[:alpha:]_]([[:alnum:]_\-\.])*)=([[:alnum:]_\-\.])+) ++SLASHIFYSTR (--(no-)?slashify-colons) ++NUMBER [0-9]+ ++OCTALNUMBER [0-7]+ ++ ++DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:) ++DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:) ++DNSERVSTR3 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/) ++DNSERVSTR4 (\/\/\[([[:xdigit:]]:.)+\](:[0-9]+)?\/) ++DNSERVSTR5 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:) ++DNSERVSTR6 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/) ++DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}|{DNSERVSTR5}|{DNSERVSTR6}) ++ ++AT_CN ([cC][[nN]) ++AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE]) ++AT_AMN ([aA][uU][tT][oO][mM][oO][uU][nN][tT][Mm][aA][pP][Nn][aA][mM][eE]) ++AT_OU ([oO][[uU]) ++AT_DC ([dD][[cC]) ++AT_O ([oO]) ++AT_C ([cC]) ++AT_L ([lL]) ++DNATTRSTR ({AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}|{AT_L}) ++DNNAMESTR1 ([[:alnum:]_.\- ]+) ++DNNAMESTR2 ([[:alnum:]_.\-]+) ++ ++INTMAP (-hosts|-null) ++MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS})) ++MULTISEP ([\-]{2}[[:blank:]]+) ++MTYPE ((file|program|exec|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod|amd))?(:{OPTWS}|{WS})) ++ ++ ++OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) ++OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeout{OPTWS}={OPTWS}) ++ ++MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS}) ++ ++%% ++ ++{ ++ {NL} | ++ \x00 { ++ if (optr != buff) { ++ *optr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return NILL; ++ } ++ } ++ ++ #.* { return COMMENT; } ++ ++ "/" { ++ if (optr != buff) { ++ *optr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return NILL; ++ } ++ BEGIN(PATHSTR); ++ bptr = buff; ++ yyless(0); ++ } ++ ++ . { *optr++ = *master_text; } ++} ++ ++{ ++ \x00 { ++ BEGIN(INITIAL); ++ *bptr++ = *master_text; ++ strcpy(master_lval.strtype, buff); ++ return NILL; ++ } ++ ++ \\. { *bptr++ = *(master_text + 1); } ++ \" { ++ BEGIN(INITIAL); ++ *bptr++ = *master_text; ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return QUOTE; ++ } ++ ++ {WS} { ++ BEGIN(MAPSTR); ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ bptr = buff; ++ memset(buff, 0, BUFF_LEN); ++ return(PATH); ++ } ++ ++ <> { ++ BEGIN(INITIAL); ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return(PATH); ++ } ++ ++ {NL} { ++ BEGIN(INITIAL); ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return PATH; ++ } ++ ++ . { *bptr++ = *master_text; } ++} ++ ++{ ++ {OPTWS}\\\n{OPTWS} {} ++ ++ {MULTI} { ++ tlen = master_leng - 1; ++ if (bptr != buff && isblank(master_text[tlen])) { ++ /* ++ * We can't handle unescaped white space in map names ++ * so just eat the white space. We always have the ++ * "multi" at the beginning of the string so the while ++ * will not fall off the end. ++ */ ++ while (isblank(master_text[tlen - 1])) ++ tlen--; ++ strncat(buff, master_text, tlen); ++ bptr += tlen; ++ yyless(tlen); ++ } else { ++ strcpy(master_lval.strtype, master_text); ++ return(MULTITYPE); ++ } ++ } ++ ++ {MTYPE} | ++ {MTYPE}/{DNSERVERSTR}{DNATTRSTR}= | ++ {MTYPE}/{DNATTRSTR}= { ++ tlen = master_leng - 1; ++ if (bptr != buff && isblank(master_text[tlen])) { ++ /* ++ * We can't handle unescaped white space in map names ++ * so just eat the white space. We always have the ++ * maptype keyword at the beginning of the string so ++ * the while will not fall off the end. ++ */ ++ while (isblank(master_text[tlen - 1])) ++ tlen--; ++ strncat(buff, master_text, tlen); ++ bptr += tlen; ++ yyless(tlen); ++ } else { ++ strcpy(master_lval.strtype, master_text); ++ return(MAPTYPE); ++ } ++ } ++ ++ {MULTISEP} { return(DDASH); } ++ ++ ":" { return(COLON); } ++ ++ "-hosts" { ++ BEGIN(OPTSTR); ++ strcpy(master_lval.strtype, master_text); ++ return MAPHOSTS; ++ } ++ ++ "-null" { ++ BEGIN(OPTSTR); ++ strcpy(master_lval.strtype, master_text); ++ return MAPNULL; ++ } ++ ++ "-xfn" { ++ /* ++ * The X/Open Federated Naming service isn't supported ++ * and the parser will call YYABORT() when it sees the ++ * MAPXFN token so we must set the start state to the ++ * INITIAL state here for the next yylex() call. ++ */ ++ BEGIN(INITIAL); ++ strcpy(master_lval.strtype, master_text); ++ return MAPXFN; ++ } ++ ++ "//" { ++ BEGIN(DNSTR); ++ yyless(0); ++ } ++ ++ {DNSERVERSTR}{DNATTRSTR}= { ++ BEGIN(DNSTR); ++ yyless(0); ++ } ++ ++ {DNATTRSTR}= { ++ BEGIN(DNSTR); ++ yyless(0); ++ } ++ ++ {OPTWS}/{NL} { ++ BEGIN(INITIAL); ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ bptr = buff; ++ return(MAPNAME); ++ } ++ ++ \\. { *bptr++ = *(master_text + 1); } ++ ++ {WS} { ++ BEGIN(OPTSTR); ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ bptr = buff; ++ return(MAPNAME); ++ } ++ ++ {NL} | ++ \x00 { ++ BEGIN(INITIAL); ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return(MAPNAME); ++ } ++ ++ <> { ++ BEGIN(INITIAL); ++ *bptr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return(MAPNAME); ++ } ++ ++ . { *bptr++ = *master_text; } ++} ++ ++{ ++ {OPTWS}\\\n{OPTWS} {} ++ ++ {DNSERVERSTR} { ++ strcpy(master_lval.strtype, master_text); ++ return DNSERVER; ++ } ++ ++ {DNATTRSTR}/"=" { ++ strcpy(master_lval.strtype, master_text); ++ return DNATTR; ++ } ++ ++ "=" { ++ return EQUAL; ++ } ++ ++ {DNNAMESTR1}/","{DNATTRSTR}"=" { ++ strcpy(master_lval.strtype, master_text); ++ return DNNAME; ++ } ++ ++ {DNNAMESTR2} { ++ strcpy(master_lval.strtype, master_text); ++ return DNNAME; ++ } ++ ++ {OPTWS}","{OPTWS} { ++ return COMMA; ++ } ++ ++ {WS}"=" | ++ "="{WS} { ++ BEGIN(INITIAL); ++ strcpy(master_lval.strtype, master_text); ++ return SPACE; ++ } ++ ++ {WS} { BEGIN(OPTSTR); } ++ ++ {NL} | ++ \x00 { BEGIN(INITIAL); } ++ ++ <> { BEGIN(INITIAL); } ++} ++ ++{ ++ {OPTWS}\\\n{OPTWS} {} ++ ++ {MULTISEP} { ++ BEGIN(MAPSTR); ++ return(DDASH); ++ } ++ ++ {OPTTOUT}/{NUMBER} { return(OPT_TIMEOUT); } ++ ++ {OPTNTOUT}/{NUMBER} { return(OPT_NTIMEOUT); } ++ ++ {NUMBER} { ++ master_lval.longtype = atol(master_text); ++ return(NUMBER); ++ } ++ ++ -?symlink { return(OPT_SYMLINK); } ++ -?nobind { return(OPT_NOBIND); } ++ -?nobrowse { return(OPT_NOGHOST); } ++ -?shared { return(OPT_SHARED); } ++ -?slave { return(OPT_SLAVE); } ++ -?private { return(OPT_PRIVATE); } ++ -?strictexpire { return(OPT_STRICTEXPIRE); } ++ -g|--ghost|-?browse { return(OPT_GHOST); } ++ -v|--verbose { return(OPT_VERBOSE); } ++ -d|--debug { return(OPT_DEBUG); } ++ -w|--use-weight-only { return(OPT_USE_WEIGHT); } ++ -r|--random-multimount-selection { return(OPT_RANDOM); } ++ ++ {MODE}/{OCTALNUMBER} { ++ BEGIN(OCTAL); ++ return(OPT_MODE); ++ } ++ ++ {OPTWS}","{OPTWS} { return(COMMA); } ++ ++ {OPTWS} {} ++ ++ {SLASHIFYSTR} { ++ strcpy(master_lval.strtype, master_text); ++ return(OPTION); ++ } ++ ++ {MACROSTR} { ++ strcpy(master_lval.strtype, master_text); ++ return(OPTION); ++ } ++ ++ {OPTIONSTR} { ++ strcpy(master_lval.strtype, master_text); ++ return(OPTION); ++ } ++ ++ "=" { ++ strcpy(master_lval.strtype, master_text); ++ return(EQUAL); ++ } ++ ++ {WS} {} ++ {NL} | ++ \x00 { BEGIN(INITIAL); } ++ ++ <> { BEGIN(INITIAL); } ++} ++ ++{ ++ {OCTALNUMBER} { ++ master_lval.longtype = strtoul(master_text, NULL, 8); ++ return(OCTALNUMBER); ++ } ++ ++ . { BEGIN(OPTSTR); yyless(0); } ++} ++ ++%% ++ ++#include "automount.h" ++ ++int master_wrap(void) ++{ ++ return 1; ++} ++ ++static void master_echo(void) ++{ ++ logmsg("%s", master_text); ++ return; ++} ++ ++#ifdef FLEX_SCANNER ++ ++void master_set_scan_buffer(const char *buffer) ++{ ++ memset(buff, 0, sizeof(buff)); ++ optr = buff; ++ ++ YY_FLUSH_BUFFER; ++ ++ line = buffer; ++ line_pos = &line[0]; ++ /* ++ * Ensure buffer is 1 greater than string and is zeroed before ++ * the parse so we can fit the extra NULL which allows us to ++ * explicitly match an end of line within the buffer (ie. the ++ * need for 2 NULLS when parsing in memeory buffers). ++ */ ++ line_lim = line + strlen(buffer) + 1; ++} ++ ++#ifndef min ++#define min(a,b) (((a) < (b)) ? (a) : (b)) ++#endif ++ ++int my_yyinput(char *buffer, int max_size) ++{ ++ int n = min(max_size, line_lim - line_pos); ++ ++ if (n > 0) { ++ memcpy(buffer, line_pos, n); ++ line_pos += n; ++ } ++ return n; ++} ++ ++#else ++ ++void master_set_scan_buffer(const char *buffer) ++{ ++ line = buffer; ++} ++ ++#endif +--- autofs-5.1.4.orig/lib/Makefile ++++ autofs-5.1.4/lib/Makefile +@@ -6,17 +6,14 @@ + include ../Makefile.rules + + SRCS = cache.c cat_path.c rpc_subs.c mounts.c log.c nsswitch.c \ +- master_tok.l master_parse.y nss_tok.c nss_parse.tab.c \ +- args.c alarm.c macros.c master.c defaults.c parse_subs.c \ +- dev-ioctl-lib.c ++ nss_tok.c nss_parse.tab.c args.c alarm.c macros.c defaults.c \ ++ parse_subs.c dev-ioctl-lib.c + RPCS = mount.h mount_clnt.c mount_xdr.c + OBJS = cache.o mount_clnt.o mount_xdr.o cat_path.o rpc_subs.o \ +- mounts.o log.o nsswitch.o master_tok.o master_parse.tab.o \ +- nss_tok.o nss_parse.tab.o args.o alarm.o macros.o master.o \ +- defaults.o parse_subs.o dev-ioctl-lib.o ++ mounts.o log.o nsswitch.o nss_tok.o nss_parse.tab.o args.o \ ++ alarm.o macros.o defaults.o parse_subs.o dev-ioctl-lib.o + +-YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h \ +- master_tok.c master_parse.tab.c master_parse.tab.h ++YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h + + LIB = autofs.a + +@@ -54,16 +51,6 @@ mount_xdr.o: mount_xdr.c + $(CC) $(CFLAGS) -Wno-unused-variable -o mount_xdr.o -c mount_xdr.c + $(STRIP) mount_xdr.o + +-master_tok.c: master_tok.l +- $(LEX) -o$@ -Pmaster_ $? +- +-master_parse.tab.c master_parse.tab.h: master_parse.y +- $(YACC) -v -d -p master_ -b master_parse $? +- +-master_tok.o: master_tok.c master_parse.tab.h +- +-master_parse.tab.o: master_parse.tab.c master_parse.tab.h +- + nss_tok.c: nss_tok.l + $(LEX) -o$@ -Pnss_ $? + +--- autofs-5.1.4.orig/lib/master.c ++++ /dev/null +@@ -1,1885 +0,0 @@ +-/* ----------------------------------------------------------------------- * +- * +- * master.c - master map utility routines. +- * +- * Copyright 2006 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 "automount.h" +- +-/* The root of the map entry tree */ +-struct master *master_list = NULL; +- +-extern const char *global_options; +-extern long global_negative_timeout; +- +-/* Attribute to create a joinable thread */ +-extern pthread_attr_t th_attr; +- +-extern struct startup_cond suc; +- +-static struct map_source * +-__master_find_map_source(struct master_mapent *, +- const char *, const char *, int, const char **); +- +-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, unsigned logopt, +- unsigned nobind, unsigned ghost, int submount) +-{ +- struct autofs_point *ap; +- int status; +- +- ap = malloc(sizeof(struct autofs_point)); +- if (!ap) +- return 0; +- +- ap->state = ST_INIT; +- +- ap->state_pipe[0] = -1; +- ap->state_pipe[1] = -1; +- ap->logpri_fifo = -1; +- +- ap->path = strdup(entry->path); +- if (!ap->path) { +- free(ap); +- return 0; +- } +- ap->pref = NULL; +- +- ap->entry = entry; +- ap->exp_thread = 0; +- ap->readmap_thread = 0; +- /* +- * Program command line option overrides config. +- * We can't use 0 negative timeout so use default. +- */ +- if (global_negative_timeout <= 0) +- ap->negative_timeout = defaults_get_negative_timeout(); +- else +- ap->negative_timeout = global_negative_timeout; +- ap->exp_timeout = defaults_get_timeout(); +- ap->exp_runfreq = 0; +- ap->flags = 0; +- +- if (defaults_get_use_ignore_mount_option()) +- ap->flags = MOUNT_FLAG_IGNORE; +- if (ghost) +- ap->flags |= MOUNT_FLAG_GHOST; +- +- if (nobind) +- ap->flags |= MOUNT_FLAG_NOBIND; +- +- if (ap->path[1] == '-') +- ap->type = LKP_DIRECT; +- else +- ap->type = LKP_INDIRECT; +- +- 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); +- INIT_LIST_HEAD(&ap->amdmounts); +- ap->shutdown = 0; +- +- status = pthread_mutex_init(&ap->mounts_mutex, NULL); +- if (status) { +- free(ap->path); +- free(ap); +- return 0; +- } +- ap->mode = 0; +- +- entry->ap = ap; +- +- return 1; +-} +- +-void master_free_autofs_point(struct autofs_point *ap) +-{ +- struct list_head *p, *head; +- int status; +- +- if (!ap) +- return; +- +- mounts_mutex_lock(ap); +- head = &ap->amdmounts; +- p = head->next; +- while (p != head) { +- struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount); +- p = p->next; +- ext_mount_remove(mnt->ext_mp); +- mnts_remove_amdmount(mnt->mp); +- } +- mounts_mutex_unlock(ap); +- +- status = pthread_mutex_destroy(&ap->mounts_mutex); +- if (status) +- fatal(status); +- +- if (ap->pref) +- free(ap->pref); +- free(ap->path); +- free(ap); +-} +- +-struct map_source * +-master_add_map_source(struct master_mapent *entry, +- char *type, char *format, time_t age, +- int argc, const char **argv) +-{ +- struct map_source *source; +- char *ntype, *nformat; +- const char **tmpargv; +- +- source = malloc(sizeof(struct map_source)); +- if (!source) +- return NULL; +- memset(source, 0, sizeof(struct map_source)); +- source->ref = 1; +- +- if (type) { +- ntype = strdup(type); +- if (!ntype) { +- master_free_map_source(source, 0); +- return NULL; +- } +- source->type = ntype; +- } +- +- if (format) { +- nformat = strdup(format); +- if (!nformat) { +- master_free_map_source(source, 0); +- return NULL; +- } +- source->format = nformat; +- if (!strcmp(nformat, "amd")) +- source->flags |= MAP_FLAG_FORMAT_AMD; +- } +- +- source->age = age; +- source->stale = 1; +- +- tmpargv = copy_argv(argc, argv); +- if (!tmpargv) { +- master_free_map_source(source, 0); +- return NULL; +- } +- source->argc = argc; +- source->argv = tmpargv; +- if (source->argv[0]) +- source->name = strdup(source->argv[0]); +- +- master_source_writelock(entry); +- +- if (!entry->maps) { +- source->mc = cache_init(entry->ap, source); +- if (!source->mc) { +- master_free_map_source(source, 0); +- master_source_unlock(entry); +- return NULL; +- } +- entry->maps = source; +- } else { +- struct map_source *this, *last, *next; +- +- /* Typically there only a few map sources */ +- +- this = __master_find_map_source(entry, type, format, argc, tmpargv); +- if (this) { +- debug(entry->ap->logopt, +- "map source used without taking reference"); +- this->age = age; +- master_free_map_source(source, 0); +- master_source_unlock(entry); +- return this; +- } +- +- source->mc = cache_init(entry->ap, source); +- if (!source->mc) { +- master_free_map_source(source, 0); +- master_source_unlock(entry); +- return NULL; +- } +- +- last = NULL; +- next = entry->maps; +- while (next) { +- last = next; +- next = next->next; +- } +- if (last) +- last->next = source; +- else +- entry->maps = source; +- } +- +- master_source_unlock(entry); +- +- return source; +-} +- +-static int compare_source_type_and_format(struct map_source *map, const char *type, const char *format) +-{ +- int res = 0; +- +- if (type) { +- if (!map->type) +- goto done; +- +- if (strcmp(map->type, type)) +- goto done; +- } else if (map->type) +- goto done; +- +- if (format) { +- if (!map->format) +- goto done; +- +- if (strcmp(map->format, format)) +- goto done; +- } else if (map->format) +- goto done; +- +- res = 1; +-done: +- return res; +-} +- +-static struct map_source * +-__master_find_map_source(struct master_mapent *entry, +- const char *type, const char *format, +- int argc, const char **argv) +-{ +- struct map_source *map; +- struct map_source *source = NULL; +- int res; +- +- map = entry->maps; +- while (map) { +- res = compare_source_type_and_format(map, type, format); +- if (!res) +- goto next; +- +- res = compare_argv(map->argc, map->argv, argc, argv); +- if (!res) +- goto next; +- +- source = map; +- break; +-next: +- map = map->next; +- } +- +- return source; +-} +- +-struct map_source *master_find_map_source(struct master_mapent *entry, +- const char *type, const char *format, +- int argc, const char **argv) +-{ +- struct map_source *source = NULL; +- +- master_source_readlock(entry); +- source = __master_find_map_source(entry, type, format, argc, argv); +- master_source_unlock(entry); +- +- return source; +-} +- +-struct map_source * +-master_get_map_source(struct master_mapent *entry, +- const char *type, const char *format, +- int argc, const char **argv) +-{ +- struct map_source *source = NULL; +- +- master_source_readlock(entry); +- source = __master_find_map_source(entry, type, format, argc, argv); +- if (source) +- source->ref++; +- master_source_unlock(entry); +- +- return source; +-} +- +-static void __master_free_map_source(struct map_source *source, unsigned int free_cache) +-{ +- /* instance map sources are not ref counted */ +- if (source->ref && --source->ref) +- return; +- if (source->type) +- free(source->type); +- if (source->format) +- free(source->format); +- if (source->name) +- free(source->name); +- if (free_cache && source->mc) +- cache_release(source); +- if (source->lookup) { +- struct map_source *instance; +- +- instance = source->instance; +- while (instance) { +- if (instance->lookup) +- close_lookup(instance->lookup); +- instance = instance->next; +- } +- close_lookup(source->lookup); +- } +- if (source->argv) +- free_argv(source->argc, source->argv); +- if (source->instance) { +- struct map_source *instance, *next; +- +- instance = source->instance; +- while (instance) { +- next = instance->next; +- __master_free_map_source(instance, 0); +- instance = next; +- } +- } +- +- free(source); +- +- return; +-} +- +-void master_free_map_source(struct map_source *source, unsigned int free_cache) +-{ +- int status; +- +- status = pthread_mutex_lock(&instance_mutex); +- if (status) +- fatal(status); +- +- __master_free_map_source(source, free_cache); +- +- status = pthread_mutex_unlock(&instance_mutex); +- if (status) +- fatal(status); +-} +- +-struct map_source *master_find_source_instance(struct map_source *source, const char *type, const char *format, int argc, const char **argv) +-{ +- struct map_source *map; +- struct map_source *instance = NULL; +- int status, res; +- +- status = pthread_mutex_lock(&instance_mutex); +- if (status) +- fatal(status); +- +- map = source->instance; +- while (map) { +- res = compare_source_type_and_format(map, type, format); +- if (!res) +- goto next; +- +- if (!argv) { +- instance = map; +- break; +- } +- +- res = compare_argv(map->argc, map->argv, argc, argv); +- if (!res) +- goto next; +- +- instance = map; +- break; +-next: +- map = map->next; +- } +- +- status = pthread_mutex_unlock(&instance_mutex); +- if (status) +- fatal(status); +- +- return instance; +-} +- +-struct map_source * +-master_add_source_instance(struct map_source *source, const char *type, const char *format, time_t age, int argc, const char **argv) +-{ +- struct map_source *instance; +- struct map_source *new; +- char *ntype, *nformat; +- const char **tmpargv; +- int status; +- +- instance = master_find_source_instance(source, type, format, argc, argv); +- if (instance) +- return instance; +- +- new = malloc(sizeof(struct map_source)); +- if (!new) +- return NULL; +- memset(new, 0, sizeof(struct map_source)); +- +- if (type) { +- ntype = strdup(type); +- if (!ntype) { +- master_free_map_source(new, 0); +- return NULL; +- } +- new->type = ntype; +- } +- +- if (format) { +- nformat = strdup(format); +- if (!nformat) { +- master_free_map_source(new, 0); +- return NULL; +- } +- new->format = nformat; +- if (!strcmp(nformat, "amd")) +- new->flags |= MAP_FLAG_FORMAT_AMD; +- } +- +- new->age = age; +- new->master_line = 0; +- new->mc = source->mc; +- new->exp_timeout = source->exp_timeout; +- new->stale = 1; +- +- tmpargv = copy_argv(argc, argv); +- if (!tmpargv) { +- master_free_map_source(new, 0); +- return NULL; +- } +- new->argc = argc; +- new->argv = tmpargv; +- if (source->name) +- new->name = strdup(source->name); +- +- status = pthread_mutex_lock(&instance_mutex); +- if (status) +- fatal(status); +- +- if (!source->instance) +- source->instance = new; +- else { +- /* +- * We know there's no other instance of this +- * type so just add to head of list +- */ +- new->next = source->instance; +- source->instance = new; +- } +- +- status = pthread_mutex_unlock(&instance_mutex); +- if (status) +- fatal(status); +- +- return new; +-} +- +-int check_stale_instances(struct map_source *source) +-{ +- struct map_source *map; +- +- if (!source) +- return 0; +- +- map = source->instance; +- while (map) { +- if (map->stale) +- return 1; +- if (check_stale_instances(map)) +- return 1; +- map = map->next; +- } +- +- return 0; +-} +- +-void clear_stale_instances(struct map_source *source) +-{ +- struct map_source *map; +- +- if (!source) +- return; +- +- map = source->instance; +- while (map) { +- clear_stale_instances(map); +- if (map->stale) +- map->stale = 0; +- map = map->next; +- } +- +- return; +-} +- +-void send_map_update_request(struct autofs_point *ap) +-{ +- struct map_source *map; +- int status, need_update = 0; +- +- status = pthread_mutex_lock(&instance_mutex); +- if (status) +- fatal(status); +- +- map = ap->entry->maps; +- while (map) { +- if (check_stale_instances(map)) +- map->stale = 1; +- if (map->stale) { +- need_update = 1; +- break; +- } +- map = map->next; +- } +- +- status = pthread_mutex_unlock(&instance_mutex); +- if (status) +- fatal(status); +- +- if (!need_update) +- return; +- +- st_add_task(ap, ST_READMAP); +- +- return; +-} +- +-void master_source_writelock(struct master_mapent *entry) +-{ +- int status; +- +- status = pthread_rwlock_wrlock(&entry->source_lock); +- if (status) { +- logmsg("master_mapent source write lock failed"); +- fatal(status); +- } +- return; +-} +- +-void master_source_readlock(struct master_mapent *entry) +-{ +- int retries = 25; +- int status; +- +- while (retries--) { +- status = pthread_rwlock_rdlock(&entry->source_lock); +- if (status != EAGAIN && status != EBUSY) +- break; +- else { +- struct timespec t = { 0, 200000000 }; +- struct timespec r; +- +- if (status == EAGAIN) +- logmsg("master_mapent source too many readers"); +- else +- logmsg("master_mapent source write lock held"); +- +- while (nanosleep(&t, &r) == -1 && errno == EINTR) +- memcpy(&t, &r, sizeof(struct timespec)); +- } +- } +- +- if (status) { +- logmsg("master_mapent source read lock failed"); +- fatal(status); +- } +- +- return; +-} +- +-void master_source_unlock(struct master_mapent *entry) +-{ +- int status; +- +- status = pthread_rwlock_unlock(&entry->source_lock); +- if (status) { +- logmsg("master_mapent source unlock failed"); +- fatal(status); +- } +- return; +-} +- +-void master_source_lock_cleanup(void *arg) +-{ +- struct master_mapent *entry = (struct master_mapent *) arg; +- +- master_source_unlock(entry); +- +- return; +-} +- +-void master_source_current_wait(struct master_mapent *entry) +-{ +- int status; +- +- status = pthread_mutex_lock(&entry->current_mutex); +- if (status) { +- logmsg("entry current source lock failed"); +- fatal(status); +- } +- +- while (entry->current != NULL) { +- status = pthread_cond_wait( +- &entry->current_cond, &entry->current_mutex); +- if (status) { +- logmsg("entry current source condition wait failed"); +- fatal(status); +- } +- } +- +- return; +-} +- +-void master_source_current_signal(struct master_mapent *entry) +-{ +- int status; +- +- status = pthread_cond_signal(&entry->current_cond); +- if (status) { +- logmsg("entry current source condition signal failed"); +- fatal(status); +- } +- +- status = pthread_mutex_unlock(&entry->current_mutex); +- if (status) { +- logmsg("entry current source unlock failed"); +- fatal(status); +- } +- +- return; +-} +- +-struct master_mapent *master_find_mapent(struct master *master, const char *path) +-{ +- struct list_head *head, *p; +- +- head = &master->mounts; +- list_for_each(p, head) { +- struct master_mapent *entry; +- +- entry = list_entry(p, struct master_mapent, list); +- +- if (!strcmp(entry->path, path)) +- return entry; +- } +- +- return NULL; +-} +- +-unsigned int master_partial_match_mapent(struct master *master, const char *path) +-{ +- struct list_head *head, *p; +- size_t path_len = strlen(path); +- int ret = 0; +- +- head = &master->mounts; +- list_for_each(p, head) { +- struct master_mapent *entry; +- size_t entry_len; +- size_t cmp_len; +- +- entry = list_entry(p, struct master_mapent, list); +- +- entry_len = strlen(entry->path); +- cmp_len = min(entry_len, path_len); +- +- if (!strncmp(entry->path, path, cmp_len)) { +- /* paths are equal, matching master map entry ? */ +- if (entry_len == path_len) { +- if (entry->maps && +- entry->maps->flags & MAP_FLAG_FORMAT_AMD) +- ret = 1; +- else +- ret = -1; +- break; +- } +- +- /* amd mount conflicts with entry mount */ +- if (entry_len > path_len && +- *(entry->path + path_len) == '/') { +- ret = -1; +- break; +- } +- +- /* entry mount conflicts with amd mount */ +- if (entry_len < path_len && +- *(path + entry_len) == '/') { +- ret = -1; +- break; +- } +- } +- } +- +- return ret; +-} +- +-struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age) +-{ +- struct master_mapent *entry; +- int status; +- char *tmp; +- +- entry = malloc(sizeof(struct master_mapent)); +- if (!entry) +- return NULL; +- +- memset(entry, 0, sizeof(struct master_mapent)); +- +- tmp = strdup(path); +- if (!tmp) { +- free(entry); +- return NULL; +- } +- entry->path = tmp; +- +- entry->thid = 0; +- entry->age = age; +- entry->master = master; +- entry->current = NULL; +- entry->maps = NULL; +- entry->ap = NULL; +- +- status = pthread_rwlock_init(&entry->source_lock, NULL); +- if (status) +- fatal(status); +- +- status = pthread_mutex_init(&entry->current_mutex, NULL); +- if (status) +- fatal(status); +- +- status = pthread_cond_init(&entry->current_cond, NULL); +- if (status) +- fatal(status); +- +- INIT_LIST_HEAD(&entry->list); +- +- return entry; +-} +- +-void master_add_mapent(struct master *master, struct master_mapent *entry) +-{ +- list_add_tail(&entry->list, &master->mounts); +- return; +-} +- +-void master_remove_mapent(struct master_mapent *entry) +-{ +- struct master *master = entry->master; +- +- if (entry->ap->submount) +- return; +- +- if (!list_empty(&entry->list)) { +- list_del_init(&entry->list); +- list_add(&entry->join, &master->completed); +- } +- +- return; +-} +- +-void master_free_mapent_sources(struct master_mapent *entry, unsigned int free_cache) +-{ +- if (entry->maps) { +- struct map_source *m, *n; +- +- m = entry->maps; +- while (m) { +- n = m->next; +- master_free_map_source(m, free_cache); +- m = n; +- } +- entry->maps = NULL; +- } +- +- return; +-} +- +-void master_free_mapent(struct master_mapent *entry) +-{ +- int status; +- +- if (entry->path) +- free(entry->path); +- +- master_free_autofs_point(entry->ap); +- +- status = pthread_rwlock_destroy(&entry->source_lock); +- if (status) +- fatal(status); +- +- status = pthread_mutex_destroy(&entry->current_mutex); +- if (status) +- fatal(status); +- +- status = pthread_cond_destroy(&entry->current_cond); +- if (status) +- fatal(status); +- +- free(entry); +- +- return; +-} +- +-struct master *master_new(const char *name, unsigned int timeout, unsigned int flags) +-{ +- struct master *master; +- char *tmp; +- +- master = malloc(sizeof(struct master)); +- if (!master) +- return NULL; +- +- if (!name) +- tmp = (char *) defaults_get_master_map(); +- else +- tmp = strdup(name); +- +- if (!tmp) { +- free(master); +- return NULL; +- } +- +- master->name = tmp; +- master->nc = NULL; +- +- master->recurse = 0; +- master->depth = 0; +- master->reading = 0; +- master->read_fail = 0; +- master->readall = 0; +- master->default_ghost = flags & DAEMON_FLAGS_GHOST; +- master->default_timeout = timeout; +- master->default_logging = defaults_get_logging(); +- master->logopt = master->default_logging; +- +- INIT_LIST_HEAD(&master->mounts); +- INIT_LIST_HEAD(&master->completed); +- +- return master; +-} +- +-static void master_add_amd_mount_section_mounts(struct master *master, time_t age) +-{ +- unsigned int m_logopt = master->logopt; +- struct master_mapent *entry; +- struct map_source *source; +- unsigned int loglevel; +- unsigned int logopt; +- unsigned int flags; +- char *argv[2]; +- char **paths; +- int ret; +- int i; +- +- loglevel = conf_amd_get_log_options(); +- +- paths = conf_amd_get_mount_paths(); +- if (!paths) +- return; +- +- i = 0; +- while (paths[i]) { +- const char *path = paths[i]; +- unsigned int ghost = 0; +- time_t timeout; +- char *type = NULL; +- char *map = NULL; +- char *opts; +- +- ret = master_partial_match_mapent(master, path); +- if (ret) { +- /* If this amd entry is already present in the +- * master map it's not a duplicate, don't issue +- * an error message. +- */ +- if (ret == 1) +- goto next; +- info(m_logopt, +- "amd section mount path conflict, %s ignored", +- path); +- goto next; +- } +- +- map = conf_amd_get_map_name(path); +- if (!map) { +- error(m_logopt, +- "failed to get map name for amd section mount %s", +- path); +- goto next; +- } +- +- entry = master_new_mapent(master, path, age); +- if (!entry) { +- error(m_logopt, +- "failed to allocate new amd section mount %s", +- path); +- goto next; +- } +- +- logopt = m_logopt; +- if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) +- logopt = LOGOPT_DEBUG; +- else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) +- logopt = LOGOPT_VERBOSE; +- +- /* It isn't possible to provide the fullybrowsable amd +- * browsing functionality within the autofs framework. +- * This flag will not be set if browsable_dirs = full +- * in the configuration or fullybrowsable is present as +- * an option. +- */ +- flags = conf_amd_get_flags(path); +- if (flags & CONF_BROWSABLE_DIRS) +- ghost = 1; +- +- ret = master_add_autofs_point(entry, logopt, 0, ghost, 0); +- if (!ret) { +- error(m_logopt, "failed to add autofs_point"); +- master_free_mapent(entry); +- goto next; +- } +- +- opts = conf_amd_get_map_options(path); +- if (opts) { +- /* autofs uses the equivalent of cache:=inc,sync +- * (except for file maps which use cache:=all,sync) +- * but if the map is large then it may be necessary +- * to read the whole map at startup even if browsing +- * is is not enabled, so look for cache:=all in the +- * map_options configuration entry. +- */ +- if (strstr(opts, "cache:=all")) +- entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; +- free(opts); +- } +- +- type = conf_amd_get_map_type(path); +- argv[0] = map; +- argv[1] = NULL; +- +- source = master_add_map_source(entry, type, "amd", +- age, 1, (const char **) argv); +- if (!source) { +- error(m_logopt, +- "failed to add source for amd section mount %s", +- path); +- master_free_mapent(entry); +- goto next; +- } +- +- timeout = conf_amd_get_dismount_interval(path); +- set_exp_timeout(entry->ap, source, timeout); +- source->master_line = 0; +- +- entry->age = age; +- entry->current = NULL; +- +- master_add_mapent(master, entry); +-next: +- if (type) +- free(type); +- if (map) +- free(map); +- i++; +- } +- +- i = 0; +- while (paths[i]) +- free(paths[i++]); +- free(paths); +-} +- +-static void wait_for_lookups_and_lock(struct master *master) +-{ +- struct list_head *p, *head; +- int status; +- +-again: +- master_mutex_lock(); +- +- head = &master->mounts; +- p = head->next; +- while (p != head) { +- struct master_mapent *this; +- +- this = list_entry(p, struct master_mapent, list); +- +- status = pthread_rwlock_trywrlock(&this->source_lock); +- if (status) { +- struct timespec t = { 0, 200000000 }; +- struct timespec r; +- +- master_mutex_unlock(); +- +- while (nanosleep(&t, &r) == -1 && errno == EINTR) +- memcpy(&t, &r, sizeof(struct timespec)); +- +- goto again; +- } +- master_source_unlock(this); +- +- p = p->next; +- } +-} +- +-int master_read_master(struct master *master, time_t age) +-{ +- unsigned int logopt = master->logopt; +- struct mapent_cache *nc; +- +- /* +- * We need to clear and re-populate the null map entry cache +- * before alowing anyone else to use it. +- */ +- wait_for_lookups_and_lock(master); +- if (master->nc) { +- cache_writelock(master->nc); +- nc = master->nc; +- cache_clean_null_cache(nc); +- } else { +- nc = cache_init_null_cache(master); +- if (!nc) { +- error(logopt, +- "failed to init null map cache for %s", +- master->name); +- return 0; +- } +- cache_writelock(nc); +- master->nc = nc; +- } +- master_init_scan(); +- lookup_nss_read_master(master, age); +- cache_unlock(nc); +- master_add_amd_mount_section_mounts(master, age); +- +- if (!master->read_fail) +- master_mount_mounts(master, age); +- else { +- master->read_fail = 0; +- /* HUP signal sets master->readall == 1 only */ +- if (!master->readall) { +- master_mutex_unlock(); +- return 0; +- } else +- master_mount_mounts(master, age); +- } +- +- if (list_empty(&master->mounts)) +- warn(logopt, "no mounts in table"); +- +- master_mutex_unlock(); +- +- return 1; +-} +- +-int master_submount_list_empty(struct autofs_point *ap) +-{ +- int res = 0; +- +- mounts_mutex_lock(ap); +- if (list_empty(&ap->submounts)) +- res = 1; +- mounts_mutex_unlock(ap); +- +- return res; +-} +- +-int master_notify_submount(struct autofs_point *ap, const char *path, enum states state) +-{ +- struct mnt_list *this, *sbmnt; +- int ret = 1; +- +- this = mnts_find_submount(path); +- if (this) { +- /* We have found a submount to expire */ +- st_mutex_lock(); +- +- if (this->ap->state == ST_SHUTDOWN) { +- this = NULL; +- st_mutex_unlock(); +- goto done; +- } +- +- this->ap->shutdown = ap->shutdown; +- +- __st_add_task(this->ap, state); +- +- st_mutex_unlock(); +- +- st_wait_task(this->ap, state, 0); +- +- /* +- * If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or +- * ST_SHUTDOWN_FORCE we need to wait until it goes away or changes +- * to ST_READY. +- */ +- st_mutex_lock(); +- while ((sbmnt = mnts_find_submount(path))) { +- struct timespec t = { 0, 300000000 }; +- struct timespec r; +- +- if (sbmnt->ap->state != ST_SHUTDOWN && +- sbmnt->ap->state != ST_SHUTDOWN_PENDING && +- sbmnt->ap->state != ST_SHUTDOWN_FORCE) { +- ret = 0; +- mnts_put_mount(sbmnt); +- break; +- } +- mnts_put_mount(sbmnt); +- +- st_mutex_unlock(); +- while (nanosleep(&t, &r) == -1 && errno == EINTR) +- memcpy(&t, &r, sizeof(struct timespec)); +- st_mutex_lock(); +- } +- st_mutex_unlock(); +-done: +- mnts_put_mount(this); +- } +- +- return ret; +-} +- +-void master_notify_state_change(struct master *master, int sig) +-{ +- struct master_mapent *entry; +- struct autofs_point *ap; +- struct list_head *p; +- int cur_state; +- unsigned int logopt; +- +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- master_mutex_lock(); +- +- list_for_each(p, &master->mounts) { +- enum states next = ST_INVAL; +- +- entry = list_entry(p, struct master_mapent, list); +- +- ap = entry->ap; +- logopt = ap->logopt; +- +- st_mutex_lock(); +- +- if (ap->state == ST_SHUTDOWN) +- goto next; +- +- switch (sig) { +- case SIGTERM: +- case SIGINT: +- if (ap->state != ST_SHUTDOWN_PENDING && +- ap->state != ST_SHUTDOWN_FORCE) { +- next = ST_SHUTDOWN_PENDING; +- ap->shutdown = 1; +- __st_add_task(ap, next); +- } +- break; +-#ifdef ENABLE_FORCED_SHUTDOWN +- case SIGUSR2: +- if (ap->state != ST_SHUTDOWN_FORCE && +- ap->state != ST_SHUTDOWN_PENDING) { +- next = ST_SHUTDOWN_FORCE; +- ap->shutdown = 1; +- __st_add_task(ap, next); +- } +- break; +-#endif +- case SIGUSR1: +- assert(ap->state == ST_READY); +- next = ST_PRUNE; +- __st_add_task(ap, next); +- break; +- } +-next: +- if (next != ST_INVAL) +- debug(logopt, +- "sig %d switching %s from %d to %d", +- sig, ap->path, ap->state, next); +- +- st_mutex_unlock(); +- } +- +- master_mutex_unlock(); +- pthread_setcancelstate(cur_state, NULL); +- +- return; +-} +- +-static int master_do_mount(struct master_mapent *entry) +-{ +- struct startup_cond suc; +- struct autofs_point *ap; +- pthread_t thid; +- int 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.root = ap->path; +- suc.done = 0; +- suc.status = 0; +- +- if (!(do_force_unlink & UNLINK_AND_EXIT)) +- debug(ap->logopt, "mounting %s", entry->path); +- +- status = pthread_create(&thid, &th_attr, handle_mounts, &suc); +- if (status) { +- crit(ap->logopt, +- "failed to create mount handler thread for %s", +- entry->path); +- handle_mounts_startup_cond_destroy(&suc); +- return 0; +- } +- +- while (!suc.done) { +- status = pthread_cond_wait(&suc.cond, &suc.mutex); +- if (status) +- fatal(status); +- } +- +- if (suc.status) { +- if (!(do_force_unlink & UNLINK_AND_EXIT)) +- error(ap->logopt, "failed to startup mount"); +- handle_mounts_startup_cond_destroy(&suc); +- return 0; +- } +- entry->thid = thid; +- +- handle_mounts_startup_cond_destroy(&suc); +- +- return 1; +-} +- +-static void check_update_map_sources(struct master_mapent *entry, int readall) +-{ +- struct map_source *source, *last; +- struct autofs_point *ap; +- int map_stale = 0; +- +- if (readall) +- map_stale = 1; +- +- ap = entry->ap; +- +- master_source_writelock(entry); +- +- last = NULL; +- source = entry->maps; +- while (source) { +- if (readall) +- source->stale = 1; +- +- /* +- * If a map source is no longer valid and all it's +- * entries have expired away we can get rid of it. +- */ +- if (entry->age > source->age) { +- struct mapent *me; +- cache_readlock(source->mc); +- me = cache_lookup_first(source->mc); +- if (!me) { +- struct map_source *next = source->next; +- +- cache_unlock(source->mc); +- +- if (!last) +- entry->maps = next; +- else +- last->next = next; +- +- if (entry->maps == source) +- entry->maps = next; +- +- master_free_map_source(source, 1); +- +- source = next; +- continue; +- } else { +- source->stale = 1; +- map_stale = 1; +- } +- cache_unlock(source->mc); +- } +- last = source; +- source = source->next; +- } +- +- master_source_unlock(entry); +- +- /* The map sources have changed */ +- if (map_stale) +- st_add_task(ap, ST_READMAP); +- +- return; +-} +- +-int master_mount_mounts(struct master *master, time_t age) +-{ +- struct mapent_cache *nc = master->nc; +- struct list_head *p, *head; +- int cur_state; +- +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- +- head = &master->mounts; +- p = head->next; +- while (p != head) { +- struct master_mapent *this; +- struct autofs_point *ap; +- struct mapent *ne, *nested; +- struct stat st; +- int state_pipe, save_errno; +- int ret; +- +- this = list_entry(p, struct master_mapent, list); +- p = p->next; +- +- ap = this->ap; +- +- /* A master map entry has gone away */ +- if (this->age < age) { +- st_add_task(ap, ST_SHUTDOWN_PENDING); +- continue; +- } +- +- cache_readlock(nc); +- ne = cache_lookup_distinct(nc, this->path); +- /* +- * If this path matched a nulled entry the master map entry +- * must be an indirect mount so the master map entry line +- * number may be obtained from this->maps. +- */ +- if (ne) { +- int lineno = ne->age; +- cache_unlock(nc); +- +- /* null entry appears after map entry */ +- if (this->maps->master_line < lineno) { +- warn(ap->logopt, +- "ignoring null entry that appears after " +- "existing entry for %s", this->path); +- goto cont; +- } +- if (ap->state != ST_INIT) { +- st_add_task(ap, ST_SHUTDOWN_PENDING); +- continue; +- } +- /* +- * The map entry hasn't been started yet and we've +- * seen a preceeding null map entry for it so just +- * delete it from the master map entry list so it +- * doesn't get in the road. +- */ +- list_del_init(&this->list); +- master_free_mapent_sources(ap->entry, 1); +- master_free_mapent(ap->entry); +- continue; +- } +- nested = cache_partial_match(nc, this->path); +- if (nested) { +- error(ap->logopt, +- "removing invalid nested null entry %s", +- nested->key); +- nested = cache_partial_match(nc, this->path); +- if (nested) +- cache_delete(nc, nested->key); +- } +- cache_unlock(nc); +-cont: +- st_mutex_lock(); +- +- state_pipe = this->ap->state_pipe[1]; +- +- /* No pipe so mount is needed */ +- ret = fstat(state_pipe, &st); +- save_errno = errno; +- +- st_mutex_unlock(); +- +- if (!ret) +- check_update_map_sources(this, master->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); +- } +- } +- } +- +- pthread_setcancelstate(cur_state, NULL); +- +- return 1; +-} +- +-/* The nss source instances end up in reverse order. */ +-static void list_source_instances(struct map_source *source, struct map_source *instance) +-{ +- if (!source || !instance) { +- printf("none"); +- return; +- } +- +- if (instance->next) +- list_source_instances(source, instance->next); +- +- /* +- * For convienience we map nss instance type "files" to "file". +- * Check for that and report corrected instance type. +- */ +- if (strcmp(instance->type, "file")) +- printf("%s ", instance->type); +- else { +- if (source->argv && *(source->argv[0]) != '/') +- printf("files "); +- else +- printf("%s ", instance->type); +- } +- +- return; +-} +- +-static void print_map_info(struct map_source *source) +-{ +- int argc = source->argc; +- int i, multi, map_num; +- +- multi = (source->type && !strcmp(source->type, "multi")); +- map_num = 1; +- for (i = 0; i < argc; i++) { +- if (source->argv[i] && *source->argv[i] != '-') { +- if (!multi) +- printf(" map: %s\n", source->argv[i]); +- else +- printf(" map[%i]: %s\n", map_num, source->argv[i]); +- i++; +- } +- +- if (i >= argc) +- return; +- +- if (!strcmp(source->argv[i], "--")) +- continue; +- +- if (source->argv[i]) { +- int need_newline = 0; +- int j; +- +- if (!multi) +- printf(" arguments:"); +- else +- printf(" arguments[%i]:", map_num); +- +- for (j = i; j < source->argc; j++) { +- if (!strcmp(source->argv[j], "--")) +- break; +- printf(" %s", source->argv[j]); +- i++; +- need_newline = 1; +- } +- if (need_newline) +- printf("\n"); +- } +- if (multi) +- map_num++; +- } +- +- return; +-} +- +-static int match_type(const char *source, const char *type) +-{ +- if (!strcmp(source, type)) +- return 1; +- /* Sources file and files are synonymous */ +- if (!strncmp(source, type, 4) && (strlen(source) <= 5)) +- return 1; +- return 0; +-} +- +-static char *get_map_name(const char *string) +-{ +- char *name, *tmp; +- char *start, *end, *base; +- +- tmp = strdup(string); +- if (!tmp) { +- printf("error: allocation failure: %s\n", strerror(errno)); +- return NULL; +- } +- +- base = basename(tmp); +- end = strchr(base, ','); +- if (end) +- *end = '\0'; +- start = strchr(tmp, '='); +- if (start) +- start++; +- else { +- char *colon = strrchr(base, ':'); +- if (colon) +- start = ++colon; +- else +- start = base; +- } +- +- name = strdup(start); +- if (!name) +- printf("error: allocation failure: %s\n", strerror(errno)); +- free(tmp); +- +- return name; +-} +- +-static int match_name(struct map_source *source, const char *name) +-{ +- int argc = source->argc; +- int ret = 0; +- int i; +- +- /* +- * This can't work for old style "multi" type sources since +- * there's no way to know from which map the cache entry came +- * from and duplicate entries are ignored at map read time. +- * All we can really do is list all the entries for the given +- * multi map if one of its map names matches. +- */ +- for (i = 0; i < argc; i++) { +- if (i == 0 || !strcmp(source->argv[i], "--")) { +- if (i != 0) { +- i++; +- if (i >= argc) +- break; +- } +- +- if (source->argv[i] && *source->argv[i] != '-') { +- char *map = get_map_name(source->argv[i]); +- if (!map) +- break; +- if (!strcmp(map, name)) { +- ret = 1; +- free(map); +- break; +- } +- free(map); +- } +- } +- } +- +- return ret; +-} +- +-int dump_map(struct master *master, const char *type, const char *name) +-{ +- struct list_head *p, *head; +- +- if (list_empty(&master->mounts)) { +- printf("no master map entries found\n"); +- return 1; +- } +- +- head = &master->mounts; +- p = head->next; +- while (p != head) { +- struct map_source *source; +- struct master_mapent *this; +- struct autofs_point *ap; +- time_t now = monotonic_time(NULL); +- +- this = list_entry(p, struct master_mapent, list); +- p = p->next; +- +- ap = this->ap; +- +- /* +- * Ensure we actually read indirect map entries so we can +- * list them. The map reads won't read any indirect map +- * entries (other than those in a file map) unless the +- * browse option is set. +- */ +- if (ap->type == LKP_INDIRECT) +- ap->flags |= MOUNT_FLAG_GHOST; +- +- /* Read the map content into the cache */ +- if (lookup_nss_read_map(ap, NULL, now)) +- lookup_prune_cache(ap, now); +- else { +- printf("failed to read map\n"); +- lookup_close_lookup(ap); +- continue; +- } +- +- if (!this->maps) { +- printf("no map sources found for %s\n", ap->path); +- lookup_close_lookup(ap); +- continue; +- } +- +- source = this->maps; +- while (source) { +- struct map_source *instance; +- struct mapent *me; +- +- instance = NULL; +- if (source->type) { +- if (!match_type(source->type, type)) { +- source = source->next; +- continue; +- } +- if (!match_name(source, name)) { +- source = source->next; +- continue; +- } +- instance = source; +- } else { +- struct map_source *map; +- +- map = source->instance; +- while (map) { +- if (!match_type(map->type, type)) { +- map = map->next; +- continue; +- } +- if (!match_name(map, name)) { +- map = map->next; +- continue; +- } +- instance = map; +- break; +- } +- } +- +- if (!instance) { +- source = source->next; +- lookup_close_lookup(ap); +- continue; +- } +- +- me = cache_lookup_first(source->mc); +- if (!me) +- printf("no keys found in map\n"); +- else { +- do { +- if (me->source == instance) +- printf("%s\t%s\n", me->key, me->mapent); +- } while ((me = cache_lookup_next(source->mc, me))); +- } +- +- lookup_close_lookup(ap); +- return 1; +- } +- lookup_close_lookup(ap); +- } +- +- return 0; +-} +- +-int master_show_mounts(struct master *master) +-{ +- struct list_head *p, *head; +- +- printf("\nautofs dump map information\n" +- "===========================\n\n"); +- +- printf("global options: "); +- if (!global_options) +- printf("none configured\n"); +- else { +- printf("%s\n", global_options); +- unsigned int append_options = defaults_get_append_options(); +- const char *append = append_options ? "will" : "will not"; +- printf("global options %s be appended to map entries\n", append); +- } +- +- if (list_empty(&master->mounts)) { +- printf("no master map entries found\n\n"); +- return 1; +- } +- +- head = &master->mounts; +- p = head->next; +- while (p != head) { +- struct map_source *source; +- struct master_mapent *this; +- struct autofs_point *ap; +- time_t now = monotonic_time(NULL); +- unsigned int count = 0; +- +- this = list_entry(p, struct master_mapent, list); +- p = p->next; +- +- ap = this->ap; +- +- printf("\nMount point: %s\n", ap->path); +- +- printf("\nsource(s):\n"); +- +- /* +- * Ensure we actually read indirect map entries so we can +- * list them. The map reads won't read any indirect map +- * entries (other than those in a file map) unless the +- * browse option is set. +- */ +- if (ap->type == LKP_INDIRECT) +- ap->flags |= MOUNT_FLAG_GHOST; +- +- /* Read the map content into the cache */ +- if (lookup_nss_read_map(ap, NULL, now)) +- lookup_prune_cache(ap, now); +- else { +- printf(" failed to read map\n\n"); +- continue; +- } +- +- if (!this->maps) { +- printf(" no map sources found\n\n"); +- continue; +- } +- +- source = this->maps; +- while (source) { +- struct mapent *me; +- +- if (source->type) +- printf("\n type: %s\n", source->type); +- else { +- printf("\n instance type(s): "); +- list_source_instances(source, source->instance); +- printf("\n"); +- } +- +- if (source->argc >= 1) { +- print_map_info(source); +- if (count && ap->type == LKP_INDIRECT) +- printf(" duplicate indirect map entry" +- " will be ignored at run time\n"); +- } +- +- printf("\n"); +- +- me = cache_lookup_first(source->mc); +- if (!me) +- printf(" no keys found in map\n"); +- else { +- do { +- printf(" %s | %s\n", me->key, me->mapent); +- } while ((me = cache_lookup_next(source->mc, me))); +- } +- +- count++; +- +- source = source->next; +- } +- +- lookup_close_lookup(ap); +- +- printf("\n"); +- } +- +- return 1; +-} +- +-int master_list_empty(struct master *master) +-{ +- int res = 0; +- +- master_mutex_lock(); +- if (list_empty(&master->mounts)) +- res = 1; +- master_mutex_unlock(); +- +- return res; +-} +- +-int master_done(struct master *master) +-{ +- struct list_head *head, *p; +- struct master_mapent *entry; +- int res = 0; +- +- head = &master->completed; +- p = head->next; +- while (p != head) { +- entry = list_entry(p, struct master_mapent, join); +- p = p->next; +- list_del(&entry->join); +- pthread_join(entry->thid, NULL); +- master_free_mapent_sources(entry, 1); +- master_free_mapent(entry); +- } +- if (list_empty(&master->mounts)) +- res = 1; +- +- return res; +-} +- +-unsigned int master_get_logopt(void) +-{ +- return master_list ? master_list->logopt : LOGOPT_NONE; +-} +- +-int master_kill(struct master *master) +-{ +- if (!list_empty(&master->mounts)) +- return 0; +- +- if (master->name) +- free(master->name); +- +- cache_release_null_cache(master); +- free(master); +- +- return 1; +-} +--- autofs-5.1.4.orig/lib/master_parse.y ++++ /dev/null +@@ -1,983 +0,0 @@ +-%{ +-/* ----------------------------------------------------------------------- * +- * +- * master_parser.y - master map buffer parser. +- * +- * Copyright 2006 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 "automount.h" +-#include "master.h" +- +-#define MAX_ERR_LEN 512 +- +-extern struct master *master_list; +- +-char **add_argv(int, char **, char *); +-const char **copy_argv(int, const char **); +-int free_argv(int, const char **); +- +-extern FILE *master_in; +-extern char *master_text; +-extern int master_lex(void); +-extern int master_lineno; +-extern void master_set_scan_buffer(const char *); +- +-static char *master_strdup(char *); +-static void local_init_vars(void); +-static void local_free_vars(void); +-static void trim_maptype(char *); +-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; +-static char *format; +-static long timeout; +-static long negative_timeout; +-static unsigned symlnk; +-static unsigned strictexpire; +-static unsigned nobind; +-static unsigned ghost; +-extern unsigned global_selection_options; +-static unsigned random_selection; +-static unsigned use_weight; +-static unsigned long mode; +-static char **tmp_argv; +-static int tmp_argc; +-static char **local_argv; +-static int local_argc; +- +-#define PROPAGATION_SHARED MOUNT_FLAG_SHARED +-#define PROPAGATION_SLAVE MOUNT_FLAG_SLAVE +-#define PROPAGATION_PRIVATE MOUNT_FLAG_PRIVATE +-#define PROPAGATION_MASK (MOUNT_FLAG_SHARED | \ +- MOUNT_FLAG_SLAVE | \ +- MOUNT_FLAG_PRIVATE) +-static unsigned int propagation; +- +-static char errstr[MAX_ERR_LEN]; +- +-static unsigned int verbose; +-static unsigned int debug; +- +-static int lineno; +- +-#define YYDEBUG 0 +- +-#ifndef YYENABLE_NLS +-#define YYENABLE_NLS 0 +-#endif +-#ifndef YYLTYPE_IS_TRIVIAL +-#define YYLTYPE_IS_TRIVIAL 0 +-#endif +- +-#if YYDEBUG +-static int master_fprintf(FILE *, char *, ...); +-#undef YYFPRINTF +-#define YYFPRINTF master_fprintf +-#endif +- +-%} +- +-%union { +- char strtype[2048]; +- int inttype; +- long longtype; +-} +- +-%token COMMENT +-%token MAP +-%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE +-%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE +-%token OPT_STRICTEXPIRE OPT_SHARED OPT_SLAVE OPT_PRIVATE +-%token COLON COMMA NL DDASH +-%type map +-%type options +-%type dn +-%type dnattrs +-%type dnattr +-%type option +-%type daemon_option +-%type mount_option +-%token PATH +-%token QUOTE +-%token NILL +-%token SPACE +-%token EQUAL +-%token MULTITYPE +-%token MAPTYPE +-%token DNSERVER +-%token DNATTR +-%token DNNAME +-%token MAPHOSTS +-%token MAPNULL +-%token MAPXFN +-%token MAPNAME +-%token NUMBER +-%token OCTALNUMBER +-%token OPTION +- +-%start file +- +-%% +- +-file: { +- master_lineno = 0; +-#if YYDEBUG != 0 +- master_debug = YYDEBUG; +-#endif +- } line +- ; +- +-line: +- | PATH mapspec +- { +- path = master_strdup($1); +- if (!path) { +- local_free_vars(); +- YYABORT; +- } +- } +- | PATH MULTITYPE maplist +- { +- char *tmp = NULL; +- +- trim_maptype($2); +- +- if (path) +- free(path); +- path = master_strdup($1); +- if (!path) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- +- if ((tmp = strchr($2, ','))) +- *tmp++ = '\0'; +-#ifndef WITH_HESIOD +- /* Map type or map type parser is hesiod */ +- if (!strcmp($2, "hesiod") || (tmp && !strcmp(tmp, "hesiod"))) { +- master_error("hesiod support not built in"); +- local_free_vars(); +- YYABORT; +- } +-#endif +- if (type) +- free(type); +- type = master_strdup($2); +- if (!type) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- if (tmp) { +- if (format) +- free(format); +- format = master_strdup(tmp); +- if (!format) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- } +- | PATH COLON { master_notify($1); YYABORT; } +- | PATH OPTION { master_notify($2); YYABORT; } +- | PATH NILL { master_notify($2); YYABORT; } +- | PATH OPT_RANDOM { master_notify($1); YYABORT; } +- | PATH OPT_USE_WEIGHT { master_notify($1); YYABORT; } +- | PATH OPT_DEBUG { master_notify($1); YYABORT; } +- | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } +- | PATH OPT_SYMLINK { master_notify($1); YYABORT; } +- | PATH OPT_STRICTEXPIRE { master_notify($1); YYABORT; } +- | PATH OPT_SHARED { master_notify($1); YYABORT; } +- | PATH OPT_SLAVE { master_notify($1); YYABORT; } +- | PATH OPT_PRIVATE { master_notify($1); YYABORT; } +- | PATH OPT_NOBIND { master_notify($1); YYABORT; } +- | PATH OPT_GHOST { master_notify($1); YYABORT; } +- | PATH OPT_NOGHOST { master_notify($1); YYABORT; } +- | PATH OPT_VERBOSE { master_notify($1); YYABORT; } +- | PATH OPT_MODE { master_notify($1); YYABORT; } +- | PATH { master_notify($1); YYABORT; } +- | QUOTE { master_notify($1); YYABORT; } +- | OPTION { master_notify($1); YYABORT; } +- | NILL { master_notify($1); YYABORT; } +- | COMMENT { YYABORT; } +- ; +- +-mapspec: map +- { +- if (local_argv) +- free_argv(local_argc, (const char **) local_argv); +- local_argc = tmp_argc; +- local_argv = tmp_argv; +- tmp_argc = 0; +- tmp_argv = NULL; +- } +- | map options +- { +- if (local_argv) +- free_argv(local_argc, (const char **) local_argv); +- local_argc = tmp_argc; +- local_argv = tmp_argv; +- tmp_argc = 0; +- tmp_argv = NULL; +- } +- ; +- +-maplist: map +- { +- if (!add_multi_mapstr()) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | map options +- { +- if (!add_multi_mapstr()) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | maplist DDASH map +- { +- local_argc++; +- local_argv = add_argv(local_argc, local_argv, "--"); +- if (!local_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- if (!add_multi_mapstr()) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | maplist DDASH map options +- { +- local_argc++; +- local_argv = add_argv(local_argc, local_argv, "--"); +- if (!local_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- if (!add_multi_mapstr()) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- ; +- +-map: PATH +- { +- tmp_argc++; +- tmp_argv = add_argv(tmp_argc, tmp_argv, $1); +- if (!tmp_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | MAPNAME +- { +- tmp_argc++; +- tmp_argv = add_argv(tmp_argc, tmp_argv, $1); +- if (!tmp_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | MAPHOSTS +- { +- if (type) +- free(type); +- type = master_strdup($1 + 1); +- if (!type) { +- local_free_vars(); +- YYABORT; +- } +- } +- | MAPXFN +- { +- master_notify($1); +- master_msg("X/Open Federated Naming service not supported"); +- YYABORT; +- } +- | MAPNULL +- { +- if (type) +- free(type); +- type = master_strdup($1 + 1); +- if (!type) { +- local_free_vars(); +- YYABORT; +- } +- } +- | dnattrs +- { +- if (type) +- free(type); +- type = master_strdup("ldap"); +- if (!type) { +- local_free_vars(); +- YYABORT; +- } +- tmp_argc++; +- tmp_argv = add_argv(tmp_argc, tmp_argv, $1); +- if (!tmp_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | MAPTYPE PATH +- { +- char *tmp = NULL; +- +- trim_maptype($1); +- +- if ((tmp = strchr($1, ','))) +- *tmp++ = '\0'; +-#ifndef WITH_HESIOD +- /* Map type or map type parser is hesiod */ +- if (!strcmp($1, "hesiod") || (tmp && !strcmp(tmp, "hesiod"))) { +- master_error("hesiod support not built in"); +- local_free_vars(); +- YYABORT; +- } +-#endif +- if (type) +- free(type); +- if (strcmp($1, "exec")) +- type = master_strdup($1); +- else +- type = master_strdup("program"); +- if (!type) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- if (tmp) { +- if (format) +- free(format); +- format = master_strdup(tmp); +- if (!format) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- tmp_argc++; +- tmp_argv = add_argv(tmp_argc, tmp_argv, $2); +- if (!tmp_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | MAPTYPE MAPNAME +- { +- char *tmp = NULL; +- +- trim_maptype($1); +- +- if ((tmp = strchr($1, ','))) +- *tmp++ = '\0'; +- +- if (type) +- free(type); +- if (strcmp($1, "exec")) +- type = master_strdup($1); +- else +- type = master_strdup("program"); +- if (!type) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- if (tmp) { +- if (format) +- free(format); +- format = master_strdup(tmp); +- if (!format) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- tmp_argc++; +- tmp_argv = add_argv(tmp_argc, tmp_argv, $2); +- if (!tmp_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- | MAPTYPE dn +- { +- char *tmp = NULL; +- +- trim_maptype($1); +- +- if ((tmp = strchr($1, ','))) +- *tmp++ = '\0'; +- +- if (type) +- free(type); +- if (strcmp($1, "exec")) +- type = master_strdup($1); +- else +- type = master_strdup("program"); +- if (!type) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- if (tmp) { +- if (format) +- free(format); +- format = master_strdup(tmp); +- if (!format) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- tmp_argc++; +- tmp_argv = add_argv(tmp_argc, tmp_argv, $2); +- if (!tmp_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- /* Add back the type for lookup_ldap.c to handle ldaps */ +- if (*tmp_argv[0]) { +- tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2); +- if (!tmp) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- strcpy(tmp, type); +- strcat(tmp, ":"); +- strcat(tmp, tmp_argv[0]); +- free(tmp_argv[0]); +- tmp_argv[0] = tmp; +- } +- } +- ; +- +-dn: DNSERVER dnattrs +- { +- strcpy($$, $1); +- strcat($$, $2); +- } +- | dnattrs +- { +- strcpy($$, $1); +- } +- | +- { +- master_notify("syntax error in dn"); +- YYABORT; +- } +- ; +- +-dnattrs: DNATTR EQUAL DNNAME +- { +- if (strcasecmp($1, "cn") && +- strcasecmp($1, "ou") && +- strcasecmp($1, "automountMapName") && +- strcasecmp($1, "nisMapName")) { +- strcpy(errstr, $1); +- strcat(errstr, "="); +- strcat(errstr, $3); +- master_notify(errstr); +- YYABORT; +- } +- strcpy($$, $1); +- strcat($$, "="); +- strcat($$, $3); +- } +- | DNATTR EQUAL DNNAME COMMA dnattr +- { +- if (strcasecmp($1, "cn") && +- strcasecmp($1, "ou") && +- strcasecmp($1, "automountMapName") && +- strcasecmp($1, "nisMapName")) { +- strcpy(errstr, $1); +- strcat(errstr, "="); +- strcat(errstr, $3); +- master_notify(errstr); +- YYABORT; +- } +- strcpy($$, $1); +- strcat($$, "="); +- strcat($$, $3); +- strcat($$, ","); +- strcat($$, $5); +- } +- | DNNAME +- { +- /* Matches map in old style syntax ldap:server:map */ +- strcpy($$, $1); +- } +- | DNATTR +- { +- master_notify($1); +- YYABORT; +- } +- ; +- +-dnattr: DNATTR EQUAL DNNAME +- { +- if (!strcasecmp($1, "automountMapName") || +- !strcasecmp($1, "nisMapName")) { +- strcpy(errstr, $1); +- strcat(errstr, "="); +- strcat(errstr, $3); +- master_notify(errstr); +- YYABORT; +- } +- strcpy($$, $1); +- strcat($$, "="); +- strcat($$, $3); +- } +- | DNATTR EQUAL DNNAME COMMA dnattr +- { +- if (!strcasecmp($1, "automountMapName") || +- !strcasecmp($1, "nisMapName")) { +- strcpy(errstr, $1); +- strcat(errstr, "="); +- strcat(errstr, $3); +- master_notify(errstr); +- YYABORT; +- } +- strcpy($$, $1); +- strcat($$, "="); +- strcat($$, $3); +- strcat($$, ","); +- strcat($$, $5); +- } +- | DNATTR +- { +- master_notify($1); +- YYABORT; +- } +- | DNNAME +- { +- master_notify($1); +- YYABORT; +- } +- ; +- +-options: option {} +- | options COMMA option {} +- | options option {} +- | options COMMA COMMA option +- { +- master_notify($1); +- YYABORT; +- } +- | options EQUAL +- { +- master_notify($1); +- YYABORT; +- } +- ; +- +-option: daemon_option +- | mount_option {} +- | error +- { +- master_notify("bogus option"); +- YYABORT; +- } +- ; +- +-daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } +- | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } +- | OPT_SYMLINK { symlnk = 1; } +- | OPT_STRICTEXPIRE { strictexpire = 1; } +- | OPT_SHARED { propagation = PROPAGATION_SHARED; } +- | OPT_SLAVE { propagation = PROPAGATION_SLAVE; } +- | OPT_PRIVATE { propagation = PROPAGATION_PRIVATE; } +- | OPT_NOBIND { nobind = 1; } +- | OPT_NOGHOST { ghost = 0; } +- | OPT_GHOST { ghost = 1; } +- | OPT_VERBOSE { verbose = 1; } +- | OPT_DEBUG { debug = 1; } +- | OPT_RANDOM { random_selection = 1; } +- | OPT_USE_WEIGHT { use_weight = 1; } +- | OPT_MODE OCTALNUMBER { mode = $2; } +- ; +- +-mount_option: OPTION +- { +- tmp_argc++; +- tmp_argv = add_argv(tmp_argc, tmp_argv, $1); +- if (!tmp_argv) { +- master_error("memory allocation error"); +- local_free_vars(); +- YYABORT; +- } +- } +- ; +-%% +- +-#if YYDEBUG +-static int master_fprintf(FILE *f, char *msg, ...) +-{ +- va_list ap; +- va_start(ap, msg); +- vsyslog(LOG_DEBUG, msg, ap); +- va_end(ap); +- return 1; +-} +-#endif +- +-static char *master_strdup(char *str) +-{ +- char *tmp; +- +- tmp = strdup(str); +- if (!tmp) +- master_error("memory allocation error"); +- return tmp; +-} +- +-static int master_error(const char *s) +-{ +- logmsg("%s while parsing map.", s); +- return 0; +-} +- +-static int master_notify(const char *s) +-{ +- logmsg("syntax error in map near [ %s ]", s); +- return(0); +-} +- +-static int master_msg(const char *s) +-{ +- logmsg("%s", s); +- return 0; +-} +- +-static void local_init_vars(void) +-{ +- path = NULL; +- type = NULL; +- format = NULL; +- verbose = 0; +- debug = 0; +- timeout = -1; +- negative_timeout = 0; +- symlnk = 0; +- strictexpire = 0; +- propagation = PROPAGATION_SLAVE; +- nobind = 0; +- ghost = defaults_get_browse_mode(); +- random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; +- use_weight = 0; +- mode = 0; +- tmp_argv = NULL; +- tmp_argc = 0; +- local_argv = NULL; +- local_argc = 0; +-} +- +-static void local_free_vars(void) +-{ +- if (path) +- free(path); +- +- if (type) +- free(type); +- +- if (format) +- free(format); +- +- if (local_argv) { +- free_argv(local_argc, (const char **) local_argv); +- local_argv = NULL; +- local_argc = 0; +- } +- +- if (tmp_argv) { +- free_argv(tmp_argc, (const char **) tmp_argv); +- tmp_argv = NULL; +- tmp_argc = 0; +- } +-} +- +-static void trim_maptype(char *type) +-{ +- char *tmp; +- +- tmp = strchr(type, ':'); +- if (tmp) +- *tmp = '\0'; +- else { +- int len = strlen(type); +- while (len-- && isblank(type[len])) +- type[len] = '\0'; +- } +- return; +-} +- +-static int add_multi_mapstr(void) +-{ +- if (type) { +- /* If type given and format is non-null add it back */ +- if (format) { +- int len = strlen(type) + strlen(format) + 2; +- char *tmp = realloc(type, len); +- if (!tmp) +- return 0; +- type = tmp; +- strcat(type, ","); +- strcat(type, format); +- free(format); +- format = NULL; +- } +- +- local_argc++; +- local_argv = add_argv(local_argc, local_argv, type); +- if (!local_argv) { +- free(type); +- type = NULL; +- return 0; +- } +- +- free(type); +- type = NULL; +- } +- +- local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv); +- if (!local_argv) { +- free(type); +- type = NULL; +- return 0; +- } +- local_argc += tmp_argc; +- +- tmp_argc = 0; +- tmp_argv = NULL; +- +- return 1; +-} +- +-void master_init_scan(void) +-{ +- lineno = 0; +-} +- +-int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigned int logging, time_t age) +-{ +- struct master *master = master_list; +- struct mapent_cache *nc; +- struct master_mapent *entry, *new; +- struct map_source *source; +- unsigned int logopt = logging; +- unsigned int m_logopt = master->logopt; +- size_t mp_len; +- int ret; +- +- local_init_vars(); +- +- lineno++; +- +- master_set_scan_buffer(buffer); +- +- ret = master_parse(); +- if (ret != 0) { +- local_free_vars(); +- return 0; +- } +- +- mp_len = strlen(path); +- while (mp_len && path[--mp_len] == '/') +- path[mp_len] = 0; +- +- nc = master->nc; +- +- /* Add null map entries to the null map cache */ +- if (type && !strcmp(type, "null")) { +- cache_update(nc, NULL, path, NULL, lineno); +- local_free_vars(); +- return 1; +- } +- +- /* Ignore all subsequent matching nulled entries */ +- if (cache_lookup_distinct(nc, path)) { +- local_free_vars(); +- return 1; +- } +- +- if (debug || verbose) { +- logopt = (debug ? LOGOPT_DEBUG : 0); +- logopt |= (verbose ? LOGOPT_VERBOSE : 0); +- } +- +- new = NULL; +- entry = master_find_mapent(master, path); +- if (!entry) { +- new = master_new_mapent(master, path, age); +- if (!new) { +- local_free_vars(); +- return 0; +- } +- entry = new; +- } else { +- if (entry->age && entry->age == age) { +- if (strcmp(path, "/-")) { +- info(m_logopt, +- "ignoring duplicate indirect mount %s", +- path); +- local_free_vars(); +- return 0; +- } +- } +- } +- +- if (!format) { +- if (conf_amd_mount_section_exists(path)) +- format = strdup("amd"); +- } +- +- if (format && !strcmp(format, "amd")) { +- unsigned int loglevel = conf_amd_get_log_options(); +- unsigned int flags = conf_amd_get_flags(path); +- +- if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) +- logopt = LOGOPT_DEBUG; +- else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) +- logopt = LOGOPT_VERBOSE; +- +- /* It isn't possible to provide the fullybrowsable amd +- * browsing functionality within the autofs framework. +- * This flag will not be set if browsable_dirs = full +- * in the configuration or fullybrowsable is present as +- * an option. +- */ +- if (flags & CONF_BROWSABLE_DIRS) +- ghost = 1; +- } +- +- if (!entry->ap) { +- ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0); +- if (!ret) { +- error(m_logopt, "failed to add autofs_point"); +- if (new) +- master_free_mapent(new); +- local_free_vars(); +- return 0; +- } +- } +- entry->ap->flags &= ~(PROPAGATION_MASK); +- entry->ap->flags |= propagation; +- +- if (random_selection) +- entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT; +- if (use_weight) +- entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; +- if (symlnk) +- entry->ap->flags |= MOUNT_FLAG_SYMLINK; +- if (strictexpire) +- entry->ap->flags |= MOUNT_FLAG_STRICTEXPIRE; +- if (negative_timeout) +- entry->ap->negative_timeout = negative_timeout; +- if (mode && mode < LONG_MAX) +- entry->ap->mode = mode; +- +- if (timeout < 0) { +- /* +- * If no timeout is given get the timout from the +- * autofs point, or the first map, or the config +- * for amd maps. +- */ +- if (format && !strcmp(format, "amd")) +- timeout = conf_amd_get_dismount_interval(path); +- else +- timeout = get_exp_timeout(entry->ap, entry->maps); +- } +- +- if (format && !strcmp(format, "amd")) { +- char *opts = conf_amd_get_map_options(path); +- if (opts) { +- /* autofs uses the equivalent of cache:=inc,sync +- * (except for file maps which use cache:=all,sync) +- * but if the map is large then it may be necessary +- * to read the whole map at startup even if browsing +- * is is not enabled, so look for cache:=all in the +- * map_options configuration entry. +- */ +- if (strstr(opts, "cache:=all")) +- entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; +- free(opts); +- } +- } +- +-/* +- source = master_find_map_source(entry, type, format, +- local_argc, (const char **) local_argv); +- if (!source) +- source = master_add_map_source(entry, type, format, age, +- local_argc, (const char **) local_argv); +- else +- source->age = age; +-*/ +- source = master_add_map_source(entry, type, format, age, +- local_argc, (const char **) local_argv); +- if (!source) { +- error(m_logopt, "failed to add source"); +- if (new) +- master_free_mapent(new); +- local_free_vars(); +- return 0; +- } +- set_exp_timeout(entry->ap, source, timeout); +- source->master_line = lineno; +- +- entry->age = age; +- entry->current = NULL; +- +- if (new) +- master_add_mapent(master, entry); +- +- local_free_vars(); +- +- return 1; +-} +- +--- autofs-5.1.4.orig/lib/master_tok.l ++++ /dev/null +@@ -1,504 +0,0 @@ +-%{ +-/* ----------------------------------------------------------------------- * +- * +- * master_tok.l - master map tokenizer. +- * +- * Copyright 2006 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. +- * +- * ----------------------------------------------------------------------- */ +- +-#ifdef ECHO +-# undef ECHO +-#endif /* ECHO */ +-static void master_echo(void); /* forward definition */ +-#define ECHO master_echo() +- +-#include +-#include +-#include +-#include +-#include "master_parse.tab.h" +- +-/* +- * There are some things that need to be defined only if useing GNU flex. +- * These must not be defined if using standard lex +- */ +-#ifdef FLEX_SCANNER +-int master_lineno; +-#endif +- +-int master_lex(void); +-int master_wrap(void); +- +-/* no need for yywrap() */ +-#define YY_SKIP_YYWRAP +- +-#ifndef YY_STACK_USED +-#define YY_STACK_USED 0 +-#endif +-#ifndef YY_ALWAYS_INTERACTIVE +-#define YY_ALWAYS_INTERACTIVE 0 +-#endif +-#ifndef YY_NEVER_INTERACTIVE +-#define YY_NEVER_INTERACTIVE 0 +-#endif +-#ifndef YY_MAIN +-#define YY_MAIN 0 +-#endif +- +-void master_set_scan_buffer(const char *); +-const char *line = NULL; +- +-#ifdef FLEX_SCANNER +-const char *line_pos = NULL; +-const char *line_lim = NULL; +-int my_yyinput(char *, int); +- +-#undef YY_INPUT +-#define YY_INPUT(b, r, ms) (r = my_yyinput(b, ms)) +-#else +-#undef input +-#undef unput +-#define input() (*(char *) line++) +-#define unput(c) (*(char *) --line = c) +-#endif +- +-#define BUFF_LEN 1024 +-char buff[BUFF_LEN]; +-char *bptr; +-char *optr = buff; +-unsigned int tlen; +- +-%} +- +-%option nounput +- +-%x PATHSTR MAPSTR DNSTR OPTSTR OCTAL +- +-WS [[:blank:]]+ +-OPTWS [[:blank:]]* +-NL \r?\n +-CONT \\\n{OPTWS} +- +-OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=(\"?([[:alnum:]_\-\:\.])+\"?))?)+) +-MACROSTR (-D{OPTWS}([[:alpha:]_]([[:alnum:]_\-\.])*)=([[:alnum:]_\-\.])+) +-SLASHIFYSTR (--(no-)?slashify-colons) +-NUMBER [0-9]+ +-OCTALNUMBER [0-7]+ +- +-DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:) +-DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:) +-DNSERVSTR3 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/) +-DNSERVSTR4 (\/\/\[([[:xdigit:]]:.)+\](:[0-9]+)?\/) +-DNSERVSTR5 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:) +-DNSERVSTR6 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/) +-DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}|{DNSERVSTR5}|{DNSERVSTR6}) +- +-AT_CN ([cC][[nN]) +-AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE]) +-AT_AMN ([aA][uU][tT][oO][mM][oO][uU][nN][tT][Mm][aA][pP][Nn][aA][mM][eE]) +-AT_OU ([oO][[uU]) +-AT_DC ([dD][[cC]) +-AT_O ([oO]) +-AT_C ([cC]) +-AT_L ([lL]) +-DNATTRSTR ({AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}|{AT_L}) +-DNNAMESTR1 ([[:alnum:]_.\- ]+) +-DNNAMESTR2 ([[:alnum:]_.\-]+) +- +-INTMAP (-hosts|-null) +-MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS})) +-MULTISEP ([\-]{2}[[:blank:]]+) +-MTYPE ((file|program|exec|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod|amd))?(:{OPTWS}|{WS})) +- +- +-OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) +-OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeout{OPTWS}={OPTWS}) +- +-MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS}) +- +-%% +- +-{ +- {NL} | +- \x00 { +- if (optr != buff) { +- *optr = '\0'; +- strcpy(master_lval.strtype, buff); +- return NILL; +- } +- } +- +- #.* { return COMMENT; } +- +- "/" { +- if (optr != buff) { +- *optr = '\0'; +- strcpy(master_lval.strtype, buff); +- return NILL; +- } +- BEGIN(PATHSTR); +- bptr = buff; +- yyless(0); +- } +- +- . { *optr++ = *master_text; } +-} +- +-{ +- \x00 { +- BEGIN(INITIAL); +- *bptr++ = *master_text; +- strcpy(master_lval.strtype, buff); +- return NILL; +- } +- +- \\. { *bptr++ = *(master_text + 1); } +- \" { +- BEGIN(INITIAL); +- *bptr++ = *master_text; +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- return QUOTE; +- } +- +- {WS} { +- BEGIN(MAPSTR); +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- bptr = buff; +- memset(buff, 0, BUFF_LEN); +- return(PATH); +- } +- +- <> { +- BEGIN(INITIAL); +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- return(PATH); +- } +- +- {NL} { +- BEGIN(INITIAL); +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- return PATH; +- } +- +- . { *bptr++ = *master_text; } +-} +- +-{ +- {OPTWS}\\\n{OPTWS} {} +- +- {MULTI} { +- tlen = master_leng - 1; +- if (bptr != buff && isblank(master_text[tlen])) { +- /* +- * We can't handle unescaped white space in map names +- * so just eat the white space. We always have the +- * "multi" at the beginning of the string so the while +- * will not fall off the end. +- */ +- while (isblank(master_text[tlen - 1])) +- tlen--; +- strncat(buff, master_text, tlen); +- bptr += tlen; +- yyless(tlen); +- } else { +- strcpy(master_lval.strtype, master_text); +- return(MULTITYPE); +- } +- } +- +- {MTYPE} | +- {MTYPE}/{DNSERVERSTR}{DNATTRSTR}= | +- {MTYPE}/{DNATTRSTR}= { +- tlen = master_leng - 1; +- if (bptr != buff && isblank(master_text[tlen])) { +- /* +- * We can't handle unescaped white space in map names +- * so just eat the white space. We always have the +- * maptype keyword at the beginning of the string so +- * the while will not fall off the end. +- */ +- while (isblank(master_text[tlen - 1])) +- tlen--; +- strncat(buff, master_text, tlen); +- bptr += tlen; +- yyless(tlen); +- } else { +- strcpy(master_lval.strtype, master_text); +- return(MAPTYPE); +- } +- } +- +- {MULTISEP} { return(DDASH); } +- +- ":" { return(COLON); } +- +- "-hosts" { +- BEGIN(OPTSTR); +- strcpy(master_lval.strtype, master_text); +- return MAPHOSTS; +- } +- +- "-null" { +- BEGIN(OPTSTR); +- strcpy(master_lval.strtype, master_text); +- return MAPNULL; +- } +- +- "-xfn" { +- /* +- * The X/Open Federated Naming service isn't supported +- * and the parser will call YYABORT() when it sees the +- * MAPXFN token so we must set the start state to the +- * INITIAL state here for the next yylex() call. +- */ +- BEGIN(INITIAL); +- strcpy(master_lval.strtype, master_text); +- return MAPXFN; +- } +- +- "//" { +- BEGIN(DNSTR); +- yyless(0); +- } +- +- {DNSERVERSTR}{DNATTRSTR}= { +- BEGIN(DNSTR); +- yyless(0); +- } +- +- {DNATTRSTR}= { +- BEGIN(DNSTR); +- yyless(0); +- } +- +- {OPTWS}/{NL} { +- BEGIN(INITIAL); +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- bptr = buff; +- return(MAPNAME); +- } +- +- \\. { *bptr++ = *(master_text + 1); } +- +- {WS} { +- BEGIN(OPTSTR); +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- bptr = buff; +- return(MAPNAME); +- } +- +- {NL} | +- \x00 { +- BEGIN(INITIAL); +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- return(MAPNAME); +- } +- +- <> { +- BEGIN(INITIAL); +- *bptr = '\0'; +- strcpy(master_lval.strtype, buff); +- return(MAPNAME); +- } +- +- . { *bptr++ = *master_text; } +-} +- +-{ +- {OPTWS}\\\n{OPTWS} {} +- +- {DNSERVERSTR} { +- strcpy(master_lval.strtype, master_text); +- return DNSERVER; +- } +- +- {DNATTRSTR}/"=" { +- strcpy(master_lval.strtype, master_text); +- return DNATTR; +- } +- +- "=" { +- return EQUAL; +- } +- +- {DNNAMESTR1}/","{DNATTRSTR}"=" { +- strcpy(master_lval.strtype, master_text); +- return DNNAME; +- } +- +- {DNNAMESTR2} { +- strcpy(master_lval.strtype, master_text); +- return DNNAME; +- } +- +- {OPTWS}","{OPTWS} { +- return COMMA; +- } +- +- {WS}"=" | +- "="{WS} { +- BEGIN(INITIAL); +- strcpy(master_lval.strtype, master_text); +- return SPACE; +- } +- +- {WS} { BEGIN(OPTSTR); } +- +- {NL} | +- \x00 { BEGIN(INITIAL); } +- +- <> { BEGIN(INITIAL); } +-} +- +-{ +- {OPTWS}\\\n{OPTWS} {} +- +- {MULTISEP} { +- BEGIN(MAPSTR); +- return(DDASH); +- } +- +- {OPTTOUT}/{NUMBER} { return(OPT_TIMEOUT); } +- +- {OPTNTOUT}/{NUMBER} { return(OPT_NTIMEOUT); } +- +- {NUMBER} { +- master_lval.longtype = atol(master_text); +- return(NUMBER); +- } +- +- -?symlink { return(OPT_SYMLINK); } +- -?nobind { return(OPT_NOBIND); } +- -?nobrowse { return(OPT_NOGHOST); } +- -?shared { return(OPT_SHARED); } +- -?slave { return(OPT_SLAVE); } +- -?private { return(OPT_PRIVATE); } +- -?strictexpire { return(OPT_STRICTEXPIRE); } +- -g|--ghost|-?browse { return(OPT_GHOST); } +- -v|--verbose { return(OPT_VERBOSE); } +- -d|--debug { return(OPT_DEBUG); } +- -w|--use-weight-only { return(OPT_USE_WEIGHT); } +- -r|--random-multimount-selection { return(OPT_RANDOM); } +- +- {MODE}/{OCTALNUMBER} { +- BEGIN(OCTAL); +- return(OPT_MODE); +- } +- +- {OPTWS}","{OPTWS} { return(COMMA); } +- +- {OPTWS} {} +- +- {SLASHIFYSTR} { +- strcpy(master_lval.strtype, master_text); +- return(OPTION); +- } +- +- {MACROSTR} { +- strcpy(master_lval.strtype, master_text); +- return(OPTION); +- } +- +- {OPTIONSTR} { +- strcpy(master_lval.strtype, master_text); +- return(OPTION); +- } +- +- "=" { +- strcpy(master_lval.strtype, master_text); +- return(EQUAL); +- } +- +- {WS} {} +- {NL} | +- \x00 { BEGIN(INITIAL); } +- +- <> { BEGIN(INITIAL); } +-} +- +-{ +- {OCTALNUMBER} { +- master_lval.longtype = strtoul(master_text, NULL, 8); +- return(OCTALNUMBER); +- } +- +- . { BEGIN(OPTSTR); yyless(0); } +-} +- +-%% +- +-#include "automount.h" +- +-int master_wrap(void) +-{ +- return 1; +-} +- +-static void master_echo(void) +-{ +- logmsg("%s", master_text); +- return; +-} +- +-#ifdef FLEX_SCANNER +- +-void master_set_scan_buffer(const char *buffer) +-{ +- memset(buff, 0, sizeof(buff)); +- optr = buff; +- +- YY_FLUSH_BUFFER; +- +- line = buffer; +- line_pos = &line[0]; +- /* +- * Ensure buffer is 1 greater than string and is zeroed before +- * the parse so we can fit the extra NULL which allows us to +- * explicitly match an end of line within the buffer (ie. the +- * need for 2 NULLS when parsing in memeory buffers). +- */ +- line_lim = line + strlen(buffer) + 1; +-} +- +-#ifndef min +-#define min(a,b) (((a) < (b)) ? (a) : (b)) +-#endif +- +-int my_yyinput(char *buffer, int max_size) +-{ +- int n = min(max_size, line_lim - line_pos); +- +- if (n > 0) { +- memcpy(buffer, line_pos, n); +- line_pos += n; +- } +- return n; +-} +- +-#else +- +-void master_set_scan_buffer(const char *buffer) +-{ +- line = buffer; +-} +- +-#endif diff --git a/autofs-5.1.6-move-readall-into-struct-master.patch b/autofs-5.1.6-move-readall-into-struct-master.patch new file mode 100644 index 0000000..9555edd --- /dev/null +++ b/autofs-5.1.6-move-readall-into-struct-master.patch @@ -0,0 +1,203 @@ +autofs-5.1.6 - move readall into struct master + +From: Ian Kent + +The lookup modules may need to know if the master map is being re-read +vis a HUP signal or is being read for the first time. + +This is indicated by the readall variable so move it into the master +map structure so it's accessable to lookup modules. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 28 +++++++++++++++++----------- + include/master.h | 5 +++-- + lib/master.c | 15 ++++++++------- + 4 files changed, 29 insertions(+), 20 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 4d83df2..4a6c042 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -103,6 +103,7 @@ xx/xx/2018 autofs-5.1.5 + - refactor sss getautomntent(). + - improve sss getautomntent() error handling. + - sss introduce calculate_retry_count() function. ++- move readall into struct master. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/daemon/automount.c b/daemon/automount.c +index 019bd81..9660f3f 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1465,7 +1465,6 @@ static void *do_read_master(void *arg) + struct master *master; + unsigned int logopt; + time_t age; +- int readall = 1; + int status; + + status = pthread_mutex_lock(&mrc.mutex); +@@ -1496,8 +1495,11 @@ static void *do_read_master(void *arg) + + info(logopt, "re-reading master map %s", master->name); + +- status = master_read_master(master, age, readall); ++ master->readall = 1; + ++ status = master_read_master(master, age); ++ ++ master->readall = 0; + master->reading = 0; + + return NULL; +@@ -2196,7 +2198,7 @@ static void do_master_list_reset(struct master *master) + master_mutex_unlock(); + } + +-static int do_master_read_master(struct master *master, int wait) ++static int do_master_read_master(struct master *master, time_t *age, int wait) + { + sigset_t signalset; + /* Wait must be at least 1 second */ +@@ -2204,7 +2206,6 @@ static int do_master_read_master(struct master *master, int wait) + unsigned int elapsed = 0; + int max_wait = wait; + int ret = 0; +- time_t age; + + sigemptyset(&signalset); + sigaddset(&signalset, SIGTERM); +@@ -2217,8 +2218,8 @@ static int do_master_read_master(struct master *master, int wait) + + do_master_list_reset(master); + +- age = monotonic_time(NULL); +- if (master_read_master(master, age, 0)) { ++ *age = monotonic_time(NULL); ++ if (master_read_master(master, *age)) { + ret = 1; + break; + } +@@ -2692,14 +2693,14 @@ int main(int argc, char *argv[]) + dh_tirpc = dlopen("libtirpc.so.3", RTLD_NOW); + #endif + +- master_read = master_read_master(master_list, age, 0); ++ master_read = master_read_master(master_list, age); + if (!master_read) { + /* + * Read master map, waiting until it is available, unless + * a signal is received, in which case exit returning an + * error. + */ +- if (!do_master_read_master(master_list, master_wait)) { ++ if (!do_master_read_master(master_list, &age, master_wait)) { + logmsg("%s: warning: could not read at least one " + "map source after waiting, continuing ...", + program); +@@ -2707,9 +2708,14 @@ int main(int argc, char *argv[]) + * Failed to read master map, continue with what + * we have anyway. + */ +- do_master_list_reset(master_list); +- age = monotonic_time(NULL); +- master_read_master(master_list, age, 1); ++ master_mutex_lock(); ++ master_list->readall = 1; ++ master_mount_mounts(master_list, age); ++ master_list->readall = 0; ++ ++ if (list_empty(&master_list->mounts)) ++ warn(master_list->logopt, "no mounts in table"); ++ master_mutex_unlock(); + } + } + +diff --git a/include/master.h b/include/master.h +index e1d272f..f689297 100644 +--- a/include/master.h ++++ b/include/master.h +@@ -63,6 +63,7 @@ struct master { + unsigned int depth; + unsigned int reading; + unsigned int read_fail; ++ unsigned int readall; + unsigned int default_ghost; + unsigned int default_logging; + unsigned int default_timeout; +@@ -118,11 +119,11 @@ void master_remove_mapent(struct master_mapent *); + void master_free_mapent_sources(struct master_mapent *, unsigned int); + void master_free_mapent(struct master_mapent *); + struct master *master_new(const char *, unsigned int, unsigned int); +-int master_read_master(struct master *, time_t, int); ++int master_read_master(struct master *, time_t); + int master_submount_list_empty(struct autofs_point *ap); + int master_notify_submount(struct autofs_point *, const char *path, enum states); + void master_notify_state_change(struct master *, int); +-int master_mount_mounts(struct master *, time_t, int); ++int master_mount_mounts(struct master *, time_t); + int dump_map(struct master *, const char *, const char *); + int master_show_mounts(struct master *); + unsigned int master_get_logopt(void); +diff --git a/lib/master.c b/lib/master.c +index fedf807..d87d7e2 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -951,6 +951,7 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int f + master->depth = 0; + master->reading = 0; + master->read_fail = 0; ++ master->readall = 0; + master->default_ghost = flags & DAEMON_FLAGS_GHOST; + master->default_timeout = timeout; + master->default_logging = defaults_get_logging(); +@@ -1126,7 +1127,7 @@ again: + } + } + +-int master_read_master(struct master *master, time_t age, int readall) ++int master_read_master(struct master *master, time_t age) + { + unsigned int logopt = master->logopt; + struct mapent_cache *nc; +@@ -1157,15 +1158,15 @@ int master_read_master(struct master *master, time_t age, int readall) + master_add_amd_mount_section_mounts(master, age); + + if (!master->read_fail) +- master_mount_mounts(master, age, readall); ++ master_mount_mounts(master, age); + else { + master->read_fail = 0; +- /* HUP signal sets readall == 1 only */ +- if (!readall) { ++ /* HUP signal sets master->readall == 1 only */ ++ if (!master->readall) { + master_mutex_unlock(); + return 0; + } else +- master_mount_mounts(master, age, readall); ++ master_mount_mounts(master, age); + } + + if (list_empty(&master->mounts)) +@@ -1452,7 +1453,7 @@ static void check_update_map_sources(struct master_mapent *entry, int readall) + return; + } + +-int master_mount_mounts(struct master *master, time_t age, int readall) ++int master_mount_mounts(struct master *master, time_t age) + { + struct mapent_cache *nc = master->nc; + struct list_head *p, *head; +@@ -1536,7 +1537,7 @@ cont: + st_mutex_unlock(); + + if (!ret) +- check_update_map_sources(this, readall); ++ check_update_map_sources(this, master->readall); + else if (ret == -1 && save_errno == EBADF) { + if (!master_do_mount(this)) { + list_del_init(&this->list); diff --git a/autofs-5.1.6-move-submount-check-into-conditional_alarm_add.patch b/autofs-5.1.6-move-submount-check-into-conditional_alarm_add.patch new file mode 100644 index 0000000..eff3fd1 --- /dev/null +++ b/autofs-5.1.6-move-submount-check-into-conditional_alarm_add.patch @@ -0,0 +1,201 @@ +autofs-5.1.6 - move submount check into conditional_alarm_add() + +From: Ian Kent + +The expire of submounts is driven by the top level autofs mount in the +mount tree so an expire alarm doesn't need to set if the autofs point +is a submount. + +Take that check into conditional_alarm_add(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 6 ++---- + daemon/direct.c | 3 +-- + daemon/indirect.c | 3 +-- + daemon/state.c | 26 +++++++++----------------- + lib/alarm.c | 2 ++ + lib/mounts.c | 6 ++---- + 7 files changed, 18 insertions(+), 29 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -132,6 +132,7 @@ xx/xx/2018 autofs-5.1.5 + - use struct mnt_list mounted list for expire. + - remove unused function tree_get_mnt_list(). + - only add expre alarm for active mounts. ++- move submount check into conditional_alarm_add(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1843,8 +1843,7 @@ int handle_mounts_exit(struct autofs_poi + } + + if (ap->state != ST_SHUTDOWN) { +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + /* Return to ST_READY is done immediately */ + st_add_task(ap, ST_READY); + if (ap->submount) +@@ -1888,8 +1887,7 @@ int handle_mounts_exit(struct autofs_poi + + /* Failed shutdown returns to ready */ + warn(ap->logopt, "can't shutdown: filesystem %s still busy", ap->path); +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + /* Return to ST_READY is done immediately */ + st_add_task(ap, ST_READY); + if (ap->submount) +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -1246,8 +1246,7 @@ static void *do_mount_direct(void *arg) + + mnts_set_mounted_mount(ap, mt.name); + +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + /* TODO: get mount return status from lookup_nss_mount */ + ops->send_fail(ap->logopt, +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -754,8 +754,7 @@ static void *do_mount_indirect(void *arg + + mnts_set_mounted_mount(ap, mt.name); + +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + /* TODO: get mount return status from lookup_nss_mount */ + ops->send_fail(ap->logopt, +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -154,7 +154,7 @@ void expire_cleanup(void *arg) + } else if (ap->submount > 1) + ap->submount = 1; + +- if (ap->state == ST_EXPIRE && !ap->submount) ++ if (ap->state == ST_EXPIRE) + conditional_alarm_add(ap, ap->exp_runfreq); + + /* FALLTHROUGH */ +@@ -172,8 +172,7 @@ void expire_cleanup(void *arg) + rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle); + if (!rv && !idle && !ap->shutdown) { + next = ST_READY; +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + break; + } + +@@ -186,8 +185,7 @@ void expire_cleanup(void *arg) + + /* Failed shutdown returns to ready */ + warn(ap->logopt, "filesystem %s still busy", ap->path); +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + next = ST_READY; + break; + #endif +@@ -577,8 +575,7 @@ static unsigned int st_readmap(struct au + error(ap->logopt, "failed to malloc readmap cond struct"); + /* It didn't work: return to ready */ + st_ready(ap); +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + return 0; + } + +@@ -604,8 +601,7 @@ static unsigned int st_readmap(struct au + free(ra); + /* It didn't work: return to ready */ + st_ready(ap); +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + return 0; + } + ap->readmap_thread = thid; +@@ -640,8 +636,7 @@ static unsigned int st_prepare_shutdown( + case EXP_ERROR: + case EXP_PARTIAL: + /* It didn't work: return to ready */ +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +@@ -666,8 +661,7 @@ static unsigned int st_force_shutdown(st + case EXP_ERROR: + case EXP_PARTIAL: + /* It didn't work: return to ready */ +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +@@ -699,8 +693,7 @@ static unsigned int st_prune(struct auto + switch (expire_proc(ap, AUTOFS_EXP_IMMEDIATE)) { + case EXP_ERROR: + case EXP_PARTIAL: +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +@@ -720,8 +713,7 @@ static unsigned int st_expire(struct aut + switch (expire_proc(ap, AUTOFS_EXP_NORMAL)) { + case EXP_ERROR: + case EXP_PARTIAL: +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +--- autofs-5.1.4.orig/lib/alarm.c ++++ autofs-5.1.4/lib/alarm.c +@@ -187,6 +187,8 @@ int conditional_alarm_add(struct autofs_ + { + int status; + ++ if (ap->submount) ++ return 1; + if (!mnts_has_mounted_mounts(ap)) + return 1; + +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1921,8 +1921,7 @@ static int do_remount_direct(struct auto + + info(ap->logopt, "re-connected to %s", path); + +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + status = REMOUNT_FAIL; + info(ap->logopt, "failed to re-connect %s", path); +@@ -1997,8 +1996,7 @@ static int do_remount_indirect(struct au + + info(ap->logopt, "re-connected to %s", buf); + +- if (!ap->submount) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + status = REMOUNT_FAIL; + info(ap->logopt, "failed to re-connect %s", buf); diff --git a/autofs-5.1.6-only-add-expire-alarm-for-active-mounts.patch b/autofs-5.1.6-only-add-expire-alarm-for-active-mounts.patch new file mode 100644 index 0000000..c7ecc32 --- /dev/null +++ b/autofs-5.1.6-only-add-expire-alarm-for-active-mounts.patch @@ -0,0 +1,334 @@ +autofs-5.1.6 - only add expire alarm for active mounts + +From: Ian Kent + +There's no need to add expire alarms for mount points that have no +expirable mounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 9 +------- + daemon/direct.c | 3 ++ + daemon/indirect.c | 3 ++ + daemon/state.c | 25 +++++++++++----------- + include/automount.h | 1 + include/mounts.h | 1 + lib/alarm.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---- + lib/mounts.c | 19 +++++++++++++++++ + 9 files changed, 96 insertions(+), 23 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -131,6 +131,7 @@ xx/xx/2018 autofs-5.1.5 + - use struct mnt_list to track mounted mounts. + - use struct mnt_list mounted list for expire. + - remove unused function tree_get_mnt_list(). ++- only add expre alarm for active mounts. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1844,7 +1844,7 @@ int handle_mounts_exit(struct autofs_poi + + if (ap->state != ST_SHUTDOWN) { + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + /* Return to ST_READY is done immediately */ + st_add_task(ap, ST_READY); + if (ap->submount) +@@ -1889,7 +1889,7 @@ int handle_mounts_exit(struct autofs_poi + /* Failed shutdown returns to ready */ + warn(ap->logopt, "can't shutdown: filesystem %s still busy", ap->path); + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + /* Return to ST_READY is done immediately */ + st_add_task(ap, ST_READY); + if (ap->submount) +@@ -1952,11 +1952,6 @@ void *handle_mounts(void *arg) + suc->status = 0; + pthread_cleanup_pop(1); + +- /* We often start several automounters at the same time. Add some +- randomness so we don't all expire at the same time. */ +- if (!ap->submount && ap->exp_runfreq) +- alarm_add(ap, ap->exp_runfreq + rand() % ap->exp_runfreq); +- + pthread_setcancelstate(cancel_state, NULL); + + while (1) { +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -1245,6 +1245,9 @@ static void *do_mount_direct(void *arg) + info(ap->logopt, "mounted %s", mt.name); + + mnts_set_mounted_mount(ap, mt.name); ++ ++ if (!ap->submount) ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + /* TODO: get mount return status from lookup_nss_mount */ + ops->send_fail(ap->logopt, +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -753,6 +753,9 @@ static void *do_mount_indirect(void *arg + info(ap->logopt, "mounted %s", buf); + + mnts_set_mounted_mount(ap, mt.name); ++ ++ if (!ap->submount) ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + /* TODO: get mount return status from lookup_nss_mount */ + ops->send_fail(ap->logopt, +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -155,7 +155,7 @@ void expire_cleanup(void *arg) + ap->submount = 1; + + if (ap->state == ST_EXPIRE && !ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + + /* FALLTHROUGH */ + +@@ -173,7 +173,7 @@ void expire_cleanup(void *arg) + if (!rv && !idle && !ap->shutdown) { + next = ST_READY; + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + break; + } + +@@ -187,7 +187,7 @@ void expire_cleanup(void *arg) + /* Failed shutdown returns to ready */ + warn(ap->logopt, "filesystem %s still busy", ap->path); + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + next = ST_READY; + break; + #endif +@@ -522,9 +522,10 @@ static void *do_readmap(void *arg) + * alarm will have been added. So add it here if there are + * now map entries. + */ +- if (append_alarm && ap->exp_runfreq) +- alarm_add(ap, ap->exp_runfreq + +- rand() % ap->exp_runfreq); ++ if (append_alarm && ap->exp_runfreq) { ++ time_t seconds = ap->exp_runfreq + rand() % ap->exp_runfreq; ++ conditional_alarm_add(ap, seconds); ++ } + + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); +@@ -577,7 +578,7 @@ static unsigned int st_readmap(struct au + /* It didn't work: return to ready */ + st_ready(ap); + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + return 0; + } + +@@ -604,7 +605,7 @@ static unsigned int st_readmap(struct au + /* It didn't work: return to ready */ + st_ready(ap); + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + return 0; + } + ap->readmap_thread = thid; +@@ -640,7 +641,7 @@ static unsigned int st_prepare_shutdown( + case EXP_PARTIAL: + /* It didn't work: return to ready */ + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +@@ -666,7 +667,7 @@ static unsigned int st_force_shutdown(st + case EXP_PARTIAL: + /* It didn't work: return to ready */ + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +@@ -699,7 +700,7 @@ static unsigned int st_prune(struct auto + case EXP_ERROR: + case EXP_PARTIAL: + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +@@ -720,7 +721,7 @@ static unsigned int st_expire(struct aut + case EXP_ERROR: + case EXP_PARTIAL: + if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); ++ conditional_alarm_add(ap, ap->exp_runfreq); + st_ready(ap); + return 0; + +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -637,6 +637,7 @@ static inline time_t monotonic_time(time + /* Expire alarm handling routines */ + int alarm_start_handler(void); + int alarm_add(struct autofs_point *ap, time_t seconds); ++int conditional_alarm_add(struct autofs_point *ap, time_t seconds); + void alarm_delete(struct autofs_point *ap); + + #endif +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -125,6 +125,7 @@ void mnts_remove_amdmount(const char *mp + struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags); + void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); ++unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name); +--- autofs-5.1.4.orig/lib/alarm.c ++++ autofs-5.1.4/lib/alarm.c +@@ -41,7 +41,7 @@ do { \ + } while (0) + + /* Insert alarm entry on ordered list. */ +-int alarm_add(struct autofs_point *ap, time_t seconds) ++int __alarm_add(struct autofs_point *ap, time_t seconds) + { + struct list_head *head; + struct list_head *p; +@@ -62,8 +62,6 @@ int alarm_add(struct autofs_point *ap, t + new->cancel = 0; + new->time = now + seconds; + +- alarm_lock(); +- + head = &alarms; + + /* Check if we have a pending alarm */ +@@ -97,9 +95,42 @@ int alarm_add(struct autofs_point *ap, t + fatal(status); + } + ++ return 1; ++} ++ ++int alarm_add(struct autofs_point *ap, time_t seconds) ++{ ++ int status; ++ ++ alarm_lock(); ++ status = __alarm_add(ap, seconds); + alarm_unlock(); + +- return 1; ++ return status; ++} ++ ++static int __alarm_exists(struct autofs_point *ap) ++{ ++ struct list_head *head; ++ struct list_head *p; ++ ++ head = &alarms; ++ ++ if (list_empty(head)) ++ return 0; ++ ++ p = head->next; ++ while (p != head) { ++ struct alarm *this; ++ ++ this = list_entry(p, struct alarm, list); ++ p = p->next; ++ ++ if (ap == this->ap) ++ return 1; ++ } ++ ++ return 0; + } + + void alarm_delete(struct autofs_point *ap) +@@ -152,6 +183,24 @@ void alarm_delete(struct autofs_point *a + return; + } + ++int conditional_alarm_add(struct autofs_point *ap, time_t seconds) ++{ ++ int status; ++ ++ if (!mnts_has_mounted_mounts(ap)) ++ return 1; ++ ++ alarm_lock(); ++ if (__alarm_exists(ap)) { ++ alarm_unlock(); ++ return 1; ++ } ++ status = __alarm_add(ap, seconds); ++ alarm_unlock(); ++ ++ return status; ++} ++ + static void *alarm_handler(void *arg) + { + struct list_head *head; +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1208,6 +1208,19 @@ void mnts_set_mounted_mount(struct autof + } + } + ++unsigned int mnts_has_mounted_mounts(struct autofs_point *ap) ++{ ++ unsigned int has_mounted_mounts = 0; ++ ++ mnts_hash_mutex_lock(); ++ if (list_empty(&ap->mounts)) ++ goto done; ++ has_mounted_mounts = 1; ++done: ++ mnts_hash_mutex_unlock(); ++ return has_mounted_mounts; ++} ++ + struct node { + struct mnt_list *mnt; + struct node *left; +@@ -1907,6 +1920,9 @@ static int do_remount_direct(struct auto + mnts_set_mounted_mount(ap, path); + + info(ap->logopt, "re-connected to %s", path); ++ ++ if (!ap->submount) ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + status = REMOUNT_FAIL; + info(ap->logopt, "failed to re-connect %s", path); +@@ -1980,6 +1996,9 @@ static int do_remount_indirect(struct au + mnts_set_mounted_mount(ap, buf); + + info(ap->logopt, "re-connected to %s", buf); ++ ++ if (!ap->submount) ++ conditional_alarm_add(ap, ap->exp_runfreq); + } else { + status = REMOUNT_FAIL; + info(ap->logopt, "failed to re-connect %s", buf); diff --git a/autofs-5.1.6-refactor-sss-getautomntbyname.patch b/autofs-5.1.6-refactor-sss-getautomntbyname.patch new file mode 100644 index 0000000..c02228d --- /dev/null +++ b/autofs-5.1.6-refactor-sss-getautomntbyname.patch @@ -0,0 +1,172 @@ +autofs-5.1.6 - refactor sss getautomntbyname() + +From: Ian Kent + +Refactor the sss getautomntbyname_r() to consolidate the error handling +in one location. + +Also add the missing ECONREFUSED handling while we are at it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/lookup_sss.c | 110 +++++++++++++++++++++++++++++--------------------- + 2 files changed, 65 insertions(+), 46 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index e48e2c0..8b662d7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -106,6 +106,7 @@ xx/xx/2018 autofs-5.1.5 + - move readall into struct master. + - sss introduce a flag to indicate map being read. + - update sss timeout documentation. ++- refactor sss getautomntbyname(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 3c0ffde..1a56ea1 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -566,6 +566,39 @@ free: + return err; + } + ++static int getautomntbyname(unsigned int logopt, ++ struct lookup_context *ctxt, ++ char *key, char **value, void *sss_ctxt) ++{ ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ int ret = NSS_STATUS_UNAVAIL; ++ ++ ret = ctxt->getautomntbyname_r(key, value, sss_ctxt); ++ if (ret) { ++ /* Host has gone down */ ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; ++ ++ if (ret != ENOENT) ++ goto error; ++ ++ ret = NSS_STATUS_NOTFOUND; ++ goto free; ++ } ++ return ret; ++ ++error: ++ estr = strerror_r(ret, buf, MAX_ERR_BUF); ++ error(logopt, MODPREFIX "getautomntbyname: %s", estr); ++free: ++ if (*value) { ++ free(*value); ++ *value = NULL; ++ } ++ return ret; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +@@ -755,7 +788,6 @@ static int lookup_one(struct autofs_point *ap, + struct mapent *we; + void *sss_ctxt = NULL; + time_t age = monotonic_time(NULL); +- char buf[MAX_ERR_BUF]; + char *value = NULL; + char *s_key; + int ret; +@@ -770,61 +802,47 @@ static int lookup_one(struct autofs_point *ap, + if (ret) + return ret; + +- ret = ctxt->getautomntbyname_r(qKey, &value, sss_ctxt); +- if (ret && ret != ENOENT) { +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(ap->logopt, +- MODPREFIX "getautomntbyname_r: %s", estr); ++ ret = getautomntbyname(ap->logopt, ctxt, qKey, &value, sss_ctxt); ++ if (ret == NSS_STATUS_NOTFOUND) ++ goto wild; ++ if (ret) { + endautomntent(ap->logopt, ctxt, &sss_ctxt); +- if (value) +- free(value); +- return NSS_STATUS_UNAVAIL; ++ return ret; + } +- if (ret != ENOENT) { +- /* +- * TODO: implement sun % hack for key translation for +- * mixed case keys in schema that are single case only. +- */ +- s_key = sanitize_path(qKey, qKey_len, ap->type, ap->logopt); +- if (!s_key) { +- free(value); +- value = NULL; +- goto wild; +- } +- cache_writelock(mc); +- ret = cache_update(mc, source, s_key, value, age); +- cache_unlock(mc); +- endautomntent(ap->logopt, ctxt, &sss_ctxt); +- free(s_key); ++ ++ /* ++ * TODO: implement sun % hack for key translation for ++ * mixed case keys in schema that are single case only. ++ */ ++ s_key = sanitize_path(qKey, qKey_len, ap->type, ap->logopt); ++ if (!s_key) { + free(value); +- return NSS_STATUS_SUCCESS; ++ value = NULL; ++ goto wild; + } ++ cache_writelock(mc); ++ ret = cache_update(mc, source, s_key, value, age); ++ cache_unlock(mc); ++ endautomntent(ap->logopt, ctxt, &sss_ctxt); ++ free(s_key); ++ free(value); ++ return NSS_STATUS_SUCCESS; + + wild: +- ret = ctxt->getautomntbyname_r("/", &value, sss_ctxt); +- if (ret && ret != ENOENT) { +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(ap->logopt, +- MODPREFIX "getautomntbyname_r: %s", estr); +- endautomntent(ap->logopt, ctxt, &sss_ctxt); +- if (value) +- free(value); +- return NSS_STATUS_UNAVAIL; +- } +- if (ret == ENOENT) { +- ret = ctxt->getautomntbyname_r("*", &value, sss_ctxt); +- if (ret && ret != ENOENT) { +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(ap->logopt, +- MODPREFIX "getautomntbyname_r: %s", estr); ++ ret = getautomntbyname(ap->logopt, ctxt, "/", &value, sss_ctxt); ++ if (ret) { ++ if (ret != NSS_STATUS_NOTFOUND) { + endautomntent(ap->logopt, ctxt, &sss_ctxt); +- if (value) +- free(value); +- return NSS_STATUS_UNAVAIL; ++ return ret; ++ } ++ ret = getautomntbyname(ap->logopt, ctxt, "*", &value, sss_ctxt); ++ if (ret && ret != NSS_STATUS_NOTFOUND) { ++ endautomntent(ap->logopt, ctxt, &sss_ctxt); ++ return ret; + } + } + +- if (ret == ENOENT) { ++ if (ret == NSS_STATUS_NOTFOUND) { + /* Failed to find wild entry, update cache if needed */ + cache_writelock(mc); + we = cache_lookup_distinct(mc, "*"); diff --git a/autofs-5.1.6-refactor-sss-getautomntent.patch b/autofs-5.1.6-refactor-sss-getautomntent.patch new file mode 100644 index 0000000..3e83679 --- /dev/null +++ b/autofs-5.1.6-refactor-sss-getautomntent.patch @@ -0,0 +1,150 @@ +autofs-5.1.6 - refactor sss getautomntent() + +From: Ian Kent + +Refactor the sss getautomntent_r() to consolidate the error handling in +one location. + +Also add the missing ECONREFUSED handling while we are at it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 88 +++++++++++++++++++++++--------------------------- + 2 files changed, 42 insertions(+), 47 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 5ccd787..ecd54e9 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -100,6 +100,7 @@ xx/xx/2018 autofs-5.1.5 + - fix retries check in setautomntent_wait(). + - refactor sss setautomntent(). + - improve sss setautomntent() error handling. ++- refactor sss getautomntent(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index e1ed83c..5addd87 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -377,6 +377,40 @@ static int endautomntent(unsigned int logopt, + return ret; + } + ++static int getautomntent(unsigned int logopt, ++ struct lookup_context *ctxt, ++ char **key, char **value, int count, void *sss_ctxt) ++{ ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ int ret = NSS_STATUS_UNAVAIL; ++ ++ ret = ctxt->getautomntent_r(key, value, sss_ctxt); ++ if (ret) { ++ /* Host has gone down */ ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; ++ if (ret != ENOENT) ++ goto error; ++ if (!count) { ++ ret = NSS_STATUS_NOTFOUND; ++ goto free; ++ } ++ goto error; ++ } ++ return ret; ++ ++error: ++ estr = strerror_r(ret, buf, MAX_ERR_BUF); ++ error(logopt, MODPREFIX "getautomntent: %s", estr); ++free: ++ if (*key) ++ free(*key); ++ if (*value) ++ free(*value); ++ return ret; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +@@ -399,30 +433,12 @@ int lookup_read_master(struct master *master, time_t age, void *context) + while (1) { + key = NULL; + value = NULL; +- ret = ctxt->getautomntent_r(&key, &value, sss_ctxt); +- if (ret && ret != ENOENT) { +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(logopt, MODPREFIX "getautomntent_r: %s", estr); ++ ret = getautomntent(logopt, ctxt, &key, &value, count, sss_ctxt); ++ if (ret) { + endautomntent(logopt, ctxt, &sss_ctxt); +- if (key) +- free(key); +- if (value) +- free(value); +- return NSS_STATUS_UNAVAIL; +- } +- if (ret == ENOENT) { +- if (!count) { +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(logopt, MODPREFIX "getautomntent_r: %s", estr); +- endautomntent(logopt, ctxt, &sss_ctxt); +- if (key) +- free(key); +- if (value) +- free(value); +- return NSS_STATUS_NOTFOUND; +- } +- break; ++ return ret; + } ++ + count++; + + buffer_len = strlen(key) + 1 + strlen(value) + 2; +@@ -470,7 +486,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + struct map_source *source; + struct mapent_cache *mc; + void *sss_ctxt = NULL; +- char buf[MAX_ERR_BUF]; + char *key; + char *value = NULL; + char *s_key; +@@ -502,31 +517,10 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + while (1) { + key = NULL; + value = NULL; +- ret = ctxt->getautomntent_r(&key, &value, sss_ctxt); +- if (ret && ret != ENOENT) { +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(ap->logopt, +- MODPREFIX "getautomntent_r: %s", estr); ++ ret = getautomntent(ap->logopt, ctxt, &key, &value, count, sss_ctxt); ++ if (ret) { + endautomntent(ap->logopt, ctxt, &sss_ctxt); +- if (key) +- free(key); +- if (value) +- free(value); +- return NSS_STATUS_UNAVAIL; +- } +- if (ret == ENOENT) { +- if (!count) { +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(ap->logopt, +- MODPREFIX "getautomntent_r: %s", estr); +- endautomntent(ap->logopt, ctxt, &sss_ctxt); +- if (key) +- free(key); +- if (value) +- free(value); +- return NSS_STATUS_NOTFOUND; +- } +- break; ++ return ret; + } + + /* diff --git a/autofs-5.1.6-refactor-sss-setautomntent.patch b/autofs-5.1.6-refactor-sss-setautomntent.patch new file mode 100644 index 0000000..38f7357 --- /dev/null +++ b/autofs-5.1.6-refactor-sss-setautomntent.patch @@ -0,0 +1,198 @@ +autofs-5.1.6 - refactor sss setautomntent() + +From: Ian Kent + +Refactor the sss setautomntent() to consolidate the error handling in +one location. + +Also move the number of retries calculation into the wait function +as it's a much more sensible place for it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/lookup_sss.c | 106 +++++++++++++++++++++++--------------------------- + 2 files changed, 49 insertions(+), 58 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b3ffbb6..141658d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -98,6 +98,7 @@ xx/xx/2018 autofs-5.1.5 + - use mapname in sss context for setautomntent(). + - add support for new sss autofs proto version call. + - fix retries check in setautomntent_wait(). ++- refactor sss setautomntent(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index d65e71c..011b232 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -232,20 +232,6 @@ int lookup_reinit(const char *mapfmt, + return 0; + } + +-static int setautomntent(unsigned int logopt, +- struct lookup_context *ctxt, void **sss_ctxt) +-{ +- int ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); +- if (ret) { +- char buf[MAX_ERR_BUF]; +- char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(logopt, MODPREFIX "setautomntent: %s", estr); +- if (*sss_ctxt) +- free(*sss_ctxt); +- } +- return ret; +-} +- + static unsigned int proto_version(struct lookup_context *ctxt) + { + unsigned int proto_version = 0; +@@ -264,14 +250,18 @@ static unsigned int proto_version(struct lookup_context *ctxt) + } + + static int setautomntent_wait(unsigned int logopt, +- struct lookup_context *ctxt, +- void **sss_ctxt, unsigned int retries) ++ struct lookup_context *ctxt, void **sss_ctxt) + { ++ unsigned int retries; + unsigned int retry = 0; + int ret = 0; + + *sss_ctxt = NULL; + ++ retries = defaults_get_sss_master_map_wait(); ++ if (retries <= 0) ++ return ENOENT; ++ + while (++retry <= retries) { + struct timespec t = { SSS_WAIT_INTERVAL, 0 }; + struct timespec r; +@@ -291,9 +281,6 @@ static int setautomntent_wait(unsigned int logopt, + + + if (ret) { +- char buf[MAX_ERR_BUF]; +- char *estr; +- + if (*sss_ctxt) { + free(*sss_ctxt); + *sss_ctxt = NULL; +@@ -301,14 +288,47 @@ static int setautomntent_wait(unsigned int logopt, + + if (retry > retries) + ret = ETIMEDOUT; +- +- estr = strerror_r(ret, buf, MAX_ERR_BUF); +- error(logopt, MODPREFIX "setautomntent: %s", estr); + } + + return ret; + } + ++static int setautomntent(unsigned int logopt, ++ struct lookup_context *ctxt, void **sss_ctxt) ++{ ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ int ret; ++ ++ ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); ++ if (ret) { ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; ++ ++ if (ret != ENOENT) ++ goto error; ++ ++ ret = setautomntent_wait(logopt, ctxt, sss_ctxt); ++ if (ret) { ++ if (ret == ECONNREFUSED) ++ return NSS_STATUS_UNKNOWN; ++ if (ret == ENOENT) ++ return NSS_STATUS_NOTFOUND; ++ goto error; ++ } ++ } ++ return ret; ++ ++error: ++ estr = strerror_r(ret, buf, MAX_ERR_BUF); ++ error(logopt, MODPREFIX "setautomntent: %s", estr); ++ if (*sss_ctxt) { ++ free(*sss_ctxt); ++ *sss_ctxt = NULL; ++ } ++ return NSS_STATUS_UNAVAIL; ++} ++ + static int endautomntent(unsigned int logopt, + struct lookup_context *ctxt, void **sss_ctxt) + { +@@ -336,28 +356,8 @@ int lookup_read_master(struct master *master, time_t age, void *context) + int count, ret; + + ret = setautomntent(logopt, ctxt, &sss_ctxt); +- if (ret) { +- unsigned int retries; +- +- if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- +- if (ret != ENOENT) +- return NSS_STATUS_UNAVAIL; +- +- retries = defaults_get_sss_master_map_wait(); +- if (retries <= 0) +- return NSS_STATUS_NOTFOUND; +- +- ret = setautomntent_wait(logopt, ctxt, &sss_ctxt, retries); +- if (ret) { +- if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- if (ret == ENOENT) +- return NSS_STATUS_NOTFOUND; +- return NSS_STATUS_UNAVAIL; +- } +- } ++ if (ret) ++ return ret; + + count = 0; + while (1) { +@@ -459,13 +459,8 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + } + + ret = setautomntent(ap->logopt, ctxt, &sss_ctxt); +- if (ret) { +- if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- if (ret == ENOENT) +- return NSS_STATUS_NOTFOUND; +- return NSS_STATUS_UNAVAIL; +- } ++ if (ret) ++ return ret; + + count = 0; + while (1) { +@@ -571,13 +566,8 @@ static int lookup_one(struct autofs_point *ap, + mc = source->mc; + + ret = setautomntent(ap->logopt, ctxt, &sss_ctxt); +- if (ret) { +- if (ret == ECONNREFUSED) +- return NSS_STATUS_UNKNOWN; +- if (ret == ENOENT) +- return NSS_STATUS_NOTFOUND; +- return NSS_STATUS_UNAVAIL; +- } ++ if (ret) ++ return ret; + + ret = ctxt->getautomntbyname_r(qKey, &value, sss_ctxt); + if (ret && ret != ENOENT) { diff --git a/autofs-5.1.6-remove-force-parameter-from-umount_all.patch b/autofs-5.1.6-remove-force-parameter-from-umount_all.patch new file mode 100644 index 0000000..16c1d63 --- /dev/null +++ b/autofs-5.1.6-remove-force-parameter-from-umount_all.patch @@ -0,0 +1,63 @@ +autofs-5.1.6 - remove force parameter from umount_all() + +From: Ian Kent + +The function umount_all() is always called with it's force parameter +true so remove it. + +Because the failure case is not used make the function void as well. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 9 +++------ + 2 files changed, 4 insertions(+), 6 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -125,6 +125,7 @@ xx/xx/2018 autofs-5.1.5 + - use mnt_list for submounts. + - use mnt_list for amdmounts. + - make umount_autofs() static. ++- remove force parameter from umount_all(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -99,7 +99,6 @@ pthread_key_t key_thread_attempt_id = (p + + int aquire_flag_file(void); + void release_flag_file(void); +-static int umount_all(struct autofs_point *ap, int force); + + extern struct master *master_list; + +@@ -710,16 +709,14 @@ int umount_multi(struct autofs_point *ap + return left; + } + +-static int umount_all(struct autofs_point *ap, int force) ++static void umount_all(struct autofs_point *ap) + { + int left; + + left = umount_multi(ap, ap->path, 0); +- if (force && left) ++ if (left) + warn(ap->logopt, "could not unmount %d dirs under %s", + left, ap->path); +- +- return left; + } + + static int umount_autofs(struct autofs_point *ap, const char *root) +@@ -737,7 +734,7 @@ static int umount_autofs(struct autofs_p + lookup_close_lookup(ap); + + if (ap->type == LKP_INDIRECT) { +- umount_all(ap, 1); ++ umount_all(ap); + ret = umount_autofs_indirect(ap, root); + } else + ret = umount_autofs_direct(ap); diff --git a/autofs-5.1.6-remove-intr-hosts-map-mount-option.patch b/autofs-5.1.6-remove-intr-hosts-map-mount-option.patch new file mode 100644 index 0000000..4b6e188 --- /dev/null +++ b/autofs-5.1.6-remove-intr-hosts-map-mount-option.patch @@ -0,0 +1,113 @@ +autofs-5.1.6 - remove intr hosts map mount option + +From: Ian Kent + +Don't use the intr option on NFS mounts by default, it's been ignored +by the kernel for a long time now. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/auto.master.5.in | 4 ++-- + man/autofs.5 | 4 ++-- + modules/parse_sun.c | 9 +++------ + samples/auto.misc | 2 +- + samples/auto.net | 2 +- + 6 files changed, 10 insertions(+), 12 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -77,6 +77,7 @@ + - add missing description of null map option. + - fix empty mounts list return from unlink_mount_tree(). + - fix nonstrict offset mount fail handling. ++- remove intr hosts map mount option. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/man/auto.master.5.in ++++ autofs-5.1.4/man/auto.master.5.in +@@ -260,8 +260,8 @@ For example, with an entry in the master + accessing /net/myserver will mount exports from myserver on directories below + /net/myserver. + .P +-NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options +-unless overridden by explicitly specifying the "suid", "dev" or "nointr" options in the ++NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev" options ++unless overridden by explicitly specifying the "suid", "dev" options in the + master map entry. + .SH BUILTIN MAP \-null + If "\-null" is given as the map it is used to tell automount(8) to ignore a subsequent +--- autofs-5.1.4.orig/man/autofs.5 ++++ autofs-5.1.4/man/autofs.5 +@@ -86,13 +86,13 @@ Indirect map: + .RS +.2i + .ta 1.0i 3.0i + .nf +-kernel \-ro,soft,intr ftp.kernel.org:/pub/linux ++kernel \-ro,soft ftp.kernel.org:/pub/linux + boot \-fstype=ext2 :/dev/hda1 + windoze \-fstype=smbfs ://windoze/c + removable \-fstype=ext2 :/dev/hdd + cd \-fstype=iso9660,ro :/dev/hdc + floppy \-fstype=auto :/dev/fd0 +-server \-rw,hard,intr / \-ro myserver.me.org:/ \\ ++server \-rw,hard / \-ro myserver.me.org:/ \\ + /usr myserver.me.org:/usr \\ + /home myserver.me.org:/home + .fi +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -628,10 +628,9 @@ static int sun_mount(struct autofs_point + int len = strlen(options); + int suid = strstr(options, "suid") ? 0 : 7; + int dev = strstr(options, "dev") ? 0 : 6; +- int nointr = strstr(options, "nointr") ? 0 : 5; + +- if (suid || dev || nointr) { +- char *tmp = alloca(len + suid + dev + nointr + 1); ++ if (suid || dev) { ++ char *tmp = alloca(len + suid + dev + 1); + if (!tmp) { + error(ap->logopt, MODPREFIX + "alloca failed for options"); +@@ -645,8 +644,6 @@ static int sun_mount(struct autofs_point + strcat(tmp, ",nosuid"); + if (dev) + strcat(tmp, ",nodev"); +- if (nointr) +- strcat(tmp, ",intr"); + options = tmp; + } + } else { +@@ -658,7 +655,7 @@ static int sun_mount(struct autofs_point + return -1; + return 1; + } +- strcpy(tmp, "nosuid,nodev,intr"); ++ strcpy(tmp, "nosuid,nodev"); + options = tmp; + } + } +--- autofs-5.1.4.orig/samples/auto.misc ++++ autofs-5.1.4/samples/auto.misc +@@ -6,7 +6,7 @@ + cd -fstype=iso9660,ro,nosuid,nodev :/dev/cdrom + + # the following entries are samples to pique your imagination +-#linux -ro,soft,intr ftp.example.org:/pub/linux ++#linux -ro,soft ftp.example.org:/pub/linux + #boot -fstype=ext2 :/dev/hda1 + #floppy -fstype=auto :/dev/fd0 + #floppy -fstype=ext2 :/dev/fd0 +--- autofs-5.1.4.orig/samples/auto.net ++++ autofs-5.1.4/samples/auto.net +@@ -9,7 +9,7 @@ key="$1" + + # add "nosymlink" here if you want to suppress symlinking local filesystems + # add "nonstrict" to make it OK for some filesystems to not mount +-opts="-fstype=nfs,hard,intr,nodev,nosuid" ++opts="-fstype=nfs,hard,nodev,nosuid" + + for P in /bin /sbin /usr/bin /usr/sbin + do diff --git a/autofs-5.1.6-remove-logpri-fifo-on-autofs-mount-fail.patch b/autofs-5.1.6-remove-logpri-fifo-on-autofs-mount-fail.patch new file mode 100644 index 0000000..23c8bfc --- /dev/null +++ b/autofs-5.1.6-remove-logpri-fifo-on-autofs-mount-fail.patch @@ -0,0 +1,36 @@ +autofs-5.1.6 - remove logpri fifo on autofs mount fail + +From: Ian Kent + +Don't leave log priority command fifo file around on autofs mount failure. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -88,6 +88,7 @@ xx/xx/2018 autofs-5.1.5 + - fix incorrect logical compare in unlink_mount_tree(). + - use bit flag for force unlink mounts. + - improve force unlink option description. ++- remove command fifo on autofs mount fail. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1161,8 +1161,10 @@ static int mount_autofs(struct autofs_po + else + status = mount_autofs_indirect(ap, root); + +- if (status < 0) ++ if (status < 0) { ++ destroy_logpri_fifo(ap); + return -1; ++ } + + st_add_task(ap, ST_READY); + diff --git a/autofs-5.1.6-remove-unused-function-tree_get_mnt_list.patch b/autofs-5.1.6-remove-unused-function-tree_get_mnt_list.patch new file mode 100644 index 0000000..b0c7bb3 --- /dev/null +++ b/autofs-5.1.6-remove-unused-function-tree_get_mnt_list.patch @@ -0,0 +1,366 @@ +autofs-5.1.6 - remove unused function tree_get_mnt_list() + +From: Ian Kent + +Remove the now unused function tree_get_mnt_list() and friends. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/mounts.h | 17 --- + lib/mounts.c | 299 ------------------------------------------------------- + 3 files changed, 1 insertion(+), 316 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -130,6 +130,7 @@ xx/xx/2018 autofs-5.1.5 + - fix stale offset directories disable mount. + - use struct mnt_list to track mounted mounts. + - use struct mnt_list mounted list for expire. ++- remove unused function tree_get_mnt_list(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -83,20 +83,8 @@ struct mnt_list { + * 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; + }; + +- + struct nfs_mount_vers { + unsigned int major; + unsigned int minor; +@@ -143,11 +131,6 @@ void mnts_set_mounted_mount(struct autof + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +-void tree_free_mnt_tree(struct mnt_list *tree); +-struct mnt_list *tree_make_mnt_tree(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); + void set_tsd_user_vars(unsigned int, uid_t, gid_t); + const char *mount_type_str(unsigned int); + void set_exp_timeout(struct autofs_point *ap, struct map_source *source, time_t timeout); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1685,305 +1685,6 @@ int is_mounted(const char *mp, unsigned + return table_is_mounted(mp, type); + } + +-/* +- * Since we have to look at the entire mount tree for direct +- * mounts (all mounts under "/") and we may have a large number +- * of entries to traverse again and again we need to +- * use a more efficient method than the routines above. +- * +- * Thre tree_... routines allow us to read the mount tree +- * once and pass it to subsequent functions for use. Since +- * it's a tree structure searching should be a low overhead +- * operation. +- */ +-void tree_free_mnt_tree(struct mnt_list *tree) +-{ +- struct list_head *head, *p; +- +- if (!tree) +- return; +- +- tree_free_mnt_tree(tree->left); +- tree_free_mnt_tree(tree->right); +- +- head = &tree->self; +- p = head->next; +- while (p != head) { +- struct mnt_list *this; +- +- this = list_entry(p, struct mnt_list, self); +- +- p = p->next; +- +- list_del(&this->self); +- +- free(this->mp); +- +- free(this); +- } +- +- free(tree->mp); +- free(tree); +-} +- +-/* +- * Make tree of system mounts in /proc/mounts. +- */ +-struct mnt_list *tree_make_mnt_tree(const char *path) +-{ +- FILE *tab; +- struct mntent mnt_wrk; +- char buf[PATH_MAX * 3]; +- struct mntent *mnt; +- struct mnt_list *ent, *mptr; +- struct mnt_list *tree = NULL; +- size_t plen; +- int eq; +- +- tab = open_fopen_r(_PROC_MOUNTS); +- if (!tab) { +- char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("fopen: %s", estr); +- return NULL; +- } +- +- plen = strlen(path); +- +- while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { +- size_t len = strlen(mnt->mnt_dir); +- +- /* Not matching path */ +- if (strncmp(mnt->mnt_dir, path, plen)) +- continue; +- +- /* Not a subdirectory of requested path */ +- if (plen > 1 && len > plen && mnt->mnt_dir[plen] != '/') +- continue; +- +- ent = malloc(sizeof(*ent)); +- if (!ent) { +- endmntent(tab); +- tree_free_mnt_tree(tree); +- return NULL; +- } +- memset(ent, 0, sizeof(*ent)); +- +- INIT_LIST_HEAD(&ent->self); +- INIT_LIST_HEAD(&ent->list); +- INIT_LIST_HEAD(&ent->entries); +- INIT_LIST_HEAD(&ent->sublist); +- +- ent->mp = malloc(len + 1); +- if (!ent->mp) { +- endmntent(tab); +- free(ent); +- tree_free_mnt_tree(tree); +- return NULL; +- } +- strcpy(ent->mp, mnt->mnt_dir); +- +- if (!strcmp(mnt->mnt_type, "autofs")) +- ent->flags |= MNTS_AUTOFS; +- +- if (ent->flags & MNTS_AUTOFS) { +- if (strstr(mnt->mnt_opts, "indirect")) +- ent->flags |= MNTS_INDIRECT; +- else if (strstr(mnt->mnt_opts, "direct")) +- ent->flags |= MNTS_DIRECT; +- else if (strstr(mnt->mnt_opts, "offset")) +- ent->flags |= MNTS_OFFSET; +- } +- +- mptr = tree; +- while (mptr) { +- int elen = strlen(ent->mp); +- int mlen = strlen(mptr->mp); +- +- if (elen < mlen) { +- if (mptr->left) { +- mptr = mptr->left; +- continue; +- } else { +- mptr->left = ent; +- break; +- } +- } else if (elen > mlen) { +- if (mptr->right) { +- mptr = mptr->right; +- continue; +- } else { +- mptr->right = ent; +- break; +- } +- } +- +- eq = strcmp(ent->mp, mptr->mp); +- if (eq < 0) { +- if (mptr->left) +- mptr = mptr->left; +- else { +- mptr->left = ent; +- break; +- } +- } else if (eq > 0) { +- if (mptr->right) +- mptr = mptr->right; +- else { +- mptr->right = ent; +- break; +- } +- } else { +- list_add_tail(&ent->self, &mptr->self); +- break; +- } +- } +- +- if (!tree) +- tree = ent; +- } +- fclose(tab); +- +- return tree; +-} +- +-/* +- * Get list of mounts under "path" in longest->shortest order +- */ +-int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include) +-{ +- size_t mlen, plen; +- +- if (!mnts) +- return 0; +- +- plen = strlen(path); +- mlen = strlen(mnts->mp); +- if (mlen < plen) +- return tree_get_mnt_list(mnts->right, list, path, include); +- else { +- struct list_head *self, *p; +- +- tree_get_mnt_list(mnts->left, list, path, include); +- +- if ((!include && mlen <= plen) || +- strncmp(mnts->mp, path, plen)) +- goto skip; +- +- if (plen > 1 && mlen > plen && mnts->mp[plen] != '/') +- goto skip; +- +- INIT_LIST_HEAD(&mnts->list); +- list_add(&mnts->list, list); +- +- self = &mnts->self; +- list_for_each(p, self) { +- struct mnt_list *this; +- +- this = list_entry(p, struct mnt_list, self); +- INIT_LIST_HEAD(&this->list); +- list_add(&this->list, list); +- } +-skip: +- tree_get_mnt_list(mnts->right, list, path, include); +- } +- +- if (list_empty(list)) +- return 0; +- +- return 1; +-} +- +-/* +- * Get list of mounts under "path" in longest->shortest order +- */ +-int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include) +-{ +- size_t mlen, plen; +- +- if (!mnts) +- return 0; +- +- plen = strlen(path); +- mlen = strlen(mnts->mp); +- if (mlen < plen) +- return tree_get_mnt_sublist(mnts->right, list, path, include); +- else { +- struct list_head *self, *p; +- +- tree_get_mnt_sublist(mnts->left, list, path, include); +- +- if ((!include && mlen <= plen) || +- strncmp(mnts->mp, path, plen)) +- goto skip; +- +- if (plen > 1 && mlen > plen && mnts->mp[plen] != '/') +- goto skip; +- +- INIT_LIST_HEAD(&mnts->sublist); +- list_add(&mnts->sublist, list); +- +- self = &mnts->self; +- list_for_each(p, self) { +- struct mnt_list *this; +- +- this = list_entry(p, struct mnt_list, self); +- INIT_LIST_HEAD(&this->sublist); +- list_add(&this->sublist, list); +- } +-skip: +- tree_get_mnt_sublist(mnts->right, list, path, include); +- } +- +- if (list_empty(list)) +- return 0; +- +- return 1; +-} +- +-int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path) +-{ +- int mlen, plen; +- +- if (!mnts) +- return 0; +- +- plen = strlen(path); +- mlen = strlen(mnts->mp); +- if (mlen < plen) +- return tree_find_mnt_ents(mnts->right, list, path); +- else if (mlen > plen) +- return tree_find_mnt_ents(mnts->left, list, path); +- else { +- struct list_head *self, *p; +- +- tree_find_mnt_ents(mnts->left, list, path); +- +- if (!strcmp(mnts->mp, path)) { +- INIT_LIST_HEAD(&mnts->entries); +- list_add(&mnts->entries, list); +- } +- +- self = &mnts->self; +- list_for_each(p, self) { +- struct mnt_list *this; +- +- this = list_entry(p, struct mnt_list, self); +- +- if (!strcmp(this->mp, path)) { +- INIT_LIST_HEAD(&this->entries); +- list_add(&this->entries, list); +- } +- } +- +- tree_find_mnt_ents(mnts->right, list, path); +- +- if (!list_empty(list)) +- return 1; +- } +- +- return 0; +-} +- + void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid) + { + struct thread_stdenv_vars *tsv; diff --git a/autofs-5.1.6-simplify-sss-source-stale-check.patch b/autofs-5.1.6-simplify-sss-source-stale-check.patch new file mode 100644 index 0000000..16adf90 --- /dev/null +++ b/autofs-5.1.6-simplify-sss-source-stale-check.patch @@ -0,0 +1,120 @@ +autofs-5.1.6 - simplify sss source stale check + +From: Ian Kent + +Now that there's a positive timeout on valid map cache entries +simplifying the map stale checks should be able to be done, and +eventually this will be much simpler in a lot of places. + +Start with the key lookup in the sss lookup module since that's +needed to prevent recently retrieved map keys from being pruned +immediately after being used since the existing check wasn't +working and was questionable anyway (and likely hadn't for worked +some time). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 47 ++++++++++------------------------------------- + 2 files changed, 11 insertions(+), 37 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 34b160e..e9c7a59 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -110,6 +110,7 @@ xx/xx/2018 autofs-5.1.5 + - improve sss getautomntbyname() error handling. + - use a valid timeout in lookup_prune_one_cache(). + - dont prune offset map entries. ++- simplify sss source stale check. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 70efc11..69be765 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -869,7 +869,7 @@ static int lookup_one(struct autofs_point *ap, + time_t age = monotonic_time(NULL); + char *value = NULL; + char *s_key; +- int ret; ++ int err, ret; + + source = ap->entry->current; + ap->entry->current = NULL; +@@ -901,8 +901,11 @@ static int lookup_one(struct autofs_point *ap, + goto wild; + } + cache_writelock(mc); +- ret = cache_update(mc, source, s_key, value, age); ++ err = cache_update(mc, source, s_key, value, age); + cache_unlock(mc); ++ /* Entry in map but not in cache, map is stale */ ++ if (err & CHE_UPDATED) ++ source->stale = 1; + endautomntent(ap->logopt, ctxt, &sss_ctxt); + free(s_key); + free(value); +@@ -952,12 +955,12 @@ wild: + } + + cache_writelock(mc); +- /* Wildcard not in map but now is */ +- we = cache_lookup_distinct(mc, "*"); +- if (!we) +- source->stale = 1; +- ret = cache_update(mc, source, "*", value, age); ++ /* Wildcard in map but not in cache, update it */ ++ err = cache_update(mc, source, "*", value, age); + cache_unlock(mc); ++ /* Wildcard in map but not in cache, map is stale */ ++ if (err & CHE_UPDATED) ++ source->stale = 1; + + endautomntent(ap->logopt, ctxt, &sss_ctxt); + free(value); +@@ -971,9 +974,6 @@ static int check_map_indirect(struct autofs_point *ap, + { + struct map_source *source; + struct mapent_cache *mc; +- struct mapent *me; +- time_t now = monotonic_time(NULL); +- time_t t_last_read; + int ret, cur_state; + + source = ap->entry->current; +@@ -1009,33 +1009,6 @@ static int check_map_indirect(struct autofs_point *ap, + } + pthread_setcancelstate(cur_state, NULL); + +- /* +- * Check for map change and update as needed for +- * following cache lookup. +- */ +- cache_readlock(mc); +- t_last_read = ap->exp_runfreq + 1; +- me = cache_lookup_first(mc); +- while (me) { +- if (me->source == source) { +- t_last_read = now - me->age; +- break; +- } +- me = cache_lookup_next(mc, me); +- } +- cache_unlock(mc); +- +- if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED) +- source->stale = 1; +- +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, "*"); +- if (ret == CHE_MISSING && (!me || me->source != source)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; +- } +- cache_unlock(mc); +- + return NSS_STATUS_SUCCESS; + } + diff --git a/autofs-5.1.6-sss-introduce-a-flag-to-indicate-map-being-read.patch b/autofs-5.1.6-sss-introduce-a-flag-to-indicate-map-being-read.patch new file mode 100644 index 0000000..18c420b --- /dev/null +++ b/autofs-5.1.6-sss-introduce-a-flag-to-indicate-map-being-read.patch @@ -0,0 +1,235 @@ +autofs-5.1.6 - sss introduce a flag to indicate map being read + +From: Ian Kent + +When the master map is being read for the first time a retry loop is +used by the caller to try harder to read the master map because it +is required for autofs to start up. + +But when re-reading the master map, reading dependent maps, or doing +key lookups that loop isn't used so a longer retry is needed for those +cases. + +Introduce a flag to indicate which map is being read, or if the master +map is being re-read, or if a key lookup is being done so the number +of retries can be adjusted accordingly. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 87 +++++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 72 insertions(+), 16 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 4a6c042..2d98a3a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -104,6 +104,7 @@ xx/xx/2018 autofs-5.1.5 + - improve sss getautomntent() error handling. + - sss introduce calculate_retry_count() function. + - move readall into struct master. ++- sss introduce a flag to indicate map being read. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 29666a3..3c0ffde 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -53,6 +53,24 @@ + */ + #define SSS_PROTO_VERSION 1 + ++#define SSS_DEFAULT_WAIT 10 ++ ++/* When the master map is being read a retry loop is used by the ++ * caller to try harder to read the master map because it is required ++ * for autofs to start up. ++ * ++ * But when reading dependent maps or looking up a key that loop isn't ++ * used so a longer retry is needed for those cases. ++ * ++ * Introduce a flag to indicate which map is being read or if a lookup ++ * is being done so the number of retries can be adjusted accordingly. ++ */ ++#define SSS_READ_NONE 0x00 ++#define SSS_READ_MASTER_MAP 0x01 ++#define SSS_REREAD_MASTER_MAP 0x02 ++#define SSS_READ_DEPENDENT_MAP 0x04 ++#define SSS_LOOKUP_KEY 0x08 ++ + unsigned int _sss_auto_protocol_version(unsigned int); + int _sss_setautomntent(const char *, void **); + int _sss_getautomntent_r(char **, char **, void *); +@@ -249,7 +267,7 @@ static unsigned int proto_version(struct lookup_context *ctxt) + return proto_version; + } + +-static unsigned int calculate_retry_count(struct lookup_context *ctxt) ++static unsigned int calculate_retry_count(struct lookup_context *ctxt, unsigned int flags) + { + int retries; + +@@ -269,15 +287,39 @@ static unsigned int calculate_retry_count(struct lookup_context *ctxt) + * a host being down, return 0 for retries. + */ + if (proto_version(ctxt) == 0) +- retries = 0; ++ return 0; + else +- retries = 10; ++ retries = SSS_DEFAULT_WAIT; + } ++ ++ if (proto_version(ctxt) == 0) ++ return retries; ++ ++ /* When the master map is being read there's an additional ++ * outer wait loop. ++ * ++ * If master map wait is set in the configuration there ++ * will be an outer loop interating master_map_wait / 2 ++ * times so adjust the number of retries here to account ++ * for this for the cases where the master map isn't being ++ * read. ++ */ ++ ++ if (!(flags & SSS_READ_MASTER_MAP) || ++ (flags & SSS_REREAD_MASTER_MAP)) { ++ unsigned int master_map_wait = defaults_get_master_wait(); ++ unsigned int m_wait; ++ ++ m_wait = master_map_wait ? master_map_wait : SSS_DEFAULT_WAIT; ++ retries *= (m_wait / 2); ++ } ++ + return retries; + } + + static int setautomntent_wait(unsigned int logopt, +- struct lookup_context *ctxt, void **sss_ctxt) ++ struct lookup_context *ctxt, void **sss_ctxt, ++ unsigned int flags) + { + unsigned int retries; + unsigned int retry = 0; +@@ -285,7 +327,7 @@ static int setautomntent_wait(unsigned int logopt, + + *sss_ctxt = NULL; + +- retries = calculate_retry_count(ctxt); ++ retries = calculate_retry_count(ctxt, flags); + if (retries == 0) { + if (proto_version(ctxt) == 0) + return EINVAL; +@@ -333,7 +375,8 @@ static int setautomntent_wait(unsigned int logopt, + } + + static int setautomntent(unsigned int logopt, +- struct lookup_context *ctxt, void **sss_ctxt) ++ struct lookup_context *ctxt, void **sss_ctxt, ++ unsigned int flags) + { + char buf[MAX_ERR_BUF]; + char *estr; +@@ -355,7 +398,7 @@ static int setautomntent(unsigned int logopt, + goto error; + } + +- ret = setautomntent_wait(logopt, ctxt, sss_ctxt); ++ ret = setautomntent_wait(logopt, ctxt, sss_ctxt, flags); + if (ret) { + if (ret == ECONNREFUSED) { + err = NSS_STATUS_UNKNOWN; +@@ -400,13 +443,14 @@ static int endautomntent(unsigned int logopt, + + static int getautomntent_wait(unsigned int logopt, + struct lookup_context *ctxt, +- char **key, char **value, void *sss_ctxt) ++ char **key, char **value, void *sss_ctxt, ++ unsigned int flags) + { + unsigned int retries; + unsigned int retry = 0; + int ret = 0; + +- retries = calculate_retry_count(ctxt); ++ retries = calculate_retry_count(ctxt, flags); + if (retries == 0) { + if (proto_version(ctxt) == 0) + return EINVAL; +@@ -446,7 +490,8 @@ static int getautomntent_wait(unsigned int logopt, + + static int getautomntent(unsigned int logopt, + struct lookup_context *ctxt, +- char **key, char **value, int count, void *sss_ctxt) ++ char **key, char **value, int count, ++ void *sss_ctxt, unsigned int flags) + { + char buf[MAX_ERR_BUF]; + char *estr; +@@ -486,7 +531,7 @@ static int getautomntent(unsigned int logopt, + } + + ret = getautomntent_wait(logopt, ctxt, +- key, value, sss_ctxt); ++ key, value, sss_ctxt, flags); + if (ret) { + if (ret == ECONNREFUSED) { + err = NSS_STATUS_UNKNOWN; +@@ -534,8 +579,13 @@ int lookup_read_master(struct master *master, time_t age, void *context) + char *key; + char *value = NULL; + int count, ret; ++ unsigned int flags; ++ ++ flags = SSS_READ_MASTER_MAP; ++ if (master->readall) ++ flags |= SSS_REREAD_MASTER_MAP; + +- ret = setautomntent(logopt, ctxt, &sss_ctxt); ++ ret = setautomntent(logopt, ctxt, &sss_ctxt, flags); + if (ret) + return ret; + +@@ -543,7 +593,9 @@ int lookup_read_master(struct master *master, time_t age, void *context) + while (1) { + key = NULL; + value = NULL; +- ret = getautomntent(logopt, ctxt, &key, &value, count, sss_ctxt); ++ ret = getautomntent(logopt, ctxt, ++ &key, &value, count, ++ sss_ctxt, SSS_READ_MASTER_MAP); + if (ret) { + endautomntent(logopt, ctxt, &sss_ctxt); + return ret; +@@ -622,7 +674,8 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_SUCCESS; + } + +- ret = setautomntent(ap->logopt, ctxt, &sss_ctxt); ++ ret = setautomntent(ap->logopt, ctxt, ++ &sss_ctxt, SSS_READ_DEPENDENT_MAP); + if (ret) + return ret; + +@@ -630,7 +683,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + while (1) { + key = NULL; + value = NULL; +- ret = getautomntent(ap->logopt, ctxt, &key, &value, count, sss_ctxt); ++ ret = getautomntent(ap->logopt, ctxt, ++ &key, &value, count, ++ sss_ctxt, SSS_READ_DEPENDENT_MAP); + if (ret) { + endautomntent(ap->logopt, ctxt, &sss_ctxt); + return ret; +@@ -711,7 +766,7 @@ static int lookup_one(struct autofs_point *ap, + + mc = source->mc; + +- ret = setautomntent(ap->logopt, ctxt, &sss_ctxt); ++ ret = setautomntent(ap->logopt, ctxt, &sss_ctxt, SSS_LOOKUP_KEY); + if (ret) + return ret; + diff --git a/autofs-5.1.6-sss-introduce-retries-calcuation-function.patch b/autofs-5.1.6-sss-introduce-retries-calcuation-function.patch new file mode 100644 index 0000000..0661da6 --- /dev/null +++ b/autofs-5.1.6-sss-introduce-retries-calcuation-function.patch @@ -0,0 +1,133 @@ +autofs-5.1.6 - sss introduce calculate_retry_count() function + +From: Ian Kent + +Add a function calculate_retry_count() to consolidate the calculation +of the retry count into a single location. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 62 ++++++++++++++++++++++++++++++-------------------- + 2 files changed, 38 insertions(+), 25 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 434e23d..4d83df2 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -102,6 +102,7 @@ xx/xx/2018 autofs-5.1.5 + - improve sss setautomntent() error handling. + - refactor sss getautomntent(). + - improve sss getautomntent() error handling. ++- sss introduce calculate_retry_count() function. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index f366b48..29666a3 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -249,14 +249,9 @@ static unsigned int proto_version(struct lookup_context *ctxt) + return proto_version; + } + +-static int setautomntent_wait(unsigned int logopt, +- struct lookup_context *ctxt, void **sss_ctxt) ++static unsigned int calculate_retry_count(struct lookup_context *ctxt) + { +- unsigned int retries; +- unsigned int retry = 0; +- int ret = 0; +- +- *sss_ctxt = NULL; ++ int retries; + + retries = defaults_get_sss_master_map_wait(); + +@@ -264,14 +259,37 @@ static int setautomntent_wait(unsigned int logopt, + * configuration give it a sensible value since we + * want to wait for a host that's down in case it + * comes back up. ++ * ++ * Use the sss_master_map_wait configuration option ++ * for the time to wait when reading a dependednt map ++ * or performing a key lookup too. + */ + if (retries <= 0) { + /* Protocol version 0 cant't tell us about +- * a host being down, return not found. ++ * a host being down, return 0 for retries. + */ + if (proto_version(ctxt) == 0) +- return ENOENT; +- retries = 10; ++ retries = 0; ++ else ++ retries = 10; ++ } ++ return retries; ++} ++ ++static int setautomntent_wait(unsigned int logopt, ++ struct lookup_context *ctxt, void **sss_ctxt) ++{ ++ unsigned int retries; ++ unsigned int retry = 0; ++ int ret = 0; ++ ++ *sss_ctxt = NULL; ++ ++ retries = calculate_retry_count(ctxt); ++ if (retries == 0) { ++ if (proto_version(ctxt) == 0) ++ return EINVAL; ++ return ENOENT; + } + + warn(logopt, +@@ -345,6 +363,9 @@ static int setautomntent(unsigned int logopt, + } + if (ret == ETIMEDOUT) + goto error; ++ /* sss proto version 0 and sss timeout not set */ ++ if (ret == EINVAL) ++ goto free; + if (ret == ENOENT) { + err = NSS_STATUS_NOTFOUND; + goto free; +@@ -385,21 +406,11 @@ static int getautomntent_wait(unsigned int logopt, + unsigned int retry = 0; + int ret = 0; + +- retries = defaults_get_sss_master_map_wait(); +- +- /* Use the sss_master_map_wait configuration option +- * for the time to wait when reading a map too. If +- * it isn't set in the antofs configuration give it +- * a sensible value since we want to wait for a host +- * that's down in case it comes back up. +- */ +- if (retries <= 0) { +- /* Protocol version 0 cant't tell us about +- * a host being down, return not found. +- */ ++ retries = calculate_retry_count(ctxt); ++ if (retries == 0) { + if (proto_version(ctxt) == 0) +- return ENOENT; +- retries = 10; ++ return EINVAL; ++ return ENOENT; + } + + warn(logopt, +@@ -483,7 +494,8 @@ static int getautomntent(unsigned int logopt, + } + if (ret == ETIMEDOUT) + goto error; +- if (ret == ENOENT) { ++ /* sss proto version 0 and sss timeout not set => EINVAL */ ++ if (ret == ENOENT || ret == EINVAL) { + err = NSS_STATUS_NOTFOUND; + if (count) + err = NSS_STATUS_SUCCESS; diff --git a/autofs-5.1.6-update-ldap-READMEs-and-schema-definitions.patch b/autofs-5.1.6-update-ldap-READMEs-and-schema-definitions.patch new file mode 100644 index 0000000..b0003df --- /dev/null +++ b/autofs-5.1.6-update-ldap-READMEs-and-schema-definitions.patch @@ -0,0 +1,841 @@ +autofs-5.1.6 - update ldap READMEs and schema definitions + +From: Ian Kent + +The autofs schema in samples/autofs.schema should not be used for +autofs map information, it's very old and may be inaccurate or may +conflict with other schema definitions included in LDAP server +distributions. + +The README.autofs-schema has been updated to alert people to this +but the schema file has not yet been removed. + +A new README.ldap-schema has been added which recommends using either +of rfc2307 or rfc2307bis schema for autofs Sun format map information +stored in LDAP and at least one of these schema should be included in +LDAP server distributions. Additionally the README notes the schema +that needs to be used for autofs amd format maps is present in the +file samples/am-utils-ldap.schema. + +Ian + +Signed-off-by: Ian Kent +--- + README.autofs-schema | 8 + README.ldap-schema | 14 + + samples/am-utils-ldap-id.txt | 360 +++++++++++++++++++++++++++++++++++++++++++ + samples/am-utils-ldap.schema | 52 ++++++ + samples/rfc2307.schema | 37 ++++ + samples/rfc2307bis.schema | 310 +++++++++++++++++++++++++++++++++++++ + 6 files changed, 777 insertions(+), 4 deletions(-) + create mode 100644 README.ldap-schema + create mode 100644 samples/am-utils-ldap-id.txt + create mode 100644 samples/am-utils-ldap.schema + create mode 100644 samples/rfc2307.schema + create mode 100644 samples/rfc2307bis.schema + +--- autofs-5.1.4.orig/README.autofs-schema ++++ autofs-5.1.4/README.autofs-schema +@@ -9,10 +9,10 @@ not clear what schema to use for Linux a + + The schema was corrected somewhere along the line but the autofs + distribution copy was never updated. The schema has now been +-updated but it is not recommended for use as the schema for autofs +-map information. ++updated but may not be accurate and may conflict with other LDAP ++schemas so it is not recommended for use for autofs map information. + +-The rfc2307 or, preferably the, rfc2307bis schema is the recommened +-schema to use. ++The rfc2307 or the rfc2307bis schema is the recommened schema to ++use, based on requirements. + + Ian +--- /dev/null ++++ autofs-5.1.4/README.ldap-schema +@@ -0,0 +1,14 @@ ++LDAP Schema ++=========== ++ ++LDAP Schema definitions may be found in the samples sub-directory. ++ ++The ldap schema rfc2307.schema and rfc2307bis.schema may be used by ++autofs for Sun format automount maps, the choice of which is used is ++dependent on user needs. They are included for reference only as at ++least one of these should be included in LDAP server distributions. ++ ++The ldap schema am-utils-ldap.schema and am-utils-ldap-id.txt describe ++the schema used by autofs for amd format maps. ++ ++Ian +--- /dev/null ++++ autofs-5.1.4/samples/am-utils-ldap-id.txt +@@ -0,0 +1,360 @@ ++ ++ ++ ++ ++ ++ ++INTERNET-DRAFT Leif Johansson ++Intented Category: Experimental Stockholm University ++ ++ ++ ++ A directory (X.500 and LDAPv3) schema for Berkely automounter ++ ++ ++1. Status of this Memo ++ ++ This memo describes a directory (LDAP or X.500) schema for storing amd (Berkely- ++ style automounter) mount info maps. The schema is currently beeing supported by ++ the (beta version of the) am-utils version 6 package [AMUTILS]. ++ ++2. Overview and Rationale ++ ++ Directory services such as X.500 [X500] or LDAP [RFC2251] are a natural choice of ++ repository for amd mount map databases. All Object Identifiers in this document ++ are prefixed by amdSchema-id to be assigned later. The relation between this ++ schema and the automount schema elements in [HOWARD] are mostly superficial. The ++ model for the elements in [HOWARD] was the SUN automounter which has quite a ++ different syntax for mount maps. Furthermore the intended usage of this schema ++ differs from that of [HOWARD] in many respects. ++ ++3. DSA requirements ++ ++ Directory servers implementing this schema SHOULD maintain the modifyTimestamp ++ operational attribute. If not the amdMapCacheTtl attribute SHOULD be set to 0 ++ indicating to clients that caching of map entries SHOULD be turned off. Clients ++ wishing to use the amdMap schema MAY use the modifyTimestamp information to set ++ the ttl for internal caching schemes. A value of 0 for the amdMapCacheTtl must ++ result in clients turning off any local caching. ++ ++4. Syntax definitions ++ ++ The following attribute syntax is defined in this document: ++ ++ amdlocationlist ++ ++ This syntax represents a amd map value. This is the syntax expressed in BNF using ++ definitions from [RFC2252]: ++ ++ amdlocationlist = amdlocationselection | ++ amdlocationlist whsp "||" whsp amdlocationselection ++ ++ amdlocationselection = amdlocation | ++ amdlocationselection whsp amdlocation ++ ++ ++ ++ ++Johansson [Page 1] ++ ++ ++ ++ ++ ++Internet draft Berkeley AMD LDAP Schema 30 March 1998 ++ ++ ++ amdlocation = amdlocationinfo | ++ "-" amdlocationinfo | ++ "-" ++ ++ amdlocationinfo = seloropt | ++ amdlocationinfo ";" seloropt | ++ ";" ++ ++ seloropt = seletion | ++ optass ++ ++ selection = keystring "==" printablestring ++ keystring "!=" printablestring ++ ++ optass = keystring ++ ++ X.500 servers or LDAPv3 servers (supporting the binary attribute option) may use ++ the following syntax definition: ++ ++ AmdLocationList ::= SEQUENCE OF { ++ SEQUENCE OF { ++ location AmdLocation ++ } ++ } ++ ++ AmdLocation ::= SET OF { ++ CHOICE { ++ location [0] AmdLocationInfo ++ notlocation [1] AmdLocationInfo ++ not [2] NULL ++ } ++ } ++ ++ AmdLocationInfo ::= SET OF { ++ CHOICE { ++ selection [0] AmdSelection ++ option [1] AmdOption ++ } ++ } ++ ++ AmdSelection ::= CHOICE { ++ eq [0] AttributeAndValue ++ ne [1] AttributeAndValue ++ } ++ ++ AmdOption ::= AttributeAndValue ++ AttributeAndValue ::= SEQUENCE { ++ attribute IA5String ++ ++ ++ ++Johansson [Page 2] ++ ++ ++ ++ ++ ++Internet draft Berkeley AMD LDAP Schema 30 March 1998 ++ ++ ++ value IA5String ++ } ++ ++5. Attribute types ++ ++ The following attribute types are defined in this document: ++ ++ amdMapName ++ amdMapCacheTtl ++ amdMapEntry ++ amdMapEntryKey ++ amdMapEntryValue ++ ++ amdSchema-a OBJECT IDENTIFIER ::= { amdSchema-id 1 } ++ ++ amdMapName ATTRIBUTE ::= { ++ WITH SYNTAX IA5String ++ EQUALITY MATCHING RULE caseIgoreExactMatch ++ --ID { amdSchema-a 1 } ++ DESCRIPTION ++ "This attribute is the symbolic and in the naming ++ context unique name of an amd map. This corresponds ++ in the case of a flat file database to the name of ++ the file or the mount-point of the map." ++ } ++ ++ ++ amdMapCacheTtl ++ ATTRIBUTE ::= { ++ WITH SYNTAX Integer ++ EQUALITY MATCHING RULE integerExactMatch ++ --ID { amdSchema-a 2 } ++ SINGLE VALUED ++ DESCRIPTION ++ "The maximum time-to-live for the entries in this ++ map. After this many milliseconds the map has to ++ be cleared from local caches and reloaded. A value ++ of 0 disables caching." ++ } ++ ++ amdMapEntry ++ ATTRIBUTE ::= { ++ WITH SYNTAX DistinguishedName ++ EQUALITY MATHCING RULE dNCaseIgnoreExactMatch ++ --ID { amdSchema-a 3 } ++ DESCRIPTION ++ "A multivalued attribute listing the distinguished ++ names of the amdMapEntries making up this amdMap ++ ++ ++ ++Johansson [Page 3] ++ ++ ++ ++ ++ ++Internet draft Berkeley AMD LDAP Schema 30 March 1998 ++ ++ ++ object." ++ } ++ ++ amdMapEntryKey ::= { ++ ATTRIBUTE ::= { ++ WITH SYNTAX IA5String ++ EQUALITY MATCHING RULE stringExactMatch ++ --ID { amdSchema-a 4 } ++ SINGLE VALUED ++ DESCRIPTION ++ "The value of this attribute is usually the name of ++ a mountpoint for this amdMapEntry." ++ } ++ ++ amdMapEntryValue ::= { ++ ATTRIBUTE ::= { ++ WITH SYNTAX AmdLocationList ++ --ID { amdSchema-a 5 } ++ DESCRIPTION ++ "This is the actual mount information for the amdMapEntry ++ using the syntax described above." ++ } ++ ++ amdMapEntryKey ::= { ++ ATTRIBUTE ::= { ++ WITH SYNTAX IA5String ++ EQUALITY MATCHING RULE stringExactMatch ++ --ID { amdSchema-a 4 } ++ SINGLE VALUED ++ DESCRIPTION ++ "The value of this attribute is usually the name of ++ a mountpoint for this amdMapEntry." ++ } ++ ++ amdMapEntryValue ::= { ++ ATTRIBUTE ::= { ++ WITH SYNTAX AmdLocationList ++ --ID { amdSchema-a 5 } ++ DESCRIPTION ++ "This is the actual mount information for the amdMapEntry ++ using the syntax described above." ++ } ++ ++6. Object classes ++ ++ The following object classes are defined in this document: ++ ++ amdMap ++ ++ ++ ++Johansson [Page 4] ++ ++ ++ ++ ++ ++Internet draft Berkeley AMD LDAP Schema 30 March 1998 ++ ++ ++ amdMapEntry ++ ++ defined as follows: ++ ++ amdSchema-oc ::= { amdSchema-id 2 } ++ ++ amdMap OBJECT-CLASS ::= { ++ SUBCLASS OF { top } ++ KIND auxiliary ++ --ID { amdSchema-oc 1 } ++ MAY CONTAIN { amdMapCacheTtl , cn } ++ MUST CONTAIN { amdMapName , amdMapEntry } ++ } ++ ++ amdMapEntry OBJECT-CLASS ::= { ++ SUBCLASS OF { top } ++ KIND structural ++ --ID { amdSchema-oc 2 } ++ MUST CONTAIN { ++ amdMapName , ++ amdEntryKey , ++ amdEntryValue , ++ } MAY CONTAIN ++ { cn } DESCRIPTION "An entry of this ++ object class describes mount information relative to a ++ certain amdMap entry" ++ } ++ ++7. Examples ++ ++ ++ ++8. Security Considerations ++ ++ Due to the security problems posed by NFS care should be taken not to advertise ++ exported filesystems. Therefore it is often desirable to limit access to entries ++ carrying amd mount map information to those systems to which the corresponding ++ filesystems have been exported. ++ ++9. References ++ ++ [AMUTILS] ++ am-utils homepage: http://shekel.cs.columbia.edu/~erez/am-utils.html ++ ++ [RFC2251] ++ M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access ++ Protocol (v3)", RFC 2251, December 1997. ++ ++ ++ ++ ++Johansson [Page 5] ++ ++ ++ ++ ++ ++Internet draft Berkeley AMD LDAP Schema 30 March 1998 ++ ++ ++ [RFC2252] ++ M. Wahl, A. Coulbeck, T. Howes, S. Kille, "Lightweight Directory ++ Access Protocol (v3): Attribute Syntax Definitions", RFC 2252, ++ December 1997. ++ ++ [RFC2253] ++ M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access ++ Protocol (v3): UTF-8 String Representation of Distinguished ++ Names", RFC 2253, December 1997. ++ ++ [HOWARD] ++ Luke Howard, "An Approach for Using LDAP as a Network ++ Information Service", draft-howard-nis-schema-??.txt, Internet ++ draft. ++ ++ [X500] ++ ITU something or other. ++ ++ ++ ++Author's Address ++ ++ ++ Leif Johansson ++ Department of Mathematics ++ Stockholm University ++ S-106 91 Stockholm ++ SWEDEN ++ ++ Email: leifj AT matematik.su.se ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Johansson [Page 6] ++ ++ +--- /dev/null ++++ autofs-5.1.4/samples/am-utils-ldap.schema +@@ -0,0 +1,52 @@ ++# A schema for the Berkeley automounter (AMD) ++# Authored by Erez Zadok and/or source maintainers ++# Definition by Tim Colles ++# Revised by Adam Morley ++ ++# OID Base is 1.3.6.1.4.1.10180 ++# ++# Syntaxes are under 1.3.6.1.4.1.10180.3.175-199 ++# Attribute types are under 1.3.6.1.4.1.10180.2.175-199 ++# Object classes are under 1.3.6.1.4.1.10180.1.175-199 ++ ++# Attribute Type Definitions ++ ++attributetype ( 1.3.6.1.4.1.10180.2.175 ++ NAME 'amdmapTimestamp' ++ DESC 'Probably the time the map was last modified' ++ EQUALITY integerMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributetype ( 1.3.6.1.4.1.10180.2.176 ++ NAME 'amdmapName' ++ DESC 'The symbolic name of the map, ie. map_name' ++ EQUALITY caseIgnoreMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ++ SINGLE-VALUE ) ++ ++attributetype ( 1.3.6.1.4.1.10180.2.177 ++ NAME 'amdmapKey' ++ DESC 'The key value for this entry' ++ EQUALITY caseIgnoreMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ++ SINGLE-VALUE ) ++ ++attributetype ( 1.3.6.1.4.1.10180.2.178 ++ NAME 'amdmapValue' ++ DESC 'The mount information for this entry' ++ EQUALITY caseIgnoreMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ++ SINGLE-VALUE ) ++ ++# Object Class Definitions ++ ++objectclass ( 1.3.6.1.4.1.10180.1.175 NAME 'amdmapTimestamp' ++ SUP top STRUCTURAL ++ DESC 'Timestamp for an AMD map' ++ MUST ( cn $ amdmapName $ amdmapTimestamp ) ) ++ ++objectclass ( 1.3.6.1.4.1.10180.1.176 NAME 'amdmap' ++ SUP top STRUCTURAL ++ DESC 'Defines an AMD map entry' ++ MUST ( cn $ amdmapName $ amdmapKey $ amdmapValue ) ) +--- /dev/null ++++ autofs-5.1.4/samples/rfc2307.schema +@@ -0,0 +1,37 @@ ++attributeType ( 1.3.6.1.1.1.1.31 ++ NAME 'automountMapName' ++ DESC 'automount Map Name' ++ EQUALITY caseExactIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ++ X-ORIGIN 'user defined' ) ++ ++attributeType ( 1.3.6.1.1.1.1.32 ++ NAME 'automountKey' ++ DESC 'Automount Key value' ++ EQUALITY caseExactIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ++ X-ORIGIN 'user defined' ) ++ ++attributeType ( 1.3.6.1.1.1.1.33 ++ NAME 'automountInformation' ++ DESC 'Automount information' ++ EQUALITY caseExactIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ++ X-ORIGIN 'user defined' ) ++ ++objectClass ( 1.3.6.1.1.1.2.16 ++ NAME 'automountMap' ++ DESC 'Automount Map information' ++ SUP top STRUCTURAL ++ MUST automountMapName ++ MAY description ++ X-ORIGIN 'user defined' ) ++ ++objectClass ( 1.3.6.1.1.1.2.17 ++ NAME 'automount' ++ DESC 'Automount information' ++ SUP top STRUCTURAL ++ MUST ( automountKey $ automountInformation ) ++ MAY description ++ X-ORIGIN 'user defined' ) ++ +--- /dev/null ++++ autofs-5.1.4/samples/rfc2307bis.schema +@@ -0,0 +1,310 @@ ++### ++# Extracted from: http://tools.ietf.org/html/draft-howard-rfc2307bis-02 ++### ++ ++# Builtin ++#attributeType ( 1.3.6.1.1.1.1.0 NAME 'uidNumber' ++# DESC 'An integer uniquely identifying a user in an ++# administrative domain' ++# EQUALITY integerMatch ++# ORDERING integerOrderingMatch ++# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++# SINGLE-VALUE ) ++ ++# Builtin ++#attributeType ( 1.3.6.1.1.1.1.1 NAME 'gidNumber' ++# DESC 'An integer uniquely identifying a group in an ++# administrative domain' ++# EQUALITY integerMatch ++# ORDERING integerOrderingMatch ++# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++# SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.2 NAME 'gecos' ++ DESC 'The GECOS field; the common name' ++ EQUALITY caseIgnoreMatch ++ SUBSTR caseIgnoreSubstringsMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory' ++ DESC 'The absolute path to the home directory' ++ EQUALITY caseExactIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.4 NAME 'loginShell' ++ DESC 'The path to the login shell' ++ EQUALITY caseExactIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.6 NAME 'shadowMin' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.7 NAME 'shadowMax' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.12 NAME 'memberUid' ++ EQUALITY caseExactMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) ++ ++attributeType ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup' ++ EQUALITY caseExactMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) ++ ++attributeType ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' ++ DESC 'Netgroup triple' ++ EQUALITY caseIgnoreMatch ++ SUBSTR caseIgnoreSubstringsMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) ++ ++attributeType ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort' ++ DESC 'Service port number' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol' ++ DESC 'Service protocol name' ++ EQUALITY caseIgnoreMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) ++ ++attributeType ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber' ++ DESC 'IP protocol number' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber' ++ DESC 'ONC RPC number' ++ EQUALITY integerMatch ++ ORDERING integerOrderingMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber' ++ DESC 'IPv4 addresses as a dotted decimal omitting leading ++ zeros or IPv6 addresses as defined in RFC2373' ++ EQUALITY caseIgnoreIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) ++ ++attributeType ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber' ++ DESC 'IP network omitting leading zeros, eg. 192.168' ++ EQUALITY caseIgnoreIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber' ++ DESC 'IP netmask omitting leading zeros, eg. 255.255.255.0' ++ EQUALITY caseIgnoreIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.22 NAME 'macAddress' ++ DESC 'MAC address in maximal, colon separated hex ++ notation, eg. 00:00:92:90:ee:e2' ++ EQUALITY caseIgnoreIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) ++ ++attributeType ( 1.3.6.1.1.1.1.23 NAME 'bootParameter' ++ DESC 'rpc.bootparamd parameter' ++ EQUALITY caseExactIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) ++ ++attributeType ( 1.3.6.1.1.1.1.24 NAME 'bootFile' ++ DESC 'Boot image name' ++ EQUALITY caseExactIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) ++ ++attributeType ( 1.3.6.1.1.1.1.26 NAME 'nisMapName' ++ DESC 'Name of a generic NIS map' ++ EQUALITY caseIgnoreMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} ) ++ ++attributeType ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry' ++ DESC 'A generic NIS entry' ++ EQUALITY caseExactMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey' ++ DESC 'NIS public key' ++ EQUALITY octetStringMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey' ++ DESC 'NIS secret key' ++ EQUALITY octetStringMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.30 NAME 'nisDomain' ++ DESC 'NIS domain' ++ EQUALITY caseIgnoreIA5Match ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) ++ ++attributeType ( 1.3.6.1.1.1.1.31 NAME 'automountMapName' ++ DESC 'automount Map Name' ++ EQUALITY caseExactMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.32 NAME 'automountKey' ++ DESC 'Automount Key value' ++ EQUALITY caseExactMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ++ SINGLE-VALUE ) ++ ++attributeType ( 1.3.6.1.1.1.1.33 NAME 'automountInformation' ++ DESC 'Automount information' ++ EQUALITY caseExactMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ++ SINGLE-VALUE ) ++ ++objectClass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY ++ DESC 'Abstraction of an account with POSIX attributes' ++ MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) ++ MAY ( userPassword $ loginShell $ gecos $ ++ description ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' SUP top AUXILIARY ++ DESC 'Additional attributes for shadow passwords' ++ MUST uid ++ MAY ( userPassword $ description $ ++ shadowLastChange $ shadowMin $ shadowMax $ ++ shadowWarning $ shadowInactive $ ++ shadowExpire $ shadowFlag ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top AUXILIARY ++ DESC 'Abstraction of a group of accounts' ++ MUST gidNumber ++ MAY ( userPassword $ memberUid $ ++ description ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL ++ DESC 'Abstraction an Internet Protocol service. ++ Maps an IP port and protocol (such as tcp or udp) ++ to one or more names; the distinguished value of ++ the cn attribute denotes the services canonical ++ name' ++ MUST ( cn $ ipServicePort $ ipServiceProtocol ) ++ MAY description ) ++ ++objectClass ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL ++ DESC 'Abstraction of an IP protocol. Maps a protocol number ++ to one or more names. The distinguished value of the cn ++ attribute denotes the protocol canonical name' ++ MUST ( cn $ ipProtocolNumber ) ++ MAY description ) ++ ++objectClass ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL ++ DESC 'Abstraction of an Open Network Computing (ONC) ++ [RFC1057] Remote Procedure Call (RPC) binding. ++ This class maps an ONC RPC number to a name. ++ The distinguished value of the cn attribute denotes ++ the RPC service canonical name' ++ MUST ( cn $ oncRpcNumber ) ++ MAY description ) ++ ++objectClass ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY ++ DESC 'Abstraction of a host, an IP device. The distinguished ++ value of the cn attribute denotes the hosts canonical ++ name. Device SHOULD be used as a structural class' ++ MUST ( cn $ ipHostNumber ) ++ MAY ( userPassword $ l $ description $ ++ manager ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL ++ DESC 'Abstraction of a network. The distinguished value of ++ the cn attribute denotes the network canonical name' ++ MUST ipNetworkNumber ++ MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL ++ DESC 'Abstraction of a netgroup. May refer to other ++ netgroups' ++ MUST cn ++ MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.9 NAME 'nisMap' SUP top STRUCTURAL ++ DESC 'A generic abstraction of a NIS map' ++ MUST nisMapName ++ MAY description ) ++ ++objectClass ( 1.3.6.1.1.1.2.10 NAME 'nisObject' SUP top STRUCTURAL ++ DESC 'An entry in a NIS map' ++ MUST ( cn $ nisMapEntry $ nisMapName ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' SUP top AUXILIARY ++ DESC 'A device with a MAC address; device SHOULD be ++ used as a structural class' ++ MAY macAddress ) ++ ++objectClass ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' SUP top AUXILIARY ++ DESC 'A device with boot parameters; device SHOULD be ++ used as a structural class' ++ MAY ( bootFile $ bootParameter ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' SUP top AUXILIARY ++ DESC 'An object with a public and secret key' ++ MUST ( cn $ nisPublicKey $ nisSecretKey ) ++ MAY ( uidNumber $ description ) ) ++ ++objectClass ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP top AUXILIARY ++ DESC 'Associates a NIS domain with a naming context' ++ MUST nisDomain ) ++ ++objectClass ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL ++ MUST ( automountMapName ) ++ MAY description ) ++ ++objectClass ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL ++ DESC 'Automount information' ++ MUST ( automountKey $ automountInformation ) ++ MAY description ) ++ ++objectClass ( 1.3.6.1.1.1.2.18 NAME 'groupOfMembers' SUP top STRUCTURAL ++ DESC 'A group with members (DNs)' ++ MUST cn ++ MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ ++ description $ member ) ) diff --git a/autofs-5.1.6-update-list_h.patch b/autofs-5.1.6-update-list_h.patch new file mode 100644 index 0000000..5843b37 --- /dev/null +++ b/autofs-5.1.6-update-list_h.patch @@ -0,0 +1,513 @@ +autofs-5.1.6 - update list.h + +From: Ian Kent + +Update autofs include/list.h mostly to include the hlist +implementation but also to simplify bits of it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/list.h | 402 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 378 insertions(+), 25 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -116,6 +116,7 @@ xx/xx/2018 autofs-5.1.5 + - fix additional typing errors. + - make bind mounts propagation slave by default. + - fix browse dir not re-created on symlink expire. ++- update list.h. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/include/list.h ++++ autofs-5.1.4/include/list.h +@@ -1,6 +1,27 @@ + #ifndef _LINUX_LIST_H + #define _LINUX_LIST_H + ++#include ++ ++/* ++ * Casts a member of a structure out to the containing structure ++ * @param ptr the pointer to the member. ++ * @param type the type of the container struct this is embedded in. ++ * @param member the name of the member within the struct. ++ * ++ */ ++#define container_of(ptr, type, member) ({ \ ++ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ++ (type *)( (char *)__mptr - offsetof(type,member) );}) ++ ++/* ++ * These are non-NULL pointers that will result in page faults ++ * under normal circumstances, used to verify that nobody uses ++ * non-initialized list entries. ++ */ ++#define LIST_POISON1 ((void *) 0x00100100) ++#define LIST_POISON2 ((void *) 0x00200200) ++ + /* + * Simple doubly linked list implementation. + * +@@ -25,14 +46,14 @@ struct list_head { + } while (0) + + /* +- * Insert a new entry between two known consecutive entries. ++ * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +-static __inline__ void __list_add(struct list_head * new, +- struct list_head * prev, +- struct list_head * next) ++static inline void __list_add(struct list_head *new, ++ struct list_head *prev, ++ struct list_head *next) + { + next->prev = new; + new->next = next; +@@ -48,7 +69,7 @@ static __inline__ void __list_add(struct + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +-static __inline__ void list_add(struct list_head *new, struct list_head *head) ++static inline void list_add(struct list_head *new, struct list_head *head) + { + __list_add(new, head, head->next); + } +@@ -61,7 +82,7 @@ static __inline__ void list_add(struct l + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +-static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) ++static inline void list_add_tail(struct list_head *new, struct list_head *head) + { + __list_add(new, head->prev, head); + } +@@ -73,8 +94,7 @@ static __inline__ void list_add_tail(str + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +-static __inline__ void __list_del(struct list_head * prev, +- struct list_head * next) ++static inline void __list_del(struct list_head * prev, struct list_head * next) + { + next->prev = prev; + prev->next = next; +@@ -83,50 +103,96 @@ static __inline__ void __list_del(struct + /** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. +- * Note: list_empty on entry does not return true after this, the entry is in an undefined state. ++ * Note: list_empty on entry does not return true after this, the entry is ++ * in an undefined state. + */ +-static __inline__ void list_del(struct list_head *entry) ++static inline void list_del(struct list_head *entry) + { + __list_del(entry->prev, entry->next); ++ entry->next = LIST_POISON1; ++ entry->prev = LIST_POISON2; + } + + /** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +-static __inline__ void list_del_init(struct list_head *entry) ++static inline void list_del_init(struct list_head *entry) + { + __list_del(entry->prev, entry->next); +- INIT_LIST_HEAD(entry); ++ INIT_LIST_HEAD(entry); ++} ++ ++/* ++ * list_move - delete from one list and add as another's head ++ * @list: the entry to move ++ * @head: the head that will precede our entry ++ */ ++static inline void list_move(struct list_head *list, struct list_head *head) ++{ ++ __list_del(list->prev, list->next); ++ list_add(list, head); ++} ++ ++/** ++ * list_move_tail - delete from one list and add as another's tail ++ * @list: the entry to move ++ * @head: the head that will follow our entry ++ */ ++static inline void list_move_tail(struct list_head *list, ++ struct list_head *head) ++{ ++ __list_del(list->prev, list->next); ++ list_add_tail(list, head); + } + + /** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +-static __inline__ int list_empty(struct list_head *head) ++static inline int list_empty(const struct list_head *head) + { + return head->next == head; + } + ++static inline void __list_splice(struct list_head *list, ++ struct list_head *head) ++{ ++ struct list_head *first = list->next; ++ struct list_head *last = list->prev; ++ struct list_head *at = head->next; ++ ++ first->prev = head; ++ head->next = first; ++ ++ last->next = at; ++ at->prev = last; ++} ++ + /** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +-static __inline__ void list_splice(struct list_head *list, struct list_head *head) ++static inline void list_splice(struct list_head *list, struct list_head *head) + { +- struct list_head *first = list->next; +- +- if (first != list) { +- struct list_head *last = list->prev; +- struct list_head *at = head->next; +- +- first->prev = head; +- head->next = first; ++ if (!list_empty(list)) ++ __list_splice(list, head); ++} + +- last->next = at; +- at->prev = last; ++/** ++ * list_splice_init - join two lists and reinitialise the emptied list. ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ * ++ * The list at @list is reinitialised ++ */ ++static inline void list_splice_init(struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) { ++ __list_splice(list, head); ++ INIT_LIST_HEAD(list); + } + } + +@@ -137,7 +203,45 @@ static __inline__ void list_splice(struc + * @member: the name of the list_struct within the struct. + */ + #define list_entry(ptr, type, member) \ +- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) ++ container_of(ptr, type, member) ++ ++/** ++ * list_first_entry - get the first element from a list ++ * @ptr: the list head to take the element from. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_head within the struct. ++ * ++ * Note, that list is expected to be not empty. ++ */ ++#define list_first_entry(ptr, type, member) \ ++ list_entry((ptr)->next, type, member) ++ ++/** ++ * list_last_entry - get the last element from a list ++ * @ptr: the list head to take the element from. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_head within the struct. ++ * ++ * Note, that list is expected to be not empty. ++ */ ++#define list_last_entry(ptr, type, member) \ ++ list_entry((ptr)->prev, type, member) ++ ++/** ++ * list_next_entry - get the next element in list ++ * @pos: the type * to cursor ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_next_entry(pos, member) \ ++ list_entry((pos)->member.next, typeof(*(pos)), member) ++ ++/** ++ * list_prev_entry - get the prev element in list ++ * @pos: the type * to cursor ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_prev_entry(pos, member) \ ++ list_entry((pos)->member.prev, typeof(*(pos)), member) + + /** + * list_for_each - iterate over a list +@@ -155,4 +259,252 @@ static __inline__ void list_splice(struc + #define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + ++/** ++ * list_for_each_safe - iterate over a list safe against removal of list entry ++ * @pos: the &struct list_head to use as a loop counter. ++ * @n: another &struct list_head to use as temporary storage ++ * @head: the head for your list. ++ */ ++#define list_for_each_safe(pos, n, head) \ ++ for (pos = (head)->next, n = pos->next; pos != (head); \ ++ pos = n, n = pos->next) ++ ++/** ++ * list_for_each_entry - iterate over list of given type ++ * @pos: the type * to use as a loop counter. ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry(pos, head, member) \ ++ for (pos = list_entry((head)->next, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = list_next_entry(pos, member)) ++ ++/** ++ * list_for_each_entry_reverse - iterate backwards over list of given type. ++ * @pos: the type * to use as a loop counter. ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry_reverse(pos, head, member) \ ++ for (pos = list_last_entry(head, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = list_prev_entry(pos, member)) ++ ++/** ++ * list_prepare_entry - prepare a pos entry for use as a start point in ++ * list_for_each_entry_continue ++ * @pos: the type * to use as a start point ++ * @head: the head of the list ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_prepare_entry(pos, head, member) \ ++ ((pos) ? : list_entry(head, typeof(*pos), member)) ++ ++/** ++ * list_for_each_entry_continue - iterate over list of given type ++ * continuing after existing point ++ * @pos: the type * to use as a loop counter. ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry_continue(pos, head, member) \ ++ for (pos = list_next_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = list_next_entry(pos, member)) ++ ++/** ++ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry ++ * @pos: the type * to use as a loop counter. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry_safe(pos, n, head, member) \ ++ for (pos = list_first_entry(head, typeof(*pos), member), \ ++ n = list_next_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_next_entry(n, member)) ++ ++/** ++ * list_for_each_entry_safe_continue - iterate over list of given type ++ * continuing after existing point safe against removal of list entry ++ * @pos: the type * to use as a loop counter. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry_safe_continue(pos, n, head, member) \ ++ for (pos = list_next_entry(pos, member), \ ++ n = list_next_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_next_entry(n, member)) ++ ++/** ++ * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against ++ * removal of list entry ++ * @pos: the type * to use as a loop counter. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry_safe_reverse(pos, n, head, member) \ ++ for (pos = list_last_entry(head, typeof(*pos), member), \ ++ n = list_prev_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_prev_entry(n, member)) ++ ++ ++ ++ ++/* ++ * Double linked lists with a single pointer list head. ++ * Mostly useful for hash tables where the two pointer list head is ++ * too wasteful. ++ * You lose the ability to access the tail in O(1). ++ */ ++ ++struct hlist_head { ++ struct hlist_node *first; ++}; ++ ++struct hlist_node { ++ struct hlist_node *next, **pprev; ++}; ++ ++#define HLIST_HEAD_INIT { .first = NULL } ++#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } ++#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) ++#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL) ++ ++static inline int hlist_unhashed(const struct hlist_node *h) ++{ ++ return !h->pprev; ++} ++ ++static inline int hlist_empty(const struct hlist_head *h) ++{ ++ return !h->first; ++} ++ ++static inline void __hlist_del(struct hlist_node *n) ++{ ++ struct hlist_node *next = n->next; ++ struct hlist_node **pprev = n->pprev; ++ *pprev = next; ++ if (next) ++ next->pprev = pprev; ++} ++ ++static inline void hlist_del(struct hlist_node *n) ++{ ++ __hlist_del(n); ++ n->next = LIST_POISON1; ++ n->pprev = LIST_POISON2; ++} ++ ++ ++static inline void hlist_del_init(struct hlist_node *n) ++{ ++ if (n->pprev) { ++ __hlist_del(n); ++ INIT_HLIST_NODE(n); ++ } ++} ++ ++static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) ++{ ++ struct hlist_node *first = h->first; ++ n->next = first; ++ if (first) ++ first->pprev = &n->next; ++ h->first = n; ++ n->pprev = &h->first; ++} ++ ++ ++ ++/* next must be != NULL */ ++static inline void hlist_add_before(struct hlist_node *n, ++ struct hlist_node *next) ++{ ++ n->pprev = next->pprev; ++ n->next = next; ++ next->pprev = &n->next; ++ *(n->pprev) = n; ++} ++ ++static inline void hlist_add_after(struct hlist_node *n, ++ struct hlist_node *next) ++{ ++ next->next = n->next; ++ n->next = next; ++ next->pprev = &n->next; ++ ++ if(next->next) ++ next->next->pprev = &next->next; ++} ++ ++ ++ ++#define hlist_entry(ptr, type, member) container_of(ptr,type,member) ++ ++#define hlist_for_each(pos, head) \ ++ for (pos = (head)->first; pos; pos = pos->next) ++ ++#define hlist_for_each_safe(pos, n, head) \ ++ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ ++ pos = n) ++ ++#define hlist_entry_safe(ptr, type, member) \ ++ ({ typeof(ptr) ____ptr = (ptr); \ ++ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ ++ }) ++ ++/** ++ * hlist_for_each_entry - iterate over list of given type ++ * @tpos: the type * to use as a loop counter. ++ * @pos: the &struct hlist_node to use as a loop counter. ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry(pos, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ ++ pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++/** ++ * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point ++ * @tpos: the type * to use as a loop counter. ++ * @pos: the &struct hlist_node to use as a loop counter. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_continue(pos, member) \ ++ for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ ++ pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++/** ++ * hlist_for_each_entry_from - iterate over a hlist continuing from existing point ++ * @tpos: the type * to use as a loop counter. ++ * @pos: the &struct hlist_node to use as a loop counter. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_from(pos, member) \ ++ for (; pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++/** ++ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry ++ * @tpos: the type * to use as a loop counter. ++ * @pos: the &struct hlist_node to use as a loop counter. ++ * @n: another &struct hlist_node to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ ++ pos && ({ n = pos->next; 1; }) && \ ++ pos = hlist_entry_safe(n, typeof(*pos), member)) ++ + #endif diff --git a/autofs-5.1.6-update-sss-timeout-documentation.patch b/autofs-5.1.6-update-sss-timeout-documentation.patch new file mode 100644 index 0000000..0954604 --- /dev/null +++ b/autofs-5.1.6-update-sss-timeout-documentation.patch @@ -0,0 +1,155 @@ +autofs-5.1.6 - update sss timeout documentation + +From: Ian Kent + +Update then man page documentation and the configuration file +comments to reflect the changes to map reading and key lookups +with the sss lookup module. +--- + CHANGELOG | 1 + + man/autofs.conf.5.in | 20 +++++++++++++------- + redhat/autofs.conf.default.in | 28 +++++++++++++++++++--------- + samples/autofs.conf.default.in | 26 ++++++++++++++++++-------- + 4 files changed, 51 insertions(+), 24 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2d98a3a..e48e2c0 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -105,6 +105,7 @@ xx/xx/2018 autofs-5.1.5 + - sss introduce calculate_retry_count() function. + - move readall into struct master. + - sss introduce a flag to indicate map being read. ++- update sss timeout documentation. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in +index 8dbc313..57dd421 100644 +--- a/man/autofs.conf.5.in ++++ b/man/autofs.conf.5.in +@@ -31,9 +31,11 @@ overrides this and sets the timeout to 5 minutes to be consistent + with earlier autofs releases. + .TP + .B master_wait +-sets the default maximum time to wait for the master map to become +-available if it cannot be read at program start (program default 10, +-wait for 10 seconds then continue). ++Sets the default maximum number of retries (actaul iterations is half ++this, each is delayed by 2 seconds before retrying) waiting for the ++master map to become available if it cannot be read at program start ++(program default 10, then continue). This can be longer if the map ++source itself waits for availability (such as sss). + .TP + .B negative_timeout + .br +@@ -160,10 +162,14 @@ behaviour and so is an opt-in setting. + .TP + .B sss_master_map_wait + .br +-Set the time to wait and retry if sssd returns "no such entry" when starting +-up. When sssd is starting up it can sometimes return "no such entry" for a +-short time until it has read in the LDAP map information. Default is 0 seconds, +-don't wait. ++Set the time to wait and retry if sssd is unable to read the master map ++at program start. Program default is 0 (don't wait) or 10 if sss supports ++returning EHSTDOWN when the provider isn't available. ++ ++If the sss library supports returning EHOSTDOWN when the provider is down ++then this value is how long to wait between retries reading the master map. ++When reading dependent maps or looking up a map key this value is multiplied ++by the number of retries that would be used when reading the master map. + .TP + .B use_mount_request_log_id + .br +diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in +index bd52730..2a5a1c2 100644 +--- a/redhat/autofs.conf.default.in ++++ b/redhat/autofs.conf.default.in +@@ -14,10 +14,13 @@ + # + timeout = 300 + # +-# master_wait - set the default maximum time to wait for the +-# master map to become available if it cannot +-# be read at program start (default 10, wait +-# for 10 seconds then continue). ++# master_wait - set the default maximum number of retries (actual ++# iterations is half this, each is delayed by 2 seconds ++# before retrying) waiting for the master map to become ++# available if it cannot be read at program start ++# (default 10, then continue). This can be longer ++# if the map source itself waits for availability ++# (such as sss). + # + #master_wait = 10 + # +@@ -193,12 +196,19 @@ mount_nfs_default_protocol = 4 + #use_ignore_mount_option = no + # + # sss_master_map_wait - When sssd is starting up it can sometimes return +-# "no such entry" for a short time until it has read ++# "no such entry" for a short time until it has read + # in the LDAP map information. Internal default is 0 +-# seconds, don't wait but if there is a problem with +-# autofs not finding the master map at startup (when +-# it should) then try setting this to 10 to work +-# around it. ++# (don't wait) or 10 if sss supports returning EHSTDOWN. ++# If there is a problem with autofs not finding the ++# master map at startup (when it should) then try setting ++# this to 10 or more. If the sss library supports returning ++# EHOSTDOWN when the provider is down then this value ++# is how long to wait between retries reading the ++# master map. When reading dependent maps or looking ++# up a map key this value is multiplied by the number ++# of retries that would be used when reading the master ++# map. (Default, 0 or 10 if sss suppprts returning ++# EHOSTDOWN). + # + #sss_master_map_wait = 0 + # +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 1f55709..dd716c6 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -14,10 +14,13 @@ + # + timeout = 300 + # +-# master_wait - set the default maximum time to wait for the +-# master map to become available if it cannot +-# be read at program start (default 10, wait +-# for 10 seconds then continue). ++# master_wait - set the default maximum number of retries (actual ++# iterations is half this, each is delayed by 2 seconds ++# before retrying) waiting for the master map to become ++# available if it cannot be read at program start ++# (default 10, then continue). This can be longer ++# if the map source itself waits for availability ++# (such as sss). + # + # master_wait = 10 + # +@@ -194,10 +197,17 @@ browse_mode = no + # sss_master_map_wait - When sssd is starting up it can sometimes return + # "no such entry" for a short time until it has read + # in the LDAP map information. Internal default is 0 +-# seconds, don't wait but if there is a problem with +-# autofs not finding the master map at startup (when +-# it should) then try setting this to 10 to work +-# around it. ++# (don't wait) or 10 if sss supports returning EHSTDOWN. ++# If there is a problem with autofs not finding the ++# master map at startup (when it should) then try setting ++# this to 10 or more. If the sss library supports returning ++# EHOSTDOWN when the provider is down then this value ++# is how long to wait between retries reading the ++# master map. When reading dependent maps or looking ++# up a map key this value is multiplied by the number ++# of retries that would be used when reading the master ++# map. (Default, 0 or 10 if sss suppprts returning ++# EHOSTDOWN). + # + #sss_master_map_wait = 0 + # diff --git a/autofs-5.1.6-use-a-valid-timeout-in-lookup_prune_one_cache.patch b/autofs-5.1.6-use-a-valid-timeout-in-lookup_prune_one_cache.patch new file mode 100644 index 0000000..561f35d --- /dev/null +++ b/autofs-5.1.6-use-a-valid-timeout-in-lookup_prune_one_cache.patch @@ -0,0 +1,78 @@ +autofs-5.1.6 - use a valid timeout in lookup_prune_one_cache() + +From: Ian Kent + +For a very long time the map entry cache has been allowed to grow +without pruning old entries until a map read is needed and there's +been a constant struggle to set the map stale only when really needed +so that in use entries aren't pruned. + +But somewhere along the line that's become broken and the sss error +handling updates don't work properly because of this (or rather don't +work well). + +Add a positive map entry cache timeout so that recently seen map +entries don't get removed in the map read following the lookup that +added them when the map isn't actually read such as with nobrowse +indirect mounts. + +The valid timeout probably should become configurable at some point +too. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 15 +++++++++++++++ + include/automount.h | 1 + + 3 files changed, 17 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 309def2..3608345 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -108,6 +108,7 @@ xx/xx/2018 autofs-5.1.5 + - update sss timeout documentation. + - refactor sss getautomntbyname(). + - improve sss getautomntbyname() error handling. ++- use a valid timeout in lookup_prune_one_cache(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 2b9c7e8..8bf1335 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1354,6 +1354,21 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + continue; + } + ++ if (ap->type == LKP_INDIRECT) { ++ /* If the map hasn't been read (nobrowse ++ * indirect mounts) then keep cached entries ++ * for POSITIVE_TIMEOUT. ++ */ ++ if (!(ap->flags & (MOUNT_FLAG_GHOST | ++ MOUNT_FLAG_AMD_CACHE_ALL))) { ++ time_t until = me->age + POSITIVE_TIMEOUT; ++ if ((long) age - (long) until < 0) { ++ me = cache_enumerate(mc, me); ++ continue; ++ } ++ } ++ } ++ + key = strdup(me->key); + me = cache_enumerate(mc, me); + /* Don't consider any entries with a wildcard */ +diff --git a/include/automount.h b/include/automount.h +index 49c9ff9..bb264a1 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -139,6 +139,7 @@ struct autofs_point; + + #define NULL_MAP_HASHSIZE 64 + #define NEGATIVE_TIMEOUT 10 ++#define POSITIVE_TIMEOUT 120 + #define UMOUNT_RETRIES 8 + #define EXPIRE_RETRIES 3 + diff --git a/autofs-5.1.6-use-bit-flag-for-force-unlink-mounts.patch b/autofs-5.1.6-use-bit-flag-for-force-unlink-mounts.patch new file mode 100644 index 0000000..a850b45 --- /dev/null +++ b/autofs-5.1.6-use-bit-flag-for-force-unlink-mounts.patch @@ -0,0 +1,45 @@ +autofs-5.1.6 - use bit flag for force unlink mounts + +From: Ian Kent + +Change global varaiable do_force_unlink to be a bit flag. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + include/automount.h | 2 ++ + 3 files changed, 4 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -86,6 +86,7 @@ xx/xx/2018 autofs-5.1.5 + - fix direct mount unlink_mount_tree() path. + - fix unlink mounts umount order. + - fix incorrect logical compare in unlink_mount_tree(). ++- use bit flag for force unlink mounts. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -2337,7 +2337,7 @@ int main(int argc, char *argv[]) + break; + + case 'F': +- do_force_unlink = 1; ++ do_force_unlink = UNLINK_AND_CONT; + break; + + case '?': +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -590,6 +590,8 @@ struct autofs_point { + struct list_head submounts; /* List of child submounts */ + }; + ++#define UNLINK_AND_CONT 0x01 ++ + /* Foreably unlink existing mounts at startup. */ + extern int do_force_unlink; + diff --git a/autofs-5.1.6-use-mapname-in-sss-context-for-setautomntent.patch b/autofs-5.1.6-use-mapname-in-sss-context-for-setautomntent.patch new file mode 100644 index 0000000..5eb8e18 --- /dev/null +++ b/autofs-5.1.6-use-mapname-in-sss-context-for-setautomntent.patch @@ -0,0 +1,96 @@ +autofs-5.1.6 - use mapname in sss context for setautomntent() + +From: Ian Kent + +There's no need to pass mapname seperately when calling setautomntent(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 18 +++++++----------- + 2 files changed, 8 insertions(+), 11 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2a45829..1830730 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -95,6 +95,7 @@ xx/xx/2018 autofs-5.1.5 + - fix typo in open_sss_lib(). + - fix sss_master_map_wait timing. + - add sss ECONREFUSED return handling. ++- use mapname in sss context for setautomntent(). + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index c393296..c44c55d 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -206,10 +206,9 @@ int lookup_reinit(const char *mapfmt, + } + + static int setautomntent(unsigned int logopt, +- struct lookup_context *ctxt, const char *mapname, +- void **sss_ctxt) ++ struct lookup_context *ctxt, void **sss_ctxt) + { +- int ret = ctxt->setautomntent(mapname, sss_ctxt); ++ int ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); + if (ret) { + char buf[MAX_ERR_BUF]; + char *estr = strerror_r(ret, buf, MAX_ERR_BUF); +@@ -222,7 +221,6 @@ static int setautomntent(unsigned int logopt, + + static int setautomntent_wait(unsigned int logopt, + struct lookup_context *ctxt, +- const char *mapname, + void **sss_ctxt, unsigned int retries) + { + unsigned int retry = 0; +@@ -234,7 +232,7 @@ static int setautomntent_wait(unsigned int logopt, + struct timespec t = { SSS_WAIT_INTERVAL, 0 }; + struct timespec r; + +- ret = ctxt->setautomntent(mapname, sss_ctxt); ++ ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); + if (ret != ENOENT) + break; + +@@ -293,7 +291,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + char *value = NULL; + int count, ret; + +- ret = setautomntent(logopt, ctxt, ctxt->mapname, &sss_ctxt); ++ ret = setautomntent(logopt, ctxt, &sss_ctxt); + if (ret) { + unsigned int retries; + +@@ -307,9 +305,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + if (retries <= 0) + return NSS_STATUS_NOTFOUND; + +- ret = setautomntent_wait(logopt, +- ctxt, ctxt->mapname, &sss_ctxt, +- retries); ++ ret = setautomntent_wait(logopt, ctxt, &sss_ctxt, retries); + if (ret) { + if (ret == ECONNREFUSED) + return NSS_STATUS_UNKNOWN; +@@ -418,7 +414,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_SUCCESS; + } + +- ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt); ++ ret = setautomntent(ap->logopt, ctxt, &sss_ctxt); + if (ret) { + if (ret == ECONNREFUSED) + return NSS_STATUS_UNKNOWN; +@@ -530,7 +526,7 @@ static int lookup_one(struct autofs_point *ap, + + mc = source->mc; + +- ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt); ++ ret = setautomntent(ap->logopt, ctxt, &sss_ctxt); + if (ret) { + if (ret == ECONNREFUSED) + return NSS_STATUS_UNKNOWN; diff --git a/autofs-5.1.6-use-master_list_empty-for-list-empty-check.patch b/autofs-5.1.6-use-master_list_empty-for-list-empty-check.patch new file mode 100644 index 0000000..0617b06 --- /dev/null +++ b/autofs-5.1.6-use-master_list_empty-for-list-empty-check.patch @@ -0,0 +1,119 @@ +autofs-5.1.6 - use master_list_empty() for list empty check + +From: Ian Kent + +For consistency use the master_list_empty() function for list empty +checks everywhere. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + daemon/master.c | 24 +++++++++++++++++------- + include/master.h | 1 + + 4 files changed, 20 insertions(+), 8 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -134,6 +134,7 @@ xx/xx/2018 autofs-5.1.5 + - only add expre alarm for active mounts. + - move submount check into conditional_alarm_add(). + - move lib/master.c to daemon/master.c. ++- use master_list_empty() for list empty check. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1596,7 +1596,7 @@ static void *statemachine(void *arg) + case SIGUSR2: + master_mutex_lock(); + if (list_empty(&master_list->completed)) { +- if (list_empty(&master_list->mounts)) { ++ if (__master_list_empty(master_list)) { + master_mutex_unlock(); + return NULL; + } +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -1110,7 +1110,7 @@ int master_read_master(struct master *ma + master_mount_mounts(master, age); + } + +- if (list_empty(&master->mounts)) ++ if (__master_list_empty(master)) + warn(logopt, "no mounts in table"); + + master_mutex_unlock(); +@@ -1625,7 +1625,7 @@ int dump_map(struct master *master, cons + { + struct list_head *p, *head; + +- if (list_empty(&master->mounts)) { ++ if (__master_list_empty(master)) { + printf("no master map entries found\n"); + return 1; + } +@@ -1743,7 +1743,7 @@ int master_show_mounts(struct master *ma + printf("global options %s be appended to map entries\n", append); + } + +- if (list_empty(&master->mounts)) { ++ if (__master_list_empty(master)) { + printf("no master map entries found\n\n"); + return 1; + } +@@ -1831,13 +1831,22 @@ int master_show_mounts(struct master *ma + return 1; + } + +-int master_list_empty(struct master *master) ++int __master_list_empty(struct master *master) + { + int res = 0; + +- master_mutex_lock(); + if (list_empty(&master->mounts)) + res = 1; ++ ++ return res; ++} ++ ++int master_list_empty(struct master *master) ++{ ++ int res; ++ ++ master_mutex_lock(); ++ res = __master_list_empty(master); + master_mutex_unlock(); + + return res; +@@ -1859,7 +1868,8 @@ int master_done(struct master *master) + master_free_mapent_sources(entry, 1); + master_free_mapent(entry); + } +- if (list_empty(&master->mounts)) ++ ++ if (__master_list_empty(master)) + res = 1; + + return res; +@@ -1872,7 +1882,7 @@ unsigned int master_get_logopt(void) + + int master_kill(struct master *master) + { +- if (!list_empty(&master->mounts)) ++ if (!master_list_empty(master)) + return 0; + + if (master->name) +--- autofs-5.1.4.orig/include/master.h ++++ autofs-5.1.4/include/master.h +@@ -123,6 +123,7 @@ int master_mount_mounts(struct master *, + int dump_map(struct master *, const char *, const char *); + int master_show_mounts(struct master *); + unsigned int master_get_logopt(void); ++int __master_list_empty(struct master *); + int master_list_empty(struct master *); + int master_done(struct master *); + int master_kill(struct master *); diff --git a/autofs-5.1.6-use-mnt_list-for-amdmounts.patch b/autofs-5.1.6-use-mnt_list-for-amdmounts.patch new file mode 100644 index 0000000..ab4d0f3 --- /dev/null +++ b/autofs-5.1.6-use-mnt_list-for-amdmounts.patch @@ -0,0 +1,547 @@ +autofs-5.1.6 - use mnt_list for amdmounts + +From: Ian Kent + +Use struct mnt_list objects for the list of amd mounts instead of +struct amd_entry. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 48 ++++++++++------------ + daemon/lookup.c | 18 +++++--- + include/automount.h | 2 + include/master.h | 2 + include/mounts.h | 12 +++++ + include/parse_amd.h | 1 + lib/master.c | 36 +---------------- + lib/mounts.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++- + modules/mount_autofs.c | 15 ++++--- + modules/parse_amd.c | 43 +++++++++++++++----- + 11 files changed, 193 insertions(+), 88 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -123,6 +123,7 @@ xx/xx/2018 autofs-5.1.5 + - make external mounts use simpler hashtable. + - add a hash index to mnt_list. + - use mnt_list for submounts. ++- use mnt_list for amdmounts. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -595,7 +595,8 @@ static int umount_subtree_mounts(struct + * it already to ensure it's ok to remove any offset triggers. + */ + if (!is_mm_root && is_mounted(path, MNTS_REAL)) { +- struct amd_entry *entry; ++ struct mnt_list *mnt; ++ + debug(ap->logopt, "unmounting dir = %s", path); + if (umount_ent(ap, path) && + is_mounted(path, MNTS_REAL)) { +@@ -605,16 +606,12 @@ static int umount_subtree_mounts(struct + } + + /* Check for an external mount and umount if possible */ +- mounts_mutex_lock(ap); +- entry = __master_find_amdmount(ap, path); +- if (!entry) { +- mounts_mutex_unlock(ap); +- goto done; ++ mnt = mnts_find_amdmount(path); ++ if (mnt) { ++ umount_amd_ext_mount(ap, mnt->ext_mp); ++ mnts_remove_amdmount(path); ++ mnts_put_mount(mnt); + } +- list_del(&entry->entries); +- mounts_mutex_unlock(ap); +- umount_amd_ext_mount(ap, entry->fs); +- free_amd_entry(entry); + } + done: + return left; +@@ -639,7 +636,8 @@ int umount_multi(struct autofs_point *ap + + /* if this is a symlink we can handle it now */ + if (S_ISLNK(st.st_mode)) { +- struct amd_entry *entry; ++ struct mnt_list *mnt; ++ + if (st.st_dev != ap->dev) { + crit(ap->logopt, + "symlink %s has the wrong device, " +@@ -671,17 +669,15 @@ int umount_multi(struct autofs_point *ap + "mkdir_path %s failed: %s", path, estr); + } + } ++ + /* Check for an external mount and attempt umount if needed */ +- mounts_mutex_lock(ap); +- entry = __master_find_amdmount(ap, path); +- if (!entry) { +- mounts_mutex_unlock(ap); +- return 0; +- } +- list_del(&entry->entries); +- mounts_mutex_unlock(ap); +- umount_amd_ext_mount(ap, entry->fs); +- free_amd_entry(entry); ++ mnt = mnts_find_amdmount(path); ++ if (mnt) { ++ umount_amd_ext_mount(ap, mnt->ext_mp); ++ mnts_remove_amdmount(path); ++ mnts_put_mount(mnt); ++ } ++ + return 0; + } + +@@ -1720,17 +1716,17 @@ static void handle_mounts_cleanup(void * + clean = 1; + + if (submount) { +- struct amd_entry *am; ++ struct mnt_list *mnt; + + /* We are finishing up */ + ap->parent->submnt_count--; + + /* Submount at ap->path belongs to parent submount list. */ + mnts_remove_submount(ap->path); +- am = __master_find_amdmount(ap->parent, ap->path); +- if (am) { +- list_del_init(&am->entries); +- free_amd_entry(am); ++ mnt = mnts_find_amdmount(ap->path); ++ if (mnt) { ++ mnts_remove_amdmount(ap->path); ++ mnts_put_mount(mnt); + } + } + +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -838,7 +838,7 @@ static int lookup_amd_instance(struct au + const char *name, int name_len) + { + struct map_source *instance; +- struct amd_entry *entry; ++ struct mnt_list *mnt; + const char *argv[2]; + const char **pargv = NULL; + int argc = 0; +@@ -861,21 +861,23 @@ static int lookup_amd_instance(struct au + strcpy(m_key, ap->path); + strcat(m_key, "/"); + strcat(m_key, me->multi->key); +- entry = master_find_amdmount(ap, m_key); ++ ++ mnt = mnts_find_amdmount(m_key); + free(m_key); + +- if (!entry) { ++ if (!mnt) { + error(ap->logopt, "expected amd mount entry not found"); + return NSS_STATUS_UNKNOWN; + } + +- if (strcmp(entry->type, "host")) { +- error(ap->logopt, "unexpected map type %s", entry->type); ++ if (strcmp(mnt->amd_type, "host")) { ++ error(ap->logopt, "unexpected map type %s", mnt->amd_type); ++ mnts_put_mount(mnt); + return NSS_STATUS_UNKNOWN; + } + +- if (entry->opts && *entry->opts) { +- argv[0] = entry->opts; ++ if (mnt->amd_opts && *mnt->amd_opts) { ++ argv[0] = mnt->amd_opts; + argv[1] = NULL; + pargv = argv; + argc = 1; +@@ -894,9 +896,11 @@ static int lookup_amd_instance(struct au + } + } + if (!instance) { ++ mnts_put_mount(mnt); + error(ap->logopt, "expected hosts map instance not found"); + return NSS_STATUS_UNKNOWN; + } ++ mnts_put_mount(mnt); + + return do_lookup_mount(ap, instance, name, name_len); + } +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -568,10 +568,10 @@ struct autofs_point { + struct autofs_point *parent; /* Owner of mounts list for submount */ + pthread_mutex_t mounts_mutex; /* Protect mount lists */ + struct list_head mounts; /* List of autofs mounts at current level */ +- struct list_head amdmounts; /* List of non submount amd mounts */ + unsigned int submount; /* Is this a submount */ + unsigned int submnt_count; /* Number of submounts */ + struct list_head submounts; /* List of child submounts */ ++ struct list_head amdmounts; /* List of non submount amd mounts */ + unsigned int shutdown; /* Shutdown notification */ + }; + +--- autofs-5.1.4.orig/include/master.h ++++ autofs-5.1.4/include/master.h +@@ -109,8 +109,6 @@ void master_source_current_wait(struct m + void master_source_current_signal(struct master_mapent *); + struct master_mapent *master_find_mapent(struct master *, const char *); + unsigned int master_partial_match_mapent(struct master *, const char *); +-struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *); +-struct amd_entry *master_find_amdmount(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 *); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -38,6 +38,7 @@ + #define MNTS_INDIRECT 0x0008 + #define MNTS_DIRECT 0x0010 + #define MNTS_OFFSET 0x0020 ++#define MNTS_AMD_MOUNT 0x0040 + + #define REMOUNT_SUCCESS 0x0000 + #define REMOUNT_FAIL 0x0001 +@@ -64,6 +65,14 @@ struct mnt_list { + struct list_head submount; + struct list_head submount_work; + ++ /* List of amd-mounts of an autofs_point */ ++ char *ext_mp; ++ char *amd_pref; ++ char *amd_type; ++ char *amd_opts; ++ unsigned int amd_cache_opts; ++ struct list_head amdmount; ++ + /* + * List operations ie. get_mnt_list. + */ +@@ -118,6 +127,9 @@ struct mnt_list *mnts_add_submount(struc + void mnts_remove_submount(const char *mp); + void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_submount_list(struct list_head *mnts); ++struct mnt_list *mnts_find_amdmount(const char *path); ++struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry); ++void mnts_remove_amdmount(const char *mp); + struct mnt_list *get_mnt_list(const char *path, int include); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); +--- autofs-5.1.4.orig/include/parse_amd.h ++++ autofs-5.1.4/include/parse_amd.h +@@ -65,7 +65,6 @@ struct amd_entry { + char *umount; + struct selector *selector; + struct list_head list; +- struct list_head entries; + }; + + int amd_parse_list(struct autofs_point *, +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -152,12 +152,10 @@ void master_free_autofs_point(struct aut + head = &ap->amdmounts; + p = head->next; + while (p != head) { +- struct amd_entry *entry = list_entry(p, struct amd_entry, entries); ++ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount); + p = p->next; +- if (!list_empty(&entry->entries)) +- list_del(&entry->entries); +- ext_mount_remove(entry->fs); +- free_amd_entry(entry); ++ ext_mount_remove(mnt->ext_mp); ++ mnts_remove_amdmount(mnt->mp); + } + mounts_mutex_unlock(ap); + +@@ -761,34 +759,6 @@ unsigned int master_partial_match_mapent + return ret; + } + +-struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path) +-{ +- struct list_head *head, *p; +- +- head = &ap->amdmounts; +- list_for_each(p, head) { +- struct amd_entry *entry; +- +- entry = list_entry(p, struct amd_entry, entries); +- +- if (!strcmp(entry->path, path)) +- return entry; +- } +- +- return NULL; +-} +- +-struct amd_entry *master_find_amdmount(struct autofs_point *ap, const char *path) +-{ +- struct amd_entry *entry; +- +- mounts_mutex_lock(ap); +- entry = __master_find_amdmount(ap, path); +- mounts_mutex_unlock(ap); +- +- return entry; +-} +- + struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age) + { + struct master_mapent *entry; +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -546,7 +546,6 @@ struct amd_entry *new_amd_entry(const st + memset(new, 0, sizeof(*new)); + new->path = path; + INIT_LIST_HEAD(&new->list); +- INIT_LIST_HEAD(&new->entries); + + return new; + } +@@ -887,6 +886,7 @@ static struct mnt_list *mnts_alloc_mount + INIT_HLIST_NODE(&this->hash); + INIT_LIST_HEAD(&this->submount); + INIT_LIST_HEAD(&this->submount_work); ++ INIT_LIST_HEAD(&this->amdmount); + done: + return this; + } +@@ -1048,6 +1048,107 @@ void mnts_put_submount_list(struct list_ + mnts_hash_mutex_unlock(); + } + ++struct mnt_list *mnts_find_amdmount(const char *path) ++{ ++ struct mnt_list *mnt; ++ ++ mnt = mnts_lookup_mount(path); ++ if (mnt && mnt->flags & MNTS_AMD_MOUNT) ++ return mnt; ++ mnts_put_mount(mnt); ++ return NULL; ++} ++ ++struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry) ++{ ++ struct mnt_list *this; ++ char *type, *ext_mp, *pref, *opts; ++ ++ ext_mp = pref = type = opts = NULL; ++ ++ if (entry->fs) { ++ ext_mp = strdup(entry->fs); ++ if (!ext_mp) ++ goto fail; ++ } ++ ++ if (entry->pref) { ++ pref = strdup(entry->pref); ++ if (!pref) ++ goto fail; ++ } ++ ++ if (entry->type) { ++ type = strdup(entry->type); ++ if (!type) ++ goto fail; ++ } ++ ++ if (entry->opts) { ++ opts = strdup(entry->opts); ++ if (!opts) ++ goto fail; ++ } ++ ++ mnts_hash_mutex_lock(); ++ this = mnts_get_mount(entry->path); ++ if (this) { ++ this->ext_mp = ext_mp; ++ this->amd_pref = pref; ++ this->amd_type = type; ++ this->amd_opts = opts; ++ this->amd_cache_opts = entry->cache_opts; ++ this->flags |= MNTS_AMD_MOUNT; ++ if (list_empty(&this->amdmount)) ++ list_add_tail(&this->amdmount, &ap->amdmounts); ++ } ++ mnts_hash_mutex_unlock(); ++ ++ return this; ++fail: ++ if (ext_mp) ++ free(ext_mp); ++ if (pref) ++ free(pref); ++ if (type) ++ free(type); ++ if (opts) ++ free(opts); ++ return NULL; ++} ++ ++void mnts_remove_amdmount(const char *mp) ++{ ++ struct mnt_list *this; ++ ++ mnts_hash_mutex_lock(); ++ this = mnts_lookup(mp); ++ if (!(this && this->flags & MNTS_AMD_MOUNT)) ++ goto done; ++ this->flags &= ~MNTS_AMD_MOUNT; ++ list_del_init(&this->submount); ++ if (this->ext_mp) { ++ free(this->ext_mp); ++ this->ext_mp = NULL; ++ } ++ if (this->amd_type) { ++ free(this->amd_type); ++ this->amd_type = NULL; ++ } ++ if (this->amd_pref) { ++ free(this->amd_pref); ++ this->amd_pref = NULL; ++ } ++ if (this->amd_opts) { ++ free(this->amd_opts); ++ this->amd_opts = NULL; ++ } ++ this->amd_cache_opts = 0; ++ __mnts_put_mount(this); ++done: ++ mnts_hash_mutex_unlock(); ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names +--- autofs-5.1.4.orig/modules/mount_autofs.c ++++ autofs-5.1.4/modules/mount_autofs.c +@@ -286,16 +286,19 @@ int mount_mount(struct autofs_point *ap, + mounts_mutex_lock(ap); + + if (source->flags & MAP_FLAG_FORMAT_AMD) { +- struct amd_entry *am_entry = __master_find_amdmount(ap, entry->path); ++ struct mnt_list *mnt; + +- if (am_entry) { +- if (am_entry->pref) { +- nap->pref = am_entry->pref; +- am_entry->pref = NULL; ++ mnt = mnts_find_amdmount(entry->path); ++ if (mnt) { ++ if (mnt->amd_pref) { ++ nap->pref = mnt->amd_pref; ++ mnt->amd_pref = NULL; + } + +- if (am_entry->cache_opts & AMD_CACHE_OPTION_ALL) ++ if (mnt->amd_cache_opts & AMD_CACHE_OPTION_ALL) + nap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ ++ mnts_put_mount(mnt); + } + } + +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1300,6 +1300,7 @@ static int do_host_mount(struct autofs_p + { + struct lookup_mod *lookup; + struct map_source *instance; ++ struct mnt_list *mnt = NULL; + struct mapent *me; + const char *argv[2]; + const char **pargv = NULL; +@@ -1316,7 +1317,9 @@ static int do_host_mount(struct autofs_p + */ + if (strcmp(name, entry->rhost)) { + char *target; +- size_t len = strlen(ap->path) + strlen(entry->rhost) + 2; ++ size_t len; ++ ++ len = strlen(ap->path) + strlen(entry->rhost) + 2; + target = malloc(len); + if (!target) { + warn(ap->logopt, MODPREFIX +@@ -1329,6 +1332,15 @@ static int do_host_mount(struct autofs_p + if (entry->path) + free(entry->path); + entry->path = target; ++ ++ /* Add an mnt_list entry for the updated path. */ ++ mnt = mnts_add_amdmount(ap, entry); ++ if (!mnt) { ++ error(ap->logopt, MODPREFIX ++ "failed to update mount mnt_list entry"); ++ goto out; ++ } ++ + /* + * Wait for any expire before racing to mount the + * export tree or bail out if we're shutting down. +@@ -1388,6 +1400,8 @@ static int do_host_mount(struct autofs_p + warn(ap->logopt, MODPREFIX + "failed to create symlink to hosts mount base"); + out: ++ if (ret && mnt) ++ mnts_remove_amdmount(mnt->mp); + return ret; + } + +@@ -2204,6 +2218,7 @@ int parse_mount(struct autofs_point *ap, + struct list_head entries, *p, *head; + struct amd_entry *defaults_entry; + struct amd_entry *cur_defaults; ++ struct mnt_list *mnt; + int rv = 1; + int cur_state; + int ret; +@@ -2313,21 +2328,27 @@ int parse_mount(struct autofs_point *ap, + * add parsed entry to parent amd mount list and remove + * on mount fail. + */ +- mounts_mutex_lock(ap); +- list_add_tail(&this->entries, &ap->amdmounts); +- mounts_mutex_unlock(ap); ++ mnt = mnts_add_amdmount(ap, this); ++ if (!mnt) { ++ error(ap->logopt, MODPREFIX ++ "failed to add mount to mnt_list"); ++ break; ++ } + + rv = amd_mount(ap, name, this, source, sv, flags, ctxt); +- mounts_mutex_lock(ap); + if (!rv) { +- /* Mounted, remove entry from parsed list */ +- list_del_init(&this->list); +- mounts_mutex_unlock(ap); ++ /* ++ * If entry->path doesn't match the mnt->mp then ++ * the mount point path has changed and a new ++ * mnt_list entry added for it, so remove the ++ * original. ++ */ ++ if (strcmp(this->path, mnt->mp)) ++ mnts_remove_amdmount(this->path); + break; + } +- /* Not mounted, remove entry from the parent list */ +- list_del_init(&this->entries); +- mounts_mutex_unlock(ap); ++ /* Not mounted, remove the mnt_list entry from amdmount list */ ++ mnts_remove_amdmount(this->path); + } + free_amd_entry(cur_defaults); + diff --git a/autofs-5.1.6-use-mnt_list-for-submounts.patch b/autofs-5.1.6-use-mnt_list-for-submounts.patch new file mode 100644 index 0000000..8ffe5fe --- /dev/null +++ b/autofs-5.1.6-use-mnt_list-for-submounts.patch @@ -0,0 +1,472 @@ +autofs-5.1.6 - use mnt_list for submounts + +From: Ian Kent + +Use struct mnt_list objects for submount list entries instead of +struct autofs_point itself. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 11 ++++- + daemon/direct.c | 7 ++- + daemon/indirect.c | 5 ++ + include/automount.h | 2 - + include/master.h | 2 - + include/mounts.h | 10 +++++ + lib/master.c | 93 +++++++++++++++---------------------------------- + lib/mounts.c | 81 ++++++++++++++++++++++++++++++++++++++++++ + modules/mount_autofs.c | 17 ++++++++ + 10 files changed, 157 insertions(+), 72 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -122,6 +122,7 @@ xx/xx/2018 autofs-5.1.5 + - make external mounts independent of amd_entry. + - make external mounts use simpler hashtable. + - add a hash index to mnt_list. ++- use mnt_list for submounts. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -624,6 +624,7 @@ done: + it also tries to umount path itself */ + int umount_multi(struct autofs_point *ap, const char *path, int incl) + { ++ struct mnt_list *sbmnt; + int is_autofs_fs; + struct stat st; + int left; +@@ -685,8 +686,11 @@ int umount_multi(struct autofs_point *ap + } + + is_autofs_fs = 0; +- if (master_find_submount(ap, path)) ++ sbmnt = mnts_find_submount(path); ++ if (sbmnt) { + is_autofs_fs = 1; ++ mnts_put_mount(sbmnt); ++ } + + left = 0; + +@@ -1717,9 +1721,12 @@ static void handle_mounts_cleanup(void * + + if (submount) { + struct amd_entry *am; ++ + /* We are finishing up */ + ap->parent->submnt_count--; +- list_del_init(&ap->mounts); ++ ++ /* Submount at ap->path belongs to parent submount list. */ ++ mnts_remove_submount(ap->path); + am = __master_find_amdmount(ap->parent, ap->path); + if (am) { + list_del_init(&am->entries); +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -1211,14 +1211,17 @@ static void *do_mount_direct(void *arg) + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + if (status) { ++ struct mnt_list *sbmnt; + struct mapent *me; + struct statfs fs; + unsigned int close_fd = 0; + ++ sbmnt = mnts_find_submount(mt.name); + if (statfs(mt.name, &fs) == -1 || +- (fs.f_type == AUTOFS_SUPER_MAGIC && +- !master_find_submount(ap, mt.name))) ++ (fs.f_type == AUTOFS_SUPER_MAGIC && !sbmnt)) + close_fd = 1; ++ if (sbmnt) ++ mnts_put_mount(sbmnt); + cache_writelock(mt.mc); + if ((me = cache_lookup_distinct(mt.mc, mt.name))) { + /* +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -401,6 +401,7 @@ void *expire_proc_indirect(void *arg) + if (next->flags & MNTS_INDIRECT) + master_notify_submount(ap, next->mp, ap->state); + else if (next->flags & MNTS_OFFSET) { ++ struct mnt_list *sbmnt; + struct map_source *map; + struct mapent_cache *mc = NULL; + struct mapent *me = NULL; +@@ -413,7 +414,9 @@ void *expire_proc_indirect(void *arg) + } + + /* Don't touch submounts */ +- if (master_find_submount(ap, next->mp)) { ++ sbmnt = mnts_find_submount(next->mp); ++ if (sbmnt) { ++ mnts_put_mount(sbmnt); + pthread_setcancelstate(cur_state, NULL); + continue; + } +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -570,9 +570,9 @@ struct autofs_point { + struct list_head mounts; /* List of autofs mounts at current level */ + struct list_head amdmounts; /* List of non submount amd mounts */ + unsigned int submount; /* Is this a submount */ +- unsigned int shutdown; /* Shutdown notification */ + unsigned int submnt_count; /* Number of submounts */ + struct list_head submounts; /* List of child submounts */ ++ unsigned int shutdown; /* Shutdown notification */ + }; + + #define UNLINK_AND_CONT 0x01 +--- autofs-5.1.4.orig/include/master.h ++++ autofs-5.1.4/include/master.h +@@ -109,8 +109,6 @@ void master_source_current_wait(struct m + void master_source_current_signal(struct master_mapent *); + struct master_mapent *master_find_mapent(struct master *, const char *); + unsigned int master_partial_match_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 amd_entry *__master_find_amdmount(struct autofs_point *, const char *); + struct amd_entry *master_find_amdmount(struct autofs_point *, const char *); + struct master_mapent *master_new_mapent(struct master *, const char *, time_t); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -59,6 +59,11 @@ struct mnt_list { + struct hlist_node hash; + unsigned int ref; + ++ /* List of sub-mounts of an autofs_point */ ++ struct autofs_point *ap; ++ struct list_head submount; ++ struct list_head submount_work; ++ + /* + * List operations ie. get_mnt_list. + */ +@@ -108,6 +113,11 @@ int ext_mount_remove(const char *); + int ext_mount_inuse(const char *); + struct mnt_list *mnts_lookup_mount(const char *mp); + void mnts_put_mount(struct mnt_list *mnt); ++struct mnt_list *mnts_find_submount(const char *path); ++struct mnt_list *mnts_add_submount(struct autofs_point *ap); ++void mnts_remove_submount(const char *mp); ++void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap); ++void mnts_put_submount_list(struct list_head *mnts); + struct mnt_list *get_mnt_list(const char *path, int include); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -761,34 +761,6 @@ unsigned int master_partial_match_mapent + return ret; + } + +-struct autofs_point *__master_find_submount(struct autofs_point *ap, const char *path) +-{ +- struct list_head *head, *p; +- +- 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)) +- 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 submount; +-} +- + struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path) + { + struct list_head *head, *p; +@@ -1190,85 +1162,80 @@ int master_submount_list_empty(struct au + + int master_notify_submount(struct autofs_point *ap, const char *path, enum states state) + { +- struct list_head *head, *p; +- struct autofs_point *this = NULL; ++ struct mnt_list *this, *sbmnt; ++ LIST_HEAD(sbmnts); + int ret = 1; + +- mounts_mutex_lock(ap); +- +- head = &ap->submounts; +- p = head->prev; +- while (p != head) { +- this = list_entry(p, struct autofs_point, mounts); +- p = p->prev; ++ mnts_get_submount_list(&sbmnts, ap); ++ if (list_empty(&sbmnts)) ++ return 1; ++ ++ list_for_each_entry(this, &sbmnts, submount_work) { ++ /* Not a submount */ ++ if (!(this->flags & MNTS_AUTOFS)) ++ continue; + + /* path not the same */ +- if (strcmp(this->path, path)) ++ if (strcmp(this->mp, path)) + continue; + +- if (!master_submount_list_empty(this)) { +- char *this_path = strdup(this->path); +- if (this_path) { +- mounts_mutex_unlock(ap); +- master_notify_submount(this, path, state); +- mounts_mutex_lock(ap); +- if (!__master_find_submount(ap, this_path)) { +- free(this_path); +- continue; +- } +- free(this_path); +- } ++ if (!master_submount_list_empty(this->ap)) { ++ struct mnt_list *sm; ++ ++ master_notify_submount(this->ap, path, state); ++ sm = mnts_find_submount(path); ++ if (!sm) ++ continue; ++ mnts_put_mount(sm); + } + + /* Now we have found the submount we want to expire */ + + st_mutex_lock(); + +- if (this->state == ST_SHUTDOWN) { ++ if (this->ap->state == ST_SHUTDOWN) { + this = NULL; + st_mutex_unlock(); + break; + } + +- this->shutdown = ap->shutdown; ++ this->ap->shutdown = ap->shutdown; + +- __st_add_task(this, state); ++ __st_add_task(this->ap, state); + + st_mutex_unlock(); +- mounts_mutex_unlock(ap); + +- st_wait_task(this, state, 0); ++ st_wait_task(this->ap, state, 0); + + /* + * If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or + * ST_SHUTDOWN_FORCE 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))) { ++ while ((sbmnt = mnts_find_submount(path))) { + struct timespec t = { 0, 300000000 }; + struct timespec r; + +- if (this->state != ST_SHUTDOWN && +- this->state != ST_SHUTDOWN_PENDING && +- this->state != ST_SHUTDOWN_FORCE) { ++ if (sbmnt->ap->state != ST_SHUTDOWN && ++ sbmnt->ap->state != ST_SHUTDOWN_PENDING && ++ sbmnt->ap->state != ST_SHUTDOWN_FORCE) { + ret = 0; ++ mnts_put_mount(sbmnt); + break; + } ++ mnts_put_mount(sbmnt); + + 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(); + break; + } + +- mounts_mutex_unlock(ap); ++ mnts_put_submount_list(&sbmnts); + + return ret; + } +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -885,6 +885,8 @@ static struct mnt_list *mnts_alloc_mount + + this->ref = 1; + INIT_HLIST_NODE(&this->hash); ++ INIT_LIST_HEAD(&this->submount); ++ INIT_LIST_HEAD(&this->submount_work); + done: + return this; + } +@@ -967,6 +969,85 @@ void mnts_put_mount(struct mnt_list *mnt + mnts_hash_mutex_unlock(); + } + ++struct mnt_list *mnts_find_submount(const char *path) ++{ ++ struct mnt_list *mnt; ++ ++ mnt = mnts_lookup_mount(path); ++ if (mnt && mnt->flags & MNTS_AUTOFS) ++ return mnt; ++ mnts_put_mount(mnt); ++ return NULL; ++} ++ ++struct mnt_list *mnts_add_submount(struct autofs_point *ap) ++{ ++ struct mnt_list *this; ++ ++ mnts_hash_mutex_lock(); ++ this = mnts_get_mount(ap->path); ++ if (this) { ++ if (!this->ap) ++ this->ap = ap; ++ else if (this->ap != ap || ++ this->ap->parent != ap->parent) { ++ __mnts_put_mount(this); ++ mnts_hash_mutex_unlock(); ++ error(ap->logopt, ++ "conflict with submount owner: %s", ap->path); ++ goto fail; ++ } ++ this->flags |= MNTS_AUTOFS; ++ if (list_empty(&this->submount)) ++ list_add_tail(&this->submount, &ap->parent->submounts); ++ } ++ mnts_hash_mutex_unlock(); ++fail: ++ return this; ++} ++ ++void mnts_remove_submount(const char *mp) ++{ ++ struct mnt_list *this; ++ ++ mnts_hash_mutex_lock(); ++ this = mnts_lookup(mp); ++ if (this && this->flags & MNTS_AUTOFS) { ++ this->flags &= ~MNTS_AUTOFS; ++ this->ap = NULL; ++ list_del_init(&this->submount); ++ __mnts_put_mount(this); ++ } ++ mnts_hash_mutex_unlock(); ++} ++ ++void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap) ++{ ++ struct mnt_list *mnt; ++ ++ mnts_hash_mutex_lock(); ++ if (list_empty(&ap->submounts)) ++ goto done; ++ list_for_each_entry(mnt, &ap->submounts, submount) { ++ __mnts_get_mount(mnt); ++ list_add(&mnt->submount_work, mnts); ++ } ++done: ++ mnts_hash_mutex_unlock(); ++} ++ ++void mnts_put_submount_list(struct list_head *mnts) ++{ ++ struct mnt_list *mnt, *tmp; ++ ++ mnts_hash_mutex_lock(); ++ list_for_each_entry_safe(mnt, tmp, mnts, submount_work) { ++ list_del_init(&mnt->submount_work); ++ __mnts_put_mount(mnt); ++ } ++ mnts_hash_mutex_unlock(); ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names +--- autofs-5.1.4.orig/modules/mount_autofs.c ++++ autofs-5.1.4/modules/mount_autofs.c +@@ -65,6 +65,7 @@ int mount_mount(struct autofs_point *ap, + struct master_mapent *entry; + struct map_source *source; + struct autofs_point *nap; ++ struct mnt_list *mnt; + char buf[MAX_ERR_BUF]; + char *options, *p; + int len, ret; +@@ -307,6 +308,18 @@ int mount_mount(struct autofs_point *ap, + return 1; + } + ++ mnt = mnts_add_submount(nap); ++ if (!mnt) { ++ crit(ap->logopt, ++ MODPREFIX "failed to allocate mount %s", realpath); ++ handle_mounts_startup_cond_destroy(&suc); ++ mounts_mutex_unlock(ap); ++ master_free_map_source(source, 1); ++ master_free_mapent(entry); ++ return 1; ++ } ++ ++ + suc.ap = nap; + suc.root = mountpoint; + suc.done = 0; +@@ -318,6 +331,7 @@ int mount_mount(struct autofs_point *ap, + "failed to create mount handler thread for %s", + realpath); + handle_mounts_startup_cond_destroy(&suc); ++ mnts_remove_submount(nap->path); + mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); +@@ -328,6 +342,7 @@ int mount_mount(struct autofs_point *ap, + status = pthread_cond_wait(&suc.cond, &suc.mutex); + if (status) { + handle_mounts_startup_cond_destroy(&suc); ++ mnts_remove_submount(nap->path); + mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); +@@ -339,6 +354,7 @@ int mount_mount(struct autofs_point *ap, + crit(ap->logopt, + MODPREFIX "failed to create submount for %s", realpath); + handle_mounts_startup_cond_destroy(&suc); ++ mnts_remove_submount(nap->path); + mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); +@@ -347,7 +363,6 @@ int mount_mount(struct autofs_point *ap, + nap->thid = thid; + + ap->submnt_count++; +- list_add(&nap->mounts, &ap->submounts); + + handle_mounts_startup_cond_destroy(&suc); + mounts_mutex_unlock(ap); diff --git a/autofs-5.1.6-use-struct-mnt_list-mounted-list-for-expire.patch b/autofs-5.1.6-use-struct-mnt_list-mounted-list-for-expire.patch new file mode 100644 index 0000000..91f6911 --- /dev/null +++ b/autofs-5.1.6-use-struct-mnt_list-mounted-list-for-expire.patch @@ -0,0 +1,620 @@ +autofs-5.1.6 - use struct mnt_list mounted list for expire + +From: Ian Kent + +Now we are keeping track of mounted mounts using the mnt_list struct +use it to drive the expire instead of using the system mount table. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 61 +++++++---------- + daemon/indirect.c | 66 +++++++++---------- + include/mounts.h | 5 - + lib/master.c | 36 +--------- + lib/mounts.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++-------- + 6 files changed, 223 insertions(+), 131 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -129,6 +129,7 @@ xx/xx/2018 autofs-5.1.5 + - fix remount expire. + - fix stale offset directories disable mount. + - use struct mnt_list to track mounted mounts. ++- use struct mnt_list mounted list for expire. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -77,9 +77,8 @@ static void key_mnt_params_init(void) + + static void mnts_cleanup(void *arg) + { +- struct mnt_list *mnts = (struct mnt_list *) arg; +- tree_free_mnt_tree(mnts); +- return; ++ struct list_head *mnts = (struct list_head *) arg; ++ mnts_put_expire_list(mnts); + } + + int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me) +@@ -788,8 +787,8 @@ out_err: + void *expire_proc_direct(void *arg) + { + struct ioctl_ops *ops = get_ioctl_ops(); +- struct mnt_list *mnts = NULL, *next; +- struct list_head list, *p; ++ struct mnt_list *mnt; ++ LIST_HEAD(mnts); + struct expire_args *ea; + struct expire_args ec; + struct autofs_point *ap; +@@ -821,31 +820,24 @@ void *expire_proc_direct(void *arg) + + left = 0; + +- mnts = tree_make_mnt_tree("/"); +- pthread_cleanup_push(mnts_cleanup, mnts); +- +- /* Get a list of mounts select real ones and expire them if possible */ +- INIT_LIST_HEAD(&list); +- if (!tree_get_mnt_list(mnts, &list, "/", 0)) { +- ec.status = 0; +- return NULL; +- } +- +- list_for_each(p, &list) { +- next = list_entry(p, struct mnt_list, list); +- ++ /* Get the list of real mounts and expire them if possible */ ++ mnts_get_expire_list(&mnts, ap); ++ if (list_empty(&mnts)) ++ goto done; ++ pthread_cleanup_push(mnts_cleanup, &mnts); ++ list_for_each_entry(mnt, &mnts, expire) { + /* + * 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->mp, LKP_DISTINCT); ++ me = lookup_source_mapent(ap, mnt->mp, LKP_DISTINCT); + pthread_cleanup_pop(1); + if (!me) + continue; + +- if (next->flags & MNTS_AUTOFS) { ++ if (mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET)) { + struct stat st; + int ioctlfd; + +@@ -856,22 +848,17 @@ void *expire_proc_direct(void *arg) + * one of them and pass on state change. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- if (next->flags & MNTS_INDIRECT) { +- master_notify_submount(ap, next->mp, ap->state); +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } ++ if (mnt->flags & MNTS_AUTOFS) ++ master_notify_submount(ap, mnt->mp, ap->state); + + if (me->ioctlfd == -1) { + pthread_setcancelstate(cur_state, NULL); + continue; + } + +- /* It's got a mount, deal with in the outer loop */ +- if (is_mounted(me->key, MNTS_REAL)) { +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } ++ /* It's got a mount, just send the expire. */ ++ if (is_mounted(me->key, MNTS_REAL)) ++ goto cont; + + /* + * Maybe a manual umount, repair. +@@ -888,19 +875,19 @@ void *expire_proc_direct(void *arg) + cache_writelock(me->mc); + if (me->ioctlfd != -1 && + fstat(me->ioctlfd, &st) != -1 && +- !count_mounts(ap, next->mp, st.st_dev)) { ++ !count_mounts(ap, mnt->mp, st.st_dev)) { + ops->close(ap->logopt, me->ioctlfd); + me->ioctlfd = -1; + cache_unlock(me->mc); +- mnts_remove_mount(next->mp, MNTS_MOUNTED); ++ mnts_remove_mount(mnt->mp, MNTS_MOUNTED); + pthread_setcancelstate(cur_state, NULL); + continue; + } + cache_unlock(me->mc); +- ++cont: + ioctlfd = me->ioctlfd; + +- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how); ++ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); + if (ret) { + left++; + pthread_setcancelstate(cur_state, NULL); +@@ -923,10 +910,10 @@ void *expire_proc_direct(void *arg) + if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE) + pthread_testcancel(); + +- debug(ap->logopt, "send expire to trigger %s", next->mp); ++ debug(ap->logopt, "send expire to trigger %s", mnt->mp); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how); ++ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); + if (ret) + left++; + pthread_setcancelstate(cur_state, NULL); +@@ -935,7 +922,7 @@ void *expire_proc_direct(void *arg) + + if (left) + debug(ap->logopt, "%d remaining in %s", left, ap->path); +- ++done: + ec.status = left; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -343,17 +343,17 @@ force_umount: + + static void mnts_cleanup(void *arg) + { +- struct mnt_list *mnts = (struct mnt_list *) arg; +- free_mnt_list(mnts); +- return; ++ struct list_head *mnts = (struct list_head *) arg; ++ mnts_put_expire_list(mnts); + } + + void *expire_proc_indirect(void *arg) + { + struct ioctl_ops *ops = get_ioctl_ops(); + struct autofs_point *ap; +- struct mapent *me = NULL; +- struct mnt_list *mnts = NULL, *next; ++ struct mnt_list *mnt; ++ LIST_HEAD(mnts); ++ struct mapent *me; + struct expire_args *ea; + struct expire_args ec; + unsigned int how; +@@ -385,36 +385,34 @@ void *expire_proc_indirect(void *arg) + + left = 0; + +- /* Get a list of real mounts and expire them if possible */ +- mnts = get_mnt_list(ap->path, 0); +- pthread_cleanup_push(mnts_cleanup, mnts); +- for (next = mnts; next; next = next->next) { ++ /* Get the list of real mounts and expire them if possible */ ++ mnts_get_expire_list(&mnts, ap); ++ if (list_empty(&mnts)) ++ goto done; ++ pthread_cleanup_push(mnts_cleanup, &mnts); ++ list_for_each_entry(mnt, &mnts, expire) { + char *ind_key; + int ret; + +- if (next->flags & MNTS_AUTOFS) { ++ if (mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET)) { + /* + * If we have submounts check if this path lives below + * one of them and pass on the state change. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- if (next->flags & MNTS_INDIRECT) +- master_notify_submount(ap, next->mp, ap->state); +- else if (next->flags & MNTS_OFFSET) { ++ if (mnt->flags & MNTS_AUTOFS) ++ master_notify_submount(ap, mnt->mp, ap->state); ++ ++ /* An offset without a real mount, check for manual umount */ ++ if (mnt->flags & MNTS_OFFSET && ++ !is_mounted(mnt->mp, MNTS_REAL)) { + struct mnt_list *sbmnt; + struct map_source *map; + struct mapent_cache *mc = NULL; +- struct mapent *me = NULL; + struct stat st; + +- /* It's got a mount, deal with in the outer loop */ +- if (is_mounted(next->mp, MNTS_REAL)) { +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } +- + /* Don't touch submounts */ +- sbmnt = mnts_find_submount(next->mp); ++ sbmnt = mnts_find_submount(mnt->mp); + if (sbmnt) { + mnts_put_mount(sbmnt); + pthread_setcancelstate(cur_state, NULL); +@@ -427,7 +425,7 @@ void *expire_proc_indirect(void *arg) + while (map) { + mc = map->mc; + cache_writelock(mc); +- me = cache_lookup_distinct(mc, next->mp); ++ me = cache_lookup_distinct(mc, mnt->mp); + if (me) + break; + cache_unlock(mc); +@@ -456,10 +454,10 @@ void *expire_proc_indirect(void *arg) + + cache_unlock(mc); + master_source_unlock(ap->entry); ++ pthread_setcancelstate(cur_state, NULL); ++ continue; + } +- + pthread_setcancelstate(cur_state, NULL); +- continue; + } + + if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE) +@@ -469,7 +467,7 @@ void *expire_proc_indirect(void *arg) + * If the mount corresponds to an offset trigger then + * the key is the path, otherwise it's the last component. + */ +- ind_key = strrchr(next->mp, '/'); ++ ind_key = strrchr(mnt->mp, '/'); + if (ind_key) + ind_key++; + +@@ -482,7 +480,7 @@ void *expire_proc_indirect(void *arg) + */ + pthread_cleanup_push(master_source_lock_cleanup, ap->entry); + master_source_readlock(ap->entry); +- me = lookup_source_mapent(ap, next->mp, LKP_DISTINCT); ++ me = lookup_source_mapent(ap, mnt->mp, LKP_DISTINCT); + if (!me && ind_key) + me = lookup_source_mapent(ap, ind_key, LKP_NORMAL); + pthread_cleanup_pop(1); +@@ -494,10 +492,10 @@ void *expire_proc_indirect(void *arg) + cache_unlock(me->mc); + } + +- debug(ap->logopt, "expire %s", next->mp); ++ debug(ap->logopt, "expire %s", mnt->mp); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how); ++ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); + if (ret) + left++; + pthread_setcancelstate(cur_state, NULL); +@@ -519,14 +517,14 @@ void *expire_proc_indirect(void *arg) + pthread_cleanup_pop(1); + + count = offsets = submnts = 0; +- mnts = get_mnt_list(ap->path, 0); +- pthread_cleanup_push(mnts_cleanup, mnts); ++ mnts_get_expire_list(&mnts, ap); ++ pthread_cleanup_push(mnts_cleanup, &mnts); + /* Are there any real mounts left */ +- for (next = mnts; next; next = next->next) { +- if (!(next->flags & MNTS_AUTOFS)) ++ list_for_each_entry(mnt, &mnts, expire) { ++ if (!(mnt->flags & MNTS_AUTOFS)) + count++; + else { +- if (next->flags & MNTS_INDIRECT) ++ if (mnt->flags & MNTS_INDIRECT) + submnts++; + else + offsets++; +@@ -544,7 +542,7 @@ void *expire_proc_indirect(void *arg) + */ + if (count) + debug(ap->logopt, "%d remaining in %s", count, ap->path); +- ++done: + ec.status = left; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -63,6 +63,8 @@ struct mnt_list { + + /* List of mounts of an autofs_point */ + struct list_head mount; ++ /* Mounted mounts list for expire */ ++ struct list_head expire; + + /* List of sub-mounts of an autofs_point */ + struct autofs_point *ap; +@@ -129,15 +131,12 @@ void mnts_put_mount(struct mnt_list *mnt + struct mnt_list *mnts_find_submount(const char *path); + struct mnt_list *mnts_add_submount(struct autofs_point *ap); + void mnts_remove_submount(const char *mp); +-void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap); +-void mnts_put_submount_list(struct list_head *mnts); + struct mnt_list *mnts_find_amdmount(const char *path); + struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry); + void mnts_remove_amdmount(const char *mp); + struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags); + void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); +-unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name); +--- autofs-5.1.4.orig/lib/master.c ++++ autofs-5.1.4/lib/master.c +@@ -1133,40 +1133,17 @@ int master_submount_list_empty(struct au + int master_notify_submount(struct autofs_point *ap, const char *path, enum states state) + { + struct mnt_list *this, *sbmnt; +- LIST_HEAD(sbmnts); + int ret = 1; + +- mnts_get_submount_list(&sbmnts, ap); +- if (list_empty(&sbmnts)) +- return 1; +- +- list_for_each_entry(this, &sbmnts, submount_work) { +- /* Not a submount */ +- if (!(this->flags & MNTS_AUTOFS)) +- continue; +- +- /* path not the same */ +- if (strcmp(this->mp, path)) +- continue; +- +- if (!master_submount_list_empty(this->ap)) { +- struct mnt_list *sm; +- +- master_notify_submount(this->ap, path, state); +- sm = mnts_find_submount(path); +- if (!sm) +- continue; +- mnts_put_mount(sm); +- } +- +- /* Now we have found the submount we want to expire */ +- ++ this = mnts_find_submount(path); ++ if (this) { ++ /* We have found a submount to expire */ + st_mutex_lock(); + + if (this->ap->state == ST_SHUTDOWN) { + this = NULL; + st_mutex_unlock(); +- break; ++ goto done; + } + + this->ap->shutdown = ap->shutdown; +@@ -1202,11 +1179,10 @@ int master_notify_submount(struct autofs + st_mutex_lock(); + } + st_mutex_unlock(); +- break; ++done: ++ mnts_put_mount(this); + } + +- mnts_put_submount_list(&sbmnts); +- + return ret; + } + +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -888,6 +888,7 @@ static struct mnt_list *mnts_alloc_mount + INIT_LIST_HEAD(&this->submount); + INIT_LIST_HEAD(&this->submount_work); + INIT_LIST_HEAD(&this->amdmount); ++ INIT_LIST_HEAD(&this->expire); + done: + return this; + } +@@ -1022,33 +1023,6 @@ void mnts_remove_submount(const char *mp + mnts_hash_mutex_unlock(); + } + +-void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap) +-{ +- struct mnt_list *mnt; +- +- mnts_hash_mutex_lock(); +- if (list_empty(&ap->submounts)) +- goto done; +- list_for_each_entry(mnt, &ap->submounts, submount) { +- __mnts_get_mount(mnt); +- list_add(&mnt->submount_work, mnts); +- } +-done: +- mnts_hash_mutex_unlock(); +-} +- +-void mnts_put_submount_list(struct list_head *mnts) +-{ +- struct mnt_list *mnt, *tmp; +- +- mnts_hash_mutex_lock(); +- list_for_each_entry_safe(mnt, tmp, mnts, submount_work) { +- list_del_init(&mnt->submount_work); +- __mnts_put_mount(mnt); +- } +- mnts_hash_mutex_unlock(); +-} +- + struct mnt_list *mnts_find_amdmount(const char *path) + { + struct mnt_list *mnt; +@@ -1234,6 +1208,163 @@ void mnts_set_mounted_mount(struct autof + } + } + ++struct node { ++ struct mnt_list *mnt; ++ struct node *left; ++ struct node *right; ++}; ++ ++static struct node *new(struct mnt_list *mnt) ++{ ++ struct node *n; ++ ++ n = malloc(sizeof(struct node)); ++ if (!n) ++ return NULL; ++ memset(n, 0, sizeof(struct node)); ++ n->mnt = mnt; ++ ++ return n; ++} ++ ++static struct node *tree_root(struct mnt_list *mnt) ++{ ++ struct node *n; ++ ++ n = new(mnt); ++ if (!n) { ++ error(LOGOPT_ANY, "failed to allcate tree root"); ++ return NULL; ++ } ++ ++ return n; ++} ++ ++static struct node *add_left(struct node *this, struct mnt_list *mnt) ++{ ++ struct node *n; ++ ++ n = new(mnt); ++ if (!n) { ++ error(LOGOPT_ANY, "failed to allcate tree node"); ++ return NULL; ++ } ++ this->left = n; ++ ++ return n; ++} ++ ++static struct node *add_right(struct node *this, struct mnt_list *mnt) ++{ ++ struct node *n; ++ ++ n = new(mnt); ++ if (!n) { ++ error(LOGOPT_ANY, "failed to allcate tree node"); ++ return NULL; ++ } ++ this->right = n; ++ ++ return n; ++} ++ ++static struct node *add_node(struct node *root, struct mnt_list *mnt) ++{ ++ struct node *p, *q; ++ unsigned int mp_len; ++ ++ mp_len = strlen(mnt->mp); ++ ++ q = root; ++ p = root; ++ ++ while (q && strcmp(mnt->mp, p->mnt->mp)) { ++ p = q; ++ if (mp_len < strlen(p->mnt->mp)) ++ q = p->left; ++ else ++ q = p->right; ++ } ++ ++ if (strcmp(mnt->mp, p->mnt->mp) == 0) ++ error(LOGOPT_ANY, "duplicate entry in mounts list"); ++ else { ++ if (mp_len < strlen(p->mnt->mp)) ++ return add_left(p, mnt); ++ else ++ return add_right(p, mnt); ++ } ++ ++ return NULL; ++} ++ ++static void tree_free(struct node *tree) ++{ ++ if (tree->right) ++ tree_free(tree->right); ++ if (tree->left) ++ tree_free(tree->left); ++ free(tree); ++} ++ ++static void traverse(struct node *node, struct list_head *mnts) ++{ ++ if (node->right) ++ traverse(node->right, mnts); ++ list_add_tail(&node->mnt->expire, mnts); ++ if (node->left) ++ traverse(node->left, mnts); ++} ++ ++void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) ++{ ++ struct mnt_list *mnt; ++ struct node *tree = NULL; ++ ++ mnts_hash_mutex_lock(); ++ if (list_empty(&ap->mounts)) ++ goto done; ++ ++ list_for_each_entry(mnt, &ap->mounts, mount) { ++ struct node *n; ++ ++ __mnts_get_mount(mnt); ++ ++ if (!tree) { ++ tree = tree_root(mnt); ++ if (!tree) { ++ error(LOGOPT_ANY, "failed to create expire tree root"); ++ goto done; ++ } ++ continue; ++ } ++ ++ n = add_node(tree, mnt); ++ if (!n) { ++ error(LOGOPT_ANY, "failed to add expire tree node"); ++ tree_free(tree); ++ goto done; ++ } ++ } ++ ++ traverse(tree, mnts); ++ tree_free(tree); ++done: ++ mnts_hash_mutex_unlock(); ++} ++ ++void mnts_put_expire_list(struct list_head *mnts) ++{ ++ struct mnt_list *mnt, *tmp; ++ ++ mnts_hash_mutex_lock(); ++ list_for_each_entry_safe(mnt, tmp, mnts, expire) { ++ list_del_init(&mnt->expire); ++ __mnts_put_mount(mnt); ++ } ++ mnts_hash_mutex_unlock(); ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/autofs-5.1.6-use-struct-mnt_list-to-track-mounted-mounts.patch b/autofs-5.1.6-use-struct-mnt_list-to-track-mounted-mounts.patch new file mode 100644 index 0000000..4639315 --- /dev/null +++ b/autofs-5.1.6-use-struct-mnt_list-to-track-mounted-mounts.patch @@ -0,0 +1,360 @@ +autofs-5.1.6 - use struct mnt_list to track mounted mounts + +From: Ian Kent + +Use struct mnt_list to track mounted mounts so that it's no longer +necessary to use the system mount table to get the list of mounted +mounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 5 ++ + daemon/direct.c | 19 ++++++++ + daemon/indirect.c | 3 + + include/mounts.h | 10 ++++ + lib/mounts.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++---- + 6 files changed, 154 insertions(+), 9 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -128,6 +128,7 @@ xx/xx/2018 autofs-5.1.5 + - remove force parameter from umount_all(). + - fix remount expire. + - fix stale offset directories disable mount. ++- use struct mnt_list to track mounted mounts. + + 19/12/2017 autofs-5.1.4 + - fix spec file url. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -677,6 +677,9 @@ int umount_multi(struct autofs_point *ap + mnts_put_mount(mnt); + } + ++ /* Check for mounted mount and remove it if found */ ++ mnts_remove_mount(path, MNTS_MOUNTED); ++ + return 0; + } + +@@ -1719,6 +1722,8 @@ static void handle_mounts_cleanup(void * + + /* Submount at ap->path belongs to parent submount list. */ + mnts_remove_submount(ap->path); ++ /* Also remove from parent mounted list */ ++ mnts_remove_mount(ap->path, MNTS_MOUNTED); + mnt = mnts_find_amdmount(ap->path); + if (mnt) { + mnts_remove_amdmount(ap->path); +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -606,6 +606,9 @@ force_umount: + } else + info(ap->logopt, "umounted offset mount %s", me->key); + ++ if (!rv) ++ mnts_remove_mount(me->key, MNTS_OFFSET); ++ + return rv; + } + +@@ -622,6 +625,7 @@ int mount_autofs_offset(struct autofs_po + const char *map_name = hosts_map_name; + const char *type; + char mountpoint[PATH_MAX]; ++ struct mnt_list *mnt; + + if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) { + ret = try_remount(ap, me, t_offset); +@@ -635,6 +639,11 @@ int mount_autofs_offset(struct autofs_po + if (ap->state != ST_READMAP) + warn(ap->logopt, + "trigger %s already mounted", me->key); ++ mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET); ++ if (!mnt) ++ error(ap->logopt, ++ "failed to add offset mount %s to mounted list", ++ me->key); + return MOUNT_OFFSET_OK; + } + +@@ -757,6 +766,12 @@ int mount_autofs_offset(struct autofs_po + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + ++ mnt = mnts_add_mount(ap, mountpoint, MNTS_OFFSET); ++ if (!mnt) ++ error(ap->logopt, ++ "failed to add offset mount %s to mounted list", ++ mountpoint); ++ + debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint); + + return MOUNT_OFFSET_OK; +@@ -877,6 +892,7 @@ void *expire_proc_direct(void *arg) + ops->close(ap->logopt, me->ioctlfd); + me->ioctlfd = -1; + cache_unlock(me->mc); ++ mnts_remove_mount(next->mp, MNTS_MOUNTED); + pthread_setcancelstate(cur_state, NULL); + continue; + } +@@ -1238,7 +1254,10 @@ static void *do_mount_direct(void *arg) + cache_unlock(mt.mc); + if (close_fd) + ops->close(ap->logopt, mt.ioctlfd); ++ + info(ap->logopt, "mounted %s", mt.name); ++ ++ mnts_set_mounted_mount(ap, mt.name); + } else { + /* TODO: get mount return status from lookup_nss_mount */ + ops->send_fail(ap->logopt, +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -751,7 +751,10 @@ static void *do_mount_indirect(void *arg + if (status) { + ops->send_ready(ap->logopt, + ap->ioctlfd, mt.wait_queue_token); ++ + info(ap->logopt, "mounted %s", buf); ++ ++ mnts_set_mounted_mount(ap, mt.name); + } else { + /* TODO: get mount return status from lookup_nss_mount */ + ops->send_fail(ap->logopt, +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -39,6 +39,7 @@ + #define MNTS_DIRECT 0x0010 + #define MNTS_OFFSET 0x0020 + #define MNTS_AMD_MOUNT 0x0040 ++#define MNTS_MOUNTED 0x0080 + + #define REMOUNT_SUCCESS 0x0000 + #define REMOUNT_FAIL 0x0001 +@@ -60,6 +61,9 @@ struct mnt_list { + struct hlist_node hash; + unsigned int ref; + ++ /* List of mounts of an autofs_point */ ++ struct list_head mount; ++ + /* List of sub-mounts of an autofs_point */ + struct autofs_point *ap; + struct list_head submount; +@@ -130,7 +134,13 @@ void mnts_put_submount_list(struct list_ + struct mnt_list *mnts_find_amdmount(const char *path); + struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry); + void mnts_remove_amdmount(const char *mp); ++struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags); ++void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); ++unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); ++void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); ++void mnts_put_expire_list(struct list_head *mnts); ++void mnts_set_mounted_mount(struct autofs_point *ap, const char *name); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -884,6 +884,7 @@ static struct mnt_list *mnts_alloc_mount + + this->ref = 1; + INIT_HLIST_NODE(&this->hash); ++ INIT_LIST_HEAD(&this->mount); + INIT_LIST_HEAD(&this->submount); + INIT_LIST_HEAD(&this->submount_work); + INIT_LIST_HEAD(&this->amdmount); +@@ -1149,6 +1150,90 @@ done: + mnts_hash_mutex_unlock(); + } + ++struct mnt_list *mnts_add_mount(struct autofs_point *ap, ++ const char *name, unsigned int flags) ++{ ++ struct mnt_list *this; ++ char *mp; ++ ++ if (*name == '/') { ++ mp = strdup(name); ++ if (!mp) ++ goto fail; ++ } else { ++ int len = strlen(ap->path) + strlen(name) + 2; ++ ++ mp = malloc(len); ++ if (!mp) ++ goto fail; ++ strcpy(mp, ap->path); ++ strcat(mp, "/"); ++ strcat(mp, name); ++ } ++ ++ mnts_hash_mutex_lock(); ++ this = mnts_get_mount(mp); ++ if (this) { ++ this->flags |= flags; ++ if (list_empty(&this->mount)) ++ list_add(&this->mount, &ap->mounts); ++ } ++ mnts_hash_mutex_unlock(); ++ free(mp); ++ ++ return this; ++fail: ++ if (mp) ++ free(mp); ++ return NULL; ++} ++ ++void mnts_remove_mount(const char *mp, unsigned int flags) ++{ ++ struct mnt_list *this; ++ ++ mnts_hash_mutex_lock(); ++ this = mnts_lookup(mp); ++ if (this && this->flags & flags) { ++ this->flags &= ~flags; ++ if (!(this->flags & (MNTS_OFFSET|MNTS_MOUNTED))) ++ list_del_init(&this->mount); ++ __mnts_put_mount(this); ++ } ++ mnts_hash_mutex_unlock(); ++} ++ ++void mnts_set_mounted_mount(struct autofs_point *ap, const char *name) ++{ ++ struct mnt_list *mnt; ++ ++ mnt = mnts_add_mount(ap, name, MNTS_MOUNTED); ++ if (!mnt) { ++ error(ap->logopt, ++ "failed to add mount %s to mounted list", name); ++ return; ++ } ++ ++ /* Offset mount failed but non-strict returns success */ ++ if (mnt->flags & MNTS_OFFSET && ++ !is_mounted(mnt->mp, MNTS_REAL)) { ++ mnt->flags &= ~MNTS_MOUNTED; ++ mnts_put_mount(mnt); ++ } ++ ++ /* Housekeeping. ++ * Set the base type of the mounted mount. ++ * MNTS_AUTOFS and MNTS_OFFSET are set at mount time and ++ * are used during expire. ++ */ ++ if (!(mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET))) { ++ if (ap->type == LKP_INDIRECT) ++ mnt->flags |= MNTS_INDIRECT; ++ else ++ mnt->flags |= MNTS_DIRECT; ++ } ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names +@@ -1962,7 +2047,8 @@ void notify_mount_result(struct autofs_p + return; + } + +-static int do_remount_direct(struct autofs_point *ap, int fd, const char *path) ++static int do_remount_direct(struct autofs_point *ap, ++ const unsigned int type, int fd, const char *path) + { + struct ioctl_ops *ops = get_ioctl_ops(); + int status = REMOUNT_SUCCESS; +@@ -1975,9 +2061,21 @@ static int do_remount_direct(struct auto + set_tsd_user_vars(ap->logopt, uid, gid); + + ret = lookup_nss_mount(ap, NULL, path, strlen(path)); +- if (ret) ++ if (ret) { ++ struct mnt_list *mnt; ++ ++ /* If it's an offset mount add a mount reference */ ++ if (type == t_offset) { ++ mnt = mnts_add_mount(ap, path, MNTS_OFFSET); ++ if (!mnt) ++ error(ap->logopt, ++ "failed to add mount %s to mounted list", path); ++ } ++ ++ mnts_set_mounted_mount(ap, path); ++ + info(ap->logopt, "re-connected to %s", path); +- else { ++ } else { + status = REMOUNT_FAIL; + info(ap->logopt, "failed to re-connect %s", path); + } +@@ -1985,7 +2083,7 @@ static int do_remount_direct(struct auto + return status; + } + +-static int do_remount_indirect(struct autofs_point *ap, int fd, const char *path) ++static int do_remount_indirect(struct autofs_point *ap, const unsigned int type, int fd, const char *path) + { + struct ioctl_ops *ops = get_ioctl_ops(); + int status = REMOUNT_SUCCESS; +@@ -2046,9 +2144,11 @@ static int do_remount_indirect(struct au + len = strlen(de[n]->d_name); + + ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len); +- if (ret) ++ if (ret) { ++ mnts_set_mounted_mount(ap, buf); ++ + info(ap->logopt, "re-connected to %s", buf); +- else { ++ } else { + status = REMOUNT_FAIL; + info(ap->logopt, "failed to re-connect %s", buf); + } +@@ -2149,9 +2249,9 @@ static int remount_active_mount(struct a + * following will be broken? + */ + if (type == t_indirect) +- do_remount_indirect(ap, fd, path); ++ do_remount_indirect(ap, type, fd, path); + else +- do_remount_direct(ap, fd, path); ++ do_remount_direct(ap, type, fd, path); + } + + debug(ap->logopt, "re-connected to mount %s", path); +@@ -2389,7 +2489,7 @@ int umount_ent(struct autofs_point *ap, + * so that we do not try to call rmdir_path on the + * directory. + */ +- if (!rv && is_mounted(path, MNTS_REAL)) { ++ if (is_mounted(path, MNTS_REAL)) { + crit(ap->logopt, + "the umount binary reported that %s was " + "unmounted, but there is still something " +@@ -2398,6 +2498,10 @@ int umount_ent(struct autofs_point *ap, + } + } + ++ /* On success, check for mounted mount and remove it if found */ ++ if (!rv) ++ mnts_remove_mount(path, MNTS_MOUNTED); ++ + return rv; + } + +@@ -2690,6 +2794,9 @@ int umount_multi_triggers(struct autofs_ + status = cache_delete_offset_list(mc, me->key); + if (status != CHE_OK) + warn(ap->logopt, "couldn't delete offset list"); ++ ++ /* check for mounted mount entry and remove it if found */ ++ mnts_remove_mount(root, MNTS_MOUNTED); + } + + return left; diff --git a/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch b/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch new file mode 100644 index 0000000..985d984 --- /dev/null +++ b/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch @@ -0,0 +1,122 @@ +autofs-5.1.7 - add a len field to struct autofs_point + +From: Ian Kent + +Add a path length field to struct autofs_point since the path length +is needed at various times avoiding additional strlen() calls. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 2 +- + daemon/master.c | 1 + + include/automount.h | 1 + + lib/mounts.c | 6 +++--- + modules/parse_amd.c | 4 ++-- + modules/parse_sun.c | 4 ++-- + 7 files changed, 11 insertions(+), 8 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -30,6 +30,7 @@ + - fix program map multi-mount lookup after mount fail. + - add some multi-mount macros. + - remove unused functions cache_dump_multi() and cache_dump_cache(). ++- add a len field to struct autofs_point. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -851,7 +851,7 @@ static int lookup_amd_instance(struct au + return NSS_STATUS_UNKNOWN; + } + +- m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2); ++ m_key = malloc(ap->len + strlen(MM_ROOT(me)->key) + 2); + if (!m_key) { + error(ap->logopt, + "failed to allocate storage for search key"); +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -86,6 +86,7 @@ int master_add_autofs_point(struct maste + free(ap); + return 0; + } ++ ap->len = strlen(ap->path); + ap->pref = NULL; + + ap->entry = entry; +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -547,6 +547,7 @@ struct kernel_mod_version { + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ ++ size_t len; /* Length of mount point name */ + mode_t mode; /* Mount point mode */ + char *pref; /* amd prefix */ + int pipefd; /* File descriptor for pipe */ +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1158,7 +1158,7 @@ struct mnt_list *mnts_add_mount(struct a + if (!mp) + goto fail; + } else { +- int len = strlen(ap->path) + strlen(name) + 2; ++ int len = ap->len + strlen(name) + 2; + + mp = malloc(len); + if (!mp) +@@ -2489,9 +2489,9 @@ static int rmdir_path_offset(struct auto + dir = strdup(oe->key); + + if (ap->flags & MOUNT_FLAG_GHOST) +- split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1; ++ split = ap->len + strlen(MM_ROOT(oe)->key) + 1; + else +- split = strlen(ap->path); ++ split = ap->len; + + dir[split] = '\0'; + path = &dir[split + 1]; +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -147,7 +147,7 @@ static struct substvar *add_lookup_vars( + struct mapent *me; + int len; + +- len = strlen(ap->path) + 1 + key_len + 1; ++ len = ap->len + 1 + key_len + 1; + if (len > PATH_MAX) { + error(ap->logopt, MODPREFIX + "error: lookup key is greater than PATH_MAX"); +@@ -1319,7 +1319,7 @@ static int do_host_mount(struct autofs_p + char *target; + size_t len; + +- len = strlen(ap->path) + strlen(entry->rhost) + 2; ++ len = ap->len + strlen(entry->rhost) + 2; + target = malloc(len); + if (!target) { + warn(ap->logopt, MODPREFIX +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1156,7 +1156,7 @@ static int mount_subtree(struct autofs_p + mm_root = mm_key; + start = strlen(mm_key); + } else { +- start = strlen(ap->path) + strlen(mm_key) + 1; ++ start = ap->len + strlen(mm_key) + 1; + mm_root = alloca(start + 3); + strcpy(mm_root, ap->path); + strcat(mm_root, "/"); +@@ -1479,7 +1479,7 @@ dont_expand: + } + strcpy(m_root, name); + } else { +- m_root_len = strlen(ap->path) + name_len + 1; ++ m_root_len = ap->len + name_len + 1; + m_root = alloca(m_root_len + 1); + if (!m_root) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); diff --git a/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch b/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch new file mode 100644 index 0000000..11ec2f8 --- /dev/null +++ b/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch @@ -0,0 +1,100 @@ +autofs-5.1.7 - add ext_mount_hash_mutex lock helpers + +From: Ian Kent + +Coverity: check_return: Calling "pthread_mutex_lock" without checking + return value. + +Well, I use helpers to do this in many places so can't really disagree. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 26 ++++++++++++++++++++------ + 2 files changed, 21 insertions(+), 6 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -65,6 +65,7 @@ + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). ++- add ext_mount_hash_mutex lock helpers. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -788,6 +788,20 @@ char *make_mnt_name_string(char *path) + return mnt_name; + } + ++static void ext_mount_hash_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&ext_mount_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static void ext_mount_hash_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&ext_mount_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ + static struct ext_mount *ext_mount_lookup(const char *mp) + { + uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash)); +@@ -806,7 +820,7 @@ int ext_mount_add(const char *path, cons + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + + em = ext_mount_lookup(path); + if (em) { +@@ -840,7 +854,7 @@ int ext_mount_add(const char *path, cons + + ret = 1; + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + +@@ -849,7 +863,7 @@ int ext_mount_remove(const char *path) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + + em = ext_mount_lookup(path); + if (!em) +@@ -867,7 +881,7 @@ int ext_mount_remove(const char *path) + ret = 1; + } + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + +@@ -876,13 +890,13 @@ int ext_mount_inuse(const char *path) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + em = ext_mount_lookup(path); + if (!em) + goto done; + ret = em->ref; + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + diff --git a/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch b/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch new file mode 100644 index 0000000..150a949 --- /dev/null +++ b/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch @@ -0,0 +1,38 @@ +autofs-5.1.7 - add length check in umount_subtree_mounts() + +From: Ian Kent + +Coverity: fixed_size_dest: You might overrun the 4097-character + fixed-size string "key" by copying "me->key" without + checking the length. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -55,6 +55,7 @@ + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). ++- add length check in umount_subtree_mounts(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct + left++; + } + ++ if (me->len > PATH_MAX) { ++ crit(ap->logopt, "me->key too long for buffer"); ++ return 1; ++ } ++ + strcpy(key, me->key); + + cache_unlock(mc); diff --git a/autofs-5.1.7-add-mapent-tree-implementation.patch b/autofs-5.1.7-add-mapent-tree-implementation.patch new file mode 100644 index 0000000..71e8b68 --- /dev/null +++ b/autofs-5.1.7-add-mapent-tree-implementation.patch @@ -0,0 +1,167 @@ +autofs-5.1.7 - add mapent tree implementation + +From: Ian Kent + +Add a struct mapent basic tree implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 4 ++++ + include/mounts.h | 8 ++++++++ + lib/cache.c | 9 ++++++++- + lib/mounts.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 71 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -32,6 +32,7 @@ + - remove unused functions cache_dump_multi() and cache_dump_cache(). + - add a len field to struct autofs_point. + - make tree implementation data independent. ++- add mapent tree implementation. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -166,10 +166,14 @@ struct mapent { + struct mapent_cache *mc; + struct map_source *source; + /* Need to know owner if we're a multi-mount */ ++ struct tree_node *mm_root; ++ struct tree_node *mm_parent; ++ struct tree_node node; + struct mapent *multi; + /* Parent nesting point within multi-mount */ + struct mapent *parent; + char *key; ++ size_t len; + char *mapent; + struct stack *stack; + time_t age; +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -66,6 +66,13 @@ struct tree_node { + #define MNT_LIST(n) (container_of(n, struct mnt_list, node)) + #define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) + ++#define MAPENT(n) (container_of(n, struct mapent, node)) ++#define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node) ++#define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root) ++#define MAPENT_PARENT(p) ((struct tree_node *) ((struct mapent *) p)->mm_parent) ++#define MAPENT_SET_ROOT(p, r) { (((struct mapent *) p)->mm_root = (struct tree_node *) r); } ++#define MAPENT_SET_PARENT(p, n) { (((struct mapent *) p)->mm_parent = (struct tree_node *) n); } ++ + typedef struct tree_node *(*tree_new_t) (void *ptr); + typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr); + typedef void (*tree_free_t) (struct tree_node *n); +@@ -161,6 +168,7 @@ unsigned int mnts_has_mounted_mounts(str + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); ++struct tree_node *tree_mapent_root(struct mapent *me); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -546,17 +546,21 @@ int cache_add(struct mapent_cache *mc, s + struct mapent *me, *existing = NULL; + char *pkey, *pent; + u_int32_t hashval = hash(key, mc->size); ++ size_t len; + + me = (struct mapent *) malloc(sizeof(struct mapent)); + if (!me) + return CHE_FAIL; + +- pkey = malloc(strlen(key) + 1); ++ len = strlen(key); ++ ++ pkey = malloc(len + 1); + if (!pkey) { + free(me); + return CHE_FAIL; + } + me->key = strcpy(pkey, key); ++ me->len = len; + + if (mapent) { + pent = malloc(strlen(mapent) + 1); +@@ -575,6 +579,9 @@ int cache_add(struct mapent_cache *mc, s + me->status = 0; + me->mc = mc; + me->source = ms; ++ me->mm_root = NULL; ++ me->mm_parent = NULL; ++ INIT_TREE_NODE(&me->node); + INIT_LIST_HEAD(&me->ino_index); + INIT_LIST_HEAD(&me->multi_list); + me->multi = NULL; +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = { + }; + static struct tree_ops *tree_mnt_ops = &mnt_ops; + ++static struct tree_node *tree_mapent_new(void *ptr); ++static int tree_mapent_cmp(struct tree_node *n, void *ptr); ++static void tree_mapent_free(struct tree_node *n); ++ ++static struct tree_ops mapent_ops = { ++ .new = tree_mapent_new, ++ .cmp = tree_mapent_cmp, ++ .free = tree_mapent_free, ++}; ++static struct tree_ops *tree_mapent_ops = &mapent_ops; ++ + unsigned int linux_version_code(void) + { + struct utsname my_utsname; +@@ -1431,6 +1442,45 @@ void mnts_put_expire_list(struct list_he + mnts_hash_mutex_unlock(); + } + ++struct tree_node *tree_mapent_root(struct mapent *me) ++{ ++ return tree_root(tree_mapent_ops, me); ++} ++ ++static struct tree_node *tree_mapent_new(void *ptr) ++{ ++ struct tree_node *n = MAPENT_NODE(ptr); ++ ++ n->ops = tree_mapent_ops; ++ n->left = NULL; ++ n->right = NULL; ++ ++ return n; ++} ++ ++static int tree_mapent_cmp(struct tree_node *n, void *ptr) ++{ ++ struct mapent *n_me = MAPENT(n); ++ size_t n_me_len = n_me->len; ++ struct mapent *me = ptr; ++ size_t me_len = me->len; ++ ++ if (strncmp(me->key, n_me->key, n_me_len) == 0) { ++ if (me_len < n_me_len) ++ return -1; ++ else if (me_len > n_me_len) ++ return 1; ++ } ++ return strcmp(me->key, n_me->key); ++} ++ ++static void tree_mapent_free(struct tree_node *n) ++{ ++ n->ops = NULL; ++ n->left = NULL; ++ n->right = NULL; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/autofs-5.1.7-add-missing-description-of-null-map-option.patch b/autofs-5.1.7-add-missing-description-of-null-map-option.patch new file mode 100644 index 0000000..f469d6d --- /dev/null +++ b/autofs-5.1.7-add-missing-description-of-null-map-option.patch @@ -0,0 +1,51 @@ +autofs-5.1.7 - add missing desciption of null map option + +From: Ian Kent + +The description of how the -null master map option behaves is +mising from auto.master(5). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/auto.master.5.in | 19 +++++++++++++++++++ + 2 files changed, 20 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -74,6 +74,7 @@ + - fix hosts map offset order. + - fix direct mount deadlock. + - fix lookup_prune_one_cache() refactoring change. ++- add missing description of null map option. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/man/auto.master.5.in ++++ autofs-5.1.4/man/auto.master.5.in +@@ -263,6 +263,25 @@ accessing /net/myserver will mount expor + NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options + unless overridden by explicitly specifying the "suid", "dev" or "nointr" options in the + master map entry. ++.SH BUILTIN MAP \-null ++If "\-null" is given as the map it is used to tell automount(8) to ignore a subsequent ++master map entry with the given path. ++.P ++It can only be used for paths that appear in the master map (or in direct mount maps). ++.P ++An indirect mount map top level mount point path can be nulled. If so no mounts from ++the nulled mount are performed (essentially it isn't mounted). ++.P ++Direct mount map path entries can be nulled. Since they must be present at startup ++they are (notionally) part of the master map. ++.P ++A nulled master map entry path will ignore a single subsequent matching entry. Any ++matching entry following that will be treated as it normally would be. An example ++use of this is allowing local master map entries to override remote ones. ++.P ++NOTE: If a duplicate master map entry path is seen (excluding paths of null entries) ++it will be ignored and noted in the log, that is the first encountered master map ++entry is used unless there is a corresponding null entry. + .SH LDAP MAPS + If the map type \fBldap\fP is specified the mapname is of the form + \fB[//servername/]dn\fP, where the optional \fBservername\fP is diff --git a/autofs-5.1.7-add-missing-free-in-handle_mounts.patch b/autofs-5.1.7-add-missing-free-in-handle_mounts.patch new file mode 100644 index 0000000..f320006 --- /dev/null +++ b/autofs-5.1.7-add-missing-free-in-handle_mounts.patch @@ -0,0 +1,38 @@ +autofs-5.1.7 - add missing free in handle_mounts() + +From: Ian Kent + +Coverity: error[doubleFree]: Memory pointed to by 'root' is freed twice + +No it's not, but root isn't freed before the fatal call which crashes +automount so add a free() before the fatal() call. + +It appears Coverity doesn't recognise pthread_exit() as an exit condition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 ++ + 2 files changed, 3 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -50,6 +50,7 @@ + - check for offset with no mount location. + - remove mounts_mutex. + - remove unused variable from get_exports(). ++- add missing free in handle_mounts(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1917,6 +1917,8 @@ void *handle_mounts(void *arg) + status = pthread_mutex_lock(&suc->mutex); + if (status) { + logerr("failed to lock startup condition mutex!"); ++ if (root) ++ free(root); + fatal(status); + } + diff --git a/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch b/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch new file mode 100644 index 0000000..d35dbbd --- /dev/null +++ b/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch @@ -0,0 +1,304 @@ +autofs-5.1.7 - add mount and umount offsets functions + +From: Ian Kent + +Add tree_mapent_mount_offsets() and tree_mapent_umount_offsets() to +the mapent tree handling implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/mounts.h | 2 + lib/mounts.c | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 263 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -39,6 +39,7 @@ + - fix mount_fullpath(). + - add tree_mapent_cleanup_offsets(). + - add set_offset_tree_catatonic(). ++- add mount and umount offsets functions. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -172,6 +172,8 @@ struct tree_node *tree_mapent_root(struc + int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); ++int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); ++int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1692,6 +1692,266 @@ void tree_mapent_cleanup_offsets(struct + } + } + ++static int tree_mapent_rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) ++{ ++ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe)); ++ char *dir, *path; ++ unsigned int split; ++ int ret; ++ ++ if (ap->type == LKP_DIRECT) ++ return rmdir_path(ap, oe->key, mm_root->dev); ++ ++ dir = strdup(oe->key); ++ ++ if (ap->flags & MOUNT_FLAG_GHOST) ++ split = ap->len + mm_root->len + 1; ++ else ++ split = ap->len; ++ ++ dir[split] = '\0'; ++ path = &dir[split + 1]; ++ ++ if (chdir(dir) == -1) { ++ error(ap->logopt, "failed to chdir to %s", dir); ++ free(dir); ++ return -1; ++ } ++ ++ ret = rmdir_path(ap, path, ap->dev); ++ ++ free(dir); ++ ++ if (chdir("/") == -1) ++ error(ap->logopt, "failed to chdir to /"); ++ ++ return ret; ++} ++ ++static int tree_mapent_mount_offset(struct mapent *oe, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct autofs_point *ap = ctxt->ap; ++ int ret; ++ ++ debug(ap->logopt, "mount offset %s", oe->key); ++ ++ ret = mount_autofs_offset(ap, oe); ++ if (ret < MOUNT_OFFSET_OK) { ++ if (ret != MOUNT_OFFSET_IGNORE) { ++ warn(ap->logopt, "failed to mount offset"); ++ return 0; ++ } else { ++ debug(ap->logopt, ++ "ignoring \"nohide\" trigger %s", oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. ++ */ ++ free(oe->mapent); ++ oe->mapent = NULL; ++ } ++ } ++ ++ return 1; ++} ++ ++static int tree_mapent_umount_offset(struct mapent *oe, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct autofs_point *ap = ctxt->ap; ++ int ret = 1; ++ ++ /* ++ * Check for and umount subtree offsets resulting from ++ * nonstrict mount fail. ++ */ ++ ret = tree_mapent_umount_offsets(oe, ctxt->strict); ++ if (!ret) ++ return 0; ++ ++ /* ++ * If an offset that has an active mount has been removed ++ * from the multi-mount we don't want to attempt to trigger ++ * mounts for it. Obviously this is because it has been ++ * removed, but less obvious is the potential strange ++ * behaviour that can result if we do try and mount it ++ * again after it's been expired. For example, if an NFS ++ * file system is no longer exported and is later umounted ++ * it can be mounted again without any error message but ++ * shows as an empty directory. That's going to confuse ++ * people for sure. ++ * ++ * If the mount cannot be umounted (the process is now ++ * using a stale mount) the offset needs to be invalidated ++ * so no further mounts will be attempted but the offset ++ * cache entry must remain so expires can continue to ++ * attempt to umount it. If the mount can be umounted and ++ * the offset is removed, at least for NFS we will get ++ * ESTALE errors when attempting list the directory. ++ */ ++ if (oe->ioctlfd != -1 || ++ is_mounted(oe->key, MNTS_REAL)) { ++ if (umount_ent(ap, oe->key) && ++ is_mounted(oe->key, MNTS_REAL)) { ++ debug(ap->logopt, ++ "offset %s has active mount, invalidate", ++ oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. ++ */ ++ if (oe->mapent) { ++ free(oe->mapent); ++ oe->mapent = NULL; ++ } ++ return 0; ++ } ++ } ++ ++ /* Don't bother if there's noting to umount. */ ++ if (!is_mounted(oe->key, MNTS_AUTOFS)) ++ goto done; ++ ++ debug(ap->logopt, "umount offset %s", oe->key); ++ ++ if (umount_autofs_offset(ap, oe)) { ++ warn(ap->logopt, "failed to umount offset"); ++ ret = 0; ++ } else { ++ struct stat st; ++ int ret; ++ ++ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) ++ goto done; ++ ++ /* ++ * An error due to partial directory removal is ++ * ok so only try and remount the offset if the ++ * actual mount point still exists. ++ */ ++ ret = tree_mapent_rmdir_path_offset(ap, oe); ++ if (ret == -1 && !stat(oe->key, &st)) { ++ ret = tree_mapent_mount_offset(oe, ctxt); ++ /* But we did origianlly create this */ ++ oe->flags |= MOUNT_FLAG_DIR_CREATED; ++ } ++ } ++done: ++ return ret; ++} ++ ++static int tree_mapent_mount_offsets_work(struct tree_node *n, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct mapent *oe = MAPENT(n); ++ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe)); ++ struct autofs_point *ap = ctxt->ap; ++ int ret; ++ ++ if (!oe->mapent) ++ return 1; ++ ++ /* Stale offset, no longer present in the mapent */ ++ if (oe->age != mm_root->age) { ++ /* Best effort */ ++ tree_mapent_umount_offset(oe, ctxt); ++ return 1; ++ } ++ ++ ret = tree_mapent_mount_offset(oe, ctxt); ++ ++ /* ++ * If re-constructing a multi-mount it's necessary to walk ++ * into nested mounts, unlike the usual "mount only what's ++ * needed as you go" behavior. ++ */ ++ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { ++ if (oe->ioctlfd != -1 || ++ is_mounted(oe->key, MNTS_REAL)) ++ /* Best effort */ ++ tree_mapent_mount_offsets(oe, !ctxt->strict); ++ } ++ ++ return ret; ++} ++ ++int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict) ++{ ++ struct tree_node *base = MAPENT_NODE(oe); ++ struct traverse_subtree_context ctxt = { ++ .ap = oe->mc->ap, ++ .base = base, ++ .strict = !nonstrict, ++ }; ++ ++ return tree_mapent_traverse_subtree(base, ++ tree_mapent_mount_offsets_work, &ctxt); ++} ++ ++static int tree_mapent_umount_offsets_work(struct tree_node *n, void *ptr) ++{ ++ struct mapent *oe = MAPENT(n); ++ ++ return tree_mapent_umount_offset(oe, ptr); ++} ++ ++int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict) ++{ ++ struct tree_node *base = MAPENT_NODE(oe); ++ struct autofs_point *ap = oe->mc->ap; ++ struct traverse_subtree_context ctxt = { ++ .ap = ap, ++ .base = base, ++ .strict = !nonstrict, ++ }; ++ int ret; ++ ++ ret = tree_mapent_traverse_subtree(base, ++ tree_mapent_umount_offsets_work, &ctxt); ++ if (ret && tree_mapent_is_root(oe)) { ++ char mp[PATH_MAX + 1]; ++ ++ /* ++ * The map entry cache stores mapent keys. For indirect ++ * mount maps they are single direcory components so when ++ * one of these keys is the root of a multi-mount the mount ++ * path must be constructed. ++ */ ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) { ++ error(ap->logopt, "mount path is too long"); ++ return 0; ++ } ++ ++ /* ++ * 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(mp, MNTS_REAL)) { ++ info(ap->logopt, "unmounting dir = %s", mp); ++ if (umount_ent(ap, mp) && ++ is_mounted(mp, MNTS_REAL)) { ++ if (!tree_mapent_mount_offsets(oe, 1)) ++ warn(ap->logopt, ++ "failed to remount offset triggers"); ++ return 0; ++ } ++ } ++ ++ /* check for mounted mount entry and remove it if found */ ++ mnts_remove_mount(mp, MNTS_MOUNTED); ++ ++ } ++ ++ return ret; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/autofs-5.1.7-add-set_offset_tree_catatonic.patch b/autofs-5.1.7-add-set_offset_tree_catatonic.patch new file mode 100644 index 0000000..11761b3 --- /dev/null +++ b/autofs-5.1.7-add-set_offset_tree_catatonic.patch @@ -0,0 +1,46 @@ +autofs-5.1.7 - add set_offset_tree_catatonic() + +From: Ian Kent + +Add tree mapent support function set_offset_tree_catatonic(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 15 +++++++++++++++ + 2 files changed, 16 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -38,6 +38,7 @@ + - add tree_mapent_traverse_subtree(). + - fix mount_fullpath(). + - add tree_mapent_cleanup_offsets(). ++- add set_offset_tree_catatonic(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2574,6 +2574,21 @@ static int set_mount_catatonic(struct au + return 0; + } + ++static int set_offset_tree_catatonic_work(struct tree_node *n, void *ptr) ++{ ++ struct mapent *me = MAPENT(n); ++ struct autofs_point *ap = me->mc->ap; ++ ++ set_mount_catatonic(ap, me, me->ioctlfd); ++ ++ return 1; ++} ++ ++static void set_offset_tree_catatonic(struct autofs_point *ap, struct mapent *me) ++{ ++ tree_traverse_inorder(MAPENT_ROOT(me), set_offset_tree_catatonic_work, NULL); ++} ++ + static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) + { + if (!list_empty(&me->multi_list)) { diff --git a/autofs-5.1.7-add-some-multi-mount-macros.patch b/autofs-5.1.7-add-some-multi-mount-macros.patch new file mode 100644 index 0000000..cfcc693 --- /dev/null +++ b/autofs-5.1.7-add-some-multi-mount-macros.patch @@ -0,0 +1,522 @@ +autofs-5.1.7 - add some multi-mount macros + +From: Ian Kent + +Add convienience macros IS_MM() to check is a mapent is part of a +multi-mount, IS_MM_ROOT() to check if a mapent is the root of a +multi-mount tree and MM_ROOT() to return the multi-mount root mapent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 14 +++++++------- + daemon/direct.c | 6 +++--- + daemon/lookup.c | 10 +++++----- + include/automount.h | 5 +++++ + lib/cache.c | 30 +++++++++++++++--------------- + lib/mounts.c | 14 +++++++------- + modules/lookup_file.c | 4 ++-- + modules/lookup_hosts.c | 4 ++-- + modules/lookup_ldap.c | 4 ++-- + modules/lookup_nisplus.c | 4 ++-- + modules/lookup_program.c | 4 ++-- + modules/lookup_sss.c | 4 ++-- + modules/lookup_yp.c | 4 ++-- + modules/parse_sun.c | 12 ++++++------ + 15 files changed, 63 insertions(+), 57 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -28,6 +28,7 @@ + - don't pass root to do_mount_autofs_offset(). + - rename tree implementation functions. + - fix program map multi-mount lookup after mount fail. ++- add some multi-mount macros. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -545,27 +545,27 @@ static int umount_subtree_mounts(struct + + if (me) { + mc = me->mc; +- is_mm_root = (me->multi == me); ++ is_mm_root = IS_MM_ROOT(me); + } + + left = 0; + +- if (me && me->multi) { ++ if (me && IS_MM(me)) { + char root[PATH_MAX + 1]; + char key[PATH_MAX + 1]; + struct mapent *tmp; + int status; + char *base; + +- if (!strchr(me->multi->key, '/')) ++ if (!strchr(MM_ROOT(me)->key, '/')) + /* Indirect multi-mount root */ + /* sprintf okay - if it's mounted, it's + * PATH_MAX or less bytes */ +- sprintf(root, "%s/%s", ap->path, me->multi->key); ++ sprintf(root, "%s/%s", ap->path, MM_ROOT(me)->key); + else +- strcpy(root, me->multi->key); ++ strcpy(root, MM_ROOT(me)->key); + +- if (is_mm_root) ++ if (IS_MM_ROOT(me)) + base = NULL; + else + base = me->key + strlen(root); +@@ -588,7 +588,7 @@ static int umount_subtree_mounts(struct + return 0; + } + +- if (!left && is_mm_root) { ++ if (!left && IS_MM_ROOT(me)) { + status = cache_delete_offset_list(mc, me->key); + if (status != CHE_OK) { + warn(ap->logopt, "couldn't delete offset list"); +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -686,7 +686,7 @@ int mount_autofs_offset(struct autofs_po + * a mount that has been automatically mounted by + * the kernel NFS client. + */ +- if (me->multi != me && ++ if (!IS_MM_ROOT(me) && + is_mounted(me->key, MNTS_REAL)) + return MOUNT_OFFSET_IGNORE; + +@@ -1220,11 +1220,11 @@ static void *do_mount_direct(void *arg) + * for direct mount multi-mounts with no real mount at + * their base so they will be expired. + */ +- if (close_fd && me == me->multi) ++ if (close_fd && IS_MM_ROOT(me)) + close_fd = 0; + if (!close_fd) + me->ioctlfd = mt.ioctlfd; +- if (me->multi && me->multi != me) ++ if (IS_MM(me) && !IS_MM_ROOT(me)) + flags |= MNTS_OFFSET; + } + ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -756,7 +756,7 @@ int lookup_ghost(struct autofs_point *ap + goto next; + + /* It's a busy multi-mount - leave till next time */ +- if (list_empty(&me->multi_list)) ++ if (IS_MM(me)) + error(ap->logopt, + "invalid key %s", me->key); + goto next; +@@ -846,12 +846,12 @@ static int lookup_amd_instance(struct au + char *m_key; + + me = cache_lookup_distinct(map->mc, name); +- if (!me || !me->multi) { ++ if (!me || !IS_MM(me)) { + error(ap->logopt, "expected multi mount entry not found"); + return NSS_STATUS_UNKNOWN; + } + +- m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 2); ++ m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2); + if (!m_key) { + error(ap->logopt, + "failed to allocate storage for search key"); +@@ -860,7 +860,7 @@ static int lookup_amd_instance(struct au + + strcpy(m_key, ap->path); + strcat(m_key, "/"); +- strcat(m_key, me->multi->key); ++ strcat(m_key, MM_ROOT(me)->key); + + mnt = mnts_find_amdmount(m_key); + free(m_key); +@@ -1363,7 +1363,7 @@ void lookup_prune_one_cache(struct autof + * created on demand and managed by expire and don't + * prune the multi-map owner map entry. + */ +- if (*me->key == '/' || me->multi == me) { ++ if (*me->key == '/' || IS_MM_ROOT(me)) { + me = cache_enumerate(mc, me); + continue; + } +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -183,6 +183,11 @@ struct mapent { + ino_t ino; + }; + ++#define IS_MM(me) (me->multi) ++#define IS_MM_ROOT(me) (me->multi == me) ++#define MM_ROOT(me) (me->multi) ++#define MM_PARENT(me) (me->parent) ++ + void cache_lock_cleanup(void *arg); + void cache_readlock(struct mapent_cache *mc); + void cache_writelock(struct mapent_cache *mc); +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -374,7 +374,7 @@ struct mapent *cache_lookup_first(struct + + while (me) { + /* Multi mount entries are not primary */ +- if (me->multi && me->multi != me) { ++ if (IS_MM(me) && !IS_MM_ROOT(me)) { + me = me->next; + continue; + } +@@ -397,7 +397,7 @@ struct mapent *cache_lookup_next(struct + this = me->next; + while (this) { + /* Multi mount entries are not primary */ +- if (this->multi && this->multi != this) { ++ if (IS_MM(this) && !IS_MM_ROOT(this)) { + this = this->next; + continue; + } +@@ -413,7 +413,7 @@ struct mapent *cache_lookup_next(struct + + while (this) { + /* Multi mount entries are not primary */ +- if (this->multi && this->multi != this) { ++ if (IS_MM(this) && !IS_MM_ROOT(this)) { + this = this->next; + continue; + } +@@ -435,7 +435,7 @@ struct mapent *cache_lookup_key_next(str + next = me->next; + while (next) { + /* Multi mount entries are not primary */ +- if (me->multi && me->multi != me) ++ if (IS_MM(me) && !IS_MM_ROOT(me)) + continue; + if (!strcmp(me->key, next->key)) + return next; +@@ -706,7 +706,7 @@ int cache_update_offset(struct mapent_ca + me = cache_lookup_distinct(mc, key); + if (me) { + cache_add_ordered_offset(me, &owner->multi_list); +- me->multi = owner; ++ MM_ROOT(me) = owner; + goto done; + } + ret = CHE_FAIL; +@@ -784,14 +784,14 @@ int cache_set_offset_parent(struct mapen + this = cache_lookup_distinct(mc, offset); + if (!this) + return 0; +- if (!this->multi) ++ if (!IS_MM(this)) + return 0; + + parent = get_offset_parent(mc, offset); + if (parent) + this->parent = parent; + else +- this->parent = this->multi; ++ this->parent = MM_ROOT(this); + + return 1; + } +@@ -849,7 +849,7 @@ int cache_delete_offset(struct mapent_ca + return CHE_FAIL; + + if (strcmp(key, me->key) == 0) { +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + return CHE_FAIL; + mc->hash[hashval] = me->next; + goto delete; +@@ -859,7 +859,7 @@ int cache_delete_offset(struct mapent_ca + pred = me; + me = me->next; + if (strcmp(key, me->key) == 0) { +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + return CHE_FAIL; + pred->next = me->next; + goto delete; +@@ -897,7 +897,7 @@ int cache_delete(struct mapent_cache *mc + me = me->next; + if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; +- if (me->multi && !list_empty(&me->multi_list)) { ++ if (IS_MM(me)) { + ret = CHE_FAIL; + goto done; + } +@@ -926,7 +926,7 @@ int cache_delete(struct mapent_cache *mc + + if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; +- if (me->multi && !list_empty(&me->multi_list)) { ++ if (IS_MM(me)) { + ret = CHE_FAIL; + goto done; + } +@@ -965,7 +965,7 @@ int cache_delete_offset_list(struct mape + return CHE_FAIL; + + /* Not offset list owner */ +- if (me->multi != me) ++ if (!IS_MM_ROOT(me)) + return CHE_FAIL; + + head = &me->multi_list; +@@ -986,13 +986,13 @@ int cache_delete_offset_list(struct mape + this = list_entry(next, struct mapent, multi_list); + next = next->next; + list_del_init(&this->multi_list); +- this->multi = NULL; ++ MM_ROOT(this) = NULL; + debug(logopt, "deleting offset key %s", this->key); + status = cache_delete(mc, this->key); + if (status == CHE_FAIL) { + warn(logopt, + "failed to delete offset %s", this->key); +- this->multi = me; ++ MM_ROOT(this) = me; + /* TODO: add list back in */ + remain++; + } +@@ -1000,7 +1000,7 @@ int cache_delete_offset_list(struct mape + + if (!remain) { + list_del_init(&me->multi_list); +- me->multi = NULL; ++ MM_ROOT(me) = NULL; + } + + if (remain) +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2159,7 +2159,7 @@ int try_remount(struct autofs_point *ap, + } else { + me->flags &= ~MOUNT_FLAG_DIR_CREATED; + if (type == t_offset) { +- if (!is_mounted(me->parent->key, MNTS_REAL)) ++ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL)) + me->flags |= MOUNT_FLAG_DIR_CREATED; + } + } +@@ -2306,7 +2306,7 @@ void set_indirect_mount_tree_catatonic(s + goto next; + + /* Only need to set offset mounts catatonic */ +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + set_multi_mount_tree_catatonic(ap, me); + next: + me = cache_enumerate(mc, me); +@@ -2326,7 +2326,7 @@ next: + void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) + { + /* Set offset mounts catatonic for this mapent */ +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + set_multi_mount_tree_catatonic(ap, me); + set_mount_catatonic(ap, me, me->ioctlfd); + } +@@ -2484,12 +2484,12 @@ static int rmdir_path_offset(struct auto + int ret; + + if (ap->type == LKP_DIRECT) +- return rmdir_path(ap, oe->key, oe->multi->dev); ++ return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev); + + dir = strdup(oe->key); + + if (ap->flags & MOUNT_FLAG_GHOST) +- split = strlen(ap->path) + strlen(oe->multi->key) + 1; ++ split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1; + else + split = strlen(ap->path); + +@@ -2684,7 +2684,7 @@ int mount_multi_triggers(struct autofs_p + oe = cache_lookup_distinct(me->mc, key); + if (!oe || !oe->mapent) + goto cont; +- if (oe->age != me->multi->age) { ++ if (oe->age != MM_ROOT(me)->age) { + /* Best effort */ + do_umount_offset(ap, oe, root, start); + goto cont; +@@ -2718,7 +2718,7 @@ int umount_multi_triggers(struct autofs_ + + left = do_umount_multi_triggers(ap, me, root, start, base); + +- if (!left && me->multi == me) { ++ if (!left && IS_MM_ROOT(me)) { + /* + * Special case. + * If we can't umount the root container then we can't +--- autofs-5.1.4.orig/modules/lookup_file.c ++++ autofs-5.1.4/modules/lookup_file.c +@@ -1217,8 +1217,8 @@ int lookup_mount(struct autofs_point *ap + + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +--- autofs-5.1.4.orig/modules/lookup_hosts.c ++++ autofs-5.1.4/modules/lookup_hosts.c +@@ -177,7 +177,7 @@ static void update_hosts_mounts(struct a + me = cache_lookup_first(mc); + while (me) { + /* Hosts map entry not yet expanded or already expired */ +- if (!me->multi) ++ if (!IS_MM(me)) + goto next; + + debug(ap->logopt, MODPREFIX "get list of exports for %s", me->key); +@@ -200,7 +200,7 @@ next: + * Hosts map entry not yet expanded, already expired + * or not the base of the tree + */ +- if (!me->multi || me->multi != me) ++ if (!IS_MM(me) || !IS_MM_ROOT(me)) + goto cont; + + debug(ap->logopt, MODPREFIX +--- autofs-5.1.4.orig/modules/lookup_ldap.c ++++ autofs-5.1.4/modules/lookup_ldap.c +@@ -3718,8 +3718,8 @@ int lookup_mount(struct autofs_point *ap + if (ap->type == LKP_INDIRECT && *key != '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +--- autofs-5.1.4.orig/modules/lookup_nisplus.c ++++ autofs-5.1.4/modules/lookup_nisplus.c +@@ -740,8 +740,8 @@ int lookup_mount(struct autofs_point *ap + if (ap->type == LKP_INDIRECT && *key != '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +--- autofs-5.1.4.orig/modules/lookup_program.c ++++ autofs-5.1.4/modules/lookup_program.c +@@ -664,7 +664,7 @@ int lookup_mount(struct autofs_point *ap + name_len, ent, ctxt->parse->context); + goto out_free; + } else { +- if (me->multi && me->multi != me) { ++ if (IS_MM(me) && !IS_MM_ROOT(me)) { + cache_unlock(mc); + warn(ap->logopt, MODPREFIX + "unexpected lookup for active multi-mount" +@@ -675,7 +675,7 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(mc); + me = cache_lookup_distinct(mc, name); + if (me) { +- if (me->multi) ++ if (IS_MM(me)) + cache_delete_offset_list(mc, name); + cache_delete(mc, name); + } +--- autofs-5.1.4.orig/modules/lookup_sss.c ++++ autofs-5.1.4/modules/lookup_sss.c +@@ -1073,8 +1073,8 @@ int lookup_mount(struct autofs_point *ap + + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else + lkp_key = strdup(key); + cache_unlock(mc); +--- autofs-5.1.4.orig/modules/lookup_yp.c ++++ autofs-5.1.4/modules/lookup_yp.c +@@ -844,8 +844,8 @@ int lookup_mount(struct autofs_point *ap + if (ap->type == LKP_INDIRECT && *key != '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1150,7 +1150,7 @@ static int mount_subtree(struct autofs_p + + rv = 0; + +- mm_key = me->multi->key; ++ mm_key = MM_ROOT(me)->key; + + if (*mm_key == '/') { + mm_root = mm_key; +@@ -1164,7 +1164,7 @@ static int mount_subtree(struct autofs_p + } + mm_root_len = strlen(mm_root); + +- if (me == me->multi) { ++ if (IS_MM_ROOT(me)) { + char key[PATH_MAX + 1]; + + if (mm_root_len + 1 > PATH_MAX) { +@@ -1181,7 +1181,7 @@ static int mount_subtree(struct autofs_p + + /* Mount root offset if it exists */ + ro = cache_lookup_distinct(me->mc, key); +- if (ro && ro->age == me->multi->age) { ++ if (ro && ro->age == MM_ROOT(me)->age) { + char *myoptions, *ro_loc; + int namelen = name ? strlen(name) : 0; + int ro_len; +@@ -1352,7 +1352,7 @@ int parse_mount(struct autofs_point *ap, + if (*name == '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, name); +- if (me && me->multi && me->multi != me) { ++ if (me && IS_MM(me) && !IS_MM_ROOT(me)) { + cache_unlock(mc); + mapent_len = strlen(mapent) + 1; + pmapent = malloc(mapent_len + 1); +@@ -1507,7 +1507,7 @@ dont_expand: + } + + /* So we know we're the multi-mount root */ +- if (!me->multi) ++ if (!IS_MM(me)) + me->multi = me; + else { + /* +@@ -1632,7 +1632,7 @@ dont_expand: + */ + cache_readlock(mc); + if (*name == '/' && +- (me = cache_lookup_distinct(mc, name)) && me->multi) { ++ (me = cache_lookup_distinct(mc, name)) && IS_MM(me)) { + cache_unlock(mc); + loc = strdup(p); + if (!loc) { diff --git a/autofs-5.1.7-add-tree_mapent_add_node.patch b/autofs-5.1.7-add-tree_mapent_add_node.patch new file mode 100644 index 0000000..952c1f6 --- /dev/null +++ b/autofs-5.1.7-add-tree_mapent_add_node.patch @@ -0,0 +1,123 @@ +autofs-5.1.7 - add tree_mapent_add_node() + +From: Ian Kent + +Add function tree_mapent_add_node() to the mapent tree handling +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 1 + + include/mounts.h | 1 + + lib/cache.c | 5 ++--- + lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 52 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -33,6 +33,7 @@ + - add a len field to struct autofs_point. + - make tree implementation data independent. + - add mapent tree implementation. ++- add tree_mapent_add_node(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -215,6 +215,7 @@ struct mapent *cache_partial_match_wild( + int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); + void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); ++struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key); + int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); + 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); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -169,6 +169,7 @@ void mnts_get_expire_list(struct list_he + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); ++int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -719,8 +719,7 @@ void cache_update_negative(struct mapent + } + + +-static struct mapent *get_offset_parent(struct mapent_cache *mc, +- const char *key) ++struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key) + { + struct mapent *me; + char *parent, *tail; +@@ -766,7 +765,7 @@ int cache_set_offset_parent(struct mapen + if (!IS_MM(this)) + return 0; + +- parent = get_offset_parent(mc, offset); ++ parent = cache_get_offset_parent(mc, offset); + if (parent) + this->parent = parent; + else +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1481,6 +1481,53 @@ static void tree_mapent_free(struct tree + n->right = NULL; + } + ++int tree_mapent_add_node(struct mapent_cache *mc, ++ const char *root, const char *key) ++{ ++ unsigned int logopt = mc->ap->logopt; ++ struct tree_node *tree, *n; ++ struct mapent *base; ++ struct mapent *parent; ++ struct mapent *me; ++ ++ base = cache_lookup_distinct(mc, root); ++ if (!base) { ++ error(logopt, ++ "failed to find multi-mount root for key %s", key); ++ return 0; ++ } ++ ++ if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { ++ error(logopt, ++ "failed to find multi-mount root of offset tree", ++ key); ++ return 0; ++ } ++ tree = MAPENT_ROOT(base); ++ ++ me = cache_lookup_distinct(mc, key); ++ if (!me) { ++ error(logopt, ++ "failed to find key %s of multi-mount", key); ++ return 0; ++ } ++ ++ n = tree_add_node(tree, me); ++ if (!n) ++ return 0; ++ ++ MAPENT_SET_ROOT(me, tree) ++ ++ /* Set the subtree parent */ ++ parent = cache_get_offset_parent(mc, key); ++ if (!parent) ++ MAPENT_SET_PARENT(me, tree) ++ else ++ MAPENT_SET_PARENT(me, MAPENT_NODE(parent)) ++ ++ return 1; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch b/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch new file mode 100644 index 0000000..93c4828 --- /dev/null +++ b/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch @@ -0,0 +1,88 @@ +autofs-5.1.7 - add tree_mapent_cleanup_offsets() + +From: Ian Kent + +Add function tree_mapent_cleanup_offsets() to the mapent tree handling +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 1 + + lib/mounts.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 47 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -37,6 +37,7 @@ + - add tree_mapent_delete_offsets(). + - add tree_mapent_traverse_subtree(). + - fix mount_fullpath(). ++- add tree_mapent_cleanup_offsets(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -171,6 +171,7 @@ void mnts_set_mounted_mount(struct autof + struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); ++void tree_mapent_cleanup_offsets(struct mapent *oe); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1647,6 +1647,51 @@ int tree_mapent_delete_offsets(struct ma + return 1; + } + ++static void tree_mapent_umount_mount(struct autofs_point *ap, const char *mp) ++{ ++ if (is_mounted(mp, MNTS_ALL)) { ++ if (umount(mp)) { ++ error(ap->logopt, "error recovering from mount fail"); ++ error(ap->logopt, "cannot umount %s", mp); ++ } ++ } ++} ++ ++static int tree_mapent_cleanup_offsets_work(struct tree_node *n, void *ptr) ++{ ++ struct mapent *oe = MAPENT(n); ++ struct traverse_subtree_context *ctxt = ptr; ++ ++ tree_mapent_umount_mount(ctxt->ap, oe->key); ++ ++ return 1; ++} ++ ++void tree_mapent_cleanup_offsets(struct mapent *oe) ++{ ++ struct tree_node *base = MAPENT_NODE(oe); ++ struct traverse_subtree_context ctxt = { ++ .ap = oe->mc->ap, ++ .base = base, ++ .strict = 0, ++ }; ++ struct autofs_point *ap = oe->mc->ap; ++ ++ tree_mapent_traverse_subtree(base, tree_mapent_cleanup_offsets_work, &ctxt); ++ ++ /* Cleanup base mount after offsets have been cleaned up */ ++ if (*oe->key == '/') ++ tree_mapent_umount_mount(ap, oe->key); ++ else { ++ char mp[PATH_MAX + 1]; ++ ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) ++ error(ap->logopt, "mount path is too long"); ++ else ++ tree_mapent_umount_mount(ap, mp); ++ } ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/autofs-5.1.7-add-tree_mapent_delete_offsets.patch b/autofs-5.1.7-add-tree_mapent_delete_offsets.patch new file mode 100644 index 0000000..5357cb5 --- /dev/null +++ b/autofs-5.1.7-add-tree_mapent_delete_offsets.patch @@ -0,0 +1,113 @@ +autofs-5.1.7 - add tree_mapent_delete_offsets() + +From: Ian Kent + +Add function tree_mapent_delete_offsets() to the mapent tree handling +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/mounts.h | 1 + lib/mounts.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 72 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -34,6 +34,7 @@ + - make tree implementation data independent. + - add mapent tree implementation. + - add tree_mapent_add_node(). ++- add tree_mapent_delete_offsets(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -170,6 +170,7 @@ void mnts_put_expire_list(struct list_he + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); ++int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1528,6 +1528,76 @@ int tree_mapent_add_node(struct mapent_c + return 1; + } + ++static int tree_mapent_delete_offset_tree(struct tree_node *root) ++{ ++ struct mapent *me = MAPENT(root); ++ unsigned int logopt = me->mc->ap->logopt; ++ int ret = CHE_OK; ++ ++ if (root->left) { ++ ret = tree_mapent_delete_offset_tree(root->left); ++ if (!ret) ++ return 0; ++ root->left = NULL; ++ } ++ if (root->right) { ++ ret = tree_mapent_delete_offset_tree(root->right); ++ if (!ret) ++ return 0; ++ root->right = NULL; ++ } ++ ++ /* Keep the owner of the multi-mount offset tree and clear ++ * the root and parent when done. ++ */ ++ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) { ++ struct tree_node *root = MAPENT_ROOT(me); ++ ++ debug(logopt, "deleting offset key %s", me->key); ++ ++ /* cache_delete won't delete an active offset */ ++ MAPENT_SET_ROOT(me, NULL); ++ ret = cache_delete(me->mc, me->key); ++ if (ret != CHE_OK) { ++ MAPENT_SET_ROOT(me, root); ++ warn(logopt, "failed to delete offset %s", me->key); ++ } ++ } else { ++ MAPENT_SET_ROOT(me, NULL); ++ MAPENT_SET_PARENT(me, NULL); ++ } ++ ++ return ret == CHE_OK ? 1 : 0; ++} ++ ++int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key) ++{ ++ unsigned int logopt = mc->ap->logopt; ++ struct mapent *me; ++ ++ me = cache_lookup_distinct(mc, key); ++ if (!me) { ++ error(logopt, ++ "failed to find multi-mount root for key %s", key); ++ return 0; ++ } ++ ++ /* Not offset list owner */ ++ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) { ++ error(logopt, ++ "mapent for key %s is not multi-mount owner", key); ++ return 0; ++ } ++ ++ if (!tree_mapent_delete_offset_tree(MAPENT_ROOT(me))) { ++ error(logopt, ++ "could not delete map entry offsets for key %s", key); ++ return 0; ++ } ++ ++ return 1; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch b/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch new file mode 100644 index 0000000..482aea7 --- /dev/null +++ b/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch @@ -0,0 +1,79 @@ +autofs-5.1.7 - add tree_mapent_traverse_subtree() + +From: Ian Kent + +Add function tree_mapent_traverse_subtree() that enumerates offsets from +a given base node bounded by subtree nesting points. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -35,6 +35,7 @@ + - add mapent tree implementation. + - add tree_mapent_add_node(). + - add tree_mapent_delete_offsets(). ++- add tree_mapent_traverse_subtree(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1528,6 +1528,53 @@ int tree_mapent_add_node(struct mapent_c + return 1; + } + ++static inline int tree_mapent_is_root(struct mapent *oe) ++{ ++ /* Offset "/" is a special case, it's looked up and mounted ++ * seperately because the offset tree may or may not have a ++ * real mount at the base and the triggers inside it need to ++ * be mounted in either case. Also the order requires the ++ * offset at the top of the (sub)tree to be handled after ++ * the traversal. ++ */ ++ return (oe->key[oe->len - 1] == '/' || ++ MAPENT_ROOT(oe) == MAPENT_NODE(oe)); ++} ++ ++struct traverse_subtree_context { ++ struct autofs_point *ap; ++ struct tree_node *base; ++ int strict; ++}; ++ ++static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct mapent *oe = MAPENT(n); ++ int ret = 1; ++ ++ if (n->left) { ++ ret = tree_mapent_traverse_subtree(n->left, work, ctxt); ++ if (!ret && ctxt->strict) ++ goto done; ++ } ++ ++ /* Node is not multi-mount root and is part of current subtree */ ++ if (!tree_mapent_is_root(oe) && MAPENT_PARENT(oe) == ctxt->base) { ++ ret = work(n, ctxt); ++ if (!ret && ctxt->strict) ++ goto done; ++ } ++ ++ if (n->right) { ++ ret = tree_mapent_traverse_subtree(n->right, work, ctxt); ++ if (!ret && ctxt->strict) ++ goto done; ++ } ++done: ++ return ret; ++} ++ + static int tree_mapent_delete_offset_tree(struct tree_node *root) + { + struct mapent *me = MAPENT(root); diff --git a/autofs-5.1.7-add-xdr_exports.patch b/autofs-5.1.7-add-xdr_exports.patch new file mode 100644 index 0000000..93abd0a --- /dev/null +++ b/autofs-5.1.7-add-xdr_exports.patch @@ -0,0 +1,325 @@ +autofs-5.1.7 - add xdr_exports() + +From: Ian Kent + +Add an xdr_exports() function to get NFS exports from a server. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 3 + + include/rpc_subs.h | 14 ++++++ + lib/rpc_subs.c | 120 +++++++++++++++++++++++++++++++++++------------- + modules/lookup_hosts.c | 25 +++------- + 4 files changed, 112 insertions(+), 50 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -1,3 +1,6 @@ ++ ++- add xdr_exports(). ++ + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. + - fix directory create permission. +--- autofs-5.1.4.orig/include/rpc_subs.h ++++ autofs-5.1.4/include/rpc_subs.h +@@ -17,6 +17,7 @@ + #define _RPC_SUBS_H + + #include ++#include + #include + #include + #include +@@ -47,6 +48,17 @@ + + #define HOST_ENT_BUF_SIZE 2048 + ++struct hostinfo { ++ char *name; ++ struct hostinfo *next; ++}; ++ ++struct exportinfo { ++ char *dir; ++ struct hostinfo *hosts; ++ struct exportinfo *next; ++}; ++ + struct conn_info { + const char *host; + struct sockaddr *addr; +@@ -71,6 +83,8 @@ int rpc_portmap_getport(struct conn_info + int rpc_ping_proto(struct conn_info *); + int rpc_ping(const char *, int, unsigned int, long, long, unsigned int); + double monotonic_elapsed(struct timespec, struct timespec); ++struct exportinfo *rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); ++void rpc_exports_free(struct exportinfo *exports); + const char *get_addr_string(struct sockaddr *, char *, socklen_t); + + #endif +--- autofs-5.1.4.orig/lib/rpc_subs.c ++++ autofs-5.1.4/lib/rpc_subs.c +@@ -41,7 +41,6 @@ const rpcprog_t rpcb_prog = PMAPPROG; + const rpcvers_t rpcb_version = PMAPVERS; + #endif + +-#include "mount.h" + #include "rpc_subs.h" + #include "replicated.h" + #include "automount.h" +@@ -58,6 +57,17 @@ const rpcvers_t rpcb_version = PMAPVERS; + + #define MAX_NETWORK_LEN 255 + ++#define EXPPATHLEN 1024 ++#define EXPNAMELEN 255 ++ ++#define MOUNTPROG 100005 ++ ++#define MOUNTVERS 1 ++#define MOUNTVERS_NFSV3 3 ++#define MOUNTVERS_POSIX 2 ++ ++#define MOUNTPROC_EXPORT 5 ++ + /* Get numeric value of the n bits starting at position p */ + #define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) + +@@ -1102,7 +1112,55 @@ double monotonic_elapsed(struct timespec + return t2 - t1; + } + +-static int rpc_get_exports_proto(struct conn_info *info, exports *exp) ++static bool_t xdr_host(XDR *xdrs, struct hostinfo *host) ++{ ++ if (!xdr_string(xdrs, &host->name, EXPNAMELEN)) ++ return FALSE; ++ return TRUE; ++} ++ ++static bool_t xdr_hosts(XDR *xdrs, struct hostinfo **hosts) ++{ ++ unsigned int size = sizeof(struct hostinfo); ++ char **host; ++ ++ host = (char **) hosts; ++ while (1) { ++ if (!xdr_pointer(xdrs, host, size, (xdrproc_t) xdr_host)) ++ return FALSE; ++ if (!*host) ++ break; ++ host = (char **) &((struct hostinfo *) *host)->next; ++ } ++ return TRUE; ++} ++ ++static bool_t xdr_export(XDR *xdrs, struct exportinfo *export) ++{ ++ if (!xdr_string(xdrs, &export->dir, EXPPATHLEN)) ++ return FALSE; ++ if (!xdr_hosts(xdrs, &export->hosts)) ++ return FALSE; ++ return TRUE; ++} ++ ++bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports) ++{ ++ unsigned int size = sizeof(struct exportinfo); ++ char **export; ++ ++ export = (char **) exports; ++ while (1) { ++ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) ++ return FALSE; ++ if (!*export) ++ break; ++ export = (char **) &((struct exportinfo *) *export)->next; ++ } ++ return TRUE; ++} ++ ++static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exports) + { + CLIENT *client; + enum clnt_stat status; +@@ -1133,7 +1191,7 @@ static int rpc_get_exports_proto(struct + while (1) { + status = clnt_call(client, MOUNTPROC_EXPORT, + (xdrproc_t) xdr_void, NULL, +- (xdrproc_t) xdr_exports, (caddr_t) exp, ++ (xdrproc_t) xdr_exports, (caddr_t) exports, + info->timeout); + if (status == RPC_SUCCESS) + break; +@@ -1168,41 +1226,43 @@ static int rpc_get_exports_proto(struct + return 1; + } + +-static void rpc_export_free(exports item) ++static void rpc_export_free(struct exportinfo *export) + { +- groups grp; +- groups tmp; ++ struct hostinfo *host, *tmp; + +- if (item->ex_dir) +- free(item->ex_dir); ++ if (export->dir) ++ free(export->dir); + +- grp = item->ex_groups; +- while (grp) { +- if (grp->gr_name) +- free(grp->gr_name); +- tmp = grp; +- grp = grp->gr_next; ++ host = export->hosts; ++ while (host) { ++ if (host->name) ++ free(host->name); ++ tmp = host; ++ host = host->next; + free(tmp); + } +- free(item); ++ free(export); + } + +-void rpc_exports_free(exports list) ++void rpc_exports_free(struct exportinfo *exports) + { +- exports tmp; ++ struct exportinfo *export, *tmp; + +- while (list) { +- tmp = list; +- list = list->ex_next; ++ export = exports; ++ while (export) { ++ tmp = export; ++ export = export->next; + rpc_export_free(tmp); + } + return; + } + +-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option) ++struct exportinfo *rpc_get_exports(const char *host, ++ long seconds, long micros, ++ unsigned int option) + { + struct conn_info info; +- exports exportlist; ++ struct exportinfo *exports = NULL; + struct pmap parms; + int status; + +@@ -1231,11 +1291,9 @@ exports rpc_get_exports(const char *host + if (status < 0) + goto try_tcp; + +- memset(&exportlist, '\0', sizeof(exportlist)); +- +- status = rpc_get_exports_proto(&info, &exportlist); ++ status = rpc_get_exports_proto(&info, &exports); + if (status) +- return exportlist; ++ return exports; + + try_tcp: + info.proto = IPPROTO_TCP; +@@ -1246,13 +1304,11 @@ try_tcp: + if (status < 0) + return NULL; + +- memset(&exportlist, '\0', sizeof(exportlist)); +- +- status = rpc_get_exports_proto(&info, &exportlist); ++ status = rpc_get_exports_proto(&info, &exports); + if (!status) + return NULL; + +- return exportlist; ++ return exports; + } + + const char *get_addr_string(struct sockaddr *sa, char *name, socklen_t len) +--- autofs-5.1.4.orig/modules/lookup_hosts.c ++++ autofs-5.1.4/modules/lookup_hosts.c +@@ -20,14 +20,6 @@ + #include + #include + +-/* +- * Avoid annoying compiler noise by using an alternate name for +- * typedef name in mount.h +- */ +-#define name __dummy_type_name +-#include "mount.h" +-#undef name +- + #define MODULE_LOOKUP + #include "automount.h" + #include "nsswitch.h" +@@ -43,9 +35,6 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); +-void rpc_exports_free(exports list); +- + int lookup_init(const char *mapfmt, + int argc, const char *const *argv, void **context) + { +@@ -99,7 +88,7 @@ static char *get_exports(struct autofs_p + { + char buf[MAX_ERR_BUF]; + char *mapent; +- exports exp, this; ++ struct exportinfo *exp, *this; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + +@@ -111,7 +100,7 @@ static char *get_exports(struct autofs_p + if (mapent) { + int len = strlen(mapent) + 1; + +- len += strlen(host) + 2*(strlen(this->ex_dir) + 2) + 3; ++ len += strlen(host) + 2*(strlen(this->dir) + 2) + 3; + mapent = realloc(mapent, len); + if (!mapent) { + char *estr; +@@ -121,10 +110,10 @@ static char *get_exports(struct autofs_p + return NULL; + } + strcat(mapent, " \""); +- strcat(mapent, this->ex_dir); ++ strcat(mapent, this->dir); + strcat(mapent, "\""); + } else { +- int len = 2*(strlen(this->ex_dir) + 2) + strlen(host) + 3; ++ int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3; + + mapent = malloc(len); + if (!mapent) { +@@ -135,16 +124,16 @@ static char *get_exports(struct autofs_p + return NULL; + } + strcpy(mapent, "\""); +- strcat(mapent, this->ex_dir); ++ strcat(mapent, this->dir); + strcat(mapent, "\""); + } + strcat(mapent, " \""); + strcat(mapent, host); + strcat(mapent, ":"); +- strcat(mapent, this->ex_dir); ++ strcat(mapent, this->dir); + strcat(mapent, "\""); + +- this = this->ex_next; ++ this = this->next; + } + rpc_exports_free(exp); + diff --git a/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch b/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch new file mode 100644 index 0000000..ee72041 --- /dev/null +++ b/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - cater for empty mounts list in mnts_get_expire_list() + +From: Ian Kent + +Coverity: var_deref_model: Passing null pointer "tree" to + "tree_traverse_inorder", which dereferences it. + +This obviously can't happen but deal with it anyway to quiet Coverity. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -64,6 +64,7 @@ + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. ++- cater for empty mounts list in mnts_get_expire_list(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_he + } + } + +- tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); +- tree_free(tree); ++ if (tree) { ++ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); ++ tree_free(tree); ++ } + done: + mnts_hash_mutex_unlock(); + } diff --git a/autofs-5.1.7-check-for-offset-with-no-mount-location.patch b/autofs-5.1.7-check-for-offset-with-no-mount-location.patch new file mode 100644 index 0000000..945c56d --- /dev/null +++ b/autofs-5.1.7-check-for-offset-with-no-mount-location.patch @@ -0,0 +1,46 @@ +autofs-5.1.7 - check for offset with no mount location + +From: Ian Kent + +Offsets need to have a mount location, check for it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 15 ++++++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -47,6 +47,7 @@ + - pass root length to mount_fullpath(). + - remove unused function master_submount_list_empty(). + - move amd mounts removal into lib/mounts.c. ++- check for offset with no mount location. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -803,7 +803,20 @@ update_offset_entry(struct autofs_point + + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); + +- /* Internal hosts map may have loc == NULL */ ++ if (!loc || !*loc) { ++ const char *type = ap->entry->maps->type; ++ ++ /* If it's not the internal hosts map it must have a ++ * mount location. ++ */ ++ if (!type || strcmp(type, "hosts")) { ++ error(ap->logopt, ++ MODPREFIX "syntax error in offset %s -> %s", ++ m_offset, loc); ++ return CHE_FAIL; ++ } ++ } ++ + if (!*m_offset) { + error(ap->logopt, + MODPREFIX "syntax error in offset %s -> %s", m_offset, loc); diff --git a/autofs-5.1.7-cleanup-cache_delete-a-little.patch b/autofs-5.1.7-cleanup-cache_delete-a-little.patch new file mode 100644 index 0000000..9fd6022 --- /dev/null +++ b/autofs-5.1.7-cleanup-cache_delete-a-little.patch @@ -0,0 +1,60 @@ +autofs-5.1.7 - cleanup cache_delete() a little + +From: Ian Kent + +There's no reason to use local function storage for the passed in key +just use the given key. + +Also, if there's no hash array entry for the key then there's no cache +entry so don't return a fail for this case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 11 +++-------- + 2 files changed, 4 insertions(+), 8 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -23,6 +23,7 @@ + - eliminate some strlen calls in offset handling. + - don't add offset mounts to mounted mounts table. + - reduce umount EBUSY check delay. ++- cleanup cache_delete() a little. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -887,20 +887,15 @@ int cache_delete(struct mapent_cache *mc + struct mapent *me = NULL, *pred; + u_int32_t hashval = hash(key, mc->size); + int ret = CHE_OK; +- char this[PATH_MAX]; +- +- strcpy(this, key); + + me = mc->hash[hashval]; +- if (!me) { +- ret = CHE_FAIL; ++ if (!me) + goto done; +- } + + while (me->next != NULL) { + pred = me; + me = me->next; +- if (strcmp(this, me->key) == 0) { ++ if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; + if (me->multi && !list_empty(&me->multi_list)) { + ret = CHE_FAIL; +@@ -929,7 +924,7 @@ int cache_delete(struct mapent_cache *mc + if (!me) + goto done; + +- if (strcmp(this, me->key) == 0) { ++ if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; + if (me->multi && !list_empty(&me->multi_list)) { + ret = CHE_FAIL; diff --git a/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch b/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch new file mode 100644 index 0000000..b6a2afd --- /dev/null +++ b/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch @@ -0,0 +1,197 @@ +autofs-5.1.7 - don't add offset mounts to mounted mounts table + +From: Ian Kent + +Multi-mount offset mounts are added to the mounted mounts table whether +they have a real mount or not. If there are a large number of offsets +this can add unnecessary overhead to the mounted mounts table processing. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 14 ++++---------- + daemon/indirect.c | 4 +++- + include/mounts.h | 2 +- + lib/mounts.c | 43 +++++++++++-------------------------------- + 5 files changed, 20 insertions(+), 44 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -21,6 +21,7 @@ + - remove unused mount offset list lock functions. + - eliminate count_mounts() from expire_proc_indirect(). + - eliminate some strlen calls in offset handling. ++- don't add offset mounts to mounted mounts table. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -605,9 +605,6 @@ force_umount: + } else + info(ap->logopt, "umounted offset mount %s", me->key); + +- if (!rv) +- mnts_remove_mount(me->key, MNTS_OFFSET); +- + return rv; + } + +@@ -761,12 +758,6 @@ int mount_autofs_offset(struct autofs_po + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + +- mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET); +- if (!mnt) +- error(ap->logopt, +- "failed to add offset mount %s to mounted list", +- me->key); +- + debug(ap->logopt, "mounted trigger %s", me->key); + + return MOUNT_OFFSET_OK; +@@ -1214,6 +1205,7 @@ static void *do_mount_direct(void *arg) + struct mapent *me; + struct statfs fs; + unsigned int close_fd = 0; ++ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED; + + sbmnt = mnts_find_submount(mt.name); + if (statfs(mt.name, &fs) == -1 || +@@ -1232,6 +1224,8 @@ static void *do_mount_direct(void *arg) + close_fd = 0; + if (!close_fd) + me->ioctlfd = mt.ioctlfd; ++ if (me->multi && me->multi != me) ++ flags |= MNTS_OFFSET; + } + ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); + cache_unlock(mt.mc); +@@ -1240,7 +1234,7 @@ static void *do_mount_direct(void *arg) + + info(ap->logopt, "mounted %s", mt.name); + +- mnts_set_mounted_mount(ap, mt.name); ++ mnts_set_mounted_mount(ap, mt.name, flags); + + conditional_alarm_add(ap, ap->exp_runfreq); + } else { +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -747,12 +747,14 @@ static void *do_mount_indirect(void *arg + status = lookup_nss_mount(ap, NULL, mt.name, mt.len); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + if (status) { ++ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED; ++ + ops->send_ready(ap->logopt, + ap->ioctlfd, mt.wait_queue_token); + + info(ap->logopt, "mounted %s", buf); + +- mnts_set_mounted_mount(ap, mt.name); ++ mnts_set_mounted_mount(ap, mt.name, flags); + + conditional_alarm_add(ap, ap->exp_runfreq); + } else { +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -131,7 +131,7 @@ struct mnt_list *get_mnt_list(const char + unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); +-void mnts_set_mounted_mount(struct autofs_point *ap, const char *name); ++void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1172,7 +1172,7 @@ struct mnt_list *mnts_add_mount(struct a + this = mnts_get_mount(mp); + if (this) { + this->flags |= flags; +- if (list_empty(&this->mount)) ++ if ((this->flags & MNTS_MOUNTED) && list_empty(&this->mount)) + list_add(&this->mount, &ap->mounts); + } + mnts_hash_mutex_unlock(); +@@ -1193,42 +1193,23 @@ void mnts_remove_mount(const char *mp, u + this = mnts_lookup(mp); + if (this && this->flags & flags) { + this->flags &= ~flags; +- if (!(this->flags & (MNTS_OFFSET|MNTS_MOUNTED))) ++ if (!(this->flags & MNTS_MOUNTED)) + list_del_init(&this->mount); + __mnts_put_mount(this); + } + mnts_hash_mutex_unlock(); + } + +-void mnts_set_mounted_mount(struct autofs_point *ap, const char *name) ++void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags) + { + struct mnt_list *mnt; + +- mnt = mnts_add_mount(ap, name, MNTS_MOUNTED); ++ mnt = mnts_add_mount(ap, name, flags); + if (!mnt) { + error(ap->logopt, + "failed to add mount %s to mounted list", name); + return; + } +- +- /* Offset mount failed but non-strict returns success */ +- if (mnt->flags & MNTS_OFFSET && +- !is_mounted(mnt->mp, MNTS_REAL)) { +- mnt->flags &= ~MNTS_MOUNTED; +- mnts_put_mount(mnt); +- } +- +- /* Housekeeping. +- * Set the base type of the mounted mount. +- * MNTS_AUTOFS and MNTS_OFFSET are set at mount time and +- * are used during expire. +- */ +- if (!(mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET))) { +- if (ap->type == LKP_INDIRECT) +- mnt->flags |= MNTS_INDIRECT; +- else +- mnt->flags |= MNTS_DIRECT; +- } + } + + unsigned int mnts_has_mounted_mounts(struct autofs_point *ap) +@@ -1943,17 +1924,13 @@ static int do_remount_direct(struct auto + + ret = lookup_nss_mount(ap, NULL, path, strlen(path)); + if (ret) { +- struct mnt_list *mnt; ++ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED; + + /* If it's an offset mount add a mount reference */ +- if (type == t_offset) { +- mnt = mnts_add_mount(ap, path, MNTS_OFFSET); +- if (!mnt) +- error(ap->logopt, +- "failed to add mount %s to mounted list", path); +- } ++ if (type == t_offset) ++ flags |= MNTS_OFFSET; + +- mnts_set_mounted_mount(ap, path); ++ mnts_set_mounted_mount(ap, path, flags); + + info(ap->logopt, "re-connected to %s", path); + +@@ -2028,7 +2005,9 @@ static int do_remount_indirect(struct au + + ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len); + if (ret) { +- mnts_set_mounted_mount(ap, buf); ++ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED; ++ ++ mnts_set_mounted_mount(ap, buf, flags); + + info(ap->logopt, "re-connected to %s", buf); + diff --git a/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch b/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch new file mode 100644 index 0000000..421a00d --- /dev/null +++ b/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch @@ -0,0 +1,60 @@ +autofs-5.1.7 - don't pass root to do_mount_autofs_offset() + +From: Ian Kent + +The root parameter of do_mount_autofs_offset() is used only in a +debug log message. It doesn't really add any value to debugging +so remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 9 ++++----- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -25,6 +25,7 @@ + - reduce umount EBUSY check delay. + - cleanup cache_delete() a little. + - rename path to m_offset in update_offset_entry(). ++- don't pass root to do_mount_autofs_offset(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2447,13 +2447,12 @@ out: + return rv; + } + +-static int do_mount_autofs_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root) ++static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe) + { + int mounted = 0; + int ret; + +- debug(ap->logopt, "mount offset %s at %s", oe->key, root); ++ debug(ap->logopt, "mount offset %s", oe->key); + + ret = mount_autofs_offset(ap, oe); + if (ret >= MOUNT_OFFSET_OK) +@@ -2645,7 +2644,7 @@ static int do_umount_offset(struct autof + */ + ret = rmdir_path_offset(ap, oe); + if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root); ++ ret = do_mount_autofs_offset(ap, oe); + if (ret) + left++; + /* But we did origianlly create this */ +@@ -2691,7 +2690,7 @@ int mount_multi_triggers(struct autofs_p + goto cont; + } + +- mounted += do_mount_autofs_offset(ap, oe, root); ++ mounted += do_mount_autofs_offset(ap, oe); + + /* + * If re-constructing a multi-mount it's necessary to walk diff --git a/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch b/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch new file mode 100644 index 0000000..aba0639 --- /dev/null +++ b/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch @@ -0,0 +1,41 @@ +autofs-5.1.7 - dont try umount after stat() ENOENT fail + +From: Ian Kent + +Coverity: Calling function "umount" that uses "me->key" after a check + function. This can cause a time-of-check, time-of-use race + condition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -57,6 +57,7 @@ + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). ++- dont try umount after stat() ENOENT fail. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_po + + ret = stat(me->key, &st); + if (ret == -1) { ++ int save_errno = errno; ++ + error(ap->logopt, + "failed to stat direct mount trigger %s", me->key); +- goto out_umount; ++ if (save_errno != ENOENT) ++ goto out_umount; ++ goto out_err; + } + + ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); diff --git a/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch b/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch new file mode 100644 index 0000000..f4c2354 --- /dev/null +++ b/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch @@ -0,0 +1,107 @@ +autofs-5.1.7 - dont use realloc in host exports list processing + +From: Ian Kent + +If a server exports list is very large calling realloc(3) for each +export is slow. It's better to traverse the exports list twice, once +to calculate the length of the mapent then allocate the memory and +traverse the exports list again to construct the mapent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 59 +++++++++++++++++++++--------------------------- + 2 files changed, 27 insertions(+), 33 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -1,6 +1,7 @@ + + - add xdr_exports(). + - remove mount.x and rpcgen dependencies. ++- dont use realloc in host exports list processing. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/lookup_hosts.c ++++ autofs-5.1.4/modules/lookup_hosts.c +@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_p + char buf[MAX_ERR_BUF]; + char *mapent; + struct exportinfo *exp, *this; ++ size_t hostlen = strlen(host); ++ size_t mapent_len; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + + exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER); + +- mapent = NULL; + this = exp; ++ mapent_len = 0; + while (this) { +- if (mapent) { +- int len = strlen(mapent) + 1; ++ mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3; ++ this = this->next; ++ } + +- len += strlen(host) + 2*(strlen(this->dir) + 2) + 3; +- mapent = realloc(mapent, len); +- if (!mapent) { +- char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, MODPREFIX "malloc: %s", estr); +- rpc_exports_free(exp); +- return NULL; +- } +- strcat(mapent, " \""); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); +- } else { +- int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3; +- +- mapent = malloc(len); +- if (!mapent) { +- char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, MODPREFIX "malloc: %s", estr); +- rpc_exports_free(exp); +- return NULL; +- } ++ mapent = malloc(mapent_len + 1); ++ if (!mapent) { ++ char *estr; ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ error(ap->logopt, MODPREFIX "exports lookup failed for %s", host); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++ *mapent = 0; ++ ++ this = exp; ++ while (this) { ++ if (!*mapent) + strcpy(mapent, "\""); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); +- } ++ else ++ strcat(mapent, " \""); ++ strcat(mapent, this->dir); ++ strcat(mapent, "\""); ++ + strcat(mapent, " \""); + strcat(mapent, host); + strcat(mapent, ":"); +@@ -137,9 +133,6 @@ static char *get_exports(struct autofs_p + } + rpc_exports_free(exp); + +- if (!mapent) +- error(ap->logopt, MODPREFIX "exports lookup failed for %s", host); +- + return mapent; + } + diff --git a/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch b/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch new file mode 100644 index 0000000..2c506c1 --- /dev/null +++ b/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch @@ -0,0 +1,372 @@ +autofs-5.1.7 - eliminate cache_lookup_offset() usage + +From: Ian Kent + +The function cache_lookup_offset() will do a linear search when +looking for an offset. If the number of offsets is large this +can be a lot of overhead. + +But it's possible to use the information already present where +this is called to to do a hashed lookup instead. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 82 +++++++++++++++++++++++++++++++++------------------- + modules/parse_sun.c | 77 ++++++++++++++++++++++++++++++------------------ + 3 files changed, 102 insertions(+), 58 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -4,6 +4,7 @@ + - dont use realloc in host exports list processing. + - use sprintf() when constructing hosts mapent. + - fix mnts_remove_amdmount() uses wrong list. ++- eliminate cache_lookup_offset() usage. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2489,24 +2489,27 @@ int mount_multi_triggers(struct autofs_p + char *offset = path; + struct mapent *oe; + struct list_head *pos = NULL; +- unsigned int fs_path_len; ++ unsigned int root_len = strlen(root); + int mounted; + +- fs_path_len = start + strlen(base); +- if (fs_path_len > PATH_MAX) +- return -1; +- + mounted = 0; + offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); + while (offset) { +- int plen = fs_path_len + strlen(offset); ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); + +- if (plen > PATH_MAX) { ++ if (key_len > PATH_MAX) { + warn(ap->logopt, "path loo long"); + goto cont; + } + +- oe = cache_lookup_offset(base, offset, start, &me->multi_list); ++ /* The root offset is always mounted seperately so the ++ * offset path will always be root + offset. ++ */ ++ strcpy(key, root); ++ strcat(key, offset); ++ ++ oe = cache_lookup_distinct(me->mc, key); + if (!oe || !oe->mapent) + goto cont; + +@@ -2519,12 +2522,8 @@ int mount_multi_triggers(struct autofs_p + */ + if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { + if (oe->ioctlfd != -1 || +- is_mounted(oe->key, MNTS_REAL)) { +- char oe_root[PATH_MAX + 1]; +- strcpy(oe_root, root); +- strcat(oe_root, offset); +- mount_multi_triggers(ap, oe, oe_root, strlen(oe_root), base); +- } ++ is_mounted(oe->key, MNTS_REAL)) ++ mount_multi_triggers(ap, oe, key, strlen(key), base); + } + cont: + offset = cache_get_offset(base, +@@ -2578,6 +2577,8 @@ int umount_multi_triggers(struct autofs_ + const char o_root[] = "/"; + const char *mm_base; + int left, start; ++ unsigned int root_len; ++ unsigned int mm_base_len; + + left = 0; + start = strlen(root); +@@ -2591,11 +2592,28 @@ int umount_multi_triggers(struct autofs_ + + pos = NULL; + offset = path; ++ root_len = start; ++ mm_base_len = strlen(mm_base); + + while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); + char *oe_base; + +- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); ++ if (mm_base_len > 1) ++ key_len += mm_base_len; ++ ++ if (key_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ continue; ++ } ++ ++ strcpy(key, root); ++ if (mm_base_len > 1) ++ strcat(key, mm_base); ++ strcat(key, offset); ++ ++ oe = cache_lookup_distinct(me->mc, key); + /* root offset is a special case */ + if (!oe || (strlen(oe->key) - start) == 1) + continue; +@@ -2680,13 +2698,14 @@ int clean_stale_multi_triggers(struct au + char *root; + char mm_top[PATH_MAX + 1]; + char path[PATH_MAX + 1]; +- char buf[MAX_ERR_BUF]; + char *offset; + struct mapent *oe; + struct list_head *mm_root, *pos; + const char o_root[] = "/"; + const char *mm_base; + int left, start; ++ unsigned int root_len; ++ unsigned int mm_base_len; + time_t age; + + if (top) +@@ -2714,14 +2733,30 @@ int clean_stale_multi_triggers(struct au + + pos = NULL; + offset = path; ++ root_len = start; ++ mm_base_len = strlen(mm_base); + age = me->multi->age; + + while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); + char *oe_base; +- char *key; + int ret; + +- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); ++ if (mm_base_len > 1) ++ key_len += mm_base_len; ++ ++ if (key_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ continue; ++ } ++ ++ strcpy(key, root); ++ if (mm_base_len > 1) ++ strcat(key, mm_base); ++ strcat(key, offset); ++ ++ oe = cache_lookup_distinct(me->mc, key); + /* root offset is a special case */ + if (!oe || (strlen(oe->key) - start) == 1) + continue; +@@ -2772,14 +2807,6 @@ int clean_stale_multi_triggers(struct au + } + } + +- key = strdup(oe->key); +- if (!key) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, "malloc: %s", estr); +- left++; +- continue; +- } +- + debug(ap->logopt, "umount offset %s", oe->key); + + if (umount_autofs_offset(ap, oe)) { +@@ -2794,7 +2821,6 @@ int clean_stale_multi_triggers(struct au + if (cache_delete_offset(oe->mc, key) == CHE_FAIL) + error(ap->logopt, + "failed to delete offset key %s", key); +- free(key); + continue; + } + +@@ -2810,7 +2836,6 @@ int clean_stale_multi_triggers(struct au + left++; + /* But we did origianlly create this */ + oe->flags |= MOUNT_FLAG_DIR_CREATED; +- free(key); + continue; + } + /* +@@ -2828,7 +2853,6 @@ int clean_stale_multi_triggers(struct au + error(ap->logopt, + "failed to delete offset key %s", key); + } +- free(key); + } + + return left; +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1088,6 +1088,8 @@ static void cleanup_multi_triggers(struc + struct list_head *mm_root, *pos; + const char o_root[] = "/"; + const char *mm_base; ++ unsigned int root_len; ++ unsigned int mm_base_len; + + mm_root = &me->multi->multi_list; + +@@ -1097,16 +1099,31 @@ static void cleanup_multi_triggers(struc + mm_base = base; + + pos = NULL; ++ root_len = strlen(root); ++ mm_base_len = strlen(mm_base); + + /* 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) ++ unsigned int path_len = root_len + strlen(poffset); ++ ++ if (mm_base_len > 1) ++ path_len += mm_base_len; ++ ++ if (path_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); + continue; ++ } + + strcpy(path, root); ++ if (mm_base_len > 1) ++ strcat(path, mm_base); + strcat(path, poffset); ++ ++ oe = cache_lookup_distinct(me->mc, path); ++ /* root offset is a special case */ ++ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) ++ continue; ++ + if (umount(path)) { + error(ap->logopt, "error recovering from mount fail"); + error(ap->logopt, "cannot umount offset %s", path); +@@ -1119,17 +1136,14 @@ static void cleanup_multi_triggers(struc + 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 *mm_root, *mm_base, *mm_key; +- const char *mnt_root; +- unsigned int mm_root_len, mnt_root_len; ++ unsigned int mm_root_len; + int start, ret = 0, rv; + + rv = 0; + +- mm = me->multi; +- mm_key = mm->key; ++ mm_key = me->multi->key; + + if (*mm_key == '/') { + mm_root = mm_key; +@@ -1143,20 +1157,26 @@ static int mount_subtree(struct autofs_p + } + mm_root_len = strlen(mm_root); + +- mnt_root = mm_root; +- mnt_root_len = mm_root_len; +- + if (me == me->multi) { ++ char key[PATH_MAX + 1]; ++ ++ if (mm_root_len + 1 > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ return 1; ++ } ++ + /* name = NULL */ + /* destination = mm_root */ + mm_base = "/"; + ++ strcpy(key, mm_root); ++ strcat(key, mm_base); ++ + /* Mount root offset if it exists */ +- ro = cache_lookup_offset(mm_base, mm_base, strlen(mm_root), &me->multi_list); ++ ro = cache_lookup_distinct(me->mc, key); + if (ro) { +- char *myoptions, *ro_loc, *tmp; ++ char *myoptions, *ro_loc; + int namelen = name ? strlen(name) : 0; +- const char *root; + int ro_len; + + myoptions = NULL; +@@ -1174,13 +1194,7 @@ static int mount_subtree(struct autofs_p + if (ro_loc) + ro_len = strlen(ro_loc); + +- tmp = alloca(mnt_root_len + 2); +- strcpy(tmp, mnt_root); +- tmp[mnt_root_len] = '/'; +- tmp[mnt_root_len + 1] = '\0'; +- root = tmp; +- +- rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt); ++ rv = sun_mount(ap, key, name, namelen, ro_loc, ro_len, myoptions, ctxt); + + free(myoptions); + if (ro_loc) +@@ -1188,11 +1202,11 @@ static int mount_subtree(struct autofs_p + } + + if (ro && rv == 0) { +- ret = mount_multi_triggers(ap, me, mnt_root, start, mm_base); ++ 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, mnt_root, start, mm_base); ++ cleanup_multi_triggers(ap, me, mm_root, start, mm_base); + return 1; + } + } else if (rv <= 0) { +@@ -1208,24 +1222,29 @@ static int mount_subtree(struct autofs_p + int loclen = strlen(loc); + int namelen = strlen(name); + +- mnt_root = name; +- + /* name = mm_root + mm_base */ + /* destination = mm_root + mm_base = name */ + mm_base = &me->key[start]; + +- rv = sun_mount(ap, mnt_root, name, namelen, loc, loclen, options, ctxt); ++ rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); + if (rv == 0) { +- ret = mount_multi_triggers(ap, me->multi, mnt_root, start, mm_base); ++ ret = mount_multi_triggers(ap, me->multi, name, start, mm_base); + if (ret == -1) { + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, mnt_root, start, mm_base); ++ cleanup_multi_triggers(ap, me, name, start, mm_base); + return 1; + } + } else if (rv < 0) { +- char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1); ++ char mm_root_base[PATH_MAX + 1]; ++ unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1; + ++ if (mm_root_base_len > PATH_MAX) { ++ warn(ap->logopt, MODPREFIX "path too long"); ++ cache_delete_offset_list(me->mc, name); ++ return 1; ++ } ++ + strcpy(mm_root_base, mm_root); + strcat(mm_root_base, mm_base); + diff --git a/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch b/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch new file mode 100644 index 0000000..f1138c0 --- /dev/null +++ b/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch @@ -0,0 +1,285 @@ +autofs-5.1.7 - eliminate clean_stale_multi_triggers() + +From: Ian Kent + +Eliminate clean_stale_multi_triggers() by checking for stale offsets at +the time mount_subtree() is called. + +This should result in the same behaviour but eliminate an additional +seperate traversal of the offset list. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 209 ++++++++++------------------------------------------ + modules/parse_sun.c | 10 -- + 3 files changed, 43 insertions(+), 177 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -11,6 +11,7 @@ + - remove redundant variables from mount_autofs_offset(). + - remove unused parameter form do_mount_autofs_offset(). + - refactor umount_multi_triggers(). ++- eliminate clean_stale_multi_triggers(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2595,10 +2595,44 @@ static int do_umount_offset(struct autof + oe_base = oe->key + strlen(root); + left += do_umount_multi_triggers(ap, oe, root, oe_base); + ++ /* ++ * If an offset that has an active mount has been removed ++ * from the multi-mount we don't want to attempt to trigger ++ * mounts for it. Obviously this is because it has been ++ * removed, but less obvious is the potential strange ++ * behaviour that can result if we do try and mount it ++ * again after it's been expired. For example, if an NFS ++ * file system is no longer exported and is later umounted ++ * it can be mounted again without any error message but ++ * shows as an empty directory. That's going to confuse ++ * people for sure. ++ * ++ * If the mount cannot be umounted (the process is now ++ * using a stale mount) the offset needs to be invalidated ++ * so no further mounts will be attempted but the offset ++ * cache entry must remain so expires can continue to ++ * attempt to umount it. If the mount can be umounted and ++ * the offset is removed, at least for NFS we will get ++ * ESTALE errors when attempting list the directory. ++ */ + if (oe->ioctlfd != -1 || + is_mounted(oe->key, MNTS_REAL)) { +- left++; +- return left; ++ if (umount_ent(ap, oe->key) && ++ is_mounted(oe->key, MNTS_REAL)) { ++ debug(ap->logopt, ++ "offset %s has active mount, invalidate", ++ oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key. ++ */ ++ if (oe->mapent) { ++ free(oe->mapent); ++ oe->mapent = NULL; ++ } ++ return ++left; ++ } + } + + debug(ap->logopt, "umount offset %s", oe->key); +@@ -2660,6 +2694,11 @@ int mount_multi_triggers(struct autofs_p + oe = cache_lookup_distinct(me->mc, key); + if (!oe || !oe->mapent) + goto cont; ++ if (oe->age != me->multi->age) { ++ /* Best effort */ ++ do_umount_offset(ap, oe, root); ++ goto cont; ++ } + + mounted += do_mount_autofs_offset(ap, oe, root); + +@@ -2718,170 +2757,4 @@ int umount_multi_triggers(struct autofs_ + } + + return left; +-} +- +-int clean_stale_multi_triggers(struct autofs_point *ap, +- struct mapent *me, char *top, const char *base) +-{ +- char *root; +- char mm_top[PATH_MAX + 1]; +- 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; +- unsigned int root_len; +- unsigned int mm_base_len; +- time_t age; +- +- if (top) +- root = top; +- else { +- if (!strchr(me->multi->key, '/')) +- /* Indirect multi-mount root */ +- /* sprintf okay - if it's mounted, it's +- * PATH_MAX or less bytes */ +- sprintf(mm_top, "%s/%s", ap->path, me->multi->key); +- else +- strcpy(mm_top, me->multi->key); +- root = mm_top; +- } +- +- 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; +- root_len = start; +- mm_base_len = strlen(mm_base); +- age = me->multi->age; +- +- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- char *oe_base; +- int ret; +- +- if (mm_base_len > 1) +- key_len += mm_base_len; +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- continue; +- } +- +- strcpy(key, root); +- if (mm_base_len > 1) +- strcat(key, mm_base); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- /* root offset is a special case */ +- if (!oe || (strlen(oe->key) - start) == 1) +- continue; +- +- /* Check for and umount stale subtree offsets */ +- oe_base = oe->key + strlen(root); +- ret = clean_stale_multi_triggers(ap, oe, root, oe_base); +- left += ret; +- if (ret) +- continue; +- +- if (oe->age == age) +- continue; +- +- /* +- * If an offset that has an active mount has been removed +- * from the multi-mount we don't want to attempt to trigger +- * mounts for it. Obviously this is because it has been +- * removed, but less obvious is the potential strange +- * behaviour that can result if we do try and mount it +- * again after it's been expired. For example, if an NFS +- * file system is no longer exported and is later umounted +- * it can be mounted again without any error message but +- * shows as an empty directory. That's going to confuse +- * people for sure. +- * +- * If the mount cannot be umounted (the process is now +- * using a stale mount) the offset needs to be invalidated +- * so no further mounts will be attempted but the offset +- * cache entry must remain so expires can continue to +- * attempt to umount it. If the mount can be umounted and +- * the offset is removed, at least for NFS we will get +- * ESTALE errors when attempting list the directory. +- */ +- if (oe->ioctlfd != -1 || +- is_mounted(oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key) && +- is_mounted(oe->key, MNTS_REAL)) { +- debug(ap->logopt, +- "offset %s has active mount, invalidate", +- oe->key); +- if (oe->mapent) { +- free(oe->mapent); +- oe->mapent = NULL; +- } +- left++; +- continue; +- } +- } +- +- debug(ap->logopt, "umount offset %s", oe->key); +- +- if (umount_autofs_offset(ap, oe)) { +- warn(ap->logopt, "failed to umount offset %s", key); +- left++; +- } else { +- struct stat st; +- +- /* Mount point not ours to delete ? */ +- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) { +- debug(ap->logopt, "delete offset key %s", key); +- if (cache_delete_offset(oe->mc, key) == CHE_FAIL) +- error(ap->logopt, +- "failed to delete offset key %s", key); +- continue; +- } +- +- /* +- * An error due to partial directory removal is +- * ok so only try and remount the offset if the +- * actual mount point still exists. +- */ +- ret = rmdir_path_offset(ap, oe); +- if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root); +- if (ret) { +- left++; +- /* But we did origianlly create this */ +- oe->flags |= MOUNT_FLAG_DIR_CREATED; +- continue; +- } +- /* +- * Fall through if the trigger can't be mounted +- * again, since there is no offset there can't +- * be any mount requests so remove the map +- * entry from the cache. There's now a dead +- * offset mount, but what else can we do .... +- */ +- } +- +- debug(ap->logopt, "delete offset key %s", key); +- +- if (cache_delete_offset(oe->mc, key) == CHE_FAIL) +- error(ap->logopt, +- "failed to delete offset key %s", key); +- } +- } +- +- return left; + } +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1178,7 +1178,7 @@ static int mount_subtree(struct autofs_p + + /* Mount root offset if it exists */ + ro = cache_lookup_distinct(me->mc, key); +- if (ro) { ++ if (ro && ro->age == me->multi->age) { + char *myoptions, *ro_loc; + int namelen = name ? strlen(name) : 0; + int ro_len; +@@ -1612,14 +1612,6 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + +- /* +- * We've got the ordered list of multi-mount entries so go +- * through and remove any stale entries if this is the top +- * of the multi-mount and set the parent entry of each. +- */ +- if (me == me->multi) +- clean_stale_multi_triggers(ap, me, NULL, NULL); +- + rv = mount_subtree(ap, me, name, NULL, options, ctxt); + + cache_multi_unlock(me); diff --git a/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch b/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch new file mode 100644 index 0000000..e630e8b --- /dev/null +++ b/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch @@ -0,0 +1,132 @@ +autofs-5.1.7 - eliminate count_mounts() from expire_proc_indirect() + +From: Ian Kent + +The count_mounts() function traverses the directory tree under a given +automount in order to count the number of mounts. + +If there are many directories (such as when there is a very large +number of offset trigger mounts) this can take a long time. + +Eliminate the call in expire_proc_indirect() by changing the expire +ioctl function to better use the expire return from the kernel. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 4 ++-- + daemon/indirect.c | 10 +++++----- + lib/dev-ioctl-lib.c | 21 +++++++++++++-------- + 4 files changed, 21 insertions(+), 15 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -19,6 +19,7 @@ + - pass mapent_cache to update_offset_entry(). + - fix inconsistent locking in parse_mount(). + - remove unused mount offset list lock functions. ++- eliminate count_mounts() from expire_proc_indirect(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -884,7 +884,7 @@ cont: + ioctlfd = me->ioctlfd; + + ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); +- if (ret) { ++ if (ret == 1) { + left++; + pthread_setcancelstate(cur_state, NULL); + continue; +@@ -910,7 +910,7 @@ cont: + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); +- if (ret) ++ if (ret == 1) + left++; + pthread_setcancelstate(cur_state, NULL); + } +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -358,7 +358,6 @@ void *expire_proc_indirect(void *arg) + struct expire_args ec; + unsigned int how; + int offsets, submnts, count; +- int retries; + int ioctlfd, cur_state; + int status, ret, left; + +@@ -496,7 +495,7 @@ void *expire_proc_indirect(void *arg) + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); +- if (ret) ++ if (ret == 1) + left++; + pthread_setcancelstate(cur_state, NULL); + } +@@ -507,10 +506,11 @@ void *expire_proc_indirect(void *arg) + * so we need to umount or unlink them here. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- retries = (count_mounts(ap, ap->path, ap->dev) + 1); +- while (retries--) { ++ while (1) { + ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how); +- if (ret) ++ if (ret != 0 && errno == EAGAIN) ++ break; ++ if (ret == 1) + left++; + } + pthread_setcancelstate(cur_state, NULL); +--- autofs-5.1.4.orig/lib/dev-ioctl-lib.c ++++ autofs-5.1.4/lib/dev-ioctl-lib.c +@@ -650,6 +650,7 @@ static int expire(unsigned int logopt, + { + int ret, retries = EXPIRE_RETRIES; + unsigned int may_umount; ++ int save_errno = 0; + + while (retries--) { + struct timespec tm = {0, 100000000}; +@@ -657,9 +658,11 @@ static int expire(unsigned int logopt, + /* Ggenerate expire message for the mount. */ + ret = ioctl(fd, cmd, arg); + if (ret == -1) { ++ save_errno = errno; ++ + /* Mount has gone away */ + if (errno == EBADF || errno == EINVAL) +- return 0; ++ break; + + /* + * Other than EAGAIN is an expire error so continue. +@@ -673,14 +676,16 @@ static int expire(unsigned int logopt, + nanosleep(&tm, NULL); + } + +- may_umount = 0; +- if (ctl.ops->askumount(logopt, ioctlfd, &may_umount)) +- return -1; +- +- if (!may_umount) +- return 1; ++ if (!ret || save_errno == EAGAIN) { ++ may_umount = 0; ++ if (!ctl.ops->askumount(logopt, ioctlfd, &may_umount)) { ++ if (!may_umount) ++ ret = 1; ++ } ++ } ++ errno = save_errno; + +- return 0; ++ return ret; + } + + static int dev_ioctl_expire(unsigned int logopt, diff --git a/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch b/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch new file mode 100644 index 0000000..4bb965f --- /dev/null +++ b/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch @@ -0,0 +1,82 @@ +autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node() + +From: Ian Kent + +Since we need to create the offset tree after adding the offset entries +to the mapent cache (from a list.h list) there's no need to lookup the +mapent in tree_mapent_add_node() and validate it. Just use it directly +when calling tree_mapent_add_node() and avoid a cache lookup on every +node addition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 13 ++----------- + modules/parse_sun.c | 2 +- + 4 files changed, 5 insertions(+), 13 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -70,6 +70,7 @@ + - fix amd hosts mount expire. + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). ++- eliminate redundant cache lookup in tree_mapent_add_node(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); +-int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key); ++int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree + } + + int tree_mapent_add_node(struct mapent_cache *mc, +- struct tree_node *root, const char *key) ++ struct tree_node *root, struct mapent *me) + { +- unsigned int logopt = mc->ap->logopt; + struct tree_node *n; + struct mapent *parent; +- struct mapent *me; +- +- me = cache_lookup_distinct(mc, key); +- if (!me) { +- error(logopt, +- "failed to find key %s of multi-mount", key); +- return 0; +- } + + n = tree_add_node(root, me); + if (!n) +@@ -1540,7 +1531,7 @@ int tree_mapent_add_node(struct mapent_c + MAPENT_SET_ROOT(me, root) + + /* Set the subtree parent */ +- parent = cache_get_offset_parent(mc, key); ++ parent = cache_get_offset_parent(mc, me->key); + if (!parent) + MAPENT_SET_PARENT(me, root) + else +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1548,7 +1548,7 @@ dont_expand: + return 1; + } + list_for_each_entry_safe(oe, tmp, &offsets, work) { +- if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key)) ++ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe)) + error(ap->logopt, "failed to add offset %s to tree", oe->key); + list_del_init(&oe->work); + } diff --git a/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch b/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch new file mode 100644 index 0000000..03f39ab --- /dev/null +++ b/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch @@ -0,0 +1,124 @@ +autofs-5.1.7 - eliminate some strlen calls in offset handling + +From: Ian Kent + +There are a number of places where strlen() is used to re-calculate +the length of a string. Eliminate some of those by calculating the +length once and passing it to the functions that do the re-calculation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 30 +++++++++++++++++------------- + 2 files changed, 18 insertions(+), 13 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -20,6 +20,7 @@ + - fix inconsistent locking in parse_mount(). + - remove unused mount offset list lock functions. + - eliminate count_mounts() from expire_proc_indirect(). ++- eliminate some strlen calls in offset handling. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2534,10 +2534,12 @@ static int rmdir_path_offset(struct auto + return ret; + } + +-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root); ++static int do_umount_offset(struct autofs_point *ap, ++ struct mapent *oe, const char *root, int start); + + static int do_umount_multi_triggers(struct autofs_point *ap, +- struct mapent *me, const char *root, const char *base) ++ struct mapent *me, const char *root, ++ int start, const char *base) + { + char path[PATH_MAX + 1]; + char *offset; +@@ -2545,12 +2547,11 @@ static int do_umount_multi_triggers(stru + struct list_head *mm_root, *pos; + const char o_root[] = "/"; + const char *mm_base; +- int left, start; ++ int left; + unsigned int root_len; + unsigned int mm_base_len; + + left = 0; +- start = strlen(root); + + mm_root = &me->multi->multi_list; + +@@ -2586,13 +2587,14 @@ static int do_umount_multi_triggers(stru + if (!oe || (strlen(oe->key) - start) == 1) + continue; + +- left += do_umount_offset(ap, oe, root); ++ left += do_umount_offset(ap, oe, root, start); + } + + return left; + } + +-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root) ++static int do_umount_offset(struct autofs_point *ap, ++ struct mapent *oe, const char *root, int start) + { + char *oe_base; + int left = 0; +@@ -2601,8 +2603,8 @@ static int do_umount_offset(struct autof + * Check for and umount subtree offsets resulting from + * nonstrict mount fail. + */ +- oe_base = oe->key + strlen(root); +- left += do_umount_multi_triggers(ap, oe, root, oe_base); ++ oe_base = oe->key + start; ++ left += do_umount_multi_triggers(ap, oe, root, start, oe_base); + + /* + * If an offset that has an active mount has been removed +@@ -2706,7 +2708,7 @@ int mount_multi_triggers(struct autofs_p + goto cont; + if (oe->age != me->multi->age) { + /* Best effort */ +- do_umount_offset(ap, oe, root); ++ do_umount_offset(ap, oe, root, start); + goto cont; + } + +@@ -2720,7 +2722,7 @@ int mount_multi_triggers(struct autofs_p + if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { + if (oe->ioctlfd != -1 || + is_mounted(oe->key, MNTS_REAL)) +- mount_multi_triggers(ap, oe, key, strlen(key), base); ++ mount_multi_triggers(ap, oe, key, key_len, base); + } + cont: + offset = cache_get_offset(base, +@@ -2732,9 +2734,11 @@ cont: + + int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) + { +- int left; ++ int left, start; ++ ++ start = strlen(root); + +- left = do_umount_multi_triggers(ap, me, root, base); ++ left = do_umount_multi_triggers(ap, me, root, start, base); + + if (!left && me->multi == me) { + /* +@@ -2747,7 +2751,7 @@ int umount_multi_triggers(struct autofs_ + info(ap->logopt, "unmounting dir = %s", root); + if (umount_ent(ap, root) && + is_mounted(root, MNTS_REAL)) { +- if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0) ++ if (mount_multi_triggers(ap, me, root, start, "/") < 0) + warn(ap->logopt, + "failed to remount offset triggers"); + return ++left; diff --git a/autofs-5.1.7-fix-amd-hosts-mount-expire.patch b/autofs-5.1.7-fix-amd-hosts-mount-expire.patch new file mode 100644 index 0000000..5087c74 --- /dev/null +++ b/autofs-5.1.7-fix-amd-hosts-mount-expire.patch @@ -0,0 +1,48 @@ +autofs-5.1.7 - fix amd hosts mount expire + +From: Ian Kent + +When swicthing to use the mnt_list to track mounts for expire, if the +amd hosts map entry name is for the host short name, the amd mount +entry for the short name gets removed. This causes a subsequent mounts +for host exports to fail. + +What should happen is the short name amd entry not be removed and a +mounted mount entry for the symlinked FQDN mount added so it expires. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 9 +++++---- + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -67,6 +67,7 @@ + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. + - fix amd section mounts map reload. ++- fix amd hosts mount expire. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap, + if (!rv) { + /* + * If entry->path doesn't match the mnt->mp then +- * the mount point path has changed and a new +- * mnt_list entry added for it, so remove the +- * original. ++ * it's a "host" map and the mount point path is ++ * different to the lookup name. Add a new mnt_list ++ * entry so that both the symlinked name and the ++ * mount expire. + */ + if (strcmp(this->path, mnt->mp)) +- mnts_remove_amdmount(this->path); ++ mnts_add_mount(ap, this->rhost, MNTS_INDIRECT|MNTS_MOUNTED); + break; + } + /* Not mounted, remove the mnt_list entry from amdmount list */ diff --git a/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch b/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch new file mode 100644 index 0000000..572ba6d --- /dev/null +++ b/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch @@ -0,0 +1,120 @@ +autofs-5.1.7 - fix amd section mounts map reload + +From: Ian Kent + +Master map section mounts (amd format mounts) get umounted on reload. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/master.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 81 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -66,6 +66,7 @@ + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. ++- fix amd section mounts map reload. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -882,6 +882,83 @@ struct master *master_new(const char *na + return master; + } + ++static void master_update_amd_mount_section_mount(struct master *master, ++ const char *path, time_t age) ++{ ++ unsigned int m_logopt = master->logopt; ++ struct master_mapent *entry; ++ struct map_source *source; ++ unsigned int loglevel; ++ unsigned int logopt; ++ unsigned int flags; ++ time_t timeout; ++ char *map; ++ char *opts; ++ ++ entry = master_find_mapent(master, path); ++ if (!entry) ++ return; ++ ++ map = conf_amd_get_map_name(path); ++ if (!map) ++ return; ++ ++ /* amd top level mounts have only one map */ ++ source = entry->maps; ++ if (strcmp(source->name, map) != 0) { ++ struct map_source *new; ++ char *type; ++ char *argv[2]; ++ ++ type = conf_amd_get_map_type(path); ++ argv[0] = map; ++ argv[1] = NULL; ++ ++ new = master_add_map_source(entry, type, "amd", ++ age, 1, (const char **) argv); ++ if (!new) { ++ error(m_logopt, ++ "failed to add source for amd section mount %s", ++ path); ++ if (type) ++ free(type); ++ goto out; ++ } ++ master_free_map_source(source, 0); ++ entry->maps = new; ++ source = new; ++ if (type) ++ free(type); ++ } ++ ++ loglevel = conf_amd_get_log_options(); ++ logopt = m_logopt; ++ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) ++ logopt = LOGOPT_DEBUG; ++ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) ++ logopt = LOGOPT_VERBOSE; ++ ++ flags = conf_amd_get_flags(path); ++ if (flags & CONF_BROWSABLE_DIRS) ++ entry->ap->flags |= MOUNT_FLAG_GHOST; ++ ++ opts = conf_amd_get_map_options(path); ++ if (opts) { ++ if (strstr(opts, "cache:=all")) ++ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ free(opts); ++ } ++ ++ entry->ap->logopt = logopt; ++ ++ timeout = conf_amd_get_dismount_interval(path); ++ set_exp_timeout(entry->ap, source, timeout); ++ source->master_line = 0; ++ entry->age = age; ++out: ++ free(map); ++} ++ + static void master_add_amd_mount_section_mounts(struct master *master, time_t age) + { + unsigned int m_logopt = master->logopt; +@@ -916,8 +993,10 @@ static void master_add_amd_mount_section + * master map it's not a duplicate, don't issue + * an error message. + */ +- if (ret == 1) ++ if (ret == 1) { ++ master_update_amd_mount_section_mount(master, path, age); + goto next; ++ } + info(m_logopt, + "amd section mount path conflict, %s ignored", + path); diff --git a/autofs-5.1.7-fix-arg-not-used-in-print.patch b/autofs-5.1.7-fix-arg-not-used-in-print.patch new file mode 100644 index 0000000..69196bf --- /dev/null +++ b/autofs-5.1.7-fix-arg-not-used-in-print.patch @@ -0,0 +1,36 @@ +autofs-5.1.7 - fix arg not used in error print + +From: Ian Kent + +Coverity: extra_argument: This argument was not used by the format + string: "key". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 4 +--- + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -60,6 +60,7 @@ + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). ++- fix arg not used in error print. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_c + } + + if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { +- error(logopt, +- "failed to find multi-mount root of offset tree", +- key); ++ error(logopt, "key %s is not multi-mount root", root); + return 0; + } + tree = MAPENT_ROOT(base); diff --git a/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch b/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch new file mode 100644 index 0000000..c83d273 --- /dev/null +++ b/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch @@ -0,0 +1,51 @@ +autofs-5.1.7 - fix dead code in mnts_add_mount() + +From: Ian Kent + +Coverity: dead_error_line: Execution cannot reach this statement: "free(mp);". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++------ + 2 files changed, 3 insertions(+), 6 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -59,6 +59,7 @@ + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). ++- fix dead code in mnts_add_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct a + if (*name == '/') { + mp = strdup(name); + if (!mp) +- goto fail; ++ return NULL; + } else { + int len = ap->len + strlen(name) + 2; + + mp = malloc(len); + if (!mp) +- goto fail; ++ return NULL; + strcpy(mp, ap->path); + strcat(mp, "/"); + strcat(mp, name); +@@ -1228,10 +1228,6 @@ struct mnt_list *mnts_add_mount(struct a + free(mp); + + return this; +-fail: +- if (mp) +- free(mp); +- return NULL; + } + + void mnts_remove_mount(const char *mp, unsigned int flags) diff --git a/autofs-5.1.7-fix-direct-mount-deadlock.patch b/autofs-5.1.7-fix-direct-mount-deadlock.patch new file mode 100644 index 0000000..ebe8930 --- /dev/null +++ b/autofs-5.1.7-fix-direct-mount-deadlock.patch @@ -0,0 +1,129 @@ +autofs-5.1.7 - fix direct mount deadlock + +From: Ian Kent + +When umounting direct mounts at exit or when umounting mounts no +longer in the map on re-load a deadlock can occur. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 22 +++++++++++++++++++++- + daemon/state.c | 14 +++++++++----- + 3 files changed, 31 insertions(+), 6 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -72,6 +72,7 @@ + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. ++- fix direct mount deadlock. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -84,11 +84,27 @@ static void mnts_cleanup(void *arg) + int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); ++ struct mapent_cache *mc = me->mc; + char buf[MAX_ERR_BUF]; + int ioctlfd = -1, rv, left, retries; ++ char key[PATH_MAX + 1]; ++ struct mapent *tmp; + int opened = 0; + +- left = umount_multi(ap, me->key, 0); ++ if (me->len > PATH_MAX) { ++ error(ap->logopt, "path too long"); ++ return 1; ++ } ++ strcpy(key, me->key); ++ ++ cache_unlock(mc); ++ left = umount_multi(ap, key, 0); ++ cache_readlock(mc); ++ tmp = cache_lookup_distinct(mc, key); ++ if (tmp != me) { ++ error(ap->logopt, "key %s no longer in mapent cache", key); ++ return -1; ++ } + if (left) { + warn(ap->logopt, "could not unmount %d dirs under %s", + left, me->key); +@@ -213,6 +229,7 @@ int umount_autofs_direct(struct autofs_p + mc = map->mc; + pthread_cleanup_push(cache_lock_cleanup, mc); + cache_readlock(mc); ++restart: + me = cache_enumerate(mc, NULL); + while (me) { + int error; +@@ -230,6 +247,9 @@ int umount_autofs_direct(struct autofs_p + * failed umount. + */ + error = do_umount_autofs_direct(ap, me); ++ /* cache became invalid, restart */ ++ if (error == -1) ++ goto restart; + if (!error) + goto done; + +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -348,11 +348,12 @@ static void do_readmap_cleanup(void *arg + return; + } + +-static void do_readmap_mount(struct autofs_point *ap, ++static int do_readmap_mount(struct autofs_point *ap, + struct map_source *map, struct mapent *me, time_t now) + { + struct mapent_cache *nc; + struct mapent *ne, *nested, *valid; ++ int ret = 0; + + nc = ap->entry->master->nc; + +@@ -411,7 +412,7 @@ static void do_readmap_mount(struct auto + cache_unlock(vmc); + error(ap->logopt, + "failed to find expected existing valid map entry"); +- return; ++ return ret; + } + /* Take over the mount if there is one */ + valid->ioctlfd = me->ioctlfd; +@@ -430,14 +431,14 @@ static void do_readmap_mount(struct auto + ap->exp_runfreq = runfreq; + } + } else if (!is_mounted(me->key, MNTS_REAL)) +- do_umount_autofs_direct(ap, me); ++ ret = do_umount_autofs_direct(ap, me); + else + debug(ap->logopt, + "%s is mounted", me->key); + } else + do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map)); + +- return; ++ return ret; + } + + static void *do_readmap(void *arg) +@@ -504,9 +505,12 @@ static void *do_readmap(void *arg) + mc = map->mc; + pthread_cleanup_push(cache_lock_cleanup, mc); + cache_readlock(mc); ++restart: + me = cache_enumerate(mc, NULL); + while (me) { +- do_readmap_mount(ap, map, me, now); ++ int ret = do_readmap_mount(ap, map, me, now); ++ if (ret == -1) ++ goto restart; + me = cache_enumerate(mc, me); + } + lookup_prune_one_cache(ap, map->mc, now); diff --git a/autofs-5.1.7-fix-double-free-in-parse_mapent.patch b/autofs-5.1.7-fix-double-free-in-parse_mapent.patch new file mode 100644 index 0000000..3d39c28 --- /dev/null +++ b/autofs-5.1.7-fix-double-free-in-parse_mapent.patch @@ -0,0 +1,35 @@ +autofs-5.1.7 - fix double free in parse_mapent() + +From: Ian Kent + +Coverity: +in parse_mapent(): double_free: Calling "free" frees pointer "newopt" + which has already been freed. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -62,6 +62,7 @@ + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). ++- fix double free in parse_mapent(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -976,8 +976,6 @@ static int parse_mapent(const char *ent, + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX + "concat_options: %s", estr); +- if (newopt) +- free(newopt); + free(myoptions); + return 0; + } diff --git a/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch b/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch new file mode 100644 index 0000000..ad68849 --- /dev/null +++ b/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch @@ -0,0 +1,33 @@ +autofs-5.1.7 - fix double unlock in parse_mount() + +From: Ian Kent + +Coverity: double_unlock: "cache_unlock" unlocks "mc->rwlock" while it + is unlocked. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -54,6 +54,7 @@ + - remove redundant if check. + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). ++- fix double unlock in parse_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1528,7 +1528,6 @@ dont_expand: + if (!loc) { + free(options); + free(pmapent); +- cache_unlock(mc); + warn(ap->logopt, MODPREFIX "out of memory"); + return 1; + } diff --git a/autofs-5.1.7-fix-flag-check-in-umount_multi.patch b/autofs-5.1.7-fix-flag-check-in-umount_multi.patch new file mode 100644 index 0000000..5921abd --- /dev/null +++ b/autofs-5.1.7-fix-flag-check-in-umount_multi.patch @@ -0,0 +1,34 @@ +autofs-5.1.7 - fix flags check in umount_multi() + +From: Ian Kent + +Coverity: operator_confusion: "ap->flags | 1" is always 1/true + regardless of the values of its operand. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -56,6 +56,7 @@ + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). ++- fix flags check in umount_multi(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -661,7 +661,7 @@ int umount_multi(struct autofs_point *ap + /* Check if the autofs mount has browse mode enabled. + * If so re-create the directory entry. + */ +- if (ap->flags | MOUNT_FLAG_GHOST) { ++ if (ap->flags & MOUNT_FLAG_GHOST) { + int ret; + + /* If the browse directory create fails log an diff --git a/autofs-5.1.7-fix-hosts-map-offset-order.patch b/autofs-5.1.7-fix-hosts-map-offset-order.patch new file mode 100644 index 0000000..e9b07d6 --- /dev/null +++ b/autofs-5.1.7-fix-hosts-map-offset-order.patch @@ -0,0 +1,289 @@ +autofs-5.1.7 - fix hosts map offset order + +From: Ian Kent + +Map entry offset paths to be in shortest to longest order but exports +from a server could come in any order. If there are a large number of +exports this can result in a lot of overhead when adding the offset +to the ordered list use to mount the offset during parsing since the +path length of exports can cary a lot. + +So leverage the tree implemention to sort the export offsets into +shortest to longest order as we go when constructing the mapent from +the exports list. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 2 - + include/mounts.h | 8 +++++ + include/rpc_subs.h | 3 ++ + lib/mounts.c | 57 +++++++++++++++++++++++++++++++++++++-- + modules/lookup_hosts.c | 71 ++++++++++++++++++++++++++++++++++++++----------- + 6 files changed, 124 insertions(+), 18 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -71,6 +71,7 @@ + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). ++- fix hosts map offset order. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -31,9 +31,9 @@ + #include "master.h" + #include "macros.h" + #include "log.h" ++#include "mounts.h" + #include "rpc_subs.h" + #include "parse_subs.h" +-#include "mounts.h" + #include "dev-ioctl-lib.h" + #include "parse_amd.h" + +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -52,6 +52,7 @@ extern const unsigned int t_direct; + extern const unsigned int t_offset; + + struct mnt_list; ++struct exportinfo; + struct mapent; + + struct tree_ops; +@@ -66,6 +67,9 @@ struct tree_node { + #define MNT_LIST(n) (container_of(n, struct mnt_list, node)) + #define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) + ++#define EXPORTINFO(n) (container_of(n, struct exportinfo, node)) ++#define EXPORT_NODE(ptr) ((struct tree_node *) &((struct exportinfo *) ptr)->node) ++ + #define MAPENT(n) (container_of(n, struct mapent, node)) + #define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node) + #define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root) +@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct a + void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); + unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); ++int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr); ++void tree_free(struct tree_node *root); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); ++struct tree_node *tree_host_root(struct exportinfo *exp); ++struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp); + struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); +--- autofs-5.1.4.orig/include/rpc_subs.h ++++ autofs-5.1.4/include/rpc_subs.h +@@ -23,6 +23,8 @@ + #include + #include + ++#include "automount.h" ++ + #define NFS4_VERSION 4 + + /* rpc helper subs */ +@@ -57,6 +59,7 @@ struct exportinfo { + char *dir; + struct hostinfo *hosts; + struct exportinfo *next; ++ struct tree_node node; + }; + + struct conn_info { +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = { + }; + static struct tree_ops *tree_mnt_ops = &mnt_ops; + ++static struct tree_node *tree_host_new(void *ptr); ++static int tree_host_cmp(struct tree_node *n, void *ptr); ++static void tree_host_free(struct tree_node *n); ++ ++static struct tree_ops host_ops = { ++ .new = tree_host_new, ++ .cmp = tree_host_cmp, ++ .free = tree_host_free, ++}; ++static struct tree_ops *tree_host_ops = &host_ops; ++ + static struct tree_node *tree_mapent_new(void *ptr); + static int tree_mapent_cmp(struct tree_node *n, void *ptr); + static void tree_mapent_free(struct tree_node *n); +@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(s + return NULL; + } + +-static void tree_free(struct tree_node *root) ++void tree_free(struct tree_node *root) + { + struct tree_ops *ops = root->ops; + +@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node * + ops->free(root); + } + +-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) ++int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) + { + int ret; + +@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_he + mnts_hash_mutex_unlock(); + } + ++struct tree_node *tree_host_root(struct exportinfo *exp) ++{ ++ return tree_root(tree_host_ops, exp); ++} ++ ++static struct tree_node *tree_host_new(void *ptr) ++{ ++ struct tree_node *n = EXPORT_NODE(ptr); ++ ++ n->ops = tree_host_ops; ++ n->left = NULL; ++ n->right = NULL; ++ ++ return n; ++} ++ ++static int tree_host_cmp(struct tree_node *n, void *ptr) ++{ ++ struct exportinfo *n_exp = EXPORTINFO(n); ++ size_t n_exp_len = strlen(n_exp->dir); ++ struct exportinfo *exp = ptr; ++ size_t exp_len = strlen(exp->dir); ++ int eq; ++ ++ eq = strcmp(exp->dir, n_exp->dir); ++ if (!eq) ++ return 0; ++ return (exp_len < n_exp_len) ? -1 : 1; ++} ++ ++static void tree_host_free(struct tree_node *n) ++{ ++ n->ops = NULL; ++ n->left = NULL; ++ n->right = NULL; ++} ++ ++struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp) ++{ ++ return tree_add_node(root, exp); ++} ++ + struct tree_node *tree_mapent_root(struct mapent *me) + { + return tree_root(tree_mapent_ops, me); +--- autofs-5.1.4.orig/modules/lookup_hosts.c ++++ autofs-5.1.4/modules/lookup_hosts.c +@@ -84,14 +84,38 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_UNKNOWN; + } + ++struct work_info { ++ char *mapent; ++ const char *host; ++ int pos; ++}; ++ ++static int tree_host_work(struct tree_node *n, void *ptr) ++{ ++ struct exportinfo *exp = EXPORTINFO(n); ++ struct work_info *wi = ptr; ++ int len; ++ ++ if (!wi->pos) ++ len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"", ++ exp->dir, wi->host, exp->dir); ++ else ++ len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"", ++ exp->dir, wi->host, exp->dir); ++ wi->pos += len; ++ ++ return 1; ++} ++ + static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; + char *mapent; + struct exportinfo *exp, *this; ++ struct tree_node *tree = NULL; ++ struct work_info wi; + size_t hostlen = strlen(host); + size_t mapent_len; +- int len, pos; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + +@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_p + this = exp; + mapent_len = 0; + while (this) { ++ struct tree_node *n; ++ + mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3; ++ ++ if (!tree) { ++ tree = tree_host_root(this); ++ if (!tree) { ++ error(ap->logopt, "failed to create exports tree root"); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++ goto next; ++ } ++ ++ n = tree_host_add_node(tree, this); ++ if (!n) { ++ error(ap->logopt, "failed to add exports tree node"); ++ tree_free(tree); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++next: + this = this->next; + } + +@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_p + } + *mapent = 0; + +- pos = 0; +- this = exp; +- if (this) { +- len = sprintf(mapent, "\"%s\" \"%s:%s\"", +- this->dir, host, this->dir); +- pos += len; +- this = this->next; +- } +- +- while (this) { +- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"", +- this->dir, host, this->dir); +- pos += len; +- this = this->next; ++ wi.mapent = mapent; ++ wi.host = host; ++ wi.pos = 0; ++ ++ if (!tree) { ++ free(mapent); ++ mapent = NULL; ++ } else { ++ tree_traverse_inorder(tree, tree_host_work, &wi); ++ tree_free(tree); + } + rpc_exports_free(exp); + diff --git a/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch b/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch new file mode 100644 index 0000000..a36338c --- /dev/null +++ b/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch @@ -0,0 +1,245 @@ +autofs-5.1.7 - fix inconsistent locking in parse_mount() + +From: Ian Kent + +Some map entry cache locking inconsistencies have crept in. + +In parse_mount() of the sun format parser the cache read lock is too +heavily used and has too broad a scope. This has lead to some operations +that should hold the write lock being called with only the read lock. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 9 +++++++- + modules/parse_sun.c | 53 ++++++++++++++++++++++++++++++++-------------------- + 3 files changed, 42 insertions(+), 21 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -17,6 +17,7 @@ + - fix inconsistent locking in umount_subtree_mounts(). + - fix return from umount_subtree_mounts() on offset list delete. + - pass mapent_cache to update_offset_entry(). ++- fix inconsistent locking in parse_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2485,6 +2485,12 @@ static int do_mount_autofs_offset(struct + else { + debug(ap->logopt, "ignoring \"nohide\" trigger %s", + oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. ++ */ + free(oe->mapent); + oe->mapent = NULL; + } +@@ -2628,7 +2634,8 @@ static int do_umount_offset(struct autof + /* + * Ok, so we shouldn't modify the mapent but + * mount requests are blocked at a point above +- * this and expire only uses the mapent key. ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. + */ + if (oe->mapent) { + free(oe->mapent); +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -853,10 +853,12 @@ update_offset_entry(struct autofs_point + strcpy(m_mapent, loc); + } + ++ cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + + if (!cache_set_offset_parent(mc, m_key)) + error(ap->logopt, "failed to set offset parent"); ++ cache_unlock(mc); + + if (ret == CHE_DUPLICATE) { + warn(ap->logopt, MODPREFIX +@@ -1130,14 +1132,22 @@ static void cleanup_multi_triggers(struc + return; + } + +-static int mount_subtree(struct autofs_point *ap, struct mapent *me, ++static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + const char *name, char *loc, char *options, void *ctxt) + { ++ struct mapent *me; + struct mapent *ro; + char *mm_root, *mm_base, *mm_key; + unsigned int mm_root_len; + int start, ret = 0, rv; + ++ cache_readlock(mc); ++ me = cache_lookup_distinct(mc, name); ++ if (!me) { ++ cache_unlock(mc); ++ return 0; ++ } ++ + rv = 0; + + mm_key = me->multi->key; +@@ -1182,9 +1192,12 @@ static int mount_subtree(struct autofs_p + rv = parse_mapent(ro->mapent, + options, &myoptions, &ro_loc, ap->logopt); + if (!rv) { ++ cache_unlock(mc); + warn(ap->logopt, + MODPREFIX "failed to parse root offset"); +- cache_delete_offset_list(me->mc, name); ++ cache_writelock(mc); ++ cache_delete_offset_list(mc, name); ++ cache_unlock(mc); + return 1; + } + ro_len = 0; +@@ -1201,9 +1214,10 @@ static int mount_subtree(struct autofs_p + if ((ro && rv == 0) || rv <= 0) { + ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); + if (ret == -1) { ++ cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); + return 1; + } + } +@@ -1219,9 +1233,10 @@ static int mount_subtree(struct autofs_p + if (rv == 0) { + ret = mount_multi_triggers(ap, me->multi, name, start, mm_base); + if (ret == -1) { ++ cleanup_multi_triggers(ap, me, name, start, mm_base); ++ cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, name, start, mm_base); + return 1; + } + } else if (rv < 0) { +@@ -1229,8 +1244,11 @@ static int mount_subtree(struct autofs_p + unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1; + + if (mm_root_base_len > PATH_MAX) { ++ cache_unlock(mc); + warn(ap->logopt, MODPREFIX "path too long"); +- cache_delete_offset_list(me->mc, name); ++ cache_writelock(mc); ++ cache_delete_offset_list(mc, name); ++ cache_unlock(mc); + return 1; + } + +@@ -1239,13 +1257,15 @@ static int mount_subtree(struct autofs_p + + ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base); + if (ret == -1) { ++ cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); + return 1; + } + } + } ++ cache_unlock(mc); + + /* Mount for base of tree failed */ + if (rv > 0) +@@ -1486,7 +1506,6 @@ dont_expand: + return 1; + } + +- cache_multi_writelock(me); + /* So we know we're the multi-mount root */ + if (!me->multi) + me->multi = me; +@@ -1511,14 +1530,13 @@ dont_expand: + if (source->flags & MAP_FLAG_FORMAT_AMD) { + free(options); + free(pmapent); +- cache_multi_unlock(me); + cache_unlock(mc); + pthread_setcancelstate(cur_state, NULL); + return 0; + } + } +- + age = me->age; ++ cache_unlock(mc); + + /* It's a multi-mount; deal with it */ + do { +@@ -1539,8 +1557,8 @@ dont_expand: + + if (!path) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); ++ cache_writelock(mc); + cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); + cache_unlock(mc); + free(options); + free(pmapent); +@@ -1556,8 +1574,8 @@ dont_expand: + + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { ++ cache_writelock(mc); + cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); + cache_unlock(mc); + free(path); + free(options); +@@ -1575,8 +1593,8 @@ dont_expand: + + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); ++ cache_writelock(mc); + cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); + cache_unlock(mc); + free(path); + free(options); +@@ -1594,10 +1612,7 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + +- rv = mount_subtree(ap, me, name, NULL, options, ctxt); +- +- cache_multi_unlock(me); +- cache_unlock(mc); ++ rv = mount_subtree(ap, mc, name, NULL, options, ctxt); + + free(options); + free(pmapent); +@@ -1618,6 +1633,7 @@ dont_expand: + cache_readlock(mc); + if (*name == '/' && + (me = cache_lookup_distinct(mc, name)) && me->multi) { ++ cache_unlock(mc); + loc = strdup(p); + if (!loc) { + free(options); +@@ -1626,10 +1642,7 @@ dont_expand: + warn(ap->logopt, MODPREFIX "out of memory"); + return 1; + } +- cache_multi_writelock(me); +- rv = mount_subtree(ap, me, name, loc, options, ctxt); +- cache_multi_unlock(me); +- cache_unlock(mc); ++ rv = mount_subtree(ap, mc, name, loc, options, ctxt); + free(loc); + free(options); + free(pmapent); diff --git a/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch b/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch new file mode 100644 index 0000000..1a9dbfa --- /dev/null +++ b/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch @@ -0,0 +1,129 @@ +autofs-5.1.7 - fix inconsistent locking in umount_subtree_mounts() + +From: Ian Kent + +Some map entry cache locking inconsistencies have crept in. + +In umount_subtree_mounts() the cache write lock should be held when +deleting multi-mount cache entries. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 42 ++++++++++++++++++++++++++++++------------ + lib/mounts.c | 8 -------- + 3 files changed, 31 insertions(+), 20 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -14,6 +14,7 @@ + - eliminate clean_stale_multi_triggers(). + - simplify mount_subtree() mount check. + - fix mnts_get_expire_list() expire list construction. ++- fix inconsistent locking in umount_subtree_mounts(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -527,8 +527,11 @@ static int umount_subtree_mounts(struct + struct mapent_cache *mc; + struct mapent *me; + unsigned int is_mm_root = 0; ++ int cur_state; + int left; + ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ + me = lookup_source_mapent(ap, path, LKP_DISTINCT); + if (!me) { + char *ind_key; +@@ -548,11 +551,11 @@ static int umount_subtree_mounts(struct + left = 0; + + if (me && me->multi) { +- char root[PATH_MAX]; ++ char root[PATH_MAX + 1]; ++ char key[PATH_MAX + 1]; ++ struct mapent *tmp; ++ int status; + char *base; +- int cur_state; +- +- pthread_cleanup_push(cache_lock_cleanup, mc); + + if (!strchr(me->multi->key, '/')) + /* Indirect multi-mount root */ +@@ -567,25 +570,40 @@ static int umount_subtree_mounts(struct + else + base = me->key + strlen(root); + +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- /* Lock the closest parent nesting point for umount */ +- cache_multi_writelock(me->parent); +- if (umount_multi_triggers(ap, me, root, base)) { ++ left = umount_multi_triggers(ap, me, root, base); ++ if (left) { + warn(ap->logopt, + "some offset mounts still present under %s", path); ++ } ++ ++ strcpy(key, me->key); ++ ++ cache_unlock(mc); ++ cache_writelock(mc); ++ tmp = cache_lookup_distinct(mc, key); ++ /* mapent went away while we waited? */ ++ if (tmp != me) { ++ cache_unlock(mc); ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ ++ if (!left && is_mm_root) { ++ status = cache_delete_offset_list(mc, me->key); ++ if (status != CHE_OK) ++ warn(ap->logopt, "couldn't delete offset list"); + left++; + } +- cache_multi_unlock(me->parent); ++ + if (ap->entry->maps && + (ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD)) + cache_pop_mapent(me); +- pthread_setcancelstate(cur_state, NULL); +- pthread_cleanup_pop(0); + } +- + if (me) + cache_unlock(mc); + ++ pthread_setcancelstate(cur_state, NULL); ++ + if (left || is_autofs_fs) + return left; + +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2730,9 +2730,6 @@ int umount_multi_triggers(struct autofs_ + left = do_umount_multi_triggers(ap, me, root, base); + + 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 +@@ -2750,11 +2747,6 @@ int umount_multi_triggers(struct autofs_ + } + } + +- /* 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"); +- + /* check for mounted mount entry and remove it if found */ + mnts_remove_mount(root, MNTS_MOUNTED); + } diff --git a/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch b/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch new file mode 100644 index 0000000..65f6ec0 --- /dev/null +++ b/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch @@ -0,0 +1,58 @@ +autofs-5.1.7 - fix is mounted check on non existent path + +From: Ian Kent + +When checking if a path is a mount point the case of a non-existent path +was not being handled. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/dev-ioctl-lib.c | 3 +++ + lib/mounts.c | 12 +++++++++++- + 3 files changed, 15 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -5,6 +5,7 @@ + - use sprintf() when constructing hosts mapent. + - fix mnts_remove_amdmount() uses wrong list. + - eliminate cache_lookup_offset() usage. ++- fix is mounted check on non existent path. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/dev-ioctl-lib.c ++++ autofs-5.1.4/lib/dev-ioctl-lib.c +@@ -759,6 +759,9 @@ static int dev_ioctl_ismountpoint(unsign + int save_errno = errno; + free_dev_ioctl_path(param); + errno = save_errno; ++ /* Path doesn't exist */ ++ if (errno == ENOENT) ++ return 0; + return -1; + } + +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1645,8 +1645,18 @@ static int table_is_mounted(const char * + struct mntent mnt_wrk; + char buf[PATH_MAX * 3]; + size_t mp_len = strlen(mp); ++ struct stat st; + FILE *tab; +- int ret = 0; ++ int ret; ++ ++ ret = stat(mp, &st); ++ if (ret == -1) { ++ if (errno == ENOENT) { ++ /* Path does not exist */ ++ return 0; ++ } ++ ret = 0; ++ } + + if (!mp || !mp_len || mp_len >= PATH_MAX) + return 0; diff --git a/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch b/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch new file mode 100644 index 0000000..faf51d7 --- /dev/null +++ b/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch @@ -0,0 +1,56 @@ +autofs-5.1.7 - fix lookup_prune_one_cache() refactoring change + +From: Ian Kent + +Commit 256963d6b (autofs-5.1.7 - refactor lookup_prune_one_cache() a bit) +changed the position of the getting the next enumeration map entry but +failed to update a couple of other locations that assume the next map +entry has been set. Under certain fairly common conditions this leads +to an infinite loop. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -73,6 +73,7 @@ + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. + - fix direct mount deadlock. ++- fix lookup_prune_one_cache() refactoring change. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -1387,6 +1387,7 @@ void lookup_prune_one_cache(struct autof + if (!key || strchr(key, '*')) { + if (key) + free(key); ++ me = cache_enumerate(mc, me); + continue; + } + +@@ -1394,6 +1395,7 @@ void lookup_prune_one_cache(struct autof + if (!path) { + warn(ap->logopt, "can't malloc storage for path"); + free(key); ++ me = cache_enumerate(mc, me); + continue; + } + +@@ -1421,9 +1423,10 @@ void lookup_prune_one_cache(struct autof + } + if (!valid && + is_mounted(path, MNTS_REAL)) { +- debug(ap->logopt, "prune posponed, %s mounted", path); ++ debug(ap->logopt, "prune postponed, %s mounted", path); + free(key); + free(path); ++ me = cache_enumerate(mc, me); + continue; + } + if (valid) diff --git a/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch b/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch new file mode 100644 index 0000000..88acca8 --- /dev/null +++ b/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch @@ -0,0 +1,32 @@ +autofs-5.1.7 - fix missing lock release in mount_subtree() + +From: Ian Kent + +Covarity: missing_unlock: Returning without unlocking "mc->rwlock". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -61,6 +61,7 @@ + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. ++- fix missing lock release in mount_subtree(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1107,6 +1107,7 @@ static int mount_subtree(struct autofs_p + len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key); + if (!len) { + warn(ap->logopt, "path loo long"); ++ cache_unlock(mc); + return 1; + } + key[len] = '/'; diff --git a/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch b/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch new file mode 100644 index 0000000..afb8497 --- /dev/null +++ b/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch @@ -0,0 +1,36 @@ +autofs-5.1.7 - fix mnts_get_expire_list() expire list construction + +From: Ian Kent + +The mnts_get_expire_list() function is supposed to return an ordered +list of expire candidates but it is not checking the mounted status +of list entries and is returning a larger list than is needed. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 3 +++ + 2 files changed, 4 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -13,6 +13,7 @@ + - refactor umount_multi_triggers(). + - eliminate clean_stale_multi_triggers(). + - simplify mount_subtree() mount check. ++- fix mnts_get_expire_list() expire list construction. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1364,6 +1364,9 @@ void mnts_get_expire_list(struct list_he + list_for_each_entry(mnt, &ap->mounts, mount) { + struct node *n; + ++ if (!(mnt->flags & MNTS_MOUNTED)) ++ continue; ++ + __mnts_get_mount(mnt); + + if (!tree) { diff --git a/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch b/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch new file mode 100644 index 0000000..e7789fd --- /dev/null +++ b/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch @@ -0,0 +1,34 @@ +autofs-5.1.7 - fix mnts_remove_amdmount() uses wrong list + +From: Ian Kent + +Function mnts_remove_amdmount() uses the wrong list when removing an +amd mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -3,6 +3,7 @@ + - remove mount.x and rpcgen dependencies. + - dont use realloc in host exports list processing. + - use sprintf() when constructing hosts mapent. ++- fix mnts_remove_amdmount() uses wrong list. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1124,7 +1124,7 @@ void mnts_remove_amdmount(const char *mp + if (!(this && this->flags & MNTS_AMD_MOUNT)) + goto done; + this->flags &= ~MNTS_AMD_MOUNT; +- list_del_init(&this->submount); ++ list_del_init(&this->amdmount); + if (this->ext_mp) { + free(this->ext_mp); + this->ext_mp = NULL; diff --git a/autofs-5.1.7-fix-mount_fullpath.patch b/autofs-5.1.7-fix-mount_fullpath.patch new file mode 100644 index 0000000..138d6e1 --- /dev/null +++ b/autofs-5.1.7-fix-mount_fullpath.patch @@ -0,0 +1,61 @@ +autofs-5.1.7 - fix mount_fullpath() + +From: Ian Kent + +mount_fullpath() incorrecly fills fullpath with the contents of root +when name[0] == '/'. The cases root[last] == '/' and name[0] == '/' +need to be handled seperately. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 4 +++- + modules/parse_amd.c | 6 ++++-- + 3 files changed, 8 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -36,6 +36,7 @@ + - add tree_mapent_add_node(). + - add tree_mapent_delete_offsets(). + - add tree_mapent_traverse_subtree(). ++- fix mount_fullpath(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -371,8 +371,10 @@ int mount_fullpath(char *fullpath, size_ + /* Root offset of multi-mount or direct or offset mount. + * Direct or offset mount, name (or root) is absolute path. + */ +- if (root[last] == '/' || *name == '/') ++ if (root[last] == '/') + len = snprintf(fullpath, max_len, "%s", root); ++ else if (*name == '/') ++ len = snprintf(fullpath, max_len, "%s", name); + else + len = snprintf(fullpath, max_len, "%s/%s", root, name); + +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1177,7 +1177,8 @@ static int do_generic_mount(struct autof + * the automount filesystem. + */ + if (!is_mounted(entry->fs, MNTS_REAL)) { +- ret = do_mount(ap, entry->fs, "/", 1, ++ ret = do_mount(ap, entry->fs, ++ entry->fs, strlen(entry->fs), + target, entry->type, opts); + if (ret) + goto out; +@@ -1227,7 +1228,8 @@ static int do_nfs_mount(struct autofs_po + mount_nfs->context); + } else { + if (!is_mounted(entry->fs, MNTS_REAL)) { +- ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1, ++ ret = mount_nfs->mount_mount(ap, entry->fs, ++ entry->fs, strlen(entry->fs), + target, entry->type, opts, + mount_nfs->context); + if (ret) diff --git a/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch b/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch new file mode 100644 index 0000000..46572bf --- /dev/null +++ b/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch @@ -0,0 +1,54 @@ +autofs-5.1.7 - fix nonstrict offset mount fail handling + +From: Ian Kent + +If a triggered offset mount fails automount is not handling nonstrict +mount failure correctly. + +The nonstrict mount failure handling needs to convert an offset mount +failure to a success if the offset subtree below the failed mount is not +empty otherwise it must return the failure. The previous implementation +used -1 to indicate the subtree was empty and that was used to detect +when the mount should fail instead of converting the fail to a success. + +Make the new implementation do the same. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + modules/parse_sun.c | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -76,6 +76,7 @@ + - fix lookup_prune_one_cache() refactoring change. + - add missing description of null map option. + - fix empty mounts list return from unlink_mount_tree(). ++- fix nonstrict offset mount fail handling. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree( + { + struct traverse_subtree_context *ctxt = ptr; + struct mapent *oe = MAPENT(n); +- int ret = 1; ++ int ret = -1; + + if (n->left) { + ret = tree_mapent_traverse_subtree(n->left, work, ctxt); +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1183,7 +1183,7 @@ static int mount_subtree(struct autofs_p + * offsets to be mounted. + */ + rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); +- if (rv == 0) { ++ if (rv <= 0) { + ret = tree_mapent_mount_offsets(me, 1); + if (!ret) { + tree_mapent_cleanup_offsets(me); diff --git a/autofs-5.1.7-fix-offset-entries-order.patch b/autofs-5.1.7-fix-offset-entries-order.patch new file mode 100644 index 0000000..3fd36a3 --- /dev/null +++ b/autofs-5.1.7-fix-offset-entries-order.patch @@ -0,0 +1,199 @@ +autofs-5.1.7 - fix offset entries order + +From: Ian Kent + +While it's rare it's possible that a mapent entry might not have +it's offsets in shortest to longest path order. + +If this happens adding an entry to the mapent tree can result in +an incorrect tree topology that doesn't work. That's because adding +tree entries ensures that nodes in a sub-tree are placed below the +containing node so the containing node must be present for that to +work. This topology is critical to the performance of map entries +that have a very large number of offsets such as an NFS server with +many exports. + +There's no other choice but make a traversal after the offset entries +have all been added to create the mapent tree. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 1 + lib/cache.c | 1 + modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++----------- + 4 files changed, 62 insertions(+), 15 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -68,6 +68,7 @@ + - add ext_mount_hash_mutex lock helpers. + - fix amd section mounts map reload. + - fix amd hosts mount expire. ++- fix offset entries order. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -169,6 +169,7 @@ struct mapent { + /* Parent nesting point within multi-mount */ + struct tree_node *mm_parent; + struct tree_node node; ++ struct list_head work; + char *key; + size_t len; + char *mapent; +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, s + me->mm_parent = NULL; + INIT_TREE_NODE(&me->node); + INIT_LIST_HEAD(&me->ino_index); ++ INIT_LIST_HEAD(&me->work); + me->ioctlfd = -1; + me->dev = (dev_t) -1; + me->ino = (ino_t) -1; +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -791,14 +791,15 @@ static int check_is_multi(const char *ma + + static int + update_offset_entry(struct autofs_point *ap, +- struct mapent_cache *mc, const char *name, +- const char *m_root, int m_root_len, ++ struct mapent_cache *mc, struct list_head *offsets, ++ const char *name, const char *m_root, int m_root_len, + const char *m_offset, const char *myoptions, + const char *loc, time_t age) + { + char m_key[PATH_MAX + 1]; + char m_mapent[MAPENT_MAX_LEN + 1]; + int o_len, m_key_len, m_options_len, m_mapent_len; ++ struct mapent *me; + int ret; + + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); +@@ -864,8 +865,29 @@ update_offset_entry(struct autofs_point + cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + +- if (!tree_mapent_add_node(mc, name, m_key)) +- error(ap->logopt, "failed to add offset %s to tree", m_key); ++ me = cache_lookup_distinct(mc, m_key); ++ if (me && list_empty(&me->work)) { ++ struct list_head *last; ++ ++ /* Offset entries really need to be in shortest to ++ * longest path order. If not and the list of offsets ++ * is large there will be a performace hit. ++ */ ++ list_for_each_prev(last, offsets) { ++ struct mapent *this; ++ ++ this = list_entry(last, struct mapent, work); ++ if (me->len >= this->len) { ++ if (last->next == offsets) ++ list_add_tail(&me->work, offsets); ++ else ++ list_add_tail(&me->work, last); ++ break; ++ } ++ } ++ if (list_empty(&me->work)) ++ list_add(&me->work, offsets); ++ } + cache_unlock(mc); + + if (ret == CHE_DUPLICATE) { +@@ -1211,6 +1233,25 @@ static char *do_expandsunent(const char + return mapent; + } + ++static void cleanup_offset_entries(struct autofs_point *ap, ++ struct mapent_cache *mc, ++ struct list_head *offsets) ++{ ++ struct mapent *me, *tmp; ++ int ret; ++ ++ if (list_empty(offsets)) ++ return; ++ cache_writelock(mc); ++ list_for_each_entry_safe(me, tmp, offsets, work) { ++ list_del(&me->work); ++ ret = cache_delete(mc, me->key); ++ if (ret != CHE_OK) ++ crit(ap->logopt, "failed to delete offset %s", me->key); ++ } ++ cache_unlock(mc); ++} ++ + /* + * syntax is: + * [-options] location [location] ... +@@ -1230,7 +1271,8 @@ int parse_mount(struct autofs_point *ap, + char buf[MAX_ERR_BUF]; + struct map_source *source; + struct mapent_cache *mc; +- struct mapent *me; ++ struct mapent *me, *oe, *tmp; ++ LIST_HEAD(offsets); + char *pmapent, *options; + const char *p; + int mapent_len, rv = 0; +@@ -1446,9 +1488,7 @@ dont_expand: + + if (!m_offset) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(options); + free(pmapent); + pthread_setcancelstate(cur_state, NULL); +@@ -1463,9 +1503,7 @@ dont_expand: + + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(m_offset); + free(options); + free(pmapent); +@@ -1476,15 +1514,13 @@ dont_expand: + p += l; + p = skipspace(p); + +- status = update_offset_entry(ap, mc, ++ status = update_offset_entry(ap, mc, &offsets, + name, m_root, m_root_len, + m_offset, myoptions, loc, age); + + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(m_offset); + free(options); + free(pmapent); +@@ -1501,6 +1537,14 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + ++ cache_writelock(mc); ++ list_for_each_entry_safe(oe, tmp, &offsets, work) { ++ if (!tree_mapent_add_node(mc, name, oe->key)) ++ error(ap->logopt, "failed to add offset %s to tree", oe->key); ++ list_del_init(&oe->work); ++ } ++ cache_unlock(mc); ++ + rv = mount_subtree(ap, mc, name, NULL, options, ctxt); + + free(options); diff --git a/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch b/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch new file mode 100644 index 0000000..6dddb70 --- /dev/null +++ b/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch @@ -0,0 +1,34 @@ +autofs-5.1.7 - fix possible memory leak in master_parse() + +From: Ian Kent + +Coverity: Overwriting "path" in "path = master_strdup(yyvsp[-1].strtype)" + leaks the storage that "path" points to. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master_parse.y | 2 ++ + 2 files changed, 3 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -52,6 +52,7 @@ + - remove unused variable from get_exports(). + - add missing free in handle_mounts(). + - remove redundant if check. ++- fix possible memory leak in master_parse(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/master_parse.y ++++ autofs-5.1.4/daemon/master_parse.y +@@ -155,6 +155,8 @@ file: { + line: + | PATH mapspec + { ++ if (path) ++ free(path); + path = master_strdup($1); + if (!path) { + local_free_vars(); diff --git a/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch b/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch new file mode 100644 index 0000000..37c0cdf --- /dev/null +++ b/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch @@ -0,0 +1,54 @@ +autofs-5.1.7 - fix possible memory leak in mnts_add_amdmount() + +From: Ian Kent + +Coverity: leaked_storage: Variable "ext_mp" going out of scope leaks + the storage it points to. + +Same applies to the other duped fields destined for the mnt_list struct. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 20 ++++++++++---------- + 2 files changed, 11 insertions(+), 10 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -53,6 +53,7 @@ + - add missing free in handle_mounts(). + - remove redundant if check. + - fix possible memory leak in master_parse(). ++- fix possible memory leak in mnts_add_amdmount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struc + + mnts_hash_mutex_lock(); + this = mnts_get_mount(entry->path); +- if (this) { +- this->ext_mp = ext_mp; +- this->amd_pref = pref; +- this->amd_type = type; +- this->amd_opts = opts; +- this->amd_cache_opts = entry->cache_opts; +- this->flags |= MNTS_AMD_MOUNT; +- if (list_empty(&this->amdmount)) +- list_add_tail(&this->amdmount, &ap->amdmounts); +- } ++ if (!this) ++ goto fail; ++ this->ext_mp = ext_mp; ++ this->amd_pref = pref; ++ this->amd_type = type; ++ this->amd_opts = opts; ++ this->amd_cache_opts = entry->cache_opts; ++ this->flags |= MNTS_AMD_MOUNT; ++ if (list_empty(&this->amdmount)) ++ list_add_tail(&this->amdmount, &ap->amdmounts); + mnts_hash_mutex_unlock(); + + return this; diff --git a/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch b/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch new file mode 100644 index 0000000..d62cb37 --- /dev/null +++ b/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - fix return from umount_subtree_mounts() on offset list delete + +From: Ian Kent + +When there are no mounts left in a subtree of offset mounts the offset +list is deleted. If all goes well deleting the list this shouldn't cause +a positive return from umount_subtree_mounts() (essentially saying not +the umount of the subtree has not succeeded). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -15,6 +15,7 @@ + - simplify mount_subtree() mount check. + - fix mnts_get_expire_list() expire list construction. + - fix inconsistent locking in umount_subtree_mounts(). ++- fix return from umount_subtree_mounts() on offset list delete. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -590,9 +590,10 @@ static int umount_subtree_mounts(struct + + if (!left && is_mm_root) { + status = cache_delete_offset_list(mc, me->key); +- if (status != CHE_OK) ++ if (status != CHE_OK) { + warn(ap->logopt, "couldn't delete offset list"); +- left++; ++ left++; ++ } + } + + if (ap->entry->maps && diff --git a/autofs-5.1.7-make-tree-implementation-data-independent.patch b/autofs-5.1.7-make-tree-implementation-data-independent.patch new file mode 100644 index 0000000..1c6dc1f --- /dev/null +++ b/autofs-5.1.7-make-tree-implementation-data-independent.patch @@ -0,0 +1,346 @@ +autofs-5.1.7 - make tree implementation data independent + +From: Ian Kent + +Generalise the tree implementation so that it's independent of the +data structure that's used. + +Do this by refactoring it into core tree functions and functions +specific to the data structure to be used so that different data +structures can be used when needed by adding an implementation for +the data structure specific functions. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/mounts.h | 29 +++++++++ + lib/mounts.c | 174 ++++++++++++++++++++++++++++++++++--------------------- + 3 files changed, 140 insertions(+), 64 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -31,6 +31,7 @@ + - add some multi-mount macros. + - remove unused functions cache_dump_multi() and cache_dump_cache(). + - add a len field to struct autofs_point. ++- make tree implementation data independent. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -51,10 +51,36 @@ extern const unsigned int t_indirect; + extern const unsigned int t_direct; + extern const unsigned int t_offset; + ++struct mnt_list; + struct mapent; + ++struct tree_ops; ++ ++struct tree_node { ++ struct tree_ops *ops; ++ struct tree_node *left; ++ struct tree_node *right; ++}; ++#define INIT_TREE_NODE(ptr) ((ptr)->ops = NULL, (ptr)->left = NULL, (ptr)->right = NULL) ++ ++#define MNT_LIST(n) (container_of(n, struct mnt_list, node)) ++#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) ++ ++typedef struct tree_node *(*tree_new_t) (void *ptr); ++typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr); ++typedef void (*tree_free_t) (struct tree_node *n); ++ ++struct tree_ops { ++ tree_new_t new; ++ tree_cmp_t cmp; ++ tree_free_t free; ++}; ++ ++typedef int (*tree_work_fn_t) (struct tree_node *n, void *ptr); ++ + struct mnt_list { + char *mp; ++ size_t len; + unsigned int flags; + + /* Hash of all mounts */ +@@ -79,6 +105,9 @@ struct mnt_list { + unsigned int amd_cache_opts; + struct list_head amdmount; + ++ /* Tree operations */ ++ struct tree_node node; ++ + /* + * List operations ie. get_mnt_list. + */ +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -68,6 +68,17 @@ static pthread_mutex_t ext_mount_hash_mu + static DEFINE_HASHTABLE(mnts_hash, MNTS_HASH_BITS); + static pthread_mutex_t mnts_hash_mutex = PTHREAD_MUTEX_INITIALIZER; + ++static struct tree_node *tree_mnt_new(void *ptr); ++static int tree_mnt_cmp(struct tree_node *n, void *ptr); ++static void tree_mnt_free(struct tree_node *n); ++ ++static struct tree_ops mnt_ops = { ++ .new = tree_mnt_new, ++ .cmp = tree_mnt_cmp, ++ .free = tree_mnt_free, ++}; ++static struct tree_ops *tree_mnt_ops = &mnt_ops; ++ + unsigned int linux_version_code(void) + { + struct utsname my_utsname; +@@ -904,6 +915,7 @@ static struct mnt_list *mnts_alloc_mount + this = NULL; + goto done; + } ++ this->len = strlen(mp); + + this->ref = 1; + INIT_HLIST_NODE(&this->hash); +@@ -912,6 +924,7 @@ static struct mnt_list *mnts_alloc_mount + INIT_LIST_HEAD(&this->submount_work); + INIT_LIST_HEAD(&this->amdmount); + INIT_LIST_HEAD(&this->expire); ++ INIT_TREE_NODE(&this->node); + done: + return this; + } +@@ -1225,91 +1238,58 @@ done: + return has_mounted_mounts; + } + +-struct tree_node { +- struct mnt_list *mnt; +- struct tree_node *left; +- struct tree_node *right; +-}; +- +-static struct tree_node *tree_new(struct mnt_list *mnt) +-{ +- struct tree_node *n; +- +- n = malloc(sizeof(struct tree_node)); +- if (!n) +- return NULL; +- memset(n, 0, sizeof(struct tree_node)); +- n->mnt = mnt; +- +- return n; +-} +- +-static struct tree_node *tree_root(struct mnt_list *mnt) ++static inline struct tree_node *tree_root(struct tree_ops *ops, void *ptr) + { +- struct tree_node *n; +- +- n = tree_new(mnt); +- if (!n) { +- error(LOGOPT_ANY, "failed to allcate tree root"); +- return NULL; +- } +- +- return n; ++ return ops->new(ptr); + } + +-static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt) ++static struct tree_node *tree_add_left(struct tree_node *n, void *ptr) + { + struct tree_node *new; + +- new = tree_new(mnt); +- if (!new) { +- error(LOGOPT_ANY, "failed to allcate tree node"); +- return NULL; +- } ++ new = n->ops->new(ptr); + n->left = new; + +- return n; ++ return new; + } + +-static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt) ++static struct tree_node *tree_add_right(struct tree_node *n, void *ptr) + { + struct tree_node *new; + +- new = tree_new(mnt); +- if (!new) { +- error(LOGOPT_ANY, "failed to allcate tree node"); +- return NULL; +- } ++ new = n->ops->new(ptr); + n->right = new; + +- return n; ++ return new; + } + +-static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt) ++static struct tree_node *tree_add_node(struct tree_node *root, void *ptr) + { + struct tree_node *p, *q; +- unsigned int mp_len; +- +- mp_len = strlen(mnt->mp); ++ struct tree_ops *ops = root->ops; ++ int eq; + + q = root; + p = root; + +- while (q && strcmp(mnt->mp, p->mnt->mp)) { ++ while (q) { + p = q; +- if (mp_len < strlen(p->mnt->mp)) ++ eq = ops->cmp(p, ptr); ++ if (!eq) ++ break; ++ if (eq < 0) + q = p->left; + else + q = p->right; + } + +- if (strcmp(mnt->mp, p->mnt->mp) == 0) +- error(LOGOPT_ANY, "duplicate entry in mounts list"); ++ if (!eq) ++ error(LOGOPT_ANY, "cannot add duplicate entry to tree"); + else { +- if (mp_len < strlen(p->mnt->mp)) +- return tree_add_left(p, mnt); ++ if (eq < 0) ++ return tree_add_left(p, ptr); + else +- return tree_add_right(p, mnt); ++ return tree_add_right(p, ptr); + } + + return NULL; +@@ -1317,26 +1297,92 @@ static struct tree_node *tree_add_node(s + + static void tree_free(struct tree_node *root) + { ++ struct tree_ops *ops = root->ops; ++ + if (root->right) + tree_free(root->right); + if (root->left) + tree_free(root->left); +- free(root); ++ ops->free(root); ++} ++ ++static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) ++{ ++ int ret; ++ ++ if (n->left) { ++ ret = tree_traverse_inorder(n->left, work, ptr); ++ if (!ret) ++ goto done; ++ } ++ ret = work(n, ptr); ++ if (!ret) ++ goto done; ++ if (n->right) { ++ ret = tree_traverse_inorder(n->right, work, ptr); ++ if (!ret) ++ goto done; ++ } ++done: ++ return ret; ++} ++ ++static struct tree_node *tree_mnt_root(struct mnt_list *mnt) ++{ ++ return tree_root(tree_mnt_ops, mnt); ++} ++ ++static struct tree_node *tree_mnt_new(void *ptr) ++{ ++ struct tree_node *n = MNT_LIST_NODE(ptr); ++ ++ n->ops = tree_mnt_ops; ++ n->left = NULL; ++ n->right = NULL; ++ ++ return n; ++} ++ ++static int tree_mnt_cmp(struct tree_node *n, void *ptr) ++{ ++ struct mnt_list *n_mnt = MNT_LIST(n); ++ size_t n_mnt_len = n_mnt->len; ++ struct mnt_list *mnt = ptr; ++ size_t mnt_len = mnt->len; ++ int eq; ++ ++ eq = strcmp(mnt->mp, n_mnt->mp); ++ if (!eq) ++ return 0; ++ return (mnt_len < n_mnt_len) ? -1 : 1; ++} ++ ++static void tree_mnt_free(struct tree_node *n) ++{ ++ n->ops = NULL; ++ n->left = NULL; ++ n->right = NULL; + } + +-static void tree_traverse(struct tree_node *n, struct list_head *mnts) ++static int tree_mnt_expire_list_work(struct tree_node *n, void *ptr) + { +- if (n->right) +- tree_traverse(n->right, mnts); +- list_add_tail(&n->mnt->expire, mnts); +- if (n->left) +- tree_traverse(n->left, mnts); ++ struct mnt_list *mnt = MNT_LIST(n); ++ struct list_head *mnts = ptr; ++ ++ /* The expire of the root offset of an offset tree is the same ++ * as expiring the offset tree root itself (if theree is a root ++ * offset). ++ */ ++ if (mnt->mp[mnt->len - 1] != '/') ++ list_add(&mnt->expire, mnts); ++ ++ return 1; + } + + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + { +- struct mnt_list *mnt; + struct tree_node *tree = NULL; ++ struct mnt_list *mnt; + + mnts_hash_mutex_lock(); + if (list_empty(&ap->mounts)) +@@ -1351,7 +1397,7 @@ void mnts_get_expire_list(struct list_he + __mnts_get_mount(mnt); + + if (!tree) { +- tree = tree_root(mnt); ++ tree = tree_mnt_root(mnt); + if (!tree) { + error(LOGOPT_ANY, "failed to create expire tree root"); + goto done; +@@ -1367,7 +1413,7 @@ void mnts_get_expire_list(struct list_he + } + } + +- tree_traverse(tree, mnts); ++ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); + tree_free(tree); + done: + mnts_hash_mutex_unlock(); diff --git a/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch b/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch new file mode 100644 index 0000000..7b7cb0a --- /dev/null +++ b/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch @@ -0,0 +1,110 @@ +autofs-5.1.7 - move amd mounts removal into lib/mounts.c + +From: Ian Kent + +Move the amd mounts removal from master_free_autofs_point() into +lib/mounts.c along with the rest of the amd mount handling. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 12 +----------- + include/mounts.h | 1 + + lib/mounts.c | 28 ++++++++++++++++++++++++---- + 4 files changed, 27 insertions(+), 15 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -46,6 +46,7 @@ + - use mount_fullpath() in one spot in parse_mount(). + - pass root length to mount_fullpath(). + - remove unused function master_submount_list_empty(). ++- move amd mounts removal into lib/mounts.c. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -143,22 +143,12 @@ int master_add_autofs_point(struct maste + + void master_free_autofs_point(struct autofs_point *ap) + { +- struct list_head *p, *head; + int status; + + if (!ap) + return; + +- mounts_mutex_lock(ap); +- head = &ap->amdmounts; +- p = head->next; +- while (p != head) { +- struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount); +- p = p->next; +- ext_mount_remove(mnt->ext_mp); +- mnts_remove_amdmount(mnt->mp); +- } +- mounts_mutex_unlock(ap); ++ mnts_remove_amdmounts(ap); + + status = pthread_mutex_destroy(&ap->mounts_mutex); + if (status) +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -161,6 +161,7 @@ void mnts_remove_submount(const char *mp + struct mnt_list *mnts_find_amdmount(const char *path); + struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry); + void mnts_remove_amdmount(const char *mp); ++void mnts_remove_amdmounts(struct autofs_point *ap); + struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags); + void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1144,14 +1144,13 @@ fail: + return NULL; + } + +-void mnts_remove_amdmount(const char *mp) ++static void __mnts_remove_amdmount(const char *mp) + { + struct mnt_list *this; + +- mnts_hash_mutex_lock(); + this = mnts_lookup(mp); + if (!(this && this->flags & MNTS_AMD_MOUNT)) +- goto done; ++ return; + this->flags &= ~MNTS_AMD_MOUNT; + list_del_init(&this->amdmount); + if (this->ext_mp) { +@@ -1172,7 +1171,28 @@ void mnts_remove_amdmount(const char *mp + } + this->amd_cache_opts = 0; + __mnts_put_mount(this); +-done: ++} ++ ++void mnts_remove_amdmount(const char *mp) ++{ ++ mnts_hash_mutex_lock(); ++ __mnts_remove_amdmount(mp); ++ mnts_hash_mutex_unlock(); ++} ++ ++void mnts_remove_amdmounts(struct autofs_point *ap) ++{ ++ struct list_head *head, *p; ++ ++ mnts_hash_mutex_lock(); ++ head = &ap->amdmounts; ++ p = head->next; ++ while (p != head) { ++ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount); ++ p = p->next; ++ ext_mount_remove(mnt->ext_mp); ++ __mnts_remove_amdmount(mnt->mp); ++ } + mnts_hash_mutex_unlock(); + } + diff --git a/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch b/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch new file mode 100644 index 0000000..5b87e51 --- /dev/null +++ b/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch @@ -0,0 +1,68 @@ +autofs-5.1.7 - pass mapent_cache to update_offset_entry() + +From: Ian Kent + +Pass mapent_cache to update_offset_entry() rather than use the wait/signal +mechanism, it isn't needed here. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 22 ++++++---------------- + 2 files changed, 7 insertions(+), 16 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -16,6 +16,7 @@ + - fix mnts_get_expire_list() expire list construction. + - fix inconsistent locking in umount_subtree_mounts(). + - fix return from umount_subtree_mounts() on offset list delete. ++- pass mapent_cache to update_offset_entry(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -795,24 +795,17 @@ static int check_is_multi(const char *ma + } + + static int +-update_offset_entry(struct autofs_point *ap, const char *name, ++update_offset_entry(struct autofs_point *ap, ++ struct mapent_cache *mc, const char *name, + const char *m_root, int m_root_len, +- const char *path, const char *myoptions, const char *loc, +- time_t age) ++ const char *path, const char *myoptions, ++ const char *loc, time_t age) + { +- struct map_source *source; +- struct mapent_cache *mc; + char m_key[PATH_MAX + 1]; + char m_mapent[MAPENT_MAX_LEN + 1]; + int p_len, m_key_len, m_options_len, m_mapent_len; + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); + + /* Internal hosts map may have loc == NULL */ +@@ -1576,11 +1569,8 @@ dont_expand: + p += l; + p = skipspace(p); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- status = update_offset_entry(ap, name, +- m_root, m_root_len, ++ status = update_offset_entry(ap, mc, ++ name, m_root, m_root_len, + path, myoptions, loc, age); + + if (status != CHE_OK) { diff --git a/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch b/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch new file mode 100644 index 0000000..47abf2b --- /dev/null +++ b/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch @@ -0,0 +1,153 @@ +autofs-5.1.7 - pass root length to mount_fullpath() + +From: Ian Kent + +The length of root may already be known, add a parameter to allow +passing it to mount_fullpath() so a strlen() call can be avoided. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 11 +++++++---- + modules/mount_bind.c | 2 +- + modules/mount_changer.c | 2 +- + modules/mount_ext2.c | 2 +- + modules/mount_generic.c | 2 +- + modules/mount_nfs.c | 2 +- + modules/parse_sun.c | 4 ++-- + 9 files changed, 16 insertions(+), 12 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -44,6 +44,7 @@ + - remove obsolete functions. + - remove redundant local var from sun_mount(). + - use mount_fullpath() in one spot in parse_mount(). ++- pass root length to mount_fullpath(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -131,7 +131,7 @@ int check_nfs_mount_version(struct nfs_m + extern unsigned int nfs_mount_uses_string_options; + + int mount_fullpath(char *fullpath, size_t max_len, +- const char *root, const char *name); ++ const char *root, size_t root_len, const char *name); + + struct amd_entry; + +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -362,11 +362,14 @@ int check_nfs_mount_version(struct nfs_m + #endif + + int mount_fullpath(char *fullpath, size_t max_len, +- const char *root, const char *name) ++ const char *root, size_t root_len, const char *name) + { + int last, len; + +- last = strlen(root) - 1; ++ if (root_len) ++ last = root_len - 1; ++ else ++ last = strlen(root) - 1; + + /* Root offset of multi-mount or direct or offset mount. + * Direct or offset mount, name (or root) is absolute path. +@@ -1685,7 +1688,7 @@ void tree_mapent_cleanup_offsets(struct + else { + char mp[PATH_MAX + 1]; + +- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key)) + error(ap->logopt, "mount path is too long"); + else + tree_mapent_umount_mount(ap, mp); +@@ -1922,7 +1925,7 @@ int tree_mapent_umount_offsets(struct ma + * one of these keys is the root of a multi-mount the mount + * path must be constructed. + */ +- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) { ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key)) { + error(ap->logopt, "mount path is too long"); + return 0; + } +--- autofs-5.1.4.orig/modules/mount_bind.c ++++ autofs-5.1.4/modules/mount_bind.c +@@ -122,7 +122,7 @@ int mount_mount(struct autofs_point *ap, + } + } + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +--- autofs-5.1.4.orig/modules/mount_changer.c ++++ autofs-5.1.4/modules/mount_changer.c +@@ -59,7 +59,7 @@ int mount_mount(struct autofs_point *ap, + + fstype = "iso9660"; + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +--- autofs-5.1.4.orig/modules/mount_ext2.c ++++ autofs-5.1.4/modules/mount_ext2.c +@@ -55,7 +55,7 @@ int mount_mount(struct autofs_point *ap, + if (defaults_get_mount_verbose()) + mountlog = &log_info; + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +--- autofs-5.1.4.orig/modules/mount_generic.c ++++ autofs-5.1.4/modules/mount_generic.c +@@ -54,7 +54,7 @@ int mount_mount(struct autofs_point *ap, + if (defaults_get_mount_verbose()) + mountlog = &log_info; + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +--- autofs-5.1.4.orig/modules/mount_nfs.c ++++ autofs-5.1.4/modules/mount_nfs.c +@@ -213,7 +213,7 @@ int mount_mount(struct autofs_point *ap, + } + + /* Construct mount point directory */ +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1091,7 +1091,7 @@ static int mount_subtree(struct autofs_p + struct mapent *ro; + size_t len; + +- len = mount_fullpath(key, PATH_MAX, ap->path, me->key); ++ len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key); + if (!len) { + warn(ap->logopt, "path loo long"); + return 1; +@@ -1361,7 +1361,7 @@ dont_expand: + time_t age; + int l; + +- m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, name); ++ m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, ap->len, name); + if (!m_root_len) { + error(ap->logopt, + MODPREFIX "multi-mount root path too long"); diff --git a/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch b/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch new file mode 100644 index 0000000..e3758a8 --- /dev/null +++ b/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch @@ -0,0 +1,75 @@ +autofs-5.1.7 - reduce umount EBUSY check delay + +From: Ian Kent + +Some time ago I had to wait and retry umount() for autofs mounts +becuase I found EBUSY would be returned for a time after the call +causing false negative umount returns. + +I think that problem has been resolved but removing the retry is +probably a little risky. + +But the wait time is quite long at one fifth of a second so reduce +that to one twentieth of a second and increase the retries to make +it more resposive. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 4 ++-- + daemon/indirect.c | 2 +- + include/automount.h | 2 +- + 4 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -22,6 +22,7 @@ + - eliminate count_mounts() from expire_proc_indirect(). + - eliminate some strlen calls in offset handling. + - don't add offset mounts to mounted mounts table. ++- reduce umount EBUSY check delay. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -150,7 +150,7 @@ int do_umount_autofs_direct(struct autof + + retries = UMOUNT_RETRIES; + while ((rv = umount(me->key)) == -1 && retries--) { +- struct timespec tm = {0, 200000000}; ++ struct timespec tm = {0, 50000000}; + if (errno != EBUSY) + break; + nanosleep(&tm, NULL); +@@ -573,7 +573,7 @@ int umount_autofs_offset(struct autofs_p + + retries = UMOUNT_RETRIES; + while ((rv = umount(me->key)) == -1 && retries--) { +- struct timespec tm = {0, 200000000}; ++ struct timespec tm = {0, 50000000}; + if (errno != EBUSY) + break; + nanosleep(&tm, NULL); +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -265,7 +265,7 @@ int umount_autofs_indirect(struct autofs + + retries = UMOUNT_RETRIES; + while ((rv = umount(mountpoint)) == -1 && retries--) { +- struct timespec tm = {0, 200000000}; ++ struct timespec tm = {0, 50000000}; + if (errno != EBUSY) + break; + nanosleep(&tm, NULL); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -140,7 +140,7 @@ struct autofs_point; + #define NULL_MAP_HASHSIZE 64 + #define NEGATIVE_TIMEOUT 10 + #define POSITIVE_TIMEOUT 120 +-#define UMOUNT_RETRIES 8 ++#define UMOUNT_RETRIES 16 + #define EXPIRE_RETRIES 3 + + struct mapent_cache { diff --git a/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch b/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch new file mode 100644 index 0000000..c859acf --- /dev/null +++ b/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch @@ -0,0 +1,71 @@ +autofs-5.1.7 - refactor lookup_prune_one_cache() a bit + +From: Ian Kent + +Coverity: use: Using an unreliable value of "me" inside the second locked + section. + +Change lookup_prune_one_cache() a little, move the location the next +key is set (before releasing the lock) and add a comment explaining +why we don't care about the side effects of the read lock release/ +write lock aquire/write lock release/read lock reaquire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 20 +++++++++++++++++++- + 2 files changed, 20 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -63,6 +63,7 @@ + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). ++- refactor lookup_prune_one_cache() a bit. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -1383,7 +1383,6 @@ void lookup_prune_one_cache(struct autof + } + + key = strdup(me->key); +- me = cache_enumerate(mc, me); + /* Don't consider any entries with a wildcard */ + if (!key || strchr(key, '*')) { + if (key) +@@ -1430,6 +1429,7 @@ void lookup_prune_one_cache(struct autof + if (valid) + cache_unlock(valid->mc); + ++ me = cache_enumerate(mc, me); + if (me) + next_key = strdup(me->key); + +@@ -1464,6 +1464,24 @@ void lookup_prune_one_cache(struct autof + next: + cache_readlock(mc); + if (next_key) { ++ /* The lock release and reaquire above can mean ++ * a number of things could happen. ++ * ++ * First, mapents could be added between the ++ * current mapent and the mapent of next_key. ++ * Don't care about that because there's no ++ * need to prune newly added entries. ++ * ++ * Second, the next mapent data could have ++ * changed. Don't care about that either since ++ * we are looking to prune stale map entries ++ * and don't care when they become stale. ++ * ++ * Finally, the mapent of next_key could have ++ * gone away. Again don't care about this either, ++ * the loop will exit prematurely so just wait ++ * until the next prune and try again. ++ */ + me = cache_lookup_distinct(mc, next_key); + free(next_key); + } diff --git a/autofs-5.1.7-refactor-umount_multi_triggers.patch b/autofs-5.1.7-refactor-umount_multi_triggers.patch new file mode 100644 index 0000000..1770d64 --- /dev/null +++ b/autofs-5.1.7-refactor-umount_multi_triggers.patch @@ -0,0 +1,255 @@ +autofs-5.1.7 - refactor umount_multi_triggers() + +From: Ian Kent + +Refactor umount_multi_triggers() to try the umount of an offset subtree +in a seperate function. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 187 ++++++++++++++++++++++++++++++++--------------------------- + 2 files changed, 104 insertions(+), 84 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -10,6 +10,7 @@ + - set offset parent in update_offset_entry(). + - remove redundant variables from mount_autofs_offset(). + - remove unused parameter form do_mount_autofs_offset(). ++- refactor umount_multi_triggers(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2490,57 +2490,6 @@ static int do_mount_autofs_offset(struct + return mounted; + } + +-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; +- struct mapent *oe; +- struct list_head *pos = NULL; +- unsigned int root_len = strlen(root); +- int mounted; +- +- mounted = 0; +- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); +- while (offset) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- goto cont; +- } +- +- /* The root offset is always mounted seperately so the +- * offset path will always be root + offset. +- */ +- strcpy(key, root); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- if (!oe || !oe->mapent) +- goto cont; +- +- mounted += do_mount_autofs_offset(ap, oe, root); +- +- /* +- * If re-constructing a multi-mount it's necessary to walk +- * into nested mounts, unlike the usual "mount only what's +- * needed as you go" behavior. +- */ +- if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { +- if (oe->ioctlfd != -1 || +- is_mounted(oe->key, MNTS_REAL)) +- mount_multi_triggers(ap, oe, key, strlen(key), base); +- } +-cont: +- offset = cache_get_offset(base, +- offset, start, &me->multi_list, &pos); +- } +- +- return mounted; +-} +- + static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) + { + char *dir, *path; +@@ -2576,7 +2525,10 @@ static int rmdir_path_offset(struct auto + return ret; + } + +-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) ++static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root); ++ ++static int do_umount_multi_triggers(struct autofs_point *ap, ++ struct mapent *me, const char *root, const char *base) + { + char path[PATH_MAX + 1]; + char *offset; +@@ -2606,7 +2558,6 @@ int umount_multi_triggers(struct autofs_ + while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { + char key[PATH_MAX + 1]; + int key_len = root_len + strlen(offset); +- char *oe_base; + + if (mm_base_len > 1) + key_len += mm_base_len; +@@ -2626,47 +2577,116 @@ int umount_multi_triggers(struct autofs_ + if (!oe || (strlen(oe->key) - start) == 1) + continue; + ++ left += do_umount_offset(ap, oe, root); ++ } ++ ++ return left; ++} ++ ++static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root) ++{ ++ char *oe_base; ++ int left = 0; ++ ++ /* ++ * Check for and umount subtree offsets resulting from ++ * nonstrict mount fail. ++ */ ++ oe_base = oe->key + strlen(root); ++ left += do_umount_multi_triggers(ap, oe, root, oe_base); ++ ++ if (oe->ioctlfd != -1 || ++ is_mounted(oe->key, MNTS_REAL)) { ++ left++; ++ return left; ++ } ++ ++ debug(ap->logopt, "umount offset %s", oe->key); ++ ++ if (umount_autofs_offset(ap, oe)) { ++ warn(ap->logopt, "failed to umount offset"); ++ left++; ++ } else { ++ struct stat st; ++ int ret; ++ ++ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) ++ return left; ++ + /* +- * Check for and umount subtree offsets resulting from +- * nonstrict mount fail. ++ * An error due to partial directory removal is ++ * ok so only try and remount the offset if the ++ * actual mount point still exists. + */ +- oe_base = oe->key + strlen(root); +- left += umount_multi_triggers(ap, oe, root, oe_base); ++ ret = rmdir_path_offset(ap, oe); ++ if (ret == -1 && !stat(oe->key, &st)) { ++ ret = do_mount_autofs_offset(ap, oe, root); ++ if (ret) ++ left++; ++ /* But we did origianlly create this */ ++ oe->flags |= MOUNT_FLAG_DIR_CREATED; ++ } ++ } ++ return left; ++} + +- if (oe->ioctlfd != -1 || +- is_mounted(oe->key, MNTS_REAL)) { +- left++; +- continue; ++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; ++ struct mapent *oe; ++ struct list_head *pos = NULL; ++ unsigned int root_len = strlen(root); ++ int mounted; ++ ++ mounted = 0; ++ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); ++ while (offset) { ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); ++ ++ if (key_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ goto cont; + } + +- debug(ap->logopt, "umount offset %s", oe->key); ++ /* The root offset is always mounted seperately so the ++ * offset path will always be root + offset. ++ */ ++ strcpy(key, root); ++ strcat(key, offset); + +- if (umount_autofs_offset(ap, oe)) { +- warn(ap->logopt, "failed to umount offset"); +- left++; +- } else { +- struct stat st; +- int ret; ++ oe = cache_lookup_distinct(me->mc, key); ++ if (!oe || !oe->mapent) ++ goto cont; + +- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) +- continue; ++ mounted += do_mount_autofs_offset(ap, oe, root); + +- /* +- * An error due to partial directory removal is +- * ok so only try and remount the offset if the +- * actual mount point still exists. +- */ +- ret = rmdir_path_offset(ap, oe); +- if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root); +- if (ret) +- left++; +- /* But we did origianlly create this */ +- oe->flags |= MOUNT_FLAG_DIR_CREATED; +- } ++ /* ++ * If re-constructing a multi-mount it's necessary to walk ++ * into nested mounts, unlike the usual "mount only what's ++ * needed as you go" behavior. ++ */ ++ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { ++ if (oe->ioctlfd != -1 || ++ is_mounted(oe->key, MNTS_REAL)) ++ mount_multi_triggers(ap, oe, key, strlen(key), base); + } ++cont: ++ offset = cache_get_offset(base, ++ offset, start, &me->multi_list, &pos); + } + ++ return mounted; ++} ++ ++int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) ++{ ++ int left; ++ ++ left = do_umount_multi_triggers(ap, me, root, base); ++ + if (!left && me->multi == me) { + struct mapent_cache *mc = me->mc; + int status; +@@ -2865,4 +2885,3 @@ int clean_stale_multi_triggers(struct au + + return left; + } +- diff --git a/autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch b/autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch new file mode 100644 index 0000000..64fe382 --- /dev/null +++ b/autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch @@ -0,0 +1,544 @@ +autofs-5.1.7 - remove mount.x and rpcgen dependencies + +From: Ian Kent + +Adding a local implementation to get the exports list from a server +means the the rpcgen generataed code is no longer needed so remove +mount.x and the build dependencies. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + Makefile.conf.in | 1 + autofs.spec | 2 + configure | 58 --------- + configure.in | 1 + include/automount.h | 1 + include/config.h.in | 3 + lib/Makefile | 26 ---- + lib/mount.x | 345 --------------------------------------------------- + 9 files changed, 5 insertions(+), 433 deletions(-) + delete mode 100644 lib/mount.x + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -1,5 +1,6 @@ + + - add xdr_exports(). ++- remove mount.x and rpcgen dependencies. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/Makefile.conf.in ++++ autofs-5.1.4/Makefile.conf.in +@@ -65,7 +65,6 @@ FEDFS = @ENABLE_FEDFS@ + + LEX = @PATH_LEX@ + YACC = @PATH_YACC@ +-RPCGEN = @PATH_RPCGEN@ + RANLIB = @PATH_RANLIB@ + + # Use libtirpc if requested and available +--- autofs-5.1.4.orig/configure ++++ autofs-5.1.4/configure +@@ -651,8 +651,6 @@ XML_CONFIG + ENABLE_FEDFS + sssldir + HAVE_SSS_AUTOFS +-PATH_RPCGEN +-RPCGEN + PATH_RANLIB + RANLIB + PATH_YACC +@@ -4322,62 +4320,6 @@ else + as_fn_error $? "required program RANLIB not found" "$LINENO" 5 + fi + +-for ac_prog in rpcgen +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_path_RPCGEN+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- case $RPCGEN in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_RPCGEN="$RPCGEN" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-RPCGEN=$ac_cv_path_RPCGEN +-if test -n "$RPCGEN"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5 +-$as_echo "$RPCGEN" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$RPCGEN" && break +-done +- +-if test -n "$RPCGEN"; then +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_RPCGEN "$RPCGEN" +-_ACEOF +- +- PATH_RPCGEN="$RPCGEN" +-else +- as_fn_error $? "required program RPCGEN not found" "$LINENO" 5 +-fi +- + + if test -z "$sssldir"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sssd autofs library" >&5 +--- autofs-5.1.4.orig/configure.in ++++ autofs-5.1.4/configure.in +@@ -165,7 +165,6 @@ AF_PATH_INCLUDE(E4FSCK, fsck.ext4 e4fsck + AF_CHECK_PROG(LEX, flex lex, , $searchpath) + AF_CHECK_PROG(YACC, bison, , $searchpath) + AF_CHECK_PROG(RANLIB, ranlib, , $searchpath) +-AF_CHECK_PROG(RPCGEN, rpcgen, , $searchpath) + + AF_CHECK_SSS_LIB(SSS_AUTOFS, libsss_autofs.so) + AC_SUBST(HAVE_SSS_AUTOFS) +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -32,7 +32,6 @@ + #include "macros.h" + #include "log.h" + #include "rpc_subs.h" +-#include "mounts.h" + #include "parse_subs.h" + #include "mounts.h" + #include "dev-ioctl-lib.h" +--- autofs-5.1.4.orig/include/config.h.in ++++ autofs-5.1.4/include/config.h.in +@@ -135,9 +135,6 @@ + /* define if you have RANLIB */ + #undef PATH_RANLIB + +-/* define if you have RPCGEN */ +-#undef PATH_RPCGEN +- + /* define if you have UMOUNT */ + #undef PATH_UMOUNT + +--- autofs-5.1.4.orig/lib/Makefile ++++ autofs-5.1.4/lib/Makefile +@@ -8,10 +8,9 @@ include ../Makefile.rules + SRCS = cache.c cat_path.c rpc_subs.c mounts.c log.c nsswitch.c \ + nss_tok.c nss_parse.tab.c args.c alarm.c macros.c defaults.c \ + parse_subs.c dev-ioctl-lib.c +-RPCS = mount.h mount_clnt.c mount_xdr.c +-OBJS = cache.o mount_clnt.o mount_xdr.o cat_path.o rpc_subs.o \ +- mounts.o log.o nsswitch.o nss_tok.o nss_parse.tab.o args.o \ +- alarm.o macros.o defaults.o parse_subs.o dev-ioctl-lib.o ++OBJS = cache.o cat_path.o rpc_subs.o mounts.o log.o nsswitch.o \ ++ nss_tok.o nss_parse.tab.o args.o alarm.o macros.o defaults.o \ ++ parse_subs.o dev-ioctl-lib.o + + YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h + +@@ -34,23 +33,6 @@ autofs.a: $(OBJS) + $(AR) $(ARFLAGS) $(LIB) $(OBJS) + -$(RANLIB) $(LIB) + +-mount.h: mount.x +- $(RPCGEN) -h -o mount.h mount.x +- +-mount_clnt.c: mount.h +- $(RPCGEN) -l -o mount_clnt.c mount.x +- +-mount_clnt.o: mount_clnt.c +- $(CC) $(CFLAGS) -o mount_clnt.o -c mount_clnt.c +- $(STRIP) mount_clnt.o +- +-mount_xdr.c: mount.h +- $(RPCGEN) -c -o mount_xdr.c mount.x +- +-mount_xdr.o: mount_xdr.c +- $(CC) $(CFLAGS) -Wno-unused-variable -o mount_xdr.o -c mount_xdr.c +- $(STRIP) mount_xdr.o +- + nss_tok.c: nss_tok.l + $(LEX) -o$@ -Pnss_ $? + +@@ -61,8 +43,6 @@ nss_tok.o: nss_tok.c nss_parse.tab.h + + nss_parse.tab.o: nss_parse.tab.c nss_parse.tab.h + +-rpc_subs.o: mount.h +- + install: all + + clean: +--- autofs-5.1.4.orig/lib/mount.x ++++ /dev/null +@@ -1,345 +0,0 @@ +-%/* +-% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +-% * unrestricted use provided that this legend is included on all tape +-% * media and as a part of the software program in whole or part. Users +-% * may copy or modify Sun RPC without charge, but are not authorized +-% * to license or distribute it to anyone else except as part of a product or +-% * program developed by the user or with the express written consent of +-% * Sun Microsystems, Inc. +-% * +-% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +-% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +-% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +-% * +-% * Sun RPC is provided with no support and without any obligation on the +-% * part of Sun Microsystems, Inc. to assist in its use, correction, +-% * modification or enhancement. +-% * +-% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +-% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +-% * OR ANY PART THEREOF. +-% * +-% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +-% * or profits or other special, indirect and consequential damages, even if +-% * Sun has been advised of the possibility of such damages. +-% * +-% * Sun Microsystems, Inc. +-% * 2550 Garcia Avenue +-% * Mountain View, California 94043 +-% */ +- +-%/* +-% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc. +-% */ +-% +-%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */ +- +-/* +- * Protocol description for the mount program +- */ +- +-#ifdef RPC_HDR +-%#ifndef _rpcsvc_mount_h +-%#define _rpcsvc_mount_h +-%#include +-#endif +- +-const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +-const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +-const FHSIZE = 32; /* size in bytes of a file handle */ +- +-/* +- * The fhandle is the file handle that the server passes to the client. +- * All file operations are done using the file handles to refer to a file +- * or a directory. The file handle can contain whatever information the +- * server needs to distinguish an individual file. +- */ +-typedef opaque fhandle[FHSIZE]; +- +-/* +- * If a status of zero is returned, the call completed successfully, and +- * a file handle for the directory follows. A non-zero status indicates +- * some sort of error. The status corresponds with UNIX error numbers. +- */ +-union fhstatus switch (unsigned fhs_status) { +-case 0: +- fhandle fhs_fhandle; +-default: +- void; +-}; +- +-/* +- * The type dirpath is the pathname of a directory +- */ +-typedef string dirpath; +- +-/* +- * The type name is used for arbitrary names (hostnames, groupnames) +- */ +-typedef string name; +- +-/* +- * A list of who has what mounted +- */ +-typedef struct mountbody *mountlist; +-struct mountbody { +- name ml_hostname; +- dirpath ml_directory; +- mountlist ml_next; +-}; +- +-/* +- * A list of netgroups +- */ +-typedef struct groupnode *groups; +-struct groupnode { +- name gr_name; +- groups gr_next; +-}; +- +-/* +- * A list of what is exported and to whom +- */ +-typedef struct exportnode *exports; +-struct exportnode { +- dirpath ex_dir; +- groups ex_groups; +- exports ex_next; +-}; +- +-/* +- * POSIX pathconf information +- */ +-struct ppathcnf { +- int pc_link_max; /* max links allowed */ +- short pc_max_canon; /* max line len for a tty */ +- short pc_max_input; /* input a tty can eat all at once */ +- short pc_name_max; /* max file name length (dir entry) */ +- short pc_path_max; /* max path name length (/x/y/x/.. ) */ +- short pc_pipe_buf; /* size of a pipe (bytes) */ +- u_char pc_vdisable; /* safe char to turn off c_cc[i] */ +- char pc_xxx; /* alignment padding; cc_t == char */ +- short pc_mask[2]; /* validity and boolean bits */ +-}; +- +-/* +- * NFSv3 file handle +- */ +-const FHSIZE3 = 64; /* max size of NFSv3 file handle in bytes */ +-typedef opaque fhandle3; +- +-/* +- * NFSv3 mount status +- */ +-enum mountstat3 { +- MNT_OK = 0, /* no error */ +- MNT3ERR_PERM = 1, /* not owner */ +- MNT3ERR_NOENT = 2, /* no such file or directory */ +- MNT3ERR_IO = 5, /* I/O error */ +- MNT3ERR_ACCES = 13, /* Permission denied */ +- MNT3ERR_NOTDIR = 20, /* Not a directory */ +- MNT3ERR_INVAL = 22, /* Invalid argument */ +- MNT3ERR_NAMETOOLONG = 63, /* File name too long */ +- MNT3ERR_NOTSUPP = 10004,/* Operation not supported */ +- MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ +-}; +- +-/* +- * NFSv3 mount result +- */ +-struct mountres3_ok { +- fhandle3 fhandle; +- int auth_flavors<>; +-}; +- +-union mountres3 switch (mountstat3 fhs_status) { +-case MNT_OK: +- mountres3_ok mountinfo; /* File handle and supported flavors */ +-default: +- void; +-}; +- +-program MOUNTPROG { +- /* +- * Version one of the mount protocol communicates with version two +- * of the NFS protocol. The only connecting point is the fhandle +- * structure, which is the same for both protocols. +- */ +- version MOUNTVERS { +- /* +- * Does no work. It is made available in all RPC services +- * to allow server reponse testing and timing +- */ +- void +- MOUNTPROC_NULL(void) = 0; +- +- /* +- * If fhs_status is 0, then fhs_fhandle contains the +- * file handle for the directory. This file handle may +- * be used in the NFS protocol. This procedure also adds +- * a new entry to the mount list for this client mounting +- * the directory. +- * Unix authentication required. +- */ +- fhstatus +- MOUNTPROC_MNT(dirpath) = 1; +- +- /* +- * Returns the list of remotely mounted filesystems. The +- * mountlist contains one entry for each hostname and +- * directory pair. +- */ +- mountlist +- MOUNTPROC_DUMP(void) = 2; +- +- /* +- * Removes the mount list entry for the directory +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNT(dirpath) = 3; +- +- /* +- * Removes all of the mount list entries for this client +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNTALL(void) = 4; +- +- /* +- * Returns a list of all the exported filesystems, and which +- * machines are allowed to import it. +- */ +- exports +- MOUNTPROC_EXPORT(void) = 5; +- +- /* +- * Identical to MOUNTPROC_EXPORT above +- */ +- exports +- MOUNTPROC_EXPORTALL(void) = 6; +- } = 1; +- +- /* +- * Version two of the mount protocol communicates with version two +- * of the NFS protocol. +- * The only difference from version one is the addition of a POSIX +- * pathconf call. +- */ +- version MOUNTVERS_POSIX { +- /* +- * Does no work. It is made available in all RPC services +- * to allow server reponse testing and timing +- */ +- void +- MOUNTPROC_NULL(void) = 0; +- +- /* +- * If fhs_status is 0, then fhs_fhandle contains the +- * file handle for the directory. This file handle may +- * be used in the NFS protocol. This procedure also adds +- * a new entry to the mount list for this client mounting +- * the directory. +- * Unix authentication required. +- */ +- fhstatus +- MOUNTPROC_MNT(dirpath) = 1; +- +- /* +- * Returns the list of remotely mounted filesystems. The +- * mountlist contains one entry for each hostname and +- * directory pair. +- */ +- mountlist +- MOUNTPROC_DUMP(void) = 2; +- +- /* +- * Removes the mount list entry for the directory +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNT(dirpath) = 3; +- +- /* +- * Removes all of the mount list entries for this client +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNTALL(void) = 4; +- +- /* +- * Returns a list of all the exported filesystems, and which +- * machines are allowed to import it. +- */ +- exports +- MOUNTPROC_EXPORT(void) = 5; +- +- /* +- * Identical to MOUNTPROC_EXPORT above +- */ +- exports +- MOUNTPROC_EXPORTALL(void) = 6; +- +- /* +- * POSIX pathconf info (Sun hack) +- */ +- ppathcnf +- MOUNTPROC_PATHCONF(dirpath) = 7; +- } = 2; +- +- /* +- * Version 3 of the protocol is for NFSv3 +- */ +- version MOUNTVERS_NFSV3 { +- /* +- * Does no work. It is made available in all RPC services +- * to allow server reponse testing and timing +- */ +- void +- MOUNTPROC3_NULL(void) = 0; +- +- /* +- * If fhs_status is 0, then fhs_fhandle contains the +- * file handle for the directory. This file handle may +- * be used in the NFS protocol. This procedure also adds +- * a new entry to the mount list for this client mounting +- * the directory. +- * Unix authentication required. +- */ +- mountres3 +- MOUNTPROC3_MNT(dirpath) = 1; +- +- /* +- * Returns the list of remotely mounted filesystems. The +- * mountlist contains one entry for each hostname and +- * directory pair. +- */ +- mountlist +- MOUNTPROC3_DUMP(void) = 2; +- +- /* +- * Removes the mount list entry for the directory +- * Unix authentication required. +- */ +- void +- MOUNTPROC3_UMNT(dirpath) = 3; +- +- /* +- * Removes all of the mount list entries for this client +- * Unix authentication required. +- */ +- void +- MOUNTPROC3_UMNTALL(void) = 4; +- +- /* +- * Returns a list of all the exported filesystems, and which +- * machines are allowed to import it. +- */ +- exports +- MOUNTPROC3_EXPORT(void) = 5; +- } = 3; +-} = 100005; +- +-#ifdef RPC_HDR +-%#endif /*!_rpcsvc_mount_h*/ +-#endif diff --git a/autofs-5.1.7-remove-mounts_mutex.patch b/autofs-5.1.7-remove-mounts_mutex.patch new file mode 100644 index 0000000..7990ea7 --- /dev/null +++ b/autofs-5.1.7-remove-mounts_mutex.patch @@ -0,0 +1,168 @@ +autofs-5.1.7 - remove mounts_mutex + +From: Ian Kent + +The mounts_mutex is no longer used, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 8 +------- + daemon/master.c | 13 ------------- + include/automount.h | 1 - + modules/mount_autofs.c | 8 -------- + 5 files changed, 2 insertions(+), 29 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -48,6 +48,7 @@ + - remove unused function master_submount_list_empty(). + - move amd mounts removal into lib/mounts.c. + - check for offset with no mount location. ++- remove mounts_mutex. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -1749,7 +1749,6 @@ static void handle_mounts_cleanup(void * + * here. + */ + if (submount) { +- mounts_mutex_unlock(ap->parent); + master_source_unlock(ap->parent->entry); + master_free_mapent_sources(ap->entry, 1); + master_free_mapent(ap->entry); +@@ -1787,13 +1786,9 @@ static int submount_source_writelock_nes + if (status) + goto done; + +- mounts_mutex_lock(parent); +- + status = pthread_rwlock_trywrlock(&ap->entry->source_lock); +- if (status) { +- mounts_mutex_unlock(parent); ++ if (status) + master_source_unlock(parent->entry); +- } + + done: + if (status && status != EBUSY) { +@@ -1809,7 +1804,6 @@ static void submount_source_unlock_neste + struct autofs_point *parent = ap->parent; + + master_source_unlock(ap->entry); +- mounts_mutex_unlock(parent); + master_source_unlock(parent->entry); + } + +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -69,7 +69,6 @@ int master_add_autofs_point(struct maste + unsigned nobind, unsigned ghost, int submount) + { + struct autofs_point *ap; +- int status; + + ap = malloc(sizeof(struct autofs_point)); + if (!ap) +@@ -128,12 +127,6 @@ int master_add_autofs_point(struct maste + INIT_LIST_HEAD(&ap->amdmounts); + ap->shutdown = 0; + +- status = pthread_mutex_init(&ap->mounts_mutex, NULL); +- if (status) { +- free(ap->path); +- free(ap); +- return 0; +- } + ap->mode = 0; + + entry->ap = ap; +@@ -143,17 +136,11 @@ int master_add_autofs_point(struct maste + + void master_free_autofs_point(struct autofs_point *ap) + { +- int status; +- + if (!ap) + return; + + mnts_remove_amdmounts(ap); + +- status = pthread_mutex_destroy(&ap->mounts_mutex); +- if (status) +- fatal(status); +- + if (ap->pref) + free(ap->pref); + free(ap->path); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -564,7 +564,6 @@ struct autofs_point { + enum states state; /* Current state */ + int state_pipe[2]; /* State change router pipe */ + struct autofs_point *parent; /* Owner of mounts list for submount */ +- pthread_mutex_t mounts_mutex; /* Protect mount lists */ + struct list_head mounts; /* List of autofs mounts at current level */ + unsigned int submount; /* Is this a submount */ + unsigned int submnt_count; /* Number of submounts */ +--- autofs-5.1.4.orig/modules/mount_autofs.c ++++ autofs-5.1.4/modules/mount_autofs.c +@@ -283,8 +283,6 @@ int mount_mount(struct autofs_point *ap, + set_exp_timeout(nap, NULL, timeout); + nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + +- mounts_mutex_lock(ap); +- + if (source->flags & MAP_FLAG_FORMAT_AMD) { + struct mnt_list *mnt; + +@@ -305,7 +303,6 @@ int mount_mount(struct autofs_point *ap, + 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; +@@ -316,7 +313,6 @@ int mount_mount(struct autofs_point *ap, + crit(ap->logopt, + MODPREFIX "failed to allocate mount %s", realpath); + handle_mounts_startup_cond_destroy(&suc); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + return 1; +@@ -335,7 +331,6 @@ int mount_mount(struct autofs_point *ap, + realpath); + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + return 1; +@@ -346,7 +341,6 @@ int mount_mount(struct autofs_point *ap, + if (status) { + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + fatal(status); +@@ -358,7 +352,6 @@ int mount_mount(struct autofs_point *ap, + MODPREFIX "failed to create submount for %s", realpath); + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + return 1; +@@ -368,7 +361,6 @@ int mount_mount(struct autofs_point *ap, + ap->submnt_count++; + + handle_mounts_startup_cond_destroy(&suc); +- mounts_mutex_unlock(ap); + + return 0; + } diff --git a/autofs-5.1.7-remove-obsolete-functions.patch b/autofs-5.1.7-remove-obsolete-functions.patch new file mode 100644 index 0000000..5582589 --- /dev/null +++ b/autofs-5.1.7-remove-obsolete-functions.patch @@ -0,0 +1,739 @@ +autofs-5.1.7 - remove obsolete functions + +From: Ian Kent + +Remove the code that's no longer used due to the tree mapent +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 10 - + include/mounts.h | 2 + lib/cache.c | 227 ------------------------------------- + lib/mounts.c | 311 ---------------------------------------------------- + modules/parse_sun.c | 56 --------- + 6 files changed, 2 insertions(+), 605 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -41,6 +41,7 @@ + - add set_offset_tree_catatonic(). + - add mount and umount offsets functions. + - switch to use tree implementation for offsets. ++- remove obsolete functions. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -162,16 +162,13 @@ struct stack { + struct mapent { + struct mapent *next; + struct list_head ino_index; +- struct list_head multi_list; + struct mapent_cache *mc; + struct map_source *source; + /* Need to know owner if we're a multi-mount */ + struct tree_node *mm_root; ++ /* Parent nesting point within multi-mount */ + struct tree_node *mm_parent; + struct tree_node node; +- struct mapent *multi; +- /* Parent nesting point within multi-mount */ +- struct mapent *parent; + char *key; + size_t len; + char *mapent; +@@ -209,23 +206,18 @@ struct mapent *cache_lookup_next(struct + struct mapent *cache_lookup_key_next(struct mapent *me); + struct mapent *cache_lookup(struct mapent_cache *mc, const char *key); + struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key); +-struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head); + struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix); + struct mapent *cache_partial_match_wild(struct mapent_cache *mc, const char *prefix); + int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); + void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); + struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key); +-int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); + 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); +-int cache_delete_offset(struct mapent_cache *mc, const char *key); +-int cache_delete_offset_list(struct mapent_cache *mc, const char *key); + void cache_release(struct map_source *map); + void cache_clean_null_cache(struct mapent_cache *mc); + void cache_release_null_cache(struct master *master); + struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me); +-char *cache_get_offset(const char *prefix, char *offset, int start, struct list_head *head, struct list_head **pos); + + /* Utility functions */ + +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -187,8 +187,6 @@ void set_indirect_mount_tree_catatonic(s + void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); + int umount_ent(struct autofs_point *, const char *); + int umount_amd_ext_mount(struct autofs_point *, 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 *); + int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); + + #endif +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -461,30 +461,6 @@ struct mapent *cache_lookup_distinct(str + return NULL; + } + +-/* Lookup an offset within a multi-mount entry */ +-struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head) +-{ +- struct list_head *p; +- struct mapent *this; +- /* Keys for direct maps may be as long as a path name */ +- char o_key[PATH_MAX]; +- /* Avoid "//" at the beginning of paths */ +- const char *path_prefix = strlen(prefix) > 1 ? prefix : ""; +- size_t size; +- +- /* root offset duplicates "/" */ +- size = snprintf(o_key, sizeof(o_key), "%s%s", path_prefix, offset); +- if (size >= sizeof(o_key)) +- return NULL; +- +- list_for_each(p, head) { +- this = list_entry(p, struct mapent, multi_list); +- if (!strcmp(&this->key[start], o_key)) +- return this; +- } +- return NULL; +-} +- + /* cache must be read locked by caller */ + static struct mapent *__cache_partial_match(struct mapent_cache *mc, + const char *prefix, +@@ -583,9 +559,6 @@ int cache_add(struct mapent_cache *mc, s + me->mm_parent = NULL; + INIT_TREE_NODE(&me->node); + INIT_LIST_HEAD(&me->ino_index); +- INIT_LIST_HEAD(&me->multi_list); +- me->multi = NULL; +- me->parent = NULL; + me->ioctlfd = -1; + me->dev = (dev_t) -1; + me->ino = (ino_t) -1; +@@ -616,33 +589,6 @@ int cache_add(struct mapent_cache *mc, s + } + + /* cache must be write locked by caller */ +-static void cache_add_ordered_offset(struct mapent *me, struct list_head *head) +-{ +- struct list_head *p; +- struct mapent *this; +- +- list_for_each(p, head) { +- size_t tlen; +- int eq; +- +- this = list_entry(p, struct mapent, multi_list); +- tlen = strlen(this->key); +- +- eq = strncmp(this->key, me->key, tlen); +- if (!eq && tlen == strlen(me->key)) +- return; +- +- if (eq > 0) { +- list_add_tail(&me->multi_list, p); +- return; +- } +- } +- list_add_tail(&me->multi_list, p); +- +- return; +-} +- +-/* cache must be write locked by caller */ + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age) + { + unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt(); +@@ -747,25 +693,6 @@ struct mapent *cache_get_offset_parent(s + return NULL; + } + +-int cache_set_offset_parent(struct mapent_cache *mc, const char *offset) +-{ +- struct mapent *this, *parent; +- +- this = cache_lookup_distinct(mc, offset); +- if (!this) +- return 0; +- if (!IS_MM(this)) +- return 0; +- +- parent = cache_get_offset_parent(mc, offset); +- if (parent) +- this->parent = parent; +- else +- this->parent = MM_ROOT(this); +- +- return 1; +-} +- + /* cache must be write locked by caller */ + int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age) + { +@@ -807,50 +734,6 @@ int cache_update(struct mapent_cache *mc + return ret; + } + +-/* cache write lock of the multi mount owner must be held by caller */ +-int cache_delete_offset(struct mapent_cache *mc, const char *key) +-{ +- u_int32_t hashval = hash(key, mc->size); +- struct mapent *me = NULL, *pred; +- int status; +- +- me = mc->hash[hashval]; +- if (!me) +- return CHE_FAIL; +- +- if (strcmp(key, me->key) == 0) { +- if (IS_MM(me) && IS_MM_ROOT(me)) +- return CHE_FAIL; +- mc->hash[hashval] = me->next; +- goto delete; +- } +- +- while (me->next != NULL) { +- pred = me; +- me = me->next; +- if (strcmp(key, me->key) == 0) { +- if (IS_MM(me) && IS_MM_ROOT(me)) +- return CHE_FAIL; +- pred->next = me->next; +- goto delete; +- } +- } +- +- return CHE_FAIL; +- +-delete: +- list_del(&me->multi_list); +- ino_index_lock(mc); +- list_del(&me->ino_index); +- ino_index_unlock(mc); +- free(me->key); +- if (me->mapent) +- free(me->mapent); +- free(me); +- +- return CHE_OK; +-} +- + /* cache must be write locked by caller */ + int cache_delete(struct mapent_cache *mc, const char *key) + { +@@ -1024,113 +907,3 @@ struct mapent *cache_enumerate(struct ma + + return cache_lookup_next(mc, me); + } +- +-/* +- * Get each offset from list head under prefix. +- * Maintain traversal current position in pos for subsequent calls. +- * Return each offset into offset. +- */ +-/* cache must be read locked by caller */ +-char *cache_get_offset(const char *prefix, char *offset, int start, +- struct list_head *head, struct list_head **pos) +-{ +- struct list_head *next; +- struct mapent *this; +- size_t plen = strlen(prefix); +- size_t len = 0; +- +- if (*pos == head) +- return NULL; +- +- /* Find an offset */ +- *offset = '\0'; +- next = *pos ? (*pos)->next : head->next; +- while (next != head) { +- char *offset_start, *pstart, *pend; +- +- this = list_entry(next, struct mapent, multi_list); +- *pos = next; +- next = next->next; +- +- offset_start = &this->key[start]; +- if (strlen(offset_start) <= plen) +- continue; +- +- if (!strncmp(prefix, offset_start, plen)) { +- struct mapent *np = NULL; +- char pe[PATH_MAX + 1]; +- +- /* "/" doesn't count for root offset */ +- if (plen == 1) +- pstart = &offset_start[plen - 1]; +- else +- pstart = &offset_start[plen]; +- +- /* not part of this sub-tree */ +- if (*pstart != '/') +- continue; +- +- /* get next offset */ +- pend = pstart; +- while (*pend++) { +- size_t nest_pt_offset; +- +- if (*pend != '/') +- continue; +- +- nest_pt_offset = start + pend - pstart; +- if (plen > 1) +- nest_pt_offset += plen; +- strcpy(pe, this->key); +- pe[nest_pt_offset] = '\0'; +- +- np = cache_lookup_distinct(this->mc, pe); +- if (np) +- break; +- } +- if (np) +- continue; +- len = pend - pstart - 1; +- strncpy(offset, pstart, len); +- offset[len] ='\0'; +- break; +- } +- } +- +- /* Seek to next offset */ +- while (next != head) { +- char *offset_start, *pstart; +- +- this = list_entry(next, struct mapent, multi_list); +- +- offset_start = &this->key[start]; +- if (strlen(offset_start) <= plen + len) +- break; +- +- /* "/" doesn't count for root offset */ +- if (plen == 1) +- pstart = &offset_start[plen - 1]; +- else +- pstart = &offset_start[plen]; +- +- /* not part of this sub-tree */ +- if (*pstart != '/') +- break; +- +- /* new offset */ +- if (!*(pstart + len + 1)) +- break; +- +- /* compare offset */ +- if (pstart[len] != '/' || +- strlen(pstart) != len || +- strncmp(offset, pstart, len)) +- break; +- +- *pos = next; +- next = next->next; +- } +- +- return *offset ? offset : NULL; +-} +- +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2849,21 +2849,6 @@ static void set_offset_tree_catatonic(st + tree_traverse_inorder(MAPENT_ROOT(me), set_offset_tree_catatonic_work, NULL); + } + +-static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) +-{ +- if (!list_empty(&me->multi_list)) { +- struct list_head *head = &me->multi_list; +- struct list_head *p; +- +- list_for_each(p, head) { +- struct mapent *this; +- +- this = list_entry(p, struct mapent, multi_list); +- set_mount_catatonic(ap, this, this->ioctlfd); +- } +- } +-} +- + void set_indirect_mount_tree_catatonic(struct autofs_point *ap) + { + struct master_mapent *entry = ap->entry; +@@ -3028,299 +3013,3 @@ done: + out: + return rv; + } +- +-static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe) +-{ +- int mounted = 0; +- int ret; +- +- 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); +- /* +- * Ok, so we shouldn't modify the mapent but +- * mount requests are blocked at a point above +- * this and expire only uses the mapent key or +- * holds the cache write lock. +- */ +- free(oe->mapent); +- oe->mapent = NULL; +- } +- } +- +- return mounted; +-} +- +-static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) +-{ +- char *dir, *path; +- unsigned int split; +- int ret; +- +- if (ap->type == LKP_DIRECT) +- return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev); +- +- dir = strdup(oe->key); +- +- if (ap->flags & MOUNT_FLAG_GHOST) +- split = ap->len + strlen(MM_ROOT(oe)->key) + 1; +- else +- split = ap->len; +- +- dir[split] = '\0'; +- path = &dir[split + 1]; +- +- if (chdir(dir) == -1) { +- error(ap->logopt, "failed to chdir to %s", dir); +- free(dir); +- return -1; +- } +- +- ret = rmdir_path(ap, path, ap->dev); +- +- free(dir); +- +- if (chdir("/") == -1) +- error(ap->logopt, "failed to chdir to /"); +- +- return ret; +-} +- +-static int do_umount_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root, int start); +- +-static int do_umount_multi_triggers(struct autofs_point *ap, +- struct mapent *me, const char *root, +- int start, 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; +- unsigned int root_len; +- unsigned int mm_base_len; +- +- left = 0; +- +- mm_root = &me->multi->multi_list; +- +- if (!base) +- mm_base = o_root; +- else +- mm_base = base; +- +- pos = NULL; +- offset = path; +- root_len = start; +- mm_base_len = strlen(mm_base); +- +- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- +- if (mm_base_len > 1) +- key_len += mm_base_len; +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- continue; +- } +- +- strcpy(key, root); +- if (mm_base_len > 1) +- strcat(key, mm_base); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- /* root offset is a special case */ +- if (!oe || (strlen(oe->key) - start) == 1) +- continue; +- +- left += do_umount_offset(ap, oe, root, start); +- } +- +- return left; +-} +- +-static int do_umount_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root, int start) +-{ +- char *oe_base; +- int left = 0; +- +- /* +- * Check for and umount subtree offsets resulting from +- * nonstrict mount fail. +- */ +- oe_base = oe->key + start; +- left += do_umount_multi_triggers(ap, oe, root, start, oe_base); +- +- /* +- * If an offset that has an active mount has been removed +- * from the multi-mount we don't want to attempt to trigger +- * mounts for it. Obviously this is because it has been +- * removed, but less obvious is the potential strange +- * behaviour that can result if we do try and mount it +- * again after it's been expired. For example, if an NFS +- * file system is no longer exported and is later umounted +- * it can be mounted again without any error message but +- * shows as an empty directory. That's going to confuse +- * people for sure. +- * +- * If the mount cannot be umounted (the process is now +- * using a stale mount) the offset needs to be invalidated +- * so no further mounts will be attempted but the offset +- * cache entry must remain so expires can continue to +- * attempt to umount it. If the mount can be umounted and +- * the offset is removed, at least for NFS we will get +- * ESTALE errors when attempting list the directory. +- */ +- if (oe->ioctlfd != -1 || +- is_mounted(oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key) && +- is_mounted(oe->key, MNTS_REAL)) { +- debug(ap->logopt, +- "offset %s has active mount, invalidate", +- oe->key); +- /* +- * Ok, so we shouldn't modify the mapent but +- * mount requests are blocked at a point above +- * this and expire only uses the mapent key or +- * holds the cache write lock. +- */ +- if (oe->mapent) { +- free(oe->mapent); +- oe->mapent = NULL; +- } +- return ++left; +- } +- } +- +- debug(ap->logopt, "umount offset %s", oe->key); +- +- if (umount_autofs_offset(ap, oe)) { +- warn(ap->logopt, "failed to umount offset"); +- left++; +- } else { +- struct stat st; +- int ret; +- +- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) +- return left; +- +- /* +- * An error due to partial directory removal is +- * ok so only try and remount the offset if the +- * actual mount point still exists. +- */ +- ret = rmdir_path_offset(ap, oe); +- if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe); +- if (ret) +- left++; +- /* But we did origianlly create this */ +- oe->flags |= MOUNT_FLAG_DIR_CREATED; +- } +- } +- return left; +-} +- +-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; +- struct mapent *oe; +- struct list_head *pos = NULL; +- unsigned int root_len = strlen(root); +- int mounted; +- +- mounted = 0; +- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); +- while (offset) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- goto cont; +- } +- +- /* The root offset is always mounted seperately so the +- * offset path will always be root + offset. +- */ +- strcpy(key, root); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- if (!oe || !oe->mapent) +- goto cont; +- if (oe->age != MM_ROOT(me)->age) { +- /* Best effort */ +- do_umount_offset(ap, oe, root, start); +- goto cont; +- } +- +- mounted += do_mount_autofs_offset(ap, oe); +- +- /* +- * If re-constructing a multi-mount it's necessary to walk +- * into nested mounts, unlike the usual "mount only what's +- * needed as you go" behavior. +- */ +- if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { +- if (oe->ioctlfd != -1 || +- is_mounted(oe->key, MNTS_REAL)) +- mount_multi_triggers(ap, oe, key, key_len, base); +- } +-cont: +- offset = cache_get_offset(base, +- offset, start, &me->multi_list, &pos); +- } +- +- return mounted; +-} +- +-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) +-{ +- int left, start; +- +- start = strlen(root); +- +- left = do_umount_multi_triggers(ap, me, root, start, base); +- +- if (!left && IS_MM_ROOT(me)) { +- /* +- * 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(root, MNTS_REAL)) { +- info(ap->logopt, "unmounting dir = %s", root); +- if (umount_ent(ap, root) && +- is_mounted(root, MNTS_REAL)) { +- if (mount_multi_triggers(ap, me, root, start, "/") < 0) +- warn(ap->logopt, +- "failed to remount offset triggers"); +- return ++left; +- } +- } +- +- /* check for mounted mount entry and remove it if found */ +- mnts_remove_mount(root, MNTS_MOUNTED); +- } +- +- return left; +-} +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1076,62 +1076,6 @@ next: + return (p - ent); + } + +-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; +- unsigned int root_len; +- unsigned int mm_base_len; +- +- mm_root = &me->multi->multi_list; +- +- if (!base) +- mm_base = o_root; +- else +- mm_base = base; +- +- pos = NULL; +- root_len = strlen(root); +- mm_base_len = strlen(mm_base); +- +- /* Make sure "none" of the offsets have an active mount. */ +- while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) { +- unsigned int path_len = root_len + strlen(poffset); +- +- if (mm_base_len > 1) +- path_len += mm_base_len; +- +- if (path_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- continue; +- } +- +- strcpy(path, root); +- if (mm_base_len > 1) +- strcat(path, mm_base); +- strcat(path, poffset); +- +- oe = cache_lookup_distinct(me->mc, path); +- /* root offset is a special case */ +- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) +- continue; +- +- if (umount(path)) { +- error(ap->logopt, "error recovering from mount fail"); +- error(ap->logopt, "cannot umount offset %s", path); +- } +- } +- +- return; +-} +- + static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + const char *name, char *loc, char *options, void *ctxt) + { diff --git a/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch b/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch new file mode 100644 index 0000000..c5d2c17 --- /dev/null +++ b/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch @@ -0,0 +1,36 @@ +autofs-5.1.7 - remove redundant assignment in master_add_amd_mount_section_mounts() + +From: Ian Kent + +Coverity: missing_lock: Accessing "entry->current" without holding lock + "master_mapent.current_mutex". + +This is initialization not clearing current source. But the field has +already been initialized in the master_new_mapent() call. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -58,6 +58,7 @@ + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. ++- remove redundant assignment in master_add_amd_mount_section_mounts(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -996,7 +996,6 @@ static void master_add_amd_mount_section + source->master_line = 0; + + entry->age = age; +- entry->current = NULL; + + master_add_mapent(master, entry); + next: diff --git a/autofs-5.1.7-remove-redundant-if-check.patch b/autofs-5.1.7-remove-redundant-if-check.patch new file mode 100644 index 0000000..06d2cca --- /dev/null +++ b/autofs-5.1.7-remove-redundant-if-check.patch @@ -0,0 +1,36 @@ +autofs-5.1.7 - remove redundant if check + +From: Ian Kent + +Coverity: identical code in if condition branches. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 5 +---- + 2 files changed, 2 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -51,6 +51,7 @@ + - remove mounts_mutex. + - remove unused variable from get_exports(). + - add missing free in handle_mounts(). ++- remove redundant if check. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -752,10 +752,7 @@ int mount_autofs_offset(struct autofs_po + + ops->timeout(ap->logopt, ioctlfd, timeout); + cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); +- if (ap->logopt & LOGOPT_DEBUG) +- notify_mount_result(ap, me->key, timeout, str_offset); +- else +- notify_mount_result(ap, me->key, timeout, str_offset); ++ notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + + debug(ap->logopt, "mounted trigger %s", me->key); diff --git a/autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch b/autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch new file mode 100644 index 0000000..be6b966 --- /dev/null +++ b/autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch @@ -0,0 +1,70 @@ +autofs-5.1.7 - remove redundant local var from sun_mount() + +From: Ian Kent + +The local variable mountpoint in sun_mount() is set directly from a +passed in parameter and never changed and the source isn't changed +either, so use the variable directly. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 13 ++++--------- + 2 files changed, 5 insertions(+), 9 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -42,6 +42,7 @@ + - add mount and umount offsets functions. + - switch to use tree implementation for offsets. + - remove obsolete functions. ++- remove redundant local var from sun_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -530,7 +530,6 @@ static int sun_mount(struct autofs_point + int nonstrict = 1; + int use_weight_only = ap->flags & MOUNT_FLAG_USE_WEIGHT_ONLY; + int rv, cur_state; +- char *mountpoint; + char *what; + char *type; + +@@ -623,9 +622,6 @@ static int sun_mount(struct autofs_point + } + } + +- mountpoint = alloca(namelen + 1); +- sprintf(mountpoint, "%.*s", namelen, name); +- + type = ap->entry->maps->type; + if (type && !strcmp(type, "hosts")) { + if (options && *options != '\0') { +@@ -700,9 +696,9 @@ static int sun_mount(struct autofs_point + debug(ap->logopt, MODPREFIX + "mounting root %s, mountpoint %s, " + "what %s, fstype %s, options %s", +- root, mountpoint, what, fstype, options); ++ root, name, what, fstype, options); + +- rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint), ++ rv = mount_nfs->mount_mount(ap, root, name, namelen, + what, fstype, options, mount_nfs->context); + } else { + if (!loclen) +@@ -722,11 +718,10 @@ static int sun_mount(struct autofs_point + debug(ap->logopt, MODPREFIX + "mounting root %s, mountpoint %s, " + "what %s, fstype %s, options %s", +- root, mountpoint, what, fstype, options); ++ root, name, what, fstype, options); + + /* Generic mount routine */ +- rv = do_mount(ap, root, mountpoint, strlen(mountpoint), what, fstype, +- options); ++ rv = do_mount(ap, root, name, namelen, what, fstype, options); + } + pthread_setcancelstate(cur_state, NULL); + diff --git a/autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch b/autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch new file mode 100644 index 0000000..72e1016 --- /dev/null +++ b/autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch @@ -0,0 +1,174 @@ +autofs-5.1.7 - remove redundant variables from mount_autofs_offset() + +From: Ian Kent + +The path to be mounted is the key in the passed in mapent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 42 +++++++++++++++++++----------------------- + include/automount.h | 2 +- + lib/mounts.c | 2 +- + 4 files changed, 22 insertions(+), 25 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -8,6 +8,7 @@ + - fix is mounted check on non existent path. + - simplify cache_get_parent(). + - set offset parent in update_offset_entry(). ++- remove redundant variables from mount_autofs_offset(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -611,7 +611,7 @@ force_umount: + return rv; + } + +-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset) ++int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + { + const char *str_offset = mount_type_str(t_offset); + struct ioctl_ops *ops = get_ioctl_ops(); +@@ -623,7 +623,6 @@ int mount_autofs_offset(struct autofs_po + const char *hosts_map_name = "-hosts"; + const char *map_name = hosts_map_name; + const char *type; +- char mountpoint[PATH_MAX]; + struct mnt_list *mnt; + + if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) { +@@ -681,11 +680,8 @@ int mount_autofs_offset(struct autofs_po + return MOUNT_OFFSET_OK; + } + +- strcpy(mountpoint, root); +- strcat(mountpoint, offset); +- + /* In case the directory doesn't exist, try to mkdir it */ +- if (mkdir_path(mountpoint, mp_mode) < 0) { ++ if (mkdir_path(me->key, mp_mode) < 0) { + if (errno == EEXIST) { + /* + * If the mount point directory is a real mount +@@ -694,7 +690,7 @@ int mount_autofs_offset(struct autofs_po + * the kernel NFS client. + */ + if (me->multi != me && +- is_mounted(mountpoint, MNTS_REAL)) ++ is_mounted(me->key, MNTS_REAL)) + return MOUNT_OFFSET_IGNORE; + + /* +@@ -714,13 +710,13 @@ int mount_autofs_offset(struct autofs_po + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + debug(ap->logopt, + "can't create mount directory: %s, %s", +- mountpoint, estr); ++ me->key, 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", +- mountpoint, estr); ++ me->key, estr); + return MOUNT_OFFSET_FAIL; + } + } else { +@@ -730,56 +726,56 @@ int mount_autofs_offset(struct autofs_po + + debug(ap->logopt, + "calling mount -t autofs " SLOPPY " -o %s automount %s", +- mp->options, mountpoint); ++ mp->options, me->key); + + type = ap->entry->maps->type; + if (!type || strcmp(ap->entry->maps->type, "hosts")) + map_name = me->mc->map->argv[0]; + +- ret = mount(map_name, mountpoint, "autofs", MS_MGC_VAL, mp->options); ++ ret = mount(map_name, me->key, "autofs", MS_MGC_VAL, mp->options); + if (ret) { + crit(ap->logopt, + "failed to mount offset trigger %s at %s", +- me->key, mountpoint); ++ me->key, me->key); + goto out_err; + } + +- ret = stat(mountpoint, &st); ++ ret = stat(me->key, &st); + if (ret == -1) { + error(ap->logopt, +- "failed to stat direct mount trigger %s", mountpoint); ++ "failed to stat direct mount trigger %s", me->key); + goto out_umount; + } + +- ops->open(ap->logopt, &ioctlfd, st.st_dev, mountpoint); ++ ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); + if (ioctlfd < 0) { +- crit(ap->logopt, "failed to create ioctl fd for %s", mountpoint); ++ crit(ap->logopt, "failed to create ioctl fd for %s", me->key); + goto out_umount; + } + + ops->timeout(ap->logopt, ioctlfd, timeout); + cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); + if (ap->logopt & LOGOPT_DEBUG) +- notify_mount_result(ap, mountpoint, timeout, str_offset); ++ notify_mount_result(ap, me->key, timeout, str_offset); + else + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + +- mnt = mnts_add_mount(ap, mountpoint, MNTS_OFFSET); ++ mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET); + if (!mnt) + error(ap->logopt, + "failed to add offset mount %s to mounted list", +- mountpoint); ++ me->key); + +- debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint); ++ debug(ap->logopt, "mounted trigger %s", me->key); + + return MOUNT_OFFSET_OK; + + out_umount: +- umount(mountpoint); ++ umount(me->key); + out_err: +- if (stat(mountpoint, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED) +- rmdir_path(ap, mountpoint, st.st_dev); ++ if (stat(me->key, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED) ++ rmdir_path(ap, me->key, st.st_dev); + + return MOUNT_OFFSET_FAIL; + } +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -595,7 +595,7 @@ int expire_offsets_direct(struct autofs_ + int mount_autofs_indirect(struct autofs_point *ap, const char *root); + int do_mount_autofs_direct(struct autofs_point *ap, struct mapent *me, time_t timeout); + int mount_autofs_direct(struct autofs_point *ap); +-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset); ++int mount_autofs_offset(struct autofs_point *ap, struct mapent *me); + void submount_signal_parent(struct autofs_point *ap, unsigned int success); + void close_mount_fds(struct autofs_point *ap); + int umount_autofs_indirect(struct autofs_point *ap, const char *root); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2475,7 +2475,7 @@ static int do_mount_autofs_offset(struct + + debug(ap->logopt, "mount offset %s at %s", oe->key, root); + +- ret = mount_autofs_offset(ap, oe, root, offset); ++ ret = mount_autofs_offset(ap, oe); + if (ret >= MOUNT_OFFSET_OK) + mounted++; + else { diff --git a/autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch b/autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch new file mode 100644 index 0000000..f5bf7fe --- /dev/null +++ b/autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch @@ -0,0 +1,54 @@ +autofs-5.1.7 - remove unused function master_submount_list_empty() + +From: Ian Kent + +This function is not used anywhere now, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 12 ------------ + include/master.h | 1 - + 3 files changed, 1 insertion(+), 13 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -45,6 +45,7 @@ + - remove redundant local var from sun_mount(). + - use mount_fullpath() in one spot in parse_mount(). + - pass root length to mount_fullpath(). ++- remove unused function master_submount_list_empty(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -1119,18 +1119,6 @@ int master_read_master(struct master *ma + return 1; + } + +-int master_submount_list_empty(struct autofs_point *ap) +-{ +- int res = 0; +- +- mounts_mutex_lock(ap); +- if (list_empty(&ap->submounts)) +- res = 1; +- mounts_mutex_unlock(ap); +- +- return res; +-} +- + int master_notify_submount(struct autofs_point *ap, const char *path, enum states state) + { + struct mnt_list *this, *sbmnt; +--- autofs-5.1.4.orig/include/master.h ++++ autofs-5.1.4/include/master.h +@@ -116,7 +116,6 @@ void master_free_mapent_sources(struct m + void master_free_mapent(struct master_mapent *); + struct master *master_new(const char *, unsigned int, unsigned int); + int master_read_master(struct master *, time_t); +-int master_submount_list_empty(struct autofs_point *ap); + int master_notify_submount(struct autofs_point *, const char *path, enum states); + void master_notify_state_change(struct master *, int); + int master_mount_mounts(struct master *, time_t); diff --git a/autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch b/autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch new file mode 100644 index 0000000..7f71119 --- /dev/null +++ b/autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch @@ -0,0 +1,59 @@ +autofs-5.1.7 - remove unused functions cache_dump_multi() and cache_dump_cache() + +From: Ian Kent + +Remove debugging functions cache_dump_multi() and cache_dump_cache() + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 28 ---------------------------- + 2 files changed, 1 insertion(+), 28 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -29,6 +29,7 @@ + - rename tree implementation functions. + - fix program map multi-mount lookup after mount fail. + - add some multi-mount macros. ++- remove unused functions cache_dump_multi() and cache_dump_cache(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -24,34 +24,6 @@ + + #include "automount.h" + +-void cache_dump_multi(struct list_head *list) +-{ +- struct list_head *p; +- struct mapent *me; +- +- list_for_each(p, list) { +- me = list_entry(p, struct mapent, multi_list); +- logmsg("key=%s", me->key); +- } +-} +- +-void cache_dump_cache(struct mapent_cache *mc) +-{ +- struct mapent *me; +- unsigned int i; +- +- for (i = 0; i < mc->size; i++) { +- me = mc->hash[i]; +- if (me == NULL) +- continue; +- while (me) { +- logmsg("me->key=%s me->multi=%p dev=%ld ino=%ld", +- me->key, me->multi, me->dev, me->ino); +- me = me->next; +- } +- } +-} +- + void cache_readlock(struct mapent_cache *mc) + { + int status; diff --git a/autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch b/autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch new file mode 100644 index 0000000..077f93e --- /dev/null +++ b/autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch @@ -0,0 +1,173 @@ +autofs-5.1.7 - remove unused mount offset list lock functions + +From: Ian Kent + +When fixing the locking in parse_mount() it was evident that there was +no real benefit of having an additional lock for the offset list so its +use was eliminated. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 4 -- + lib/cache.c | 70 +--------------------------------------------------- + 3 files changed, 3 insertions(+), 72 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -18,6 +18,7 @@ + - fix return from umount_subtree_mounts() on offset list delete. + - pass mapent_cache to update_offset_entry(). + - fix inconsistent locking in parse_mount(). ++- remove unused mount offset list lock functions. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -162,7 +162,6 @@ struct stack { + struct mapent { + struct mapent *next; + struct list_head ino_index; +- pthread_rwlock_t multi_rwlock; + struct list_head multi_list; + struct mapent_cache *mc; + struct map_source *source; +@@ -211,9 +210,6 @@ int cache_set_offset_parent(struct mapen + 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); + int cache_delete_offset(struct mapent_cache *mc, const char *key); +-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); + void cache_clean_null_cache(struct mapent_cache *mc); +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -108,58 +108,6 @@ void cache_lock_cleanup(void *arg) + return; + } + +-void cache_multi_readlock(struct mapent *me) +-{ +- int status; +- +- if (!me) +- return; +- +- 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); +- } +- return; +-} +- +-void cache_multi_unlock(struct mapent *me) +-{ +- int status; +- +- if (!me) +- return; +- +- status = pthread_rwlock_unlock(&me->multi_rwlock); +- if (status) { +- logmsg("mapent cache multi mutex unlock failed"); +- fatal(status); +- } +- return; +-} +- +-void cache_multi_lock_cleanup(void *arg) +-{ +- struct mapent *me = (struct mapent *) arg; +- cache_multi_unlock(me); +- return; +-} +- + static inline void ino_index_lock(struct mapent_cache *mc) + { + int status = pthread_mutex_lock(&mc->ino_index_mutex); +@@ -626,7 +574,6 @@ int cache_add(struct mapent_cache *mc, s + struct mapent *me, *existing = NULL; + char *pkey, *pent; + u_int32_t hashval = hash(key, mc->size); +- int status; + + me = (struct mapent *) malloc(sizeof(struct mapent)); + if (!me) +@@ -665,10 +612,6 @@ int cache_add(struct mapent_cache *mc, s + me->ino = (ino_t) -1; + me->flags = 0; + +- status = pthread_rwlock_init(&me->multi_rwlock, NULL); +- if (status) +- fatal(status); +- + /* + * We need to add to the end if values exist in order to + * preserve the order in which the map was read on lookup. +@@ -894,7 +837,7 @@ int cache_update(struct mapent_cache *mc + return ret; + } + +-/* cache_multi_lock of the multi mount owner must be held by caller */ ++/* cache write lock of the multi mount owner must be held by caller */ + int cache_delete_offset(struct mapent_cache *mc, const char *key) + { + u_int32_t hashval = hash(key, mc->size); +@@ -926,9 +869,6 @@ int cache_delete_offset(struct mapent_ca + return CHE_FAIL; + + delete: +- status = pthread_rwlock_destroy(&me->multi_rwlock); +- if (status) +- fatal(status); + list_del(&me->multi_list); + ino_index_lock(mc); + list_del(&me->ino_index); +@@ -946,7 +886,7 @@ int cache_delete(struct mapent_cache *mc + { + struct mapent *me = NULL, *pred; + u_int32_t hashval = hash(key, mc->size); +- int status, ret = CHE_OK; ++ int ret = CHE_OK; + char this[PATH_MAX]; + + strcpy(this, key); +@@ -967,9 +907,6 @@ int cache_delete(struct mapent_cache *mc + goto done; + } + pred->next = me->next; +- status = pthread_rwlock_destroy(&me->multi_rwlock); +- if (status) +- fatal(status); + ino_index_lock(mc); + list_del(&me->ino_index); + ino_index_unlock(mc); +@@ -999,9 +936,6 @@ int cache_delete(struct mapent_cache *mc + goto done; + } + mc->hash[hashval] = me->next; +- status = pthread_rwlock_destroy(&me->multi_rwlock); +- if (status) +- fatal(status); + ino_index_lock(mc); + list_del(&me->ino_index); + ino_index_unlock(mc); diff --git a/autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch b/autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch new file mode 100644 index 0000000..52483dd --- /dev/null +++ b/autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch @@ -0,0 +1,62 @@ +autofs-5.1.7 - remove unused parameter form do_mount_autofs_offset() + +From: Ian Kent + +The offset parameter of do_mount_autofs_offset() isn't used. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 10 ++++------ + 2 files changed, 5 insertions(+), 6 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -9,6 +9,7 @@ + - simplify cache_get_parent(). + - set offset parent in update_offset_entry(). + - remove redundant variables from mount_autofs_offset(). ++- remove unused parameter form do_mount_autofs_offset(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2466,9 +2466,7 @@ out: + } + + static int do_mount_autofs_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root, +- char *offset) +- ++ struct mapent *oe, const char *root) + { + int mounted = 0; + int ret; +@@ -2523,7 +2521,7 @@ int mount_multi_triggers(struct autofs_p + if (!oe || !oe->mapent) + goto cont; + +- mounted += do_mount_autofs_offset(ap, oe, root, offset); ++ mounted += do_mount_autofs_offset(ap, oe, root); + + /* + * If re-constructing a multi-mount it's necessary to walk +@@ -2660,7 +2658,7 @@ int umount_multi_triggers(struct autofs_ + */ + ret = rmdir_path_offset(ap, oe); + if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root, offset); ++ ret = do_mount_autofs_offset(ap, oe, root); + if (ret) + left++; + /* But we did origianlly create this */ +@@ -2841,7 +2839,7 @@ int clean_stale_multi_triggers(struct au + */ + ret = rmdir_path_offset(ap, oe); + if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root, offset); ++ ret = do_mount_autofs_offset(ap, oe, root); + if (ret) { + left++; + /* But we did origianlly create this */ diff --git a/autofs-5.1.7-remove-unused-variable-from-get_exports.patch b/autofs-5.1.7-remove-unused-variable-from-get_exports.patch new file mode 100644 index 0000000..54c8f39 --- /dev/null +++ b/autofs-5.1.7-remove-unused-variable-from-get_exports.patch @@ -0,0 +1,32 @@ +autofs-5.1.7 - remove unused variable from get_exports() + +From: Ian Kent + +Fix complier warning about unused variable entry in get_exports(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -49,6 +49,7 @@ + - move amd mounts removal into lib/mounts.c. + - check for offset with no mount location. + - remove mounts_mutex. ++- remove unused variable from get_exports(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/lookup_hosts.c ++++ autofs-5.1.4/modules/lookup_hosts.c +@@ -87,7 +87,6 @@ int lookup_read_master(struct master *ma + static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; +- char entry[PATH_MAX + 1]; + char *mapent; + struct exportinfo *exp, *this; + size_t hostlen = strlen(host); diff --git a/autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch b/autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch new file mode 100644 index 0000000..8e45446 --- /dev/null +++ b/autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch @@ -0,0 +1,155 @@ +autofs-5.1.7 - rename path to m_offset in update_offset_entry() + +From: Ian Kent + +Rename local variable from path to m_offset in update_offset_entry() to +make the meaning of this variable clear. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 46 +++++++++++++++++++++++----------------------- + 2 files changed, 24 insertions(+), 23 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -24,6 +24,7 @@ + - don't add offset mounts to mounted mounts table. + - reduce umount EBUSY check delay. + - cleanup cache_delete() a little. ++- rename path to m_offset in update_offset_entry(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -798,36 +798,36 @@ static int + update_offset_entry(struct autofs_point *ap, + struct mapent_cache *mc, const char *name, + const char *m_root, int m_root_len, +- const char *path, const char *myoptions, ++ const char *m_offset, const char *myoptions, + const char *loc, time_t age) + { + char m_key[PATH_MAX + 1]; + char m_mapent[MAPENT_MAX_LEN + 1]; +- int p_len, m_key_len, m_options_len, m_mapent_len; ++ int o_len, m_key_len, m_options_len, m_mapent_len; + int ret; + + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); + + /* Internal hosts map may have loc == NULL */ +- if (!*path) { ++ if (!*m_offset) { + error(ap->logopt, +- MODPREFIX "syntax error in offset %s -> %s", path, loc); ++ MODPREFIX "syntax error in offset %s -> %s", m_offset, loc); + return CHE_FAIL; + } + +- p_len = strlen(path); ++ o_len = strlen(m_offset); + /* Trailing '/' causes us pain */ +- if (p_len > 1) { +- while (p_len > 1 && path[p_len - 1] == '/') +- p_len--; ++ if (o_len > 1) { ++ while (o_len > 1 && m_offset[o_len - 1] == '/') ++ o_len--; + } +- m_key_len = m_root_len + p_len; ++ m_key_len = m_root_len + o_len; + if (m_key_len > PATH_MAX) { + error(ap->logopt, MODPREFIX "multi mount key too long"); + return CHE_FAIL; + } + strcpy(m_key, m_root); +- strncat(m_key, path, p_len); ++ strncat(m_key, m_offset, o_len); + m_key[m_key_len] = '\0'; + + m_options_len = 0; +@@ -862,15 +862,15 @@ update_offset_entry(struct autofs_point + + if (ret == CHE_DUPLICATE) { + warn(ap->logopt, MODPREFIX +- "syntax error or duplicate offset %s -> %s", path, loc); ++ "syntax error or duplicate offset %s -> %s", m_offset, loc); + ret = CHE_OK; + } else if (ret == CHE_FAIL) + debug(ap->logopt, MODPREFIX +- "failed to update multi-mount offset %s -> %s", path, m_mapent); ++ "failed to update multi-mount offset %s -> %s", m_offset, m_mapent); + else { + ret = CHE_OK; + debug(ap->logopt, MODPREFIX +- "updated multi-mount offset %s -> %s", path, m_mapent); ++ "updated multi-mount offset %s -> %s", m_offset, m_mapent); + } + + return ret; +@@ -1540,22 +1540,22 @@ dont_expand: + + /* It's a multi-mount; deal with it */ + do { +- char *path, *myoptions, *loc; ++ char *m_offset, *myoptions, *loc; + int status; + + if ((*p == '"' && *(p + 1) != '/') || (*p != '"' && *p != '/')) { + l = 0; +- path = dequote("/", 1, ap->logopt); ++ m_offset = dequote("/", 1, ap->logopt); + debug(ap->logopt, +- MODPREFIX "dequote(\"/\") -> %s", path); ++ MODPREFIX "dequote(\"/\") -> %s", m_offset); + } else { + l = span_space(p, mapent_len - (p - pmapent)); +- path = sanitize_path(p, l, LKP_MULTI, ap->logopt); ++ m_offset = sanitize_path(p, l, LKP_MULTI, ap->logopt); + debug(ap->logopt, MODPREFIX +- "dequote(\"%.*s\") -> %s", l, p, path); ++ "dequote(\"%.*s\") -> %s", l, p, m_offset); + } + +- if (!path) { ++ if (!m_offset) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); + cache_writelock(mc); + cache_delete_offset_list(mc, name); +@@ -1577,7 +1577,7 @@ dont_expand: + cache_writelock(mc); + cache_delete_offset_list(mc, name); + cache_unlock(mc); +- free(path); ++ free(m_offset); + free(options); + free(pmapent); + pthread_setcancelstate(cur_state, NULL); +@@ -1589,14 +1589,14 @@ dont_expand: + + status = update_offset_entry(ap, mc, + name, m_root, m_root_len, +- path, myoptions, loc, age); ++ m_offset, myoptions, loc, age); + + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); + cache_writelock(mc); + cache_delete_offset_list(mc, name); + cache_unlock(mc); +- free(path); ++ free(m_offset); + free(options); + free(pmapent); + free(myoptions); +@@ -1608,7 +1608,7 @@ dont_expand: + + if (loc) + free(loc); +- free(path); ++ free(m_offset); + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + diff --git a/autofs-5.1.7-rename-tree-implementation-functions.patch b/autofs-5.1.7-rename-tree-implementation-functions.patch new file mode 100644 index 0000000..9ad2c11 --- /dev/null +++ b/autofs-5.1.7-rename-tree-implementation-functions.patch @@ -0,0 +1,196 @@ +autofs-5.1.7 - rename tree implementation functions + +From: Ian Kent + +Rename the tree struct and functions to make them consistent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 86 +++++++++++++++++++++++++++++------------------------------ + 2 files changed, 44 insertions(+), 43 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -26,6 +26,7 @@ + - cleanup cache_delete() a little. + - rename path to m_offset in update_offset_entry(). + - don't pass root to do_mount_autofs_offset(). ++- rename tree implementation functions. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1225,30 +1225,30 @@ done: + return has_mounted_mounts; + } + +-struct node { ++struct tree_node { + struct mnt_list *mnt; +- struct node *left; +- struct node *right; ++ struct tree_node *left; ++ struct tree_node *right; + }; + +-static struct node *new(struct mnt_list *mnt) ++static struct tree_node *tree_new(struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *n; + +- n = malloc(sizeof(struct node)); ++ n = malloc(sizeof(struct tree_node)); + if (!n) + return NULL; +- memset(n, 0, sizeof(struct node)); ++ memset(n, 0, sizeof(struct tree_node)); + n->mnt = mnt; + + return n; + } + +-static struct node *tree_root(struct mnt_list *mnt) ++static struct tree_node *tree_root(struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *n; + +- n = new(mnt); ++ n = tree_new(mnt); + if (!n) { + error(LOGOPT_ANY, "failed to allcate tree root"); + return NULL; +@@ -1257,37 +1257,37 @@ static struct node *tree_root(struct mnt + return n; + } + +-static struct node *add_left(struct node *this, struct mnt_list *mnt) ++static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *new; + +- n = new(mnt); +- if (!n) { ++ new = tree_new(mnt); ++ if (!new) { + error(LOGOPT_ANY, "failed to allcate tree node"); + return NULL; + } +- this->left = n; ++ n->left = new; + + return n; + } + +-static struct node *add_right(struct node *this, struct mnt_list *mnt) ++static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *new; + +- n = new(mnt); +- if (!n) { ++ new = tree_new(mnt); ++ if (!new) { + error(LOGOPT_ANY, "failed to allcate tree node"); + return NULL; + } +- this->right = n; ++ n->right = new; + + return n; + } + +-static struct node *add_node(struct node *root, struct mnt_list *mnt) ++static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt) + { +- struct node *p, *q; ++ struct tree_node *p, *q; + unsigned int mp_len; + + mp_len = strlen(mnt->mp); +@@ -1307,43 +1307,43 @@ static struct node *add_node(struct node + error(LOGOPT_ANY, "duplicate entry in mounts list"); + else { + if (mp_len < strlen(p->mnt->mp)) +- return add_left(p, mnt); ++ return tree_add_left(p, mnt); + else +- return add_right(p, mnt); ++ return tree_add_right(p, mnt); + } + + return NULL; + } + +-static void tree_free(struct node *tree) ++static void tree_free(struct tree_node *root) + { +- if (tree->right) +- tree_free(tree->right); +- if (tree->left) +- tree_free(tree->left); +- free(tree); +-} +- +-static void traverse(struct node *node, struct list_head *mnts) +-{ +- if (node->right) +- traverse(node->right, mnts); +- list_add_tail(&node->mnt->expire, mnts); +- if (node->left) +- traverse(node->left, mnts); ++ if (root->right) ++ tree_free(root->right); ++ if (root->left) ++ tree_free(root->left); ++ free(root); ++} ++ ++static void tree_traverse(struct tree_node *n, struct list_head *mnts) ++{ ++ if (n->right) ++ tree_traverse(n->right, mnts); ++ list_add_tail(&n->mnt->expire, mnts); ++ if (n->left) ++ tree_traverse(n->left, mnts); + } + + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + { + struct mnt_list *mnt; +- struct node *tree = NULL; ++ struct tree_node *tree = NULL; + + mnts_hash_mutex_lock(); + if (list_empty(&ap->mounts)) + goto done; + + list_for_each_entry(mnt, &ap->mounts, mount) { +- struct node *n; ++ struct tree_node *n; + + if (!(mnt->flags & MNTS_MOUNTED)) + continue; +@@ -1359,7 +1359,7 @@ void mnts_get_expire_list(struct list_he + continue; + } + +- n = add_node(tree, mnt); ++ n = tree_add_node(tree, mnt); + if (!n) { + error(LOGOPT_ANY, "failed to add expire tree node"); + tree_free(tree); +@@ -1367,7 +1367,7 @@ void mnts_get_expire_list(struct list_he + } + } + +- traverse(tree, mnts); ++ tree_traverse(tree, mnts); + tree_free(tree); + done: + mnts_hash_mutex_unlock(); diff --git a/autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch b/autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch new file mode 100644 index 0000000..dd2f24f --- /dev/null +++ b/autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch @@ -0,0 +1,96 @@ +autofs-5.1.7 - set offset parent in update_offset_entry() + +From: Ian Kent + +Avoid the list traversal in cache_set_parents() by setting the +offset parent when updating the offset. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 2 +- + lib/cache.c | 26 +++++++++++--------------- + modules/parse_sun.c | 5 ++++- + 4 files changed, 17 insertions(+), 17 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -7,6 +7,7 @@ + - eliminate cache_lookup_offset() usage. + - fix is mounted check on non existent path. + - simplify cache_get_parent(). ++- set offset parent in update_offset_entry(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -207,7 +207,7 @@ struct mapent *cache_partial_match_wild( + int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); + void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); +-int cache_set_parents(struct mapent *mm); ++int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); + 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); + int cache_delete_offset(struct mapent_cache *mc, const char *key); +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -834,25 +834,21 @@ static struct mapent *get_offset_parent( + return NULL; + } + +-int cache_set_parents(struct mapent *mm) ++int cache_set_offset_parent(struct mapent_cache *mc, const char *offset) + { +- struct list_head *multi_head, *p; +- struct mapent *this; ++ struct mapent *this, *parent; + +- if (!mm->multi) ++ this = cache_lookup_distinct(mc, offset); ++ if (!this) ++ return 0; ++ if (!this->multi) + return 0; + +- multi_head = &mm->multi->multi_list; +- +- list_for_each(p, multi_head) { +- struct mapent *parent; +- this = list_entry(p, struct mapent, multi_list); +- parent = get_offset_parent(mm->mc, this->key); +- if (parent) +- this->parent = parent; +- else +- this->parent = mm->multi; +- } ++ parent = get_offset_parent(mc, offset); ++ if (parent) ++ this->parent = parent; ++ else ++ this->parent = this->multi; + + return 1; + } +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -861,6 +861,10 @@ update_offset_entry(struct autofs_point + } + + ret = cache_update_offset(mc, name, m_key, m_mapent, age); ++ ++ if (!cache_set_offset_parent(mc, m_key)) ++ error(ap->logopt, "failed to set offset parent"); ++ + if (ret == CHE_DUPLICATE) { + warn(ap->logopt, MODPREFIX + "syntax error or duplicate offset %s -> %s", path, loc); +@@ -1615,7 +1619,6 @@ dont_expand: + */ + if (me == me->multi) + clean_stale_multi_triggers(ap, me, NULL, NULL); +- cache_set_parents(me); + + rv = mount_subtree(ap, me, name, NULL, options, ctxt); + diff --git a/autofs-5.1.7-simplify-get_parent.patch b/autofs-5.1.7-simplify-get_parent.patch new file mode 100644 index 0000000..f50b00e --- /dev/null +++ b/autofs-5.1.7-simplify-get_parent.patch @@ -0,0 +1,101 @@ +autofs-5.1.7 - simplify cache_get_parent() + +From: Ian Kent + +Eliminate the list traversal from get_parent() and rename it to +get_offset_parent() to better describe it's usage. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 46 ++++++++++++++++++++++++++++------------------ + 2 files changed, 29 insertions(+), 18 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -6,6 +6,7 @@ + - fix mnts_remove_amdmount() uses wrong list. + - eliminate cache_lookup_offset() usage. + - fix is mounted check on non existent path. ++- simplify cache_get_parent(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -797,47 +797,57 @@ void cache_update_negative(struct mapent + } + + +-static struct mapent *get_parent(const char *key, struct list_head *head, struct list_head **pos) ++static struct mapent *get_offset_parent(struct mapent_cache *mc, ++ const char *key) + { +- struct list_head *next; +- struct mapent *this, *last; +- int eq; ++ struct mapent *me; ++ char *parent, *tail; ++ int key_len; + +- last = NULL; +- next = *pos ? (*pos)->next : head->next; ++ key_len = strlen(key); + +- list_for_each(next, head) { +- this = list_entry(next, struct mapent, multi_list); ++ /* Check if this is the root offset */ ++ if (key[key_len - 1] == '/') ++ return NULL; + +- if (!strcmp(this->key, key)) ++ parent = strdup(key); ++ tail = &parent[key_len - 1]; ++ ++ while (*tail) { ++ while (*tail != '/') ++ tail--; ++ ++ *tail = 0; ++ ++ tail--; ++ if (tail == parent) + break; + +- eq = strncmp(this->key, key, strlen(this->key)); +- if (eq == 0) { +- *pos = next; +- last = this; +- continue; ++ me = cache_lookup_distinct(mc, parent); ++ if (me) { ++ free(parent); ++ return me; + } + } ++ free(parent); + +- return last; ++ return NULL; + } + + int cache_set_parents(struct mapent *mm) + { +- struct list_head *multi_head, *p, *pos; ++ struct list_head *multi_head, *p; + struct mapent *this; + + if (!mm->multi) + return 0; + +- pos = NULL; + multi_head = &mm->multi->multi_list; + + list_for_each(p, multi_head) { + struct mapent *parent; + this = list_entry(p, struct mapent, multi_list); +- parent = get_parent(this->key, multi_head, &pos); ++ parent = get_offset_parent(mm->mc, this->key); + if (parent) + this->parent = parent; + else diff --git a/autofs-5.1.7-simplify-mount_subtree-mount-check.patch b/autofs-5.1.7-simplify-mount_subtree-mount-check.patch new file mode 100644 index 0000000..a13453f --- /dev/null +++ b/autofs-5.1.7-simplify-mount_subtree-mount-check.patch @@ -0,0 +1,42 @@ +autofs-5.1.7 - simplify mount_subtree() mount check + +From: Ian Kent + +The check of the return from sun_mount() following the possible mount +of the root offset in mount_subtree() can be simpler. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 10 +--------- + 2 files changed, 2 insertions(+), 9 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -12,6 +12,7 @@ + - remove unused parameter form do_mount_autofs_offset(). + - refactor umount_multi_triggers(). + - eliminate clean_stale_multi_triggers(). ++- simplify mount_subtree() mount check. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1205,15 +1205,7 @@ static int mount_subtree(struct autofs_p + free(ro_loc); + } + +- if (ro && rv == 0) { +- 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_root, start, mm_base); +- return 1; +- } +- } else if (rv <= 0) { ++ if ((ro && rv == 0) || rv <= 0) { + ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); + if (ret == -1) { + error(ap->logopt, MODPREFIX diff --git a/autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch b/autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch new file mode 100644 index 0000000..aaeb832 --- /dev/null +++ b/autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch @@ -0,0 +1,398 @@ +autofs-5.1.7 - switch to use tree implementation for offsets + +From: Ian Kent + +Change to use the tree mapent implementation for the handling +of offset mounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 25 ++---------- + daemon/lookup.c | 2 - + include/automount.h | 8 ++-- + lib/cache.c | 67 --------------------------------- + lib/mounts.c | 4 +- + modules/lookup_program.c | 2 - + modules/parse_sun.c | 94 ++++++++++++----------------------------------- + 8 files changed, 39 insertions(+), 164 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -40,6 +40,7 @@ + - add tree_mapent_cleanup_offsets(). + - add set_offset_tree_catatonic(). + - add mount and umount offsets functions. ++- switch to use tree implementation for offsets. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -551,29 +551,15 @@ static int umount_subtree_mounts(struct + left = 0; + + if (me && IS_MM(me)) { +- char root[PATH_MAX + 1]; + char key[PATH_MAX + 1]; + struct mapent *tmp; +- int status; +- char *base; ++ int ret; + +- if (!strchr(MM_ROOT(me)->key, '/')) +- /* Indirect multi-mount root */ +- /* sprintf okay - if it's mounted, it's +- * PATH_MAX or less bytes */ +- sprintf(root, "%s/%s", ap->path, MM_ROOT(me)->key); +- else +- strcpy(root, MM_ROOT(me)->key); +- +- if (IS_MM_ROOT(me)) +- base = NULL; +- else +- base = me->key + strlen(root); +- +- left = umount_multi_triggers(ap, me, root, base); +- if (left) { ++ ret = tree_mapent_umount_offsets(me, 1); ++ if (!ret) { + warn(ap->logopt, + "some offset mounts still present under %s", path); ++ left++; + } + + strcpy(key, me->key); +@@ -589,8 +575,7 @@ static int umount_subtree_mounts(struct + } + + if (!left && IS_MM_ROOT(me)) { +- status = cache_delete_offset_list(mc, me->key); +- if (status != CHE_OK) { ++ if (!tree_mapent_delete_offsets(mc, me->key)) { + warn(ap->logopt, "couldn't delete offset list"); + left++; + } +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -851,7 +851,7 @@ static int lookup_amd_instance(struct au + return NSS_STATUS_UNKNOWN; + } + +- m_key = malloc(ap->len + strlen(MM_ROOT(me)->key) + 2); ++ m_key = malloc(ap->len + MM_ROOT(me)->len + 2); + if (!m_key) { + error(ap->logopt, + "failed to allocate storage for search key"); +--- autofs-5.1.4.orig/include/automount.h ++++ autofs-5.1.4/include/automount.h +@@ -187,10 +187,10 @@ struct mapent { + ino_t ino; + }; + +-#define IS_MM(me) (me->multi) +-#define IS_MM_ROOT(me) (me->multi == me) +-#define MM_ROOT(me) (me->multi) +-#define MM_PARENT(me) (me->parent) ++#define IS_MM(me) (me->mm_root) ++#define IS_MM_ROOT(me) (me->mm_root == &me->node) ++#define MM_ROOT(me) (MAPENT(me->mm_root)) ++#define MM_PARENT(me) (MAPENT(me->mm_parent)) + + void cache_lock_cleanup(void *arg); + void cache_readlock(struct mapent_cache *mc); +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -682,14 +682,6 @@ int cache_update_offset(struct mapent_ca + return CHE_FAIL; + } + +- me = cache_lookup_distinct(mc, key); +- if (me) { +- cache_add_ordered_offset(me, &owner->multi_list); +- MM_ROOT(me) = owner; +- goto done; +- } +- ret = CHE_FAIL; +-done: + return ret; + } + +@@ -928,65 +920,6 @@ done: + return ret; + } + +-/* cache must be write locked by caller */ +-int cache_delete_offset_list(struct mapent_cache *mc, const char *key) +-{ +- unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt(); +- struct mapent *me; +- struct mapent *this; +- struct list_head *head, *next; +- int remain = 0; +- int status; +- +- me = cache_lookup_distinct(mc, key); +- if (!me) +- return CHE_FAIL; +- +- /* Not offset list owner */ +- if (!IS_MM_ROOT(me)) +- return CHE_FAIL; +- +- head = &me->multi_list; +- next = head->next; +- while (next != head) { +- this = list_entry(next, struct mapent, multi_list); +- next = next->next; +- if (this->ioctlfd != -1) { +- error(logopt, +- "active offset mount key %s", this->key); +- return CHE_FAIL; +- } +- } +- +- head = &me->multi_list; +- next = head->next; +- while (next != head) { +- this = list_entry(next, struct mapent, multi_list); +- next = next->next; +- list_del_init(&this->multi_list); +- MM_ROOT(this) = NULL; +- debug(logopt, "deleting offset key %s", this->key); +- status = cache_delete(mc, this->key); +- if (status == CHE_FAIL) { +- warn(logopt, +- "failed to delete offset %s", this->key); +- MM_ROOT(this) = me; +- /* TODO: add list back in */ +- remain++; +- } +- } +- +- if (!remain) { +- list_del_init(&me->multi_list); +- MM_ROOT(me) = NULL; +- } +- +- if (remain) +- return CHE_FAIL; +- +- return CHE_OK; +-} +- + void cache_release(struct map_source *map) + { + struct mapent_cache *mc; +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2889,7 +2889,7 @@ void set_indirect_mount_tree_catatonic(s + + /* Only need to set offset mounts catatonic */ + if (IS_MM(me) && IS_MM_ROOT(me)) +- set_multi_mount_tree_catatonic(ap, me); ++ set_offset_tree_catatonic(ap, me); + next: + me = cache_enumerate(mc, me); + } +@@ -2909,7 +2909,7 @@ void set_direct_mount_tree_catatonic(str + { + /* Set offset mounts catatonic for this mapent */ + if (IS_MM(me) && IS_MM_ROOT(me)) +- set_multi_mount_tree_catatonic(ap, me); ++ set_offset_tree_catatonic(ap, me); + set_mount_catatonic(ap, me, me->ioctlfd); + } + +--- autofs-5.1.4.orig/modules/lookup_program.c ++++ autofs-5.1.4/modules/lookup_program.c +@@ -676,7 +676,7 @@ int lookup_mount(struct autofs_point *ap + me = cache_lookup_distinct(mc, name); + if (me) { + if (IS_MM(me)) +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_delete(mc, name); + } + cache_unlock(mc); +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -856,8 +856,8 @@ update_offset_entry(struct autofs_point + cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + +- if (!cache_set_offset_parent(mc, m_key)) +- error(ap->logopt, "failed to set offset parent"); ++ if (!tree_mapent_add_node(mc, name, m_key)) ++ error(ap->logopt, "failed to add offset %s to tree", m_key); + cache_unlock(mc); + + if (ret == CHE_DUPLICATE) { +@@ -1136,10 +1136,7 @@ static int mount_subtree(struct autofs_p + const char *name, char *loc, char *options, void *ctxt) + { + struct mapent *me; +- struct mapent *ro; +- char *mm_root, *mm_base, *mm_key; +- unsigned int mm_root_len; +- int start, ret = 0, rv; ++ int ret = 0, rv; + + cache_readlock(mc); + me = cache_lookup_distinct(mc, name); +@@ -1150,34 +1147,18 @@ static int mount_subtree(struct autofs_p + + rv = 0; + +- mm_key = MM_ROOT(me)->key; +- +- if (*mm_key == '/') { +- mm_root = mm_key; +- start = strlen(mm_key); +- } else { +- start = ap->len + strlen(mm_key) + 1; +- mm_root = alloca(start + 3); +- strcpy(mm_root, ap->path); +- strcat(mm_root, "/"); +- strcat(mm_root, mm_key); +- } +- mm_root_len = strlen(mm_root); +- + if (IS_MM_ROOT(me)) { + char key[PATH_MAX + 1]; ++ struct mapent *ro; ++ size_t len; + +- if (mm_root_len + 1 > PATH_MAX) { ++ len = mount_fullpath(key, PATH_MAX, ap->path, me->key); ++ if (!len) { + warn(ap->logopt, "path loo long"); + return 1; + } +- +- /* name = NULL */ +- /* destination = mm_root */ +- mm_base = "/"; +- +- strcpy(key, mm_root); +- strcat(key, mm_base); ++ key[len] = '/'; ++ key[len + 1] = 0; + + /* Mount root offset if it exists */ + ro = cache_lookup_distinct(me->mc, key); +@@ -1196,7 +1177,7 @@ static int mount_subtree(struct autofs_p + warn(ap->logopt, + MODPREFIX "failed to parse root offset"); + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + return 1; + } +@@ -1211,10 +1192,10 @@ static int mount_subtree(struct autofs_p + free(ro_loc); + } + +- if ((ro && rv == 0) || rv <= 0) { +- ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); +- if (ret == -1) { +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ if (rv <= 0) { ++ ret = tree_mapent_mount_offsets(me, 1); ++ if (!ret) { ++ tree_mapent_cleanup_offsets(me); + cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +@@ -1225,39 +1206,14 @@ static int mount_subtree(struct autofs_p + int loclen = strlen(loc); + int namelen = strlen(name); + +- /* name = mm_root + mm_base */ +- /* destination = mm_root + mm_base = name */ +- mm_base = &me->key[start]; +- ++ /* Mounts at nesting points must succeed for subtree ++ * offsets to be mounted. ++ */ + rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); + if (rv == 0) { +- ret = mount_multi_triggers(ap, me->multi, name, start, mm_base); +- if (ret == -1) { +- cleanup_multi_triggers(ap, me, name, start, mm_base); +- cache_unlock(mc); +- error(ap->logopt, MODPREFIX +- "failed to mount offset triggers"); +- return 1; +- } +- } else if (rv < 0) { +- char mm_root_base[PATH_MAX + 1]; +- unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1; +- +- if (mm_root_base_len > PATH_MAX) { +- cache_unlock(mc); +- warn(ap->logopt, MODPREFIX "path too long"); +- cache_writelock(mc); +- cache_delete_offset_list(mc, name); +- cache_unlock(mc); +- return 1; +- } +- +- 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) { +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ ret = tree_mapent_mount_offsets(me, 1); ++ if (!ret) { ++ tree_mapent_cleanup_offsets(me); + cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +@@ -1267,7 +1223,7 @@ static int mount_subtree(struct autofs_p + } + cache_unlock(mc); + +- /* Mount for base of tree failed */ ++ /* strict mount failed */ + if (rv > 0) + return rv; + +@@ -1508,7 +1464,7 @@ dont_expand: + + /* So we know we're the multi-mount root */ + if (!IS_MM(me)) +- me->multi = me; ++ MAPENT_SET_ROOT(me, tree_mapent_root(me)) + else { + /* + * The amd host mount type assumes the lookup name +@@ -1558,7 +1514,7 @@ dont_expand: + if (!m_offset) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + free(options); + free(pmapent); +@@ -1575,7 +1531,7 @@ dont_expand: + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + free(m_offset); + free(options); +@@ -1594,7 +1550,7 @@ dont_expand: + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + free(m_offset); + free(options); diff --git a/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch b/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch new file mode 100644 index 0000000..58ba41b --- /dev/null +++ b/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch @@ -0,0 +1,111 @@ +autofs-5.1.7 - use mapent tree root for tree_mapent_add_node() + +From: Ian Kent + +Since we need to create the offset tree after adding the offset entries +to the mapent cache lookup the root mapent once and use it when calling +tree_mapent_add_node() instread of doing a cache lookup on every node +addition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 24 +++++------------------- + modules/parse_sun.c | 11 ++++++++++- + 4 files changed, 17 insertions(+), 21 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -69,6 +69,7 @@ + - fix amd section mounts map reload. + - fix amd hosts mount expire. + - fix offset entries order. ++- use mapent tree root for tree_mapent_add_node(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); +-int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); ++int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1519,27 +1519,13 @@ static void tree_mapent_free(struct tree + } + + int tree_mapent_add_node(struct mapent_cache *mc, +- const char *root, const char *key) ++ struct tree_node *root, const char *key) + { + unsigned int logopt = mc->ap->logopt; +- struct tree_node *tree, *n; +- struct mapent *base; ++ struct tree_node *n; + struct mapent *parent; + struct mapent *me; + +- base = cache_lookup_distinct(mc, root); +- if (!base) { +- error(logopt, +- "failed to find multi-mount root for key %s", key); +- return 0; +- } +- +- if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { +- error(logopt, "key %s is not multi-mount root", root); +- return 0; +- } +- tree = MAPENT_ROOT(base); +- + me = cache_lookup_distinct(mc, key); + if (!me) { + error(logopt, +@@ -1547,16 +1533,16 @@ int tree_mapent_add_node(struct mapent_c + return 0; + } + +- n = tree_add_node(tree, me); ++ n = tree_add_node(root, me); + if (!n) + return 0; + +- MAPENT_SET_ROOT(me, tree) ++ MAPENT_SET_ROOT(me, root) + + /* Set the subtree parent */ + parent = cache_get_offset_parent(mc, key); + if (!parent) +- MAPENT_SET_PARENT(me, tree) ++ MAPENT_SET_PARENT(me, root) + else + MAPENT_SET_PARENT(me, MAPENT_NODE(parent)) + +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1538,8 +1538,17 @@ dont_expand: + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + + cache_writelock(mc); ++ me = cache_lookup_distinct(mc, name); ++ if (!me) { ++ cache_unlock(mc); ++ free(options); ++ free(pmapent); ++ cleanup_offset_entries(ap, mc, &offsets); ++ pthread_setcancelstate(cur_state, NULL); ++ return 1; ++ } + list_for_each_entry_safe(oe, tmp, &offsets, work) { +- if (!tree_mapent_add_node(mc, name, oe->key)) ++ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key)) + error(ap->logopt, "failed to add offset %s to tree", oe->key); + list_del_init(&oe->work); + } diff --git a/autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch b/autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch new file mode 100644 index 0000000..799fe9e --- /dev/null +++ b/autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch @@ -0,0 +1,70 @@ +autofs-5.1.7 - use mount_fullpath() in one spot in parse_mount() + +From: Ian Kent + +mount_fullpath() is meant to be used for this type of path construction +so use it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 34 ++++++++-------------------------- + 2 files changed, 9 insertions(+), 26 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -43,6 +43,7 @@ + - switch to use tree implementation for offsets. + - remove obsolete functions. + - remove redundant local var from sun_mount(). ++- use mount_fullpath() in one spot in parse_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1356,36 +1356,18 @@ dont_expand: + debug(ap->logopt, MODPREFIX "gathered options: %s", options); + + if (check_is_multi(p)) { +- char *m_root = NULL; ++ char m_root[PATH_MAX + 1]; + int m_root_len; + time_t age; + int l; + +- /* If name starts with "/" it's a direct mount */ +- if (*name == '/') { +- m_root_len = name_len; +- m_root = alloca(m_root_len + 1); +- if (!m_root) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- free(options); +- free(pmapent); +- logerr(MODPREFIX "alloca: %s", estr); +- return 1; +- } +- strcpy(m_root, name); +- } else { +- m_root_len = ap->len + name_len + 1; +- m_root = alloca(m_root_len + 1); +- if (!m_root) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- free(options); +- free(pmapent); +- logerr(MODPREFIX "alloca: %s", estr); +- return 1; +- } +- strcpy(m_root, ap->path); +- strcat(m_root, "/"); +- strcat(m_root, name); ++ m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, name); ++ if (!m_root_len) { ++ error(ap->logopt, ++ MODPREFIX "multi-mount root path too long"); ++ free(options); ++ free(pmapent); ++ return 1; + } + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); diff --git a/autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch b/autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch new file mode 100644 index 0000000..41d1c4e --- /dev/null +++ b/autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch @@ -0,0 +1,72 @@ +autofs-5.1.7 - use snprintf() when constructing hosts mapent + +From: Ian Kent + +Using multiple strcpy() and strcat() functions when constructing the +hosts map offset for each export is much slower than using a single +sprintf() for each. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 26 +++++++++++++------------- + 2 files changed, 14 insertions(+), 13 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -2,6 +2,7 @@ + - add xdr_exports(). + - remove mount.x and rpcgen dependencies. + - dont use realloc in host exports list processing. ++- use sprintf() when constructing hosts mapent. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/lookup_hosts.c ++++ autofs-5.1.4/modules/lookup_hosts.c +@@ -87,10 +87,12 @@ int lookup_read_master(struct master *ma + static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; ++ char entry[PATH_MAX + 1]; + char *mapent; + struct exportinfo *exp, *this; + size_t hostlen = strlen(host); + size_t mapent_len; ++ int len, pos; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + +@@ -114,21 +116,19 @@ static char *get_exports(struct autofs_p + } + *mapent = 0; + ++ pos = 0; + this = exp; +- while (this) { +- if (!*mapent) +- strcpy(mapent, "\""); +- else +- strcat(mapent, " \""); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); +- +- strcat(mapent, " \""); +- strcat(mapent, host); +- strcat(mapent, ":"); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); ++ if (this) { ++ len = sprintf(mapent, "\"%s\" \"%s:%s\"", ++ this->dir, host, this->dir); ++ pos += len; ++ this = this->next; ++ } + ++ while (this) { ++ len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"", ++ this->dir, host, this->dir); ++ pos += len; + this = this->next; + } + rpc_exports_free(exp); diff --git a/autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch b/autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch new file mode 100644 index 0000000..b7aaa62 --- /dev/null +++ b/autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch @@ -0,0 +1,35 @@ +autofs-5.1.8 - avoid calling pthread_getspecific() with NULL key_thread_attempt_id + +From: Ian Kent + +Don't call pthread_getspecific() if key_thread_attempt_id is NULL in +case the pthread_getspecific() implementation doesn't check for this. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/log.c | 3 +++ + 2 files changed, 4 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -90,6 +90,7 @@ + - simplify cache_add() a little. + - fix use after free in tree_mapent_delete_offset_tree(). + - fix memory leak in xdr_exports(). ++- avoid calling pthread_getspecific() with NULL key_thread_attempt_id. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/log.c ++++ autofs-5.1.4/lib/log.c +@@ -38,6 +38,9 @@ static char *prepare_attempt_prefix(cons + char buffer[ATTEMPT_ID_SIZE + 1]; + char *prefixed_msg = NULL; + ++ if (!key_thread_attempt_id) ++ return NULL; ++ + attempt_id = pthread_getspecific(key_thread_attempt_id); + if (attempt_id) { + int len = sizeof(buffer) + 1 + strlen(msg) + 1; diff --git a/autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch b/autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch new file mode 100644 index 0000000..0151500 --- /dev/null +++ b/autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch @@ -0,0 +1,46 @@ +autofs-5.1.8 - dont fail on duplicate host export entry + +From: Ian Kent + +If we encounter a duplicate host export entry don't fail, just ignore +it and return the duplicate. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -85,6 +85,7 @@ + - fix double quoting of ampersand in auto.smb as well. + - fix root offset error handling. + - fix nonstrict fail handling of last offset mount. ++- dont fail on duplicate offset entry tree add. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1341,7 +1341,7 @@ static struct tree_node *tree_add_node(s + } + + if (!eq) +- error(LOGOPT_ANY, "cannot add duplicate entry to tree"); ++ return p; + else { + if (eq < 0) + return tree_add_left(p, ptr); +@@ -1515,8 +1515,10 @@ static int tree_host_cmp(struct tree_nod + int eq; + + eq = strcmp(exp->dir, n_exp->dir); +- if (!eq) ++ if (!eq) { ++ error(LOGOPT_ANY, "duplicate entry %s ignored", exp->dir); + return 0; ++ } + return (exp_len < n_exp_len) ? -1 : 1; + } + diff --git a/autofs-5.1.8-dont-use-initgroups-at-spawn.patch b/autofs-5.1.8-dont-use-initgroups-at-spawn.patch new file mode 100644 index 0000000..bdd6e01 --- /dev/null +++ b/autofs-5.1.8-dont-use-initgroups-at-spawn.patch @@ -0,0 +1,131 @@ +autofs-5.1.8 - dont use initgroups() at spawn + +From: Ian Kent + +The initgroups(3) function isn't safe to use between fork() and +exec() in a threaded program. + +Using it this way often leads to a hang for even moderate work +loads. + +But the getgrouplist()/setgroups() combination can be used safely +in this case and this patch changes autofs to use these (the safety +of using of setgroups() is yet to to be documented). + +A large portion of the work on this patch has been contributed +by Roberto Bergantinos . + +Reported-by: Roberto Bergantinos +Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()") +Signed-off-by: Roberto Bergantinos +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 48 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -94,6 +94,7 @@ + - fix sysconf(3) return handling. + - remove nonstrict parameter from tree_mapent_umount_offsets(). + - fix handling of incorrect return from umount_ent(). ++- dont use initgroups() at spawn. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/spawn.c ++++ autofs-5.1.4/daemon/spawn.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "automount.h" + +@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, uns + struct thread_stdenv_vars *tsv; + pid_t euid = 0; + gid_t egid = 0; ++ gid_t *groups = NULL; ++ gid_t *saved_groups = NULL; ++ int ngroups = 0; ++ int nsaved_groups = 0; + + if (open_pipe(pipefd)) + return -1; +@@ -357,6 +362,31 @@ static int do_spawn(unsigned logopt, uns + } + + open_mutex_lock(); ++ ++ if (euid) { ++ struct passwd *pwd; ++ ++ pwd = getpwuid(getuid()); ++ if (!pwd) ++ fprintf(stderr, ++ "warning: getpwuid: can't get current username\n"); ++ else { ++ /* get number of groups for current gid */ ++ getgrouplist(pwd->pw_name, getgid(), NULL, &nsaved_groups); ++ saved_groups = malloc(nsaved_groups * sizeof(gid_t)); ++ ++ /* get current gid groups list */ ++ getgrouplist(pwd->pw_name, getgid(), saved_groups, &nsaved_groups); ++ } ++ ++ /* get number of groups of mount triggering process */ ++ getgrouplist(tsv->user, egid, NULL, &ngroups); ++ groups = malloc(ngroups * sizeof(gid_t)); ++ ++ /* get groups list of mount triggering process */ ++ getgrouplist(tsv->user, egid, groups, &ngroups); ++ } ++ + f = fork(); + if (f == 0) { + char **pargv = (char **) argv; +@@ -398,10 +428,13 @@ static int do_spawn(unsigned logopt, uns + if (!tsv->user) + fprintf(stderr, + "warning: can't init groups\n"); +- else if (initgroups(tsv->user, egid) == -1) +- fprintf(stderr, +- "warning: initgroups: %s\n", +- strerror(errno)); ++ else if (groups) { ++ if (setgroups(ngroups, groups) == -1) ++ fprintf(stderr, ++ "warning: setgroups: %s\n", ++ strerror(errno)); ++ free(groups); ++ } + + if (setegid(egid) == -1) + fprintf(stderr, +@@ -436,6 +469,11 @@ static int do_spawn(unsigned logopt, uns + strerror(errno)); + if (pgrp >= 0) + setpgid(0, pgrp); ++ /* Reset groups for trigger of trailing mount */ ++ if (euid && saved_groups) { ++ setgroups(nsaved_groups, saved_groups); ++ free(saved_groups); ++ } + + /* + * The kernel leaves mount type autofs alone because +@@ -474,6 +512,11 @@ done: + pthread_sigmask(SIG_SETMASK, &tmpsig, NULL); + open_mutex_unlock(); + ++ if (groups) ++ free(groups); ++ if (saved_groups) ++ free(saved_groups); ++ + close(pipefd[1]); + + if (f < 0) { diff --git a/autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch b/autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch new file mode 100644 index 0000000..ef5a07d --- /dev/null +++ b/autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch @@ -0,0 +1,110 @@ +autofs-5.1.8 - fix handling of incorrect return from umount_ent() + +From: Ian Kent + +Commit 0210535df4b ("autofs-5.1.0 - gaurd against incorrect umount +return") guards against umount_ent() returning a fail when the mount +has actually been umounted. + +But we also see umount_ent() return success when in fact the mount has +not been umounted leading to incorrect handling of automounts. + +So checking the return of umount_ent() isn't always giving the correct +result in more than just one case, consequently we should ignore the +result from the spawned umount(8) and check if the mount has in fact +been umounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 3 +-- + lib/mounts.c | 19 ++++++++++--------- + 3 files changed, 12 insertions(+), 11 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -93,6 +93,7 @@ + - avoid calling pthread_getspecific() with NULL key_thread_attempt_id. + - fix sysconf(3) return handling. + - remove nonstrict parameter from tree_mapent_umount_offsets(). ++- fix handling of incorrect return from umount_ent(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -606,8 +606,7 @@ static int umount_subtree_mounts(struct + struct mnt_list *mnt; + + debug(ap->logopt, "unmounting dir = %s", path); +- if (umount_ent(ap, path) && +- is_mounted(path, MNTS_REAL)) { ++ if (umount_ent(ap, path)) { + warn(ap->logopt, "could not umount dir %s", path); + left++; + goto done; +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1869,8 +1869,7 @@ static int tree_mapent_umount_offset(str + */ + if (oe->ioctlfd != -1 || + is_mounted(oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key) && +- is_mounted(oe->key, MNTS_REAL)) { ++ if (umount_ent(ap, oe->key)) { + debug(ap->logopt, + "offset %s has active mount, invalidate", + oe->key); +@@ -2010,8 +2009,7 @@ int tree_mapent_umount_offsets(struct ma + */ + if (is_mounted(mp, MNTS_REAL)) { + info(ap->logopt, "unmounting dir = %s", mp); +- if (umount_ent(ap, mp) && +- is_mounted(mp, MNTS_REAL)) { ++ if (umount_ent(ap, mp)) { + if (!tree_mapent_mount_offsets(oe, 1)) + warn(ap->logopt, + "failed to remount offset triggers"); +@@ -2982,6 +2980,7 @@ void set_direct_mount_tree_catatonic(str + + int umount_ent(struct autofs_point *ap, const char *path) + { ++ unsigned int mounted; + int rv; + + if (ap->state != ST_SHUTDOWN_FORCE) +@@ -2993,6 +2992,8 @@ int umount_ent(struct autofs_point *ap, + rv = spawn_umount(ap->logopt, "-l", path, NULL); + } + ++ mounted = is_mounted(path, MNTS_REAL); ++ + if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { + /* + * Verify that we actually unmounted the thing. This is a +@@ -3004,20 +3005,20 @@ int umount_ent(struct autofs_point *ap, + * so that we do not try to call rmdir_path on the + * directory. + */ +- if (is_mounted(path, MNTS_REAL)) { ++ if (mounted) { + crit(ap->logopt, + "the umount binary reported that %s was " + "unmounted, but there is still something " + "mounted on this path.", path); +- rv = -1; ++ mounted = -1; + } + } + +- /* On success, check for mounted mount and remove it if found */ +- if (!rv) ++ /* If mount is gone remove it from mounted mounts list. */ ++ if (!mounted) + mnts_remove_mount(path, MNTS_MOUNTED); + +- return rv; ++ return mounted; + } + + int umount_amd_ext_mount(struct autofs_point *ap, const char *path) diff --git a/autofs-5.1.8-fix-kernel-mount-status-notification.patch b/autofs-5.1.8-fix-kernel-mount-status-notification.patch new file mode 100644 index 0000000..544b5b2 --- /dev/null +++ b/autofs-5.1.8-fix-kernel-mount-status-notification.patch @@ -0,0 +1,135 @@ +autofs-5.1.8 - fix kernel mount status notification + +From: Ian Kent + +The status return for attempted mount notification is not done +correctly in some cases leading to a status being sent to the +kernel multiple times or the send causing an error. + +We must send a status to the kernel but it needs to be the correct +one. It definitely shouldn't be sent twice for the same mount attempt +and shouldn't be failing. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 19 +++++++++++-------- + daemon/indirect.c | 19 +++++++++++-------- + 3 files changed, 23 insertions(+), 16 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -78,6 +78,7 @@ + - fix empty mounts list return from unlink_mount_tree(). + - fix nonstrict offset mount fail handling. + - remove intr hosts map mount option. ++- fix kernel mount status notification. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -1143,12 +1143,18 @@ int handle_packet_expire_direct(struct a + return 0; + } + +-static void mount_send_fail(void *arg) ++static void mount_send_status(void *arg) + { + struct ioctl_ops *ops = get_ioctl_ops(); + struct pending_args *mt = arg; + struct autofs_point *ap = mt->ap; +- ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT); ++ ++ if (mt->status) ++ ops->send_fail(ap->logopt, mt->ioctlfd, ++ mt->wait_queue_token, mt->status); ++ else ++ ops->send_ready(ap->logopt, ++ mt->ioctlfd, mt->wait_queue_token); + ops->close(ap->logopt, mt->ioctlfd); + } + +@@ -1177,7 +1183,8 @@ static void *do_mount_direct(void *arg) + + pending_mutex_unlock(args); + +- pthread_cleanup_push(mount_send_fail, &mt); ++ mt.status = 0; ++ pthread_cleanup_push(mount_send_status, &mt); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +@@ -1191,9 +1198,7 @@ static void *do_mount_direct(void *arg) + if (status == -1) { + error(ap->logopt, + "can't stat direct mount trigger %s", mt.name); +- ops->send_fail(ap->logopt, +- mt.ioctlfd, mt.wait_queue_token, -ENOENT); +- ops->close(ap->logopt, mt.ioctlfd); ++ mt.status = -ENOENT; + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } +@@ -1203,8 +1208,6 @@ static void *do_mount_direct(void *arg) + error(ap->logopt, + "direct trigger not valid or already mounted %s", + mt.name); +- ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); +- ops->close(ap->logopt, mt.ioctlfd); + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -674,13 +674,18 @@ int handle_packet_expire_indirect(struct + return 0; + } + +-static void mount_send_fail(void *arg) ++static void mount_send_status(void *arg) + { + struct ioctl_ops *ops = get_ioctl_ops(); + struct pending_args *mt = arg; + struct autofs_point *ap = mt->ap; +- ops->send_fail(ap->logopt, +- ap->ioctlfd, mt->wait_queue_token, -ENOENT); ++ ++ if (mt->status) ++ ops->send_fail(ap->logopt, ap->ioctlfd, ++ mt->wait_queue_token, mt->status); ++ else ++ ops->send_ready(ap->logopt, ++ ap->ioctlfd, mt->wait_queue_token); + } + + static void *do_mount_indirect(void *arg) +@@ -709,7 +714,8 @@ static void *do_mount_indirect(void *arg + + pending_mutex_unlock(args); + +- pthread_cleanup_push(mount_send_fail, &mt); ++ mt.status = 0; ++ pthread_cleanup_push(mount_send_status, &mt); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +@@ -722,9 +728,7 @@ static void *do_mount_indirect(void *arg + len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len); + if (!len) { + crit(ap->logopt, "path to be mounted is to long"); +- ops->send_fail(ap->logopt, +- ap->ioctlfd, mt.wait_queue_token, +- -ENAMETOOLONG); ++ mt.status = -ENAMETOOLONG; + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } +@@ -733,7 +737,6 @@ static void *do_mount_indirect(void *arg + 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); +- ops->send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token); + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } diff --git a/autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch b/autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch new file mode 100644 index 0000000..c244254 --- /dev/null +++ b/autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch @@ -0,0 +1,36 @@ +autofs-5.1.8 - fix loop under run in cache_get_offset_parent() + +From: Frank Sorenson + +To avoid reading memory outside of the the string +allocated for parent, tail needs to stop when it +reaches or passes parent, even if it doesn't +actually equal parent. + +Signed-off-by: Frank Sorenson +--- + CHANGELOG | 1 + + lib/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -86,6 +86,7 @@ + - fix root offset error handling. + - fix nonstrict fail handling of last offset mount. + - dont fail on duplicate offset entry tree add. ++- fix loop under run in cache_get_offset_parent(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -680,7 +680,7 @@ struct mapent *cache_get_offset_parent(s + *tail = 0; + + tail--; +- if (tail == parent) ++ if (tail <= parent) + break; + + me = cache_lookup_distinct(mc, parent); diff --git a/autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch b/autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch new file mode 100644 index 0000000..750cc33 --- /dev/null +++ b/autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch @@ -0,0 +1,40 @@ +autofs-5.1.8 - fix memory leak in xdr_exports() + +From: Ian Kent + +Converting xdr_exports() to not be recursive introduced a memory leak +if an error is encountered, fix it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 7 ++++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -89,6 +89,7 @@ + - fix loop under run in cache_get_offset_parent(). + - simplify cache_add() a little. + - fix use after free in tree_mapent_delete_offset_tree(). ++- fix memory leak in xdr_exports(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/rpc_subs.c ++++ autofs-5.1.4/lib/rpc_subs.c +@@ -1151,8 +1151,13 @@ bool_t xdr_exports(XDR *xdrs, struct exp + + export = (char **) exports; + while (1) { +- if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) ++ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) { ++ if (*exports) { ++ rpc_exports_free(*exports); ++ *exports = NULL; ++ } + return FALSE; ++ } + if (!*export) + break; + export = (char **) &((struct exportinfo *) *export)->next; diff --git a/autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch b/autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch new file mode 100644 index 0000000..c9ae852 --- /dev/null +++ b/autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch @@ -0,0 +1,38 @@ +autofs-5.1.8 - fix nonstrict fail handling of last offset mount + +From: Ian Kent + +When mounting a list of multi-mount offsets the offset mount should +succeed even if there's a mount failure for the non-strict case (the +default). + +But currently if the last offset mount fails the multi-mount fails +regardless of whether the mount is non-strict or not. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -84,6 +84,7 @@ + - fix double quoting in auto.smb. + - fix double quoting of ampersand in auto.smb as well. + - fix root offset error handling. ++- fix nonstrict fail handling of last offset mount. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1940,7 +1940,7 @@ static int tree_mapent_mount_offsets_wor + tree_mapent_mount_offsets(oe, !ctxt->strict); + } + +- return ret; ++ return (ctxt->strict ? ret : 1); + } + + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict) diff --git a/autofs-5.1.8-fix-root-offset-error-handling.patch b/autofs-5.1.8-fix-root-offset-error-handling.patch new file mode 100644 index 0000000..482082f --- /dev/null +++ b/autofs-5.1.8-fix-root-offset-error-handling.patch @@ -0,0 +1,86 @@ +autofs-5.1.8 - fix root offset error handling + +From: Ian Kent + +If mounting the root or offsets of a multi-mount root fails any mounts +done so far need to be umounted and the multi-mount offset tree deleted +so it can be created cleanly and possibly mounted the next time it's +triggered. + +Also, if a subtree that is not the multi-mount root fails the expire +alarm needs to be re-instated so other subtrees (at least the root) +will continue to expire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 11 ++++++++++- + modules/parse_sun.c | 6 ++++++ + 3 files changed, 17 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -83,6 +83,7 @@ + - improve descriptor open error reporting. + - fix double quoting in auto.smb. + - fix double quoting of ampersand in auto.smb as well. ++- fix root offset error handling. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -1163,6 +1163,7 @@ static void *do_mount_direct(void *arg) + struct ioctl_ops *ops = get_ioctl_ops(); + struct pending_args *args, mt; + struct autofs_point *ap; ++ struct mapent *me; + struct stat st; + int status, state; + +@@ -1226,7 +1227,6 @@ static void *do_mount_direct(void *arg) + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + if (status) { + struct mnt_list *sbmnt; +- struct mapent *me; + struct statfs fs; + unsigned int close_fd = 0; + unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED; +@@ -1267,6 +1267,15 @@ static void *do_mount_direct(void *arg) + mt.ioctlfd, mt.wait_queue_token, -ENOENT); + ops->close(ap->logopt, mt.ioctlfd); + info(ap->logopt, "failed to mount %s", mt.name); ++ ++ /* If this is a multi-mount subtree mount failure ++ * ensure the tree continues to expire. ++ */ ++ cache_readlock(mt.mc); ++ me = cache_lookup_distinct(mt.mc, mt.name); ++ if (me && IS_MM(me) && !IS_MM_ROOT(me)) ++ conditional_alarm_add(ap, ap->exp_runfreq); ++ cache_unlock(mt.mc); + } + pthread_setcancelstate(state, NULL); + +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -1125,6 +1125,9 @@ static int mount_subtree(struct autofs_p + if (!len) { + warn(ap->logopt, "path loo long"); + cache_unlock(mc); ++ cache_writelock(mc); ++ tree_mapent_delete_offsets(mc, name); ++ cache_unlock(mc); + return 1; + } + key[len] = '/'; +@@ -1169,6 +1172,9 @@ static int mount_subtree(struct autofs_p + cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); ++ cache_writelock(mc); ++ tree_mapent_delete_offsets(mc, name); ++ cache_unlock(mc); + return 1; + } + } diff --git a/autofs-5.1.8-fix-set-open-file-limit.patch b/autofs-5.1.8-fix-set-open-file-limit.patch new file mode 100644 index 0000000..c5084b3 --- /dev/null +++ b/autofs-5.1.8-fix-set-open-file-limit.patch @@ -0,0 +1,57 @@ +autofs-5.1.8 - fix set open file limit + +From: Ian Kent + +The check of whether the open file limit needs to be changed is not +right, it checks the hard open file limit against what autofs wants +to set it to which is always less than this value. Consequently the +open file limit isn't changed. + +autofs should be changing only the soft open file limit but it is +setting both the hard and soft limits. The system hard limit is much +higer than the autofs maximum open files so the hard limit should be +left alone. + +While we are here increase the requested maximum soft open file limit +to 20k. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -79,6 +79,7 @@ + - fix nonstrict offset mount fail handling. + - remove intr hosts map mount option. + - fix kernel mount status notification. ++- fix set open file limit. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -95,7 +95,7 @@ struct startup_cond suc = { + pthread_key_t key_thread_stdenv_vars; + pthread_key_t key_thread_attempt_id = (pthread_key_t) 0L; + +-#define MAX_OPEN_FILES 10240 ++#define MAX_OPEN_FILES 20480 + + int aquire_flag_file(void); + void release_flag_file(void); +@@ -2475,9 +2475,10 @@ int main(int argc, char *argv[]) + } + + res = getrlimit(RLIMIT_NOFILE, &rlim); +- if (res == -1 || rlim.rlim_max <= MAX_OPEN_FILES) { ++ if (res == -1 || rlim.rlim_cur <= MAX_OPEN_FILES) { + rlim.rlim_cur = MAX_OPEN_FILES; +- rlim.rlim_max = MAX_OPEN_FILES; ++ if (rlim.rlim_max < MAX_OPEN_FILES) ++ rlim.rlim_max = MAX_OPEN_FILES; + } + res = setrlimit(RLIMIT_NOFILE, &rlim); + if (res) diff --git a/autofs-5.1.8-fix-sysconf-return-handling.patch b/autofs-5.1.8-fix-sysconf-return-handling.patch new file mode 100644 index 0000000..252c3b8 --- /dev/null +++ b/autofs-5.1.8-fix-sysconf-return-handling.patch @@ -0,0 +1,64 @@ +autofs-5.1.8 - fix sysconf(3) return handling + +From: Fabian Groffen + +The sysconf(3) return handling doesn't handle a -1 return with errno +not changed which indicated a maximum or minimum limit that's not +known. + +Add handling of this case. + +Signed-off-by: Fabian Groffen +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 13 +++++++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -91,6 +91,7 @@ + - fix use after free in tree_mapent_delete_offset_tree(). + - fix memory leak in xdr_exports(). + - avoid calling pthread_getspecific() with NULL key_thread_attempt_id. ++- fix sysconf(3) return handling. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2385,11 +2385,17 @@ void set_tsd_user_vars(unsigned int logo + + /* Try to get passwd info */ + ++ /* sysconf may return -1 with unchanged errno to indicate unlimited ++ * size, same for the call for _SC_GETGR_R_SIZE_MAX below ++ */ ++ errno = 0; + tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); +- if (tmplen < 0) { ++ if (tmplen < 0 && errno != 0) { + error(logopt, "failed to get buffer size for getpwuid_r"); + goto free_tsv; + } ++ if (tmplen < 0) ++ tmplen = 1024; /* assume something reasonable */ + + pw_tmp = malloc(tmplen + 1); + if (!pw_tmp) { +@@ -2422,11 +2428,14 @@ void set_tsd_user_vars(unsigned int logo + + /* Try to get group info */ + ++ errno = 0; + grplen = sysconf(_SC_GETGR_R_SIZE_MAX); +- if (grplen < 0) { ++ if (grplen < 0 && errno != 0) { + error(logopt, "failed to get buffer size for getgrgid_r"); + goto free_tsv_home; + } ++ if (grplen < 0) ++ grplen = 1024; + + gr_tmp = NULL; + status = ERANGE; diff --git a/autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch b/autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch new file mode 100644 index 0000000..a2f72e6 --- /dev/null +++ b/autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch @@ -0,0 +1,55 @@ +autofs-5.1.8 - fix use after free in tree_mapent_delete_offset_tree() + +From: Ian Kent + +The key field of the map entry of the root of the map entry tree to be +deleted can't be used for the key parameter, fix it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 16 +++++++++++++--- + 2 files changed, 14 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -88,6 +88,7 @@ + - dont fail on duplicate offset entry tree add. + - fix loop under run in cache_get_offset_parent(). + - simplify cache_add() a little. ++- fix use after free in tree_mapent_delete_offset_tree(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1666,16 +1666,26 @@ static int tree_mapent_delete_offset_tre + */ + if (MAPENT_ROOT(me) != MAPENT_NODE(me)) { + struct tree_node *root = MAPENT_ROOT(me); ++ char *key; + +- debug(logopt, "deleting offset key %s", me->key); ++ key = strdup(me->key); ++ if (!key) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "strdup: %s", estr); ++ return 0; ++ } ++ ++ debug(logopt, "deleting offset key %s", key); + + /* cache_delete won't delete an active offset */ + MAPENT_SET_ROOT(me, NULL); +- ret = cache_delete(me->mc, me->key); ++ ret = cache_delete(me->mc, key); + if (ret != CHE_OK) { + MAPENT_SET_ROOT(me, root); +- warn(logopt, "failed to delete offset %s", me->key); ++ warn(logopt, "failed to delete offset %s", key); + } ++ free(key); + } else { + MAPENT_SET_ROOT(me, NULL); + MAPENT_SET_PARENT(me, NULL); diff --git a/autofs-5.1.8-improve-descriptor-open-error-reporting.patch b/autofs-5.1.8-improve-descriptor-open-error-reporting.patch new file mode 100644 index 0000000..7ebf7b7 --- /dev/null +++ b/autofs-5.1.8-improve-descriptor-open-error-reporting.patch @@ -0,0 +1,165 @@ +autofs-5.1.8 - improve descriptor open error reporting + +From: Ian Kent + +Add error message reporting to the descriptor open functions. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 3 --- + daemon/spawn.c | 29 +++++++++++++++++++++++++++++ + lib/mounts.c | 10 ++-------- + modules/lookup_program.c | 5 +---- + 5 files changed, 33 insertions(+), 15 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -80,6 +80,7 @@ + - remove intr hosts map mount option. + - fix kernel mount status notification. + - fix set open file limit. ++- improve descriptor open error reporting. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -864,9 +864,6 @@ static int create_logpri_fifo(struct aut + + fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK); + if (fd < 0) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- crit(ap->logopt, +- "Failed to open %s: %s", fifo_name, estr); + unlink(fifo_name); + ret = -1; + goto out_free; +--- autofs-5.1.4.orig/daemon/spawn.c ++++ autofs-5.1.4/daemon/spawn.c +@@ -94,7 +94,12 @@ int open_fd(const char *path, int flags) + #endif + fd = open(path, flags); + if (fd == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open file: %s", estr); + return -1; + } + check_cloexec(fd); +@@ -113,7 +118,12 @@ int open_fd_mode(const char *path, int f + #endif + fd = open(path, flags, mode); + if (fd == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open file: %s", estr); + return -1; + } + check_cloexec(fd); +@@ -123,6 +133,8 @@ int open_fd_mode(const char *path, int f + + int open_pipe(int pipefd[2]) + { ++ char buf[MAX_ERR_BUF]; ++ char *estr; + int ret; + + open_mutex_lock(); +@@ -145,6 +157,8 @@ done: + return 0; + err: + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open pipe: %s", estr); + return -1; + } + +@@ -159,7 +173,12 @@ int open_sock(int domain, int type, int + #endif + fd = socket(domain, type, protocol); + if (fd == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open socket: %s", estr); + return -1; + } + check_cloexec(fd); +@@ -184,7 +203,12 @@ FILE *open_fopen_r(const char *path) + #endif + f = fopen(path, "r"); + if (f == NULL) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open file: %s", estr); + return NULL; + } + check_cloexec(fileno(f)); +@@ -209,7 +233,12 @@ FILE *open_setmntent_r(const char *table + #endif + tab = fopen(table, "r"); + if (tab == NULL) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open mount table: %s", estr); + return NULL; + } + check_cloexec(fileno(tab)); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2169,11 +2169,8 @@ struct mnt_list *get_mnt_list(const char + return NULL; + + tab = open_fopen_r(_PROC_MOUNTS); +- if (!tab) { +- char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("fopen: %s", estr); ++ if (!tab) + return NULL; +- } + + while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { + len = strlen(mnt->mnt_dir); +@@ -2280,11 +2277,8 @@ static int table_is_mounted(const char * + return 0; + + tab = open_fopen_r(_PROC_MOUNTS); +- if (!tab) { +- char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("fopen: %s", estr); ++ if (!tab) + return 0; +- } + + while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { + size_t len = strlen(mnt->mnt_dir); +--- autofs-5.1.4.orig/modules/lookup_program.c ++++ autofs-5.1.4/modules/lookup_program.c +@@ -214,11 +214,8 @@ static char *lookup_one(struct autofs_po + * want to send stderr to the syslog, and we don't use spawnl() + * because we need the pipe hooks + */ +- if (open_pipe(pipefd)) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "pipe: %s", estr); ++ if (open_pipe(pipefd)) + goto out_error; +- } + if (open_pipe(epipefd)) { + close(pipefd[0]); + close(pipefd[1]); diff --git a/autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch b/autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch new file mode 100644 index 0000000..88e98b4 --- /dev/null +++ b/autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch @@ -0,0 +1,77 @@ +autofs-5.1.8 - remove nonstrict parameter from tree_mapent_umount_offsets() + +From: Ian Kent + +The nonstrict parameter of tree_mapent_umount_offsets() ins't useful +because if a real mount at the base of a sub-tree fails to umount all +we can do is re-instate the offset mounts under it which must succeed +for the mount tree to remain useful. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + include/mounts.h | 2 +- + lib/mounts.c | 6 +++--- + 4 files changed, 6 insertions(+), 5 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -92,6 +92,7 @@ + - fix memory leak in xdr_exports(). + - avoid calling pthread_getspecific() with NULL key_thread_attempt_id. + - fix sysconf(3) return handling. ++- remove nonstrict parameter from tree_mapent_umount_offsets(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -555,7 +555,7 @@ static int umount_subtree_mounts(struct + struct mapent *tmp; + int ret; + +- ret = tree_mapent_umount_offsets(me, 1); ++ ret = tree_mapent_umount_offsets(me); + if (!ret) { + warn(ap->logopt, + "some offset mounts still present under %s", path); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -182,7 +182,7 @@ int tree_mapent_add_node(struct mapent_c + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); +-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict); ++int tree_mapent_umount_offsets(struct mapent *oe); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1843,7 +1843,7 @@ static int tree_mapent_umount_offset(str + * Check for and umount subtree offsets resulting from + * nonstrict mount fail. + */ +- ret = tree_mapent_umount_offsets(oe, ctxt->strict); ++ ret = tree_mapent_umount_offsets(oe); + if (!ret) + return 0; + +@@ -1975,14 +1975,14 @@ static int tree_mapent_umount_offsets_wo + return tree_mapent_umount_offset(oe, ptr); + } + +-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict) ++int tree_mapent_umount_offsets(struct mapent *oe) + { + struct tree_node *base = MAPENT_NODE(oe); + struct autofs_point *ap = oe->mc->ap; + struct traverse_subtree_context ctxt = { + .ap = ap, + .base = base, +- .strict = !nonstrict, ++ .strict = 1, + }; + int ret; + diff --git a/autofs-5.1.8-simplify-cache_add-a-little.patch b/autofs-5.1.8-simplify-cache_add-a-little.patch new file mode 100644 index 0000000..37726d0 --- /dev/null +++ b/autofs-5.1.8-simplify-cache_add-a-little.patch @@ -0,0 +1,44 @@ +autofs-5.1.8 - simplify cache_add() a little + +From: Ian Kent + +If a map entry is being added to an existing hash chain there's an +unneccessarily complicted setting of ->next of the last entry. + +Just initialize the map entry ->next field instead and remove the +confusing assignment. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -87,6 +87,7 @@ + - fix nonstrict fail handling of last offset mount. + - dont fail on duplicate offset entry tree add. + - fix loop under run in cache_get_offset_parent(). ++- simplify cache_add() a little. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/cache.c ++++ autofs-5.1.4/lib/cache.c +@@ -564,6 +564,7 @@ int cache_add(struct mapent_cache *mc, s + me->dev = (dev_t) -1; + me->ino = (ino_t) -1; + me->flags = 0; ++ me->next = NULL; + + /* + * We need to add to the end if values exist in order to +@@ -583,7 +584,6 @@ int cache_add(struct mapent_cache *mc, s + + existing = next; + } +- me->next = existing->next; + existing->next = me; + } + return CHE_OK; diff --git a/autofs.spec b/autofs.spec new file mode 100644 index 0000000..71a39c8 --- /dev/null +++ b/autofs.spec @@ -0,0 +1,3024 @@ +# +# $Id: autofs.spec,v 1.11 2003/12/04 15:41:32 raven Exp $ +# +# Use --without systemd in your rpmbuild command or force values to 0 to +# disable them. +%define with_systemd %{?_without_systemd: 0} %{?!_without_systemd: 1} + +Summary: A tool for automatically mounting and unmounting filesystems +Name: autofs +Version: 5.1.4 +Release: 83%{?dist} +Epoch: 1 +License: GPLv2+ +Group: System Environment/Daemons +Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.gz +Patch1: autofs-5.1.4-fix-flag-file-permission.patch +Patch2: autofs-5.1.4-fix-directory-create-permission.patch +Patch3: autofs-5.1.4-fix-use-after-free-in-do_master_list_reset.patch +Patch4: autofs-5.1.4-fix-deadlock-in-dumpmaps.patch +Patch5: autofs-5.1.4-dont-use-array-for-path-when-not-neccessary.patch +Patch6: autofs-5.1.4-fix-prefix-option-handling-in-expand_entry.patch +Patch7: autofs-5.1.4-fix-sublink-option-not-set-from-defaults.patch +Patch8: autofs-5.1.4-fix-error-return-in-do_nfs_mount.patch +Patch9: autofs-5.1.4-add-error-handling-for-ext_mount_add.patch +Patch10: autofs-5.1.4-account-for-libnsl-changes.patch +Patch11: autofs-5.1.4-use_hostname_for_mounts-shouldnt-prevent-selection-among-replicas.patch +Patch12: autofs-5.1.4-fix-monotonic_elapsed.patch +Patch13: autofs-5.1.4-Makefiles.rules-remove-samples-from-SUBDIRS.patch +Patch14: autofs-5.1.4-dont-allow-trailing-slash-in-master-map-mount-points.patch +Patch15: autofs-5.1.4-fix-libresolv-configure-check.patch +Patch16: autofs-5.1.4-add-fedfs-getsrvinfo_c.patch +Patch17: autofs-5.1.4-add-mount_fedfs_c.patch +Patch18: autofs-5.1.4-add-fedfs-map-nfs4_c.patch +Patch19: autofs-5.1.4-add-conditional-inclusion-of-fedfs-binaries.patch +Patch20: autofs-5.1.4-add-an-example-fedfs-master-map-entry-to-the-installed-master-map.patch +Patch21: autofs-5.1.4-improve-hostname-lookup-error-logging.patch +Patch22: autofs-5.1.4-tiny-patch-for-autofs-typo-and-possible-bug.patch +Patch23: autofs-5.1.4-add-units-After-line-to-include-statd-service.patch +Patch24: autofs-5.1.4-use-systemd-sd_notify-at-startup.patch +Patch25: autofs-5.1.4-fix-NFS-version-mask-usage.patch +Patch26: autofs-5.1.4-fix-fd-leak-in-rpc_do_create_client.patch +Patch27: autofs-5.1.4-add-man-page-note-about-extra-slashes-in-paths.patch +Patch28: autofs-5.1.4-covarity-fixes-1.patch +Patch29: autofs-5.1.4-fix-program-usage-message.patch +Patch30: autofs-5.1.4-fix-update_negative_cache-map-source-usage.patch +Patch31: autofs-5.1.4-mark-removed-cache-entry-negative.patch +Patch32: autofs-5.1.4-set-bind-mount-as-propagation-slave.patch +Patch33: autofs-5.1.4-add-master-map-pseudo-options-for-mount-propagation.patch +Patch34: autofs-5.1.4-fix-age-setting-at-startup.patch +Patch35: autofs-5.1.4-fix-use-after-free-in-parse_ldap_config.patch +Patch36: autofs-5.1.4-fix-incorrect-locking-in-sss-lookup.patch +Patch37: autofs-5.1.4-fix-amd-parser-opts-option-handling.patch +Patch38: autofs-5.1.4-better-handle-hesiod-support-not-built-in.patch +Patch39: autofs-5.1.5-fix-hesiod-string-check-in-master_parse.patch + +Patch40: autofs-5.1.4-remove-autofs4-module-load-code.patch +Patch41: autofs-5.1.4-add-NULL-check-in-prepare_attempt_prefix.patch +Patch42: autofs-5.1.4-update-build-info-with-systemd.patch +Patch43: autofs-5.1.4-use-flags-for-startup-boolean-options.patch +Patch44: autofs-5.1.4-move-close-stdio-descriptors-to-become_daemon.patch +Patch45: autofs-5.1.4-add-systemd-service-command-line-option.patch +Patch46: autofs-5.1.5-add-strictexpire-mount-option.patch +Patch47: autofs-5.1.5-add-NULL-check-for-get_addr_string-return.patch +Patch48: autofs-5.1.5-use-malloc-in-spawn_c.patch +Patch49: autofs-5.1.5-add-mount_verbose-configuration-option.patch +Patch50: autofs-5.1.5-optionally-log-mount-requestor-process-info.patch +Patch51: autofs-5.1.5-log-mount-call-arguments-if-mount_verbose-is-set.patch +Patch52: autofs-5.1.5-make-expire-remaining-log-level-debug.patch +Patch53: autofs-5.1.5-allow-period-following-macro-in-selector-value.patch +Patch54: autofs-5.1.5-fix-macro-expansion-in-selector-values.patch + +Patch60: autofs-5.1.5-also-use-strictexpire-for-offsets.patch +Patch61: autofs-5.1.4-change-expire-type-naming-to-better-reflect-usage.patch +Patch62: autofs-5.1.5-remove-unused-function-has_fstab_option.patch +Patch63: autofs-5.1.5-remove-unused-function-reverse_mnt_list.patch +Patch64: autofs-5.1.5-remove-a-couple-of-old-debug-messages.patch +Patch65: autofs-5.1.5-fix-amd-entry-memory-leak.patch +Patch66: autofs-5.1.5-fix-unlink_mount_tree-not-umounting-mounts.patch +Patch67: autofs-5.1.5-add-ignore-mount-option.patch +Patch68: autofs-5.1.5-use-ignore-option-for-offset-mounts-as-well.patch +Patch69: autofs-5.1.5-add-config-option-for-ignore-mount-option.patch +Patch70: autofs-5.1.5-use-bit-flags-for-autofs-mount-types-in-mnt_list.patch +Patch71: autofs-5.1.5-use-mp-instead-of-path-in-mnt_list-entries.patch +Patch72: autofs-5.1.5-always-use-PROC_MOUNTS-to-make-mount-lists.patch +Patch73: autofs-5.1.5-add-glibc-getmntent.patch +Patch74: autofs-5.1.5-use-local-getmntent_r-in-table_is_mounted.patch +Patch75: autofs-5.1.5-refactor-unlink_active_mounts-in-direct_c.patch +Patch76: autofs-5.1.5-dont-use-tree_is_mounted-for-mounted-checks.patch +Patch77: autofs-5.1.5-use-single-unlink_umount_tree-for-both-direct-and-indirect-mounts.patch +Patch78: autofs-5.1.5-move-unlink_mount_tree-to-lib_mounts_c.patch +Patch79: autofs-5.1.5-use-local_getmntent_r-for-unlink_mount_tree.patch +Patch80: autofs-5.1.5-use-local-getmntent_r-in-get_mnt_list.patch +Patch81: autofs-5.1.5-use-local-getmntent_r-in-tree_get_mnt_list.patch +Patch82: autofs-5.1.5-fix-missing-initialization-of-autofs_point-flags.patch + +Patch83: autofs-5.1.6-update-ldap-READMEs-and-schema-definitions.patch +Patch84: autofs-5.1.6-fix-a-regression-with-map-instance-lookup.patch + +Patch85: autofs-5.1.6-fix-trailing-dollar-sun-entry-expansion.patch +Patch86: autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch +Patch87: autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch +Patch88: autofs-5.1.6-fix-autofs-mount-options-construction.patch + +Patch89: autofs-5.1.6-mount_nfs_c-fix-local-rdma-share-not-mounting.patch +Patch90: autofs-5.1.6-fix-incorrect-systemctl-command-syntax-in-autofs-8.patch + +Patch91: autofs-5.1.6-fix-direct-mount-unlink_mount_tree-path.patch +Patch92: autofs-5.1.6-fix-unlink-mounts-umount-order.patch +Patch93: autofs-5.1.6-fix-incorrect-logical-compare-in-unlink_mount_tree.patch +Patch94: autofs-5.1.6-use-bit-flag-for-force-unlink-mounts.patch +Patch95: autofs-5.1.6-improve-force-unlink-mounts-option-description.patch +Patch96: autofs-5.1.6-remove-logpri-fifo-on-autofs-mount-fail.patch +Patch97: autofs-5.1.6-add-force-unlink-mounts-and-exit-option.patch +Patch98: autofs-5.1.6-cleanup-stale-logpri-fifo-pipes-on-unlink-and-exit.patch + +Patch100: autofs-5.1.6-fix-lookup_nss_read_master-nsswicth-check-return.patch +Patch101: autofs-5.1.6-fix-typo-in-open_sss_lib.patch +Patch102: autofs-5.1.6-fix-sss-master-map-wait-timing.patch +Patch103: autofs-5.1.6-add-sss-ECONREFUSED-return-handling.patch +Patch104: autofs-5.1.6-use-mapname-in-sss-context-for-setautomntent.patch +Patch105: autofs-5.1.6-add-support-for-new-sss-autofs-proto-version-call.patch +Patch106: autofs-5.1.6-fix-retries-check-in-setautomntent_wait.patch +Patch107: autofs-5.1.6-refactor-sss-setautomntent.patch +Patch108: autofs-5.1.6-improve-sss-setautomntent-error-handling.patch +Patch109: autofs-5.1.6-refactor-sss-getautomntent.patch +Patch110: autofs-5.1.6-improve-sss-getautomntent-error-handling.patch +Patch111: autofs-5.1.6-sss-introduce-retries-calcuation-function.patch +Patch112: autofs-5.1.6-move-readall-into-struct-master.patch +Patch113: autofs-5.1.6-sss-introduce-a-flag-to-indicate-map-being-read.patch +Patch114: autofs-5.1.6-update-sss-timeout-documentation.patch +Patch115: autofs-5.1.6-refactor-sss-getautomntbyname.patch +Patch116: autofs-5.1.6-improve-sss-getautomntbyname-error-handling.patch +Patch117: autofs-5.1.6-use-a-valid-timeout-in-lookup_prune_one_cache.patch +Patch118: autofs-5.1.6-dont-prune-offset-map-entries.patch +Patch119: autofs-5.1.6-simplify-sss-source-stale-check.patch + +# Bug 1912106 +# Dependendant patches for expire improvement series. +Patch120: autofs-5.1.4-use-defines-for-expire-type.patch +Patch121: autofs-5.1.4-remove-unused-function-dump_master.patch +Patch122: autofs-5.1.5-fix-additional-typing-errors.patch +Patch123: autofs-5.1.6-make-bind-mounts-propagation-slave-by-default.patch +Patch124: autofs-5.1.6-fix-browse-dir-not-re-created-on-symlink-expire.patch +# Expire improvement series. +Patch125: autofs-5.1.6-update-list_h.patch +Patch126: autofs-5.1.6-add-hashtable-implementation.patch +Patch127: autofs-5.1.6-change-mountpoint-to-mp-in-struct-ext_mount.patch +Patch128: autofs-5.1.6-make-external-mounts-independent-of-amd_entry.patch +Patch129: autofs-5.1.6-make-external-mounts-use-simpler-hashtable.patch +Patch130: autofs-5.1.6-add-a-hash-index-to-mnt_list.patch +Patch131: autofs-5.1.6-use-mnt_list-for-submounts.patch +Patch132: autofs-5.1.6-use-mnt_list-for-amdmounts.patch +Patch133: autofs-5.1.6-make-umount_autofs-static.patch +Patch134: autofs-5.1.6-remove-force-parameter-from-umount_all.patch +Patch135: autofs-5.1.6-fix-remount-expire.patch +Patch136: autofs-5.1.6-fix-stale-offset-directories-disable-mount.patch +Patch137: autofs-5.1.6-use-struct-mnt_list-to-track-mounted-mounts.patch +Patch138: autofs-5.1.6-use-struct-mnt_list-mounted-list-for-expire.patch +Patch139: autofs-5.1.6-remove-unused-function-tree_get_mnt_list.patch +Patch140: autofs-5.1.6-only-add-expire-alarm-for-active-mounts.patch +Patch141: autofs-5.1.6-move-submount-check-into-conditional_alarm_add.patch +Patch142: autofs-5.1.6-move-lib_master_c-to-daemon_master_c.patch +Patch143: autofs-5.1.6-use-master_list_empty-for-list-empty-check.patch +Patch144: autofs-5.1.6-add-helper-to-construct-mount-point-path.patch +# Additional fixes for bug 1912106. +Patch145: autofs-5.1.7-add-xdr_exports.patch +Patch146: autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch +Patch147: autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch +Patch148: autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch +Patch149: autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch +Patch150: autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch +Patch151: autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch +Patch152: autofs-5.1.7-simplify-get_parent.patch +Patch153: autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch +Patch154: autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch +Patch155: autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch +Patch156: autofs-5.1.7-refactor-umount_multi_triggers.patch +Patch157: autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch +Patch158: autofs-5.1.7-simplify-mount_subtree-mount-check.patch +Patch159: autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch +Patch160: autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch +Patch161: autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch +Patch162: autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch +Patch163: autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch +Patch164: autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch +Patch165: autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch +Patch166: autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch +Patch167: autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch +Patch168: autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch +Patch169: autofs-5.1.7-cleanup-cache_delete-a-little.patch +Patch170: autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch +Patch171: autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch +Patch172: autofs-5.1.7-rename-tree-implementation-functions.patch +Patch173: autofs-5.1.6-fix-program-map-multi-mount-lookup-after-mount-fail.patch +Patch174: autofs-5.1.7-add-some-multi-mount-macros.patch +Patch175: autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch +Patch176: autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch +Patch177: autofs-5.1.7-make-tree-implementation-data-independent.patch +Patch178: autofs-5.1.7-add-mapent-tree-implementation.patch +Patch179: autofs-5.1.7-add-tree_mapent_add_node.patch +Patch180: autofs-5.1.7-add-tree_mapent_delete_offsets.patch +Patch181: autofs-5.1.7-add-tree_mapent_traverse_subtree.patch +Patch182: autofs-5.1.7-fix-mount_fullpath.patch +Patch183: autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch +Patch184: autofs-5.1.7-add-set_offset_tree_catatonic.patch +Patch185: autofs-5.1.7-add-mount-and-umount-offsets-functions.patch +Patch186: autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch +Patch187: autofs-5.1.7-remove-obsolete-functions.patch +Patch188: autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch +Patch189: autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch +Patch190: autofs-5.1.7-pass-root-length-to-mount_fullpath.patch +Patch191: autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch +Patch192: autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch +Patch193: autofs-5.1.7-check-for-offset-with-no-mount-location.patch +Patch194: autofs-5.1.7-remove-mounts_mutex.patch +Patch195: autofs-5.1.7-remove-unused-variable-from-get_exports.patch +# Coverity fixes resulting from bug 1912106 change. +Patch196: autofs-5.1.7-add-missing-free-in-handle_mounts.patch +Patch197: autofs-5.1.7-remove-redundant-if-check.patch +Patch198: autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch +Patch199: autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch +Patch200: autofs-5.1.7-fix-double-unlock-in-parse_mount.patch +Patch201: autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch +Patch202: autofs-5.1.7-fix-flag-check-in-umount_multi.patch +Patch203: autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch +Patch204: autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch +Patch205: autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch +Patch206: autofs-5.1.7-fix-arg-not-used-in-print.patch +Patch207: autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch +Patch208: autofs-5.1.7-fix-double-free-in-parse_mapent.patch +Patch209: autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch +Patch210: autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch +Patch211: autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch + +Patch212: autofs-5.1.7-fix-amd-section-mounts-map-reload.patch +Patch213: autofs-5.1.7-fix-amd-hosts-mount-expire.patch +Patch214: autofs-5.1.7-fix-offset-entries-order.patch +Patch215: autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch +Patch216: autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch +Patch217: autofs-5.1.7-fix-hosts-map-offset-order.patch +Patch218: autofs-5.1.7-fix-direct-mount-deadlock.patch + +Patch219: autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch +Patch220: autofs-5.1.7-add-missing-description-of-null-map-option.patch +Patch221: autofs-5.1.6-fix-empty-mounts-list-return-from-unlink_mount_tree.patch + +Patch222: autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch +Patch223: autofs-5.1.6-remove-intr-hosts-map-mount-option.patch + +Patch224: autofs-5.1.8-fix-kernel-mount-status-notification.patch +Patch225: autofs-5.1.8-fix-set-open-file-limit.patch +Patch226: autofs-5.1.8-improve-descriptor-open-error-reporting.patch +Patch227: autofs-5.1.6-fix-double-quoting-in-auto.smb.patch +Patch228: autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch + +Patch229: autofs-5.1.8-fix-root-offset-error-handling.patch +Patch230: autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch +Patch231: autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch +Patch232: autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch +Patch233: autofs-5.1.8-simplify-cache_add-a-little.patch +Patch234: autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch +Patch235: autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch +Patch236: autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch +Patch237: autofs-5.1.8-fix-sysconf-return-handling.patch +Patch238: autofs-5.1.4-make-umount_ent-recognise-forced-umount.patch +Patch239: autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch +Patch240: autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch + +Patch241: autofs-5.1.8-dont-use-initgroups-at-spawn.patch + +%if %{with_systemd} +BuildRequires: systemd-units +BuildRequires: systemd-devel +%endif +BuildRequires: gcc +BuildRequires: autoconf, openldap-devel, bison, flex, libxml2-devel +BuildRequires: cyrus-sasl-devel, openssl-devel module-init-tools util-linux +BuildRequires: e2fsprogs libtirpc-devel libsss_autofs libnsl2-devel +BuildRequires: pkgconfig +Conflicts: cyrus-sasl-lib < 2.1.23-9 +Requires: bash coreutils sed gawk grep module-init-tools /bin/ps +%if %{with_systemd} +Requires(post): systemd-sysv +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units +%else +Requires(post): /sbin/chkconfig +Requires(preun): /sbin/service +Requires(postun): /sbin/service +Requires(postun): /sbin/chkconfig +%endif +Summary(de): autofs daemon +Summary(fr): démon autofs +Summary(tr): autofs sunucu süreci +Summary(sv): autofs-daemon + +%description +autofs is a daemon which automatically mounts filesystems when you use +them, and unmounts them later when you are not using them. This can +include network filesystems, CD-ROMs, floppies, and so forth. + +%description -l de +autofs ist ein Dämon, der Dateisysteme automatisch montiert, wenn sie +benutzt werden, und sie später bei Nichtbenutzung wieder demontiert. +Dies kann Netz-Dateisysteme, CD-ROMs, Disketten und ähnliches einschließen. + +%description -l fr +autofs est un démon qui monte automatiquement les systèmes de fichiers +lorsqu'on les utilise et les démonte lorsqu'on ne les utilise plus. Cela +inclus les systèmes de fichiers réseau, les CD-ROMs, les disquettes, etc. + +%description -l tr +autofs, kullanýlan dosya sistemlerini gerek olunca kendiliðinden baðlar +ve kullanýmlarý sona erince yine kendiliðinden çözer. Bu iþlem, að dosya +sistemleri, CD-ROM'lar ve disketler üzerinde yapýlabilir. + +%description -l sv +autofs är en daemon som mountar filsystem när de använda, och senare +unmountar dem när de har varit oanvända en bestämd tid. Detta kan +inkludera nätfilsystem, CD-ROM, floppydiskar, och så vidare. + +%prep +%setup -q -n %{name}-%{version} +echo %{version}-%{release} > .version +%if %{with_systemd} + %define unitdir %{?_unitdir:/usr/lib/systemd/system} + %define systemd_configure_arg --with-systemd +%endif +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 + +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 + +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch77 -p1 +%patch78 -p1 +%patch79 -p1 +%patch80 -p1 +%patch81 -p1 +%patch82 -p1 + +%patch83 -p1 +%patch84 -p1 + +%patch85 -p1 +%patch86 -p1 +%patch87 -p1 +%patch88 -p1 + +%patch89 -p1 +%patch90 -p1 + +%patch91 -p1 +%patch92 -p1 +%patch93 -p1 +%patch94 -p1 +%patch95 -p1 +%patch96 -p1 +%patch97 -p1 +%patch98 -p1 + +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch110 -p1 +%patch111 -p1 +%patch112 -p1 +%patch113 -p1 +%patch114 -p1 +%patch115 -p1 +%patch116 -p1 +%patch117 -p1 +%patch118 -p1 +%patch119 -p1 + +%patch120 -p1 +%patch121 -p1 +%patch122 -p1 +%patch123 -p1 +%patch124 -p1 +%patch125 -p1 +%patch126 -p1 +%patch127 -p1 +%patch128 -p1 +%patch129 -p1 +%patch130 -p1 +%patch131 -p1 +%patch132 -p1 +%patch133 -p1 +%patch134 -p1 +%patch135 -p1 +%patch136 -p1 +%patch137 -p1 +%patch138 -p1 +%patch139 -p1 +%patch140 -p1 +%patch141 -p1 +%patch142 -p1 +%patch143 -p1 +%patch144 -p1 +%patch145 -p1 +%patch146 -p1 +%patch147 -p1 +%patch148 -p1 +%patch149 -p1 +%patch150 -p1 +%patch151 -p1 +%patch152 -p1 +%patch153 -p1 +%patch154 -p1 +%patch155 -p1 +%patch156 -p1 +%patch157 -p1 +%patch158 -p1 +%patch159 -p1 +%patch160 -p1 +%patch161 -p1 +%patch162 -p1 +%patch163 -p1 +%patch164 -p1 +%patch165 -p1 +%patch166 -p1 +%patch167 -p1 +%patch168 -p1 +%patch169 -p1 +%patch170 -p1 +%patch171 -p1 +%patch172 -p1 +%patch173 -p1 +%patch174 -p1 +%patch175 -p1 +%patch176 -p1 +%patch177 -p1 +%patch178 -p1 +%patch179 -p1 +%patch180 -p1 +%patch181 -p1 +%patch182 -p1 +%patch183 -p1 +%patch184 -p1 +%patch185 -p1 +%patch186 -p1 +%patch187 -p1 +%patch188 -p1 +%patch189 -p1 +%patch190 -p1 +%patch191 -p1 +%patch192 -p1 +%patch193 -p1 +%patch194 -p1 +%patch195 -p1 +%patch196 -p1 +%patch197 -p1 +%patch198 -p1 +%patch199 -p1 +%patch200 -p1 +%patch201 -p1 +%patch202 -p1 +%patch203 -p1 +%patch204 -p1 +%patch205 -p1 +%patch206 -p1 +%patch207 -p1 +%patch208 -p1 +%patch209 -p1 +%patch210 -p1 +%patch211 -p1 + +%patch212 -p1 +%patch213 -p1 +%patch214 -p1 +%patch215 -p1 +%patch216 -p1 +%patch217 -p1 +%patch218 -p1 + +%patch219 -p1 +%patch220 -p1 +%patch221 -p1 + +%patch222 -p1 +%patch223 -p1 + +%patch224 -p1 +%patch225 -p1 +%patch226 -p1 +%patch227 -p1 +%patch228 -p1 + +%patch229 -p1 +%patch230 -p1 +%patch231 -p1 +%patch232 -p1 +%patch233 -p1 +%patch234 -p1 +%patch235 -p1 +%patch236 -p1 +%patch237 -p1 +%patch238 -p1 +%patch239 -p1 +%patch240 -p1 +%patch241 -p1 + +%build +LDFLAGS=-Wl,-z,now +%configure --disable-mount-locking --enable-ignore-busy --with-libtirpc --without-hesiod %{?systemd_configure_arg:} +make initdir=%{_initrddir} DONTSTRIP=1 + +%install +%if %{with_systemd} +install -d -m 755 $RPM_BUILD_ROOT%{unitdir} +%else +mkdir -p -m755 $RPM_BUILD_ROOT%{_initrddir} +%endif +mkdir -p -m755 $RPM_BUILD_ROOT%{_sbindir} +mkdir -p -m755 $RPM_BUILD_ROOT%{_libdir}/autofs +mkdir -p -m755 $RPM_BUILD_ROOT%{_mandir}/{man5,man8} +mkdir -p -m755 $RPM_BUILD_ROOT/etc/sysconfig +mkdir -p -m755 $RPM_BUILD_ROOT/etc/auto.master.d + +make install mandir=%{_mandir} initdir=%{_initrddir} systemddir=%{unitdir} INSTALLROOT=$RPM_BUILD_ROOT +echo make -C redhat +make -C redhat +install -m 755 -d $RPM_BUILD_ROOT/misc +%if %{with_systemd} +# Configure can get this wrong when the unit files appear under /lib and /usr/lib +find $RPM_BUILD_ROOT -type f -name autofs.service -exec rm -f {} \; +install -m 644 redhat/autofs.service $RPM_BUILD_ROOT%{unitdir}/autofs.service +%define init_file_name %{unitdir}/autofs.service +%else +install -m 755 redhat/autofs.init $RPM_BUILD_ROOT%{_initrddir}/autofs +%define init_file_name /etc/rc.d/init.d/autofs +%endif +install -m 644 redhat/autofs.conf $RPM_BUILD_ROOT/etc/autofs.conf +install -m 644 redhat/autofs.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/autofs + +install -m 644 samples/auto.master $RPM_BUILD_ROOT/etc/auto.master +install -m 644 samples/auto.misc $RPM_BUILD_ROOT/etc/auto.misc +install -m 755 samples/auto.net $RPM_BUILD_ROOT/etc/auto.net +install -m 755 samples/auto.smb $RPM_BUILD_ROOT/etc/auto.smb +install -m 600 samples/autofs_ldap_auth.conf $RPM_BUILD_ROOT/etc/autofs_ldap_auth.conf + +%post +%if %{with_systemd} +%systemd_post %{name}.service +%else +if [ $1 -eq 1 ]; then + %{_sbindir}/sbin/chkconfig --add autofs +fi +%endif + +%preun +%if %{with_systemd} +%systemd_preun %{name}.service +%else +if [ $1 -eq 0 ] ; then + %{_sbindir}/service autofs stop > /dev/null 2>&1 || : + %{_sbindir}/chkconfig --del autofs +fi +%endif + +%postun +%if %{with_systemd} +%systemd_postun_with_restart %{name}.service +%else +if [ $1 -ge 1 ] ; then + %{_sbindir}/sbin/service autofs condrestart > /dev/null 2>&1 || : +fi +%endif + +%triggerun -- %{name} < 5.0.6-5 +# Save the current service runlevel info +# User must manually run systemd-sysv-convert --apply %{name} +# to migrate them to systemd targets +%{_bindir}/systemd-sysv-convert --save %{name} >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +%{_sbindir}/chkconfig --del %{name} >/dev/null 2>&1 || : +%{_bindir}/systemctl try-restart %{name}.service >/dev/null 2>&1 || : + +%files +%doc CREDITS INSTALL COPY* README* samples/ldap* samples/*.schema +%doc samples/am-utils-ldap-id.txt +%config %{init_file_name} +%config(noreplace,missingok) /etc/auto.master +%config(noreplace) /etc/autofs.conf +%config(noreplace,missingok) /etc/auto.misc +%config(noreplace,missingok) /etc/auto.net +%config(noreplace,missingok) /etc/auto.smb +%config(noreplace) /etc/sysconfig/autofs +%config(noreplace) /etc/autofs_ldap_auth.conf +%{_sbindir}/automount +%{_mandir}/*/* +%{_libdir}/autofs/ +%dir /etc/auto.master.d + +%changelog +* Wed May 18 2022 Ian Kent - 5.1.4-83 +- bz2069097 - libnss_sss: threads stuck at sss_nss_lock from initgroups + - dont use initgroups() at spawn. +- Resolves: rhbz#2069097 + +* Tue Feb 15 2022 Ian Kent - 5.1.4-82 +- bz2052122 - autofs attempts unmount on directory in use + - make umount_ent() recognise forced umount. + - remove nonstrict parameter from tree_mapent_umount_offsets(). + - fix handling of incorrect return from umount_ent(). +- Resolves: rhbz#2052122 + +* Mon Feb 14 2022 Ian Kent - 5.1.4-81 +- bz2033552 - Using -hosts option does not work after upgrading from 8.4 to 8.5 + - fix root offset error handling. + - fix nonstrict fail handling of last offset mount. + - dont fail on duplicate offset entry tree add. + - fix loop under run in cache_get_offset_parent(). + - simplify cache_add() a little. + - fix use after free in tree_mapent_delete_offset_tree(). + - fix memory leak in xdr_exports(). + - avoid calling pthread_getspecific() with NULL key_thread_attempt_id. + - fix sysconf(3) return handling. +- Resolves: rhbz#2033552 + +* Fri Dec 03 2021 Ian Kent - 5.1.4-77 +- bz2025509 - Autofs auto.smb awk script fails on shares with dollar signs + - fix double quoting in auto.smb. + - fix double quoting of ampersand in auto.smb as well. +- Resolves: rhbz#2025509 + +* Thu Dec 02 2021 Ian Kent - 5.1.4-76 +- bz2025963 - autofs service has not proper limits set to be able to handle many mounts + - fix set open file limit. + - improve descriptor open error reporting. +- Resolves: rhbz#2025963 + +* Wed Dec 01 2021 Ian Kent - 5.1.4-75 +- bz2023740 - autofs: send FAIL cmd/ioctl mess when encountering problems + with mount trigger + - fix kernel mount status notification. +- Resolves: rhbz#2023740 + +* Tue Jun 22 2021 Ian Kent - 5.1.4-74 +- bz1974309 - Removal of default intr mount option while using -hosts + and host.net + - remove intr hosts map mount option. + - fix previous changelog entry revision. +- Resolves: rhbz#1974309 + +* Fri Jun 18 2021 Ian Kent - 5.1.4-73 +- bz1973025 - /net mount being not cleanly mounted and unmounted + - correct patch, fix nonstrict offset mount fail handling. +- Related: rhbz#1973025 + +* Fri Jun 18 2021 Ian Kent - 5.1.4-72 +- bz1973025 - /net mount being not cleanly mounted and unmounted + - fix nonstrict offset mount fail handling. +- Resolves: rhbz#1973025 + +* Tue Jun 08 2021 Ian Kent - 5.1.4-71 +- bz1969210 - autofs: already mounted as other than autofs or failed to unlink + entry in tree + - fix empty mounts list return from unlink_mount_tree(). +- Resolves: rhbz#1969210 + +* Tue Jun 01 2021 Ian Kent - 5.1.4-70 +- bz1965862 - A recent Coverity change can cause an infinit loop on map reload + - fix lookup_prune_one_cache() refactoring change. +- bz1963129 - auto.master manpage doesn't mention -null or other built-in maps + - add missing desciption of null map option. +- Resolves: rhbz#1965862 rhbz#1963129 + +* Wed May 19 2021 Ian Kent - 5.1.4-69 +- bz1961492 - autofs: regression in offset ordering + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. + - fix direct mount deadlock. +- Resolves: rhbz#1961492 + +* Mon May 10 2021 Ian Kent - 5.1.4-68 +- bz1958487 - autofs amd mounts present in the configuration get umounted + on reload + - fix amd section mounts map reload. +- bz1958485 - autofs amd type host mounts fail for certain host names + - fix amd hosts mount expire. +- Resolves: rhbz#1958487 rhbz#1958485 + +* Thu May 06 2021 Ian Kent - 5.1.4-67 +- bz1954430 - Please, rebuild autofs-5.1.4-66.el8 + - rebuild with fixed binutils. +- Resolves: rhbz#1954430 + +* Tue Mar 16 2021 Ian Kent - 5.1.4-66 +- bz1912106 - Using -hosts option does not resolve host from /etc/hosts and mount + failes + - Coverity fixes + - add missing free in handle_mounts(). + - remove redundant if check. + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. +- Related: rhbz#1912106 + +* Tue Mar 16 2021 Ian Kent - 5.1.4-65 +- bz1912106 - Using -hosts option does not resolve host from /etc/hosts and mount + failes + - fix unapplied patch. + - remove unused variable from get_exports(). +- Related: rhbz#1912106 + +* Tue Mar 16 2021 Ian Kent - 5.1.4-64 +- bz1912106 - Using -hosts option does not resolve host from /etc/hosts and mount + failes + # Dependendant patches for expire improvement series. + - use defines for expire type. + - remove unused function dump_master(). + - fix additional typing errors. + - make bind mounts propagation slave by default. + - fix browse dir not re-created on symlink expire. + # Expire improvement series. + - update list.h. + - add hashtable implementation. + - change mountpoint to mp in struct ext_mount. + - make external mounts independent of amd_entry. + - make external mounts use simpler hashtable. + - add a hash index to mnt_list. + - use mnt_list for submounts. + - use mnt_list for amdmounts. + - make umount_autofs() static. + - remove force parameter from umount_all(). + - fix remount expire. + - fix stale offset directories disable mount. + - use struct mnt_list to track mounted mounts. + - use struct mnt_list mounted list for expire. + - remove unused function tree_get_mnt_list(). + - only add expre alarm for active mounts. + - move submount check into conditional_alarm_add(). + - move lib/master.c to daemon/master.c. + - use master_list_empty() for list empty check. + - add helper to construct mount point path. + # Additional fixes. + - add xdr_exports(). + - remove mount.x and rpcgen dependencies. + - dont use realloc in host exports list processing. + - use sprintf() when constructing hosts mapent. + - fix mnts_remove_amdmount() uses wrong list. + - eliminate cache_lookup_offset() usage. + - fix is mounted check on non existent path. + - simplify cache_get_parent(). + - set offset parent in update_offset_entry(). + - remove redundant variables from mount_autofs_offset(). + - remove unused parameter form do_mount_autofs_offset(). + - refactor umount_multi_triggers(). + - eliminate clean_stale_multi_triggers(). + - simplify mount_subtree() mount check. + - fix mnts_get_expire_list() expire list construction. + - fix inconsistent locking in umount_subtree_mounts(). + - fix return from umount_subtree_mounts() on offset list delete. + - pass mapent_cache to update_offset_entry(). + - fix inconsistent locking in parse_mount(). + - remove unused mount offset list lock functions. + - eliminate count_mounts() from expire_proc_indirect(). + - eliminate some strlen calls in offset handling. + - don't add offset mounts to mounted mounts table. + - reduce umount EBUSY check delay. + - cleanup cache_delete() a little. + - rename path to m_offset in update_offset_entry(). + - don't pass root to do_mount_autofs_offset(). + - rename tree implementation functions. + - fix program map multi-mount lookup after mount fail. + - add some multi-mount macros. + - remove unused functions cache_dump_multi() and cache_dump_cache(). + - add a len field to struct autofs_point. + - make tree implementation data independent. + - add mapent tree implementation. + - add tree_mapent_add_node(). + - add tree_mapent_delete_offsets(). + - add tree_mapent_traverse_subtree(). + - fix mount_fullpath(). + - add tree_mapent_cleanup_offsets(). + - add set_offset_tree_catatonic(). + - add mount and umount offsets functions. + - switch to use tree implementation for offsets. + - remove obsolete functions. + - remove redundant local var from sun_mount(). + - use mount_fullpath() in one spot in parse_mount(). + - pass root length to mount_fullpath(). + - remove unused function master_submount_list_empty(). + - move amd mounts removal into lib/mounts.c. + - check for offset with no mount location. + - remove mounts_mutex. +- Resolves: rhbz#1912106 + +* Fri Nov 27 2020 Ian Kent - 5.1.4-48 +- bz1892184 - autofs: return a connection failure until maps have been fetched + - fix lookup_nss_read_master() nsswicth check return. + - fix typo in open_sss_lib(). + - fix sss_master_map_wait timing. + - add sss ECONREFUSED return handling. + - use mapname in sss context for setautomntent(). + - add support for new sss autofs proto version call. + - fix retries check in setautomntent_wait(). + - refactor sss setautomntent(). + - improve sss setautomntent() error handling. + - refactor sss getautomntent(). + - improve sss getautomntent() error handling. + - sss introduce calculate_retry_count() function. + - move readall into struct master. + - sss introduce a flag to indicate map being read. + - update sss timeout documentation. + - refactor sss getautomntbyname(). + - improve sss getautomntbyname() error handling. + - use a valid timeout in lookup_prune_one_cache(). + - dont prune offset map entries. + - simplify sss source stale check. +- Resolves: rhbz#1892184 + +* Wed Nov 04 2020 Ian Kent - 5.1.4-47 +- bz1887681 - automount force unlink option (-F) does not work as expected + on autofs-5.0.7-109.el7 + - fix direct mount unlink_mount_tree() path. + - fix unlink mounts umount order. + - fix incorrect logical compare in unlink_mount_tree(). + - use bit flag for force unlink mounts. + - improve force unlink mounts option description. + - remove logpri fifo on autofs mount fail. + - add force unlink mounts and exit option. + - cleanup stale logpri fifo pipes on unlink and exit. +- Resolves: rhbz#1887681 + +* Wed Nov 04 2020 Ian Kent - 5.1.4-46 +- bz1664561 - incorrect of start service command in autofs man page + - actually apply fix patch. +- fix dates and recent status messages in changelog. +-Related: rhbz#1664561 rhbz#1858742 + +* Tue Nov 03 2020 Ian Kent - 5.1.4-45 +- bz1664561 - incorrect of start service command in autofs man page + - fix incorrect systemctl command syntax in autofs(8). +-Resolves: rhbz#1664561 + +* Mon Nov 02 2020 Ian Kent - 5.1.4-44 +- bz1858742 - autofs share doesn't mount when using nobind over RDMA where + nfs-server and nfs-client are the same systems. + - mount_nfs.c fix local rdma share not mounting. +-Resolves: rhbz#1858742 + +* Mon Jun 15 2020 Ian Kent - 5.1.4-43 +- bz1841456 - automount program crashes with "malloc(): invalid next size + (unsorted) + - fix autofs mount options construction. +-Related: rhbz#1841456 + +* Tue Jun 02 2020 Ian Kent - 5.1.4-42 +- bz1841456 - automount program crashes with "malloc(): invalid next size + (unsorted) + - initialize struct addrinfo for getaddrinfo() calls. + - fix quoted string length calc in expandsunent(). +-Resolves: rhbz#1841456 + +* Mon May 18 2020 Ian Kent - 5.1.4-41 +- bz1835547 - [RHEL8]autofs cannot mount samba/cifs shares that end with a + dollar sign + - fix trailing dollar sun entry expansion. +- Resolves: rhbz#1835547 + +* Fri Feb 21 2020 Ian Kent - 5.1.4-40 +- fix incorrect changelog entry for bug 1802251. +- Related: rhbz#1802251 + +* Mon Feb 17 2020 Ian Kent - 5.1.4-39 +- bz1802251 - Autofs will only mount share once if sss is first ini + nsswitch.conf + - fix a regression with map instance lookup. +- Resolves: rhbz#1802251 + +* Mon Nov 25 2019 Ian Kent - 5.1.4-38 +- bz1660145 - autofs.schema doesn't work in RHEL8 + - update spec file doc inclusions for schema definition update. +- Related: rhbz#1660145 + +* Mon Nov 25 2019 Ian Kent - 5.1.4-37 +- bz1660145 - autofs.schema doesn't work in RHEL8 + - update ldap READMEs and schema definitions. +- Resolves: rhbz#1660145 + +* Tue Nov 12 2019 Ian Kent - 5.1.4-36 +- bz1743442 - getmntent returns additional "-hosts" entries when + automounter is used with "hosts" map (userspace part) + - also use strictexpire for offsets (mounts). + - change expire type naming to better reflect usage. + - remove unused function has_fstab_option(). + - remove unused function reverse_mnt_list(). + - remove a couple of old debug messages. + - fix amd entry memory leak. + - fix unlink_mount_tree() not umounting mounts. + - add ignore mount option. + - use ignore option for offset mounts as well. + - add config option for "ignore" mount option. + - use bit flags for autofs mount types in mnt_list. + - use mp instead of path in mnt_list entries. + - always use PROC_MOUNTS to make mount lists. + - add glibc getmntent_r(). + - use local getmntent_r in table_is_mounted(). + - refactor unlink_active_mounts() in direct.c. + - don't use tree_is_mounted() for mounted checks. + - use single unlink_umount_tree() for both direct and indirect mounts. + - move unlink_mount_tree() to lib/mounts.c. + - use local_getmntent_r() for unlink_mount_tree(). + - use local getmntent_r() in get_mnt_list(). + - use local getmntent_r() in tree_make_mnt_list(). + - fix missing initialization of autofs_point flags. +- Resolves: rhbz#1743442 + +* Thu Jun 13 2019 Ian Kent - 5.1.4-35 +- bz1681956 - autofs changes blocked until gating tests are added + - correct test name in gating.yaml. +- Related: rhbz#1681956 + +* Thu Jun 13 2019 Ian Kent - 5.1.4-34 +- bz1681956 - autofs changes blocked until gating tests are added + - add gating.yaml for manual gate testing. +- Related: rhbz#1681956 + +* Tue May 21 2019 Ian Kent - 5.1.4-33 +- bz1689466 - Sanitize autofs logging + - make expire remaining log level debug. +- bz1685805 - autofs doesn't expand macros in amd map selectors + - allow period following macro in selector value. + - fix macro expansion in selector values. +- Resolves: rhbz#1689466 rhbz#1685805 + +* Mon Apr 29 2019 Ian Kent - 5.1.4-32 +- bz1703876 - [RFE] Enable additional logging information for autofs + - add NULL check for get_addr_string() return. + - use malloc(3) in spawn.c. + - add mount_verbose configuration option. + - optionally log mount requestor process info. + - log mount call arguments if mount_verbose is set. +- Resolves: rhbz#1703876 + +* Mon Apr 29 2019 Ian Kent - 5.1.4-31 +- bz1689467 - path_resolution on an autofs managed path resets the timer. Can + this be made configurable? + - support strictexpire mount option. +- Resolves: rhbz#1689467 + +* Tue Apr 23 2019 Ian Kent - 5.1.4-30 +- bz1689469 - [autofs] The log no longer print PID of automount process + - remove autofs4 module load code. + - add NULL check in prepare_attempt_prefix(). + - update build info with systemd. + - use flags for startup boolean options. + - move close stdio descriptors to become_daemon(). + - add systemd service command line option. +- Resolves: rhbz#1689469 + +* Mon Dec 03 2018 Ian Kent - 5.1.4-29 +- bz1654541 - autofs crash when parsing master map + - fix hesiod string check in master_parse(). +- Resolves: rhbz#1654541 + +* Fri Oct 19 2018 Ian Kent - 5.1.4-28 +- bz1638487 - Drop dependency on hesiod + - actually update the spec file with the hesiod removal. +- Related: rhbz#1638487 + +* Fri Oct 19 2018 Ian Kent - 5.1.4-27 +- bz1638487 - Drop dependency on hesiod + - better handle hesiod support not built in. + - exclude hesiod support from configure options + - remove hesiod depends. +- Resolves: rhbz#1638487 + +* Thu Sep 27 2018 Ian Kent - 5.1.4-26 +- bz1630190 - yum update hanging while restarting autofs + - fix incorrect locking in sss lookup. +- bz1630194 - after upgrading to autofs-5.0.7-83.el7.x86_64 on + RHEL 7 clients, amd maps /defaults key mount options are no + longer working + - fix amd parser opts option handling. +- Resolves: rhbz#1630190 rhbz#1630194 + +* Fri Aug 24 2018 Ian Kent - 5.1.4-24 +- bz1621938 - autofs can no longer get maps from IPA server + - fix use after free in parse_ldap_config(). +- Resolves: rhbz#1621938 + +* Tue Aug 14 2018 Ian Kent - 5.1.4-23 +- bz1615782 - autofs master map age is incorrectly set + - fix age setting at startup. +- Resolves: rhbz#1615782 + +* Tue Aug 14 2018 Ian Kent - 5.1.4-22 +- bz1613630 - On Red Hat 7.x systems if you try to access local + filesystems using the automounter through /net then the shell + and mount could lock up *if* the filesystem your accessing is + double exported. + - set bind mount as propagation slave. + - add master map pseudo options for mount propagation. +- Resolves: rhbz#1613630 + +* Mon Aug 13 2018 Ian Kent - 1:5.1.4-21 +- bz1611866 - autofs reload is unable to activate new map entries, + it is autofs restart which shows new map entries. + - fix update_negative_cache() map source usage. +- bz1613621 - [autofs]Removed entries still can be accessed + - mark removed cache entry negative. +- Resolves: rhbz#1611866 rhbz#1613621 + +* Mon Aug 06 2018 Ian Kent - 1:5.1.4-20 +- bz1612565 - Man page scan results for autofs + - fix program usage message. +- Resolves: rhbz#1612565 + +* Fri Jul 20 2018 Ian Kent - 1:5.1.4-19 +- bz1602447 - Please review important issues found by covscan in + "autofs-5.1.4-18.el8+7" + - covarity fixes. +-Resolves: rhbz#1602447 + +* Mon Jun 25 2018 Ian Kent - 1:5.1.4-18 +- bz1593492 - Ignore trailing slashes at the end of executable maps in + auto.master config file + - add-man page note about extra slashes in paths +- Resolves: rhbz#1593492 + +* Thu Jun 21 2018 Ian Kent - 1:5.1.4-17 +- bz1577700 - automount leaves FDs in half-open state + - fix fd leak in rpc_do_create_client(). +- Resolves: rhbz#1577700 + +* Mon Mar 26 2018 Ian Kent - 1:5.1.4-16 +- tiny patch for autofs typo and possible bug. +- add units After line to include statd service. +- use systemd sd_notify() at startup. +- add "BuildRequires: systemd-devel". +- fix NFS version mask usage. +- fix incorrect date in changelog. + +* Tue Mar 06 2018 Ian Kent - 1:5.1.4-14 +- improve hostname lookup error logging. + +* Tue Mar 06 2018 Ian Kent - 1:5.1.4-13 +- fix install permissions of auto.net and auto.smb. + +* Mon Feb 19 2018 Ian Kent - 1:5.1.4-12 +- dont allow trailing slash in master map mount points. +- fix libresolv configure check. +- add fedfs-getsrvinfo.c. +- add mount.fedfs.c. +- add fedfs-map-nfs4.c +- add conditional inclusion of fedfs binaries. +- add an example fedfs master map entry to the installed master map. + +* Fri Feb 09 2018 Igor Gnatenko - 1:5.1.4-11 +- Escape macros in %%changelog + +* Fri Feb 9 2018 Ian Kent - 1:5.1.4-10 +- clean up obsolete spec file directives. + +* Wed Feb 7 2018 Ian Kent - 1:5.1.4-9 +- fix install mode of autofs_ldap_auth.conf. + +* Tue Feb 6 2018 Ian Kent - 1:5.1.4-8 +- add missing BuildRequires. + +* Mon Feb 5 2018 Ian Kent - 1:5.1.4-7 +- add error handling for ext_mount_add(). +- account for recent libnsl changes. +- use_hostname_for_mounts shouldn't prevent selection among replicas. +- fix monotonic_elapse. +- Makefiles.rules: remove 'samples' from SUBDIRS. + +* Thu Feb 1 2018 Ian Kent - 1:5.1.4-6 +- dont use array for path when not necessary. +- fix prefix option handling in expand_entry(). +- fix sublink option not set from defaults. +- fix error return in do_nfs_mount(). + +* Wed Jan 10 2018 Ian Kent - 1:5.1.4-5 +- actually apply fix use after free in do_master_list_reset(). +- fix deadlock in dumpmaps. +- fix rpcgen dependency problem. + +* Fri Dec 22 2017 Ian Kent - 1:5.1.4-4 +- fix use after free in do_master_list_reset(). + +* Wed Dec 20 2017 Ian Kent - 1:5.1.4-3 +- fix email in last two changelog entries. + +* Tue Dec 19 2017 Ian Kent - 1:5.1.4-2 +- fix flag file permission. +- fix directory create permission. + +* Tue Dec 19 2017 Ian Kent - 1:5.1.4-1 +- Update to upstream 5.1.4 release. + +* Tue Nov 07 2017 Igor Gnatenko - 1:5.1.3-5 +- Remove old crufty coreutils requires + +* Wed Aug 02 2017 Fedora Release Engineering - 1:5.1.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1:5.1.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon May 29 2017 Ian Kent - 1:5.1.3-2 +- Fix "Source:" URL and changelog anotations. + +* Mon May 29 2017 Ian Kent - 1:5.1.3-1 +- update to upstream 5.1.3 release. + +* Fri Feb 10 2017 Fedora Release Engineering - 1:5.1.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Wed Jun 15 2016 Fedora Release Engineering - 1:5.1.2-1 +- update to upstream 5.1.2 release. + +* Wed Feb 03 2016 Fedora Release Engineering - 1:5.1.1-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 20 2016 Ian Kent - 1:5.1.1-21 +- add some new upstream memory leak and use after free bug fixes. + +* Wed Jan 20 2016 Ian Kent - 1:5.1.1-20 +- fix incorrect committer changelog entries. +- add current released upstream patches. + +* Wed Nov 04 2015 Ian Kent - 1:5.1.1-7 +- revert fix libtirpc name clash patch (an old 5.0.6 patch). + +* Wed Nov 04 2015 Ian Kent - 1:5.1.1-6 +- remove unnecessary nfs-utils BuildRequires (bz1277669). + +* Mon Nov 02 2015 Ian Kent - 1:5.1.1-5 +- fix fix gcc5 complaints. +- update libtirpc workaround for new soname. + +* Sun Nov 01 2015 Kalev Lember - 1:5.1.1-4 +- Rebuilt for libtirpc soname bump + +* Wed Jun 17 2015 Fedora Release Engineering - 1:5.1.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Jun 12 2015 Ian Kent - 1:5.1.1-2 +- add build requires for gcc. + +* Thu Apr 23 2015 Ian Kent - 1:5.1.1-1 +- Update to autofs-5.1.1. + +* Mon Mar 23 2015 Ian Kent - 1:5.1.0-12 +- fix gcc5 complaints (bz1204685). + +* Mon Mar 23 2015 Peter Robinson 1:5.1.0-11 +- Drop ancient 2.6 kernel patches from docs + +* Wed Jan 21 2015 Ian Kent - 1:5.1.0-10 +- make negative cache update consistent for all lookup modules. +- ensure negative cache isn't updated on remount. +- dont add wildcard to negative cache. +- make service want network-online (bz1071591). + +* Tue Nov 18 2014 Ian Kent - 1:5.1.0-9 +- fix custom autofs.conf not being installed. +- init qdn before use in get_query_dn(). +- fix typo in update_hosts_mounts(). +- fix hosts map update on reload. + + +* Fri Oct 17 2014 Ian Kent - 1:5.1.0-8 +- fix fix master map type check. + +* Wed Oct 15 2014 Ian Kent - 1:5.1.0-7 +- force disable browse mode for amd format maps. +- fix hosts map options check in lookup_amd_instance(). +- fix memory leak in create_client(). +- fix memory leak in get_exports(). +- fix memory leak in get_defaults_entry(). +- fix out of order clearing of options buffer. +- fix reset amd lexer scan buffer. +- ignore multiple commas in options strings. +- fix typo in flagdir configure option. +- clarify multiple mounts description. +- gaurd against incorrect umount return. +- update man page autofs(8) for systemd. +- remove ancient kernel Requires. + +* Fri Aug 15 2014 Fedora Release Engineering - 1:5.1.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jul 8 2014 Ian Kent - 1:5.1.0-5 +- rename two incorrectly named patches. +- add missing change entry to another patch. + +* Mon Jul 7 2014 Ian Kent - 1:5.1.0-4 +- add mutex call return check in defaults.c. + +* Mon Jul 7 2014 Ian Kent - 1:5.1.0-3 +- fix compile error in defaults.c. +- add serialization to sasl init. +- dont allocate dev_ctl_ops too early. +- fix incorrect round robin host detection. +- fix race accessing qdn in get_query_dn(). +- fix leak in cache_push_mapent(). +- fix config entry read buffer not checked. +- fix FILE pointer check in defaults_read_config(). +- fix memory leak in conf_amd_get_log_options(). +- fix signed comparison in inet_fill_net(). +- fix buffer size checks in get_network_proximity(). +- fix leak in get_network_proximity(). +- fix buffer size checks in merge_options(). +- check amd lex buffer len before copy. +- add return check in ldap check_map_indirect(). +- check host macro is set before use. +- check options length before use in parse_amd.c. +- fix some out of order evaluations in parse_amd.c. +- fix copy and paste error in dup_defaults_entry(). + +* Sat Jun 07 2014 Fedora Release Engineering - 1:5.1.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu Jun 5 2014 Ian Kent - 1:5.1.0-1 +- update to upstream release, 5.1.0. + - fix reset flex scan buffer on init. + - fix fix negative status being reset on map read. + - fix out of order amd timestamp lookup. + - fix ldap default schema config. + - fix ldap default master map name config. + - fix map format init in lookup_init(). + - fix incorrect max key length in defaults get_hash(). + - fix xfn sets incorrect lexer state. + - fix old style key lookup. + - fix expire when server not responding. + - fix ldap_uri config update. + - fix typo in conf_load_autofs_defaults(). + - fix hash on confg option add and delete. + - add plus to path match pattern. + - fix multi entry ldap option handling. + - cleanup options in amd_parse.c. + - allow empty value for some map options. + - allow empty value in macro selectors. + +* Sun Apr 13 2014 Ian Kent - 1:5.1.0-0.beta1.1 +- amd lookup update lookup ldap to handle amd keys + - inadvertantly drop from initial series. +- amd lookup update lookup hesiod to handle amd keys + - inadvertantly drop from initial series. +- fix wildcard key lookup. +- check for non existent negative entries in lookup_ghost(). + +* Wed Apr 2 2014 Ian Kent - 1:5.1.0-0.beta1 +- Update to autofs-5.0.1-beta1. + +* Wed Feb 19 2014 Ian Kent - 1:5.0.8-6 +- fix portmap not trying proto v2. + +* Tue Dec 24 2013 Ian Kent - 1:5.0.8-5 +- fix ipv6 link local address handling. +- fix fix ipv6 libtirpc getport. +- get_nfs_info() should query portmapper if port is not given. +- fix rpc_portmap_getport() proto not set. + +* Mon Nov 25 2013 Ian Kent - 1:5.0.8-4 +- allow --with-systemd to take a path arg. +- fix WITH_LIBTIRPC function name. +- fix ipv6 libtirpc getport (bz1033918). + +* Thu Nov 7 2013 Ian Kent - 1:5.0.8-3 +- fix undefined authtype_requires_creds err if ldap enabled but without sasl. +- fix master map type check. +- fix task manager not getting signaled. + +* Mon Oct 21 2013 Ian Kent - 1:5.0.8-2 +- remove now unused patch files (bz1020242). + +* Mon Oct 21 2013 Ian Kent - 1:5.0.8-1 +- update to upstream version 5.0.8 (bz1020242). + +* Sat Aug 03 2013 Fedora Release Engineering - 1:5.0.7-29 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Sat Jul 13 2013 Ian Kent - 1:5.0.7-28 +- add after sssd dependency to unit file (bz984089). + +* Sat Jul 13 2013 Ian Kent - 1:5.0.7-27 +- fix a couple of compiler warnings. + +* Fri Jul 12 2013 Ian Kent - 1:5.0.7-26 +- link with full reloc options. + +* Fri Jul 12 2013 Ian Kent - 1:5.0.7-25 +- fix default path used for unitdir. +- fix changelog inconsistent dates. + +* Wed Jul 10 2013 Ian Kent - 1:5.0.7-24 +- check for protocol option. +- use ulimit max open files if greater than internal maximum. + +* Fri Jun 28 2013 Ian Kent - 1:5.0.7-23 +- fix add null check in parse_server_string() (bz979155). + +* Wed Jun 19 2013 Ian Kent - 1:5.0.7-22 +- misc man page fixes (bz948517). + +* Wed Jun 12 2013 Ian Kent - 1:5.0.7-21 +- fix probe each nfs version in turn for singleton mounts (bz973537). + +* Tue Jun 11 2013 Ian Kent - 1:5.0.7-20 +- fix master map mount options matching. +- fix master map bogus keywork match. +- fix fix map entry duplicate offset detection. +- add a number of fixes based on a Covarity report. + +* Mon May 27 2013 Ian Kent - 1:5.0.7-19 +- dont probe rdma mounts. + +* Fri May 24 2013 Ian Kent - 1:5.0.7-17 +- fix interface address null check. + +* Mon May 13 2013 Ian Kent - 1:5.0.7-16 +- make dump maps check for duplicate indirect mounts (bz961312). +- document allowed map sources in auto.master(5) (bz961312). +- add enable sloppy mount option to configure. + +* Sun Apr 28 2013 Ian Kent - 1:5.0.7-14 +- fix syncronize of handle_mounts() shutdown. +- fix submount tree not all expiring. + +* Tue Mar 26 2013 Ian Kent - 1:5.0.7-13 +- fix some automount(8) typos (bz664178). + +* Tue Mar 12 2013 Ian Kent - 1:5.0.7-12 +- dont fail on master map self include. +- fix wildcard multi map regression. +- fix file descriptor leak when reloading the daemon. +- depricate nosymlink pseudo option. +- add symlink pseudo option. +- update kernel include files. +- fix requires in spec file. +- fix libtirpc build option. +- fix systemd unidir in spec file. +- document browse option in man page. +- fix automounter support on parisc. + +* Wed Feb 13 2013 Fedora Release Engineering - 1:5.0.7-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Jan 21 2013 Ian Kent - 1:5.0.7-10 +- fix submount offset delete. +- fix init script status return. +- fix use get_proximity() without libtirpc. +- don't use dirent d_type to filter out files in scandir(). +- don't schedule new alarms after readmap. +- use numeric protocol ids instead of protoent structs. +- lib/defaults.c: use WITH_LDAP conditional around LDAP types. +- make yellow pages support optional. +- modules/replicated.c: use sin6_addr.s6_addr32. +- workaround missing GNU versionsort extension. + +* Tue Nov 20 2012 Ian Kent - 1:5.0.7-9 +- fix nobind man page description. + +* Tue Nov 20 2012 Ian Kent - 1:5.0.7-8 +- fix map entry duplicate offset detection. +- Allow nsswitch.conf to not contain "automount:" lines. + +* Thu Oct 18 2012 Ian Kent - 1:5.0.7-7 +- use spec file systemd unit file location. + +* Thu Oct 18 2012 Ian Kent - 1:5.0.7-6 +- fix recursive mount deadlock. +- increase file map read buffer size. +- handle new location of systemd. + +* Tue Oct 16 2012 Ian Kent - 1:5.0.7-5 +- configure: allow cross compilation update. +- fix date in changelog entry. + +* Mon Oct 15 2012 Ian Kent - 1:5.0.7-4 +- include usage in usage message. +- dont wait forever to restart. +- add option description to man page. +- fix null map entry order handling. +- make description of default MOUNT_WAIT setting clear. +- configure.in: allow cross compilation. +- README: update mailing list subscription info. +- allow non root user to check status. + +* Mon Sep 10 2012 Ian Kent - 1:5.0.7-3 +- fix nobind sun escaped map entries. +- fix use cache entry after free mistake. +- fix ipv6 proximity calculation. +- fix parse buffer initialization. +- fix typo in automount(8). + +* Mon Aug 27 2012 Ian Kent - 1:5.0.7-2 +- update systemd scriplet macros (bz850040). + +* Wed Jul 25 2012 Ian Kent - 1:5.0.7-1 +- Update to upstream version 5.0.7. + +* Wed Jul 25 2012 Ian Kent - 1:5.0.6-24 +- fix changelog message commit dates. + +* Wed Jul 18 2012 Fedora Release Engineering - 1:5.0.6-23 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Jul 16 2012 Ian Kent - 1:5.0.6-21 +- fix systemd argument passing. +- fix get_nfs_info() can incorrectly fail. +- fix offset directory removal. + +* Tue Jul 3 2012 Ian Kent - 1:5.0.6-21 +- fix fix LDAP result leaks on error paths. +- report map not read when debug logging. +- duplicate parent options for included maps. +- update ->timeout() function to not return timeout. +- move timeout to map_source. +- fix kernel verion check of version components. +- dont retry ldap connect if not required. +- check if /etc/mtab is a link to /proc/self/mounts. +- fix nfs4 contacts portmap. +- make autofs wait longer for shutdown. +- fix sss map age not updated. +- fix remount deadlock. +- fix umount recovery of busy direct mount. +- fix offset mount point directory removal. +- remove move mount code and configure option. +- fix remount of multi mount. +- fix devce ioctl alloc path check. +- refactor hosts lookup module. +- remove cache update from parse_mount(). +- add function to delete offset cache entry. +- allow update of multi mount offset entries. +- add hup signal handling to hosts map. + +* Tue May 22 2012 Ian Kent - 1:5.0.6-19 +- fix libtirpc name clash (bz821847). + +* Tue May 22 2012 Ian Kent - 1:5.0.6-18 +- update patch fix initialization in rpc create_client() (bz821847). + +* Wed May 16 2012 Ian Kent - 1:5.0.6-17 +- fix initialization in rpc create_client() (bz821847). + +* Tue May 1 2012 Ian Kent - 1:5.0.6-16 +- add libsss_autofs as a build dependency. + +* Tue May 1 2012 Ian Kent - 1:5.0.6-15 +- fix typo in libtirpc file name. +- fix rework error return handling in rpc code. +- allow MOUNT_WAIT to override probe. +- improve UDP RPC timeout handling. +- fix segfault in get_query_dn(). +- use strtok_r() in linux_version_code(). +- fix sss wildcard match. +- fix dlopen() error handling in sss module. +- fix configure string length tests for sss library. + +* Wed Feb 29 2012 Ian Kent - 1:5.0.6-14 +- fix function to check mount.nfs version. + +* Sun Feb 26 2012 Ian Kent - 1:5.0.6-13 +- fix error in %%post scriplet. + +* Fri Feb 24 2012 Ian Kent - 1:5.0.6-12 +- ignore duplicate exports in auto.net. +- add kernel verion check function. +- add function to check mount.nfs version. +- reinstate singleton mount probe. +- rework error return handling in rpc code. +- catch EHOSTUNREACH and bail out early. +- systemd support fixes. +- fix segmentation fault in do_remount_indirect(). + +* Thu Feb 9 2012 Ian Kent - 1:5.0.6-11 +- fix fuzz in CHANGELOG hunk when applying patch26. + +* Tue Feb 7 2012 Ian Kent - 1:5.0.6-10 +- fix rpc build error. +- add sss lookup module. +- teach automount about sss source. + +* Mon Jan 23 2012 Ian Kent - 1:5.0.6-9 +- add correct patch for "fix improve mount location error reporting". +- add correct patch for "fix fix wait for master source mutex". + +* Mon Jan 23 2012 Ian Kent - 1:5.0.6-8 +- fix fix wait for master source mutex. +- fix improve mount location error reporting (bz783496). + +* Thu Jan 12 2012 Fedora Release Engineering - 1:5.0.6-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Dec 9 2011 Ian Kent - 1:5.0.6-6 +- remove empty command line arguments (passed by systemd). + +* Mon Dec 5 2011 Ian Kent - 1:5.0.6-5 +- fix ipv6 name lookup check. +- fix ipv6 rpc calls. +- fix ipv6 configure check. +- add piddir to configure. +- add systemd unit support. +- fix MNT_DETACH define. + +* Mon Dec 5 2011 Ian Kent - 1:5.0.6-4 +- fix lsb service name in init script 2 (bz712504). + +* Tue Nov 8 2011 Ian Kent - 1:5.0.6-3 +- improve mount location error reporting. +- fix paged query more results check. +- fix dumpmaps not reading maps. +- fix result null check in read_one_map(). +- Fix LDAP result leaks on error paths. +- code analysis fixes 1. +- fix not bind mounting local filesystem. +- update dir map-type patch for changed patch order. +- fix wait for master source mutex. +- fix submount shutdown race +- fix fix map source check in file lookup. +- add disable move mount configure option. + +* Wed Jul 6 2011 Ian Kent - 1:5.0.6-2 +- add missing spec file entries for dir-type change (bz719208). + +* Mon Jul 4 2011 Ian Kent - 1:5.0.6-1 +- update source to 5.0.6. +- fix ipv6 name for lookup fix. +- add dir map-type patch. + +* Tue Jun 14 2011 Ian Kent - 1:5.0.5-38 +- fix lsb service name in init script (bz692963). + +* Fri Mar 18 2011 Ian Kent - 1:5.0.5-37 +- replace GPLv3 code with GPLv2 equivalent. + +* Thu Mar 03 2011 Ian Kent - 1:5.0.5-36 +- use weight only for server selection. +- fix isspace() wild card substition. +- auto adjust ldap page size. +- fix prune cache valid check. +- fix mountd vers retry. +- fix expire race. +- add lsb force-reload and try-restart. + +* Mon Feb 07 2011 Fedora Release Engineering - 1:5.0.5-35 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Nov 23 2010 Ian Kent - 1:5.0.5-34.fc15 +- revert wait for master map to be available at start. + +* Mon Nov 22 2010 Ian Kent - 1:5.0.5-33.fc15 +- fix wait for master map to be available at start. + +* Mon Nov 8 2010 Ian Kent - 1:5.0.5-32.fc15 +- always read file maps mount lookup map read fix. +- fix direct map not updating on reread. +- add external bind method. +- fix add simple bind auth. +- add option to dump configured automount maps. +- wait for master map to be available at start. + +* Fri Aug 27 2010 Ian Kent - 1:5.0.5-31.fc15 +- fix status privilege error (bz627605). + +* Wed Aug 18 2010 Ian Kent - 1:5.0.5-30.fc15 +- fix restart not working (bz624694). + +* Wed Aug 11 2010 Ian Kent - 1:5.0.5-29 +- remove ERR_remove_state() openssl call. + +* Tue Aug 10 2010 Ian Kent - 1:5.0.5-28 +- remove extra read master map call. +- remove extra cache create call in master_add_map_source(). +- fix error handing in do_mount_indirect(). +- expire thread use pending mutex. +- explicity link against the Kerberos library. +- remove some log message duplication for verbose logging. + +* Mon May 24 2010 Ian Kent - 1:5.0.5-27.fc14 +- fix master map source server unavailable handling. +- add autofs_ldap_auth.conf man page. +- fix random selection for host on different network. +- make redhat init script more lsb compliant. +- don't hold lock for simple mounts. +- fix remount locking. +- fix wildcard map entry match. +- fix parse_sun() module init. +- dont check null cache on expire. +- fix null cache race. +- fix cache_init() on source re-read. +- fix mapent becomes negative during lookup. +- check each dc server individually. +- fix negative cache included map lookup. +- remove state machine timed wait. + +* Fri Apr 30 2010 Ian Kent - 1:5.0.5-26.fc14 +- remove URL tag as there is not official autofs wiki (bz529804). + +* Wed Apr 7 2010 Ian Kent - 1:5.0.5-25.fc14 +- make nfs4 default for replicated selection configuration (bz579949). +- add simple bind authentication option (bz579951). + +* Fri Mar 26 2010 Ian Kent - 1:5.0.5-24.fc14 +- fix add locality as valid ldap master map attribute (bz575863). + +* Wed Mar 17 2010 Ian Kent - 1:5.0.5-22 +- fix get query dn failure. +- fix ampersand escape in auto.smb. +- add locality as valid ldap master map attribute. + +* Wed Mar 17 2010 Ian Kent - 1:5.0.5-22 +- add Conflicts to ensure we get fixed cyrus-sasl-lib for rev 21 change. + +* Tue Feb 23 2010 Ian Kent - 1:5.0.5-21 +- add missing sasl mutex callbacks. + +* Thu Feb 11 2010 Ian Kent - 1:5.0.5-19 +- fix segfault upon reconnect cannot find valid base dn. + +* Mon Feb 1 2010 Ian Kent - 1:5.0.5-17 +- dont connect at ldap lookup module init. +- fix random selection option. +- fix disable timeout. +- fix strdup() return value check. + +* Tue Dec 8 2009 Ian Kent - 1:5.0.5-16 +- fix memory leak on reload (bz545137). + +* Fri Dec 4 2009 Ian Kent - 1:5.0.5-14 +- fix rpc fail on large export list (bz543023). + +* Mon Nov 30 2009 Ian Kent - 1:5.0.5-12 +- check for path mount location in generic module. +- dont fail mount on access fail. + +* Tue Nov 24 2009 Ian Kent - 1:5.0.5-10 +- fix pidof init script usage. + +* Mon Nov 23 2009 Ian Kent - 1:5.0.5-8 +- fix timeout in connect_nb(). + +* Mon Nov 16 2009 Ian Kent - 1:5.0.5-6 +- don't use master_lex_destroy() to clear parse buffer. +- make documentation for set-log-priority clearer. + +* Tue Nov 10 2009 Ian Kent - 1:5.0.5-5 +- fix ext4 "preen" fsck at mount. + +* Mon Nov 9 2009 Ian Kent - 1:5.0.5-4 +- fix stale initialization for file map instance patch was not applied. + +* Tue Nov 3 2009 Ian Kent - 1:5.0.5-3 +- fix stale initialization for file map instance. + +* Tue Oct 6 2009 Ian Kent - 1:5.0.5-2 +- fix included map read fail handling. +- refactor ldap sasl authentication bind to eliminate extra connect + causing some servers to reject the request. +- add mount wait parameter to allow timeout of mount requests to + unresponsive servers. +- special case cifs escape handling. +- fix libxml2 workaround configure. +- more code analysis corrections (and fix a typo in an init script). +- fix backwards #ifndef INET6. + +* Fri Sep 4 2009 Ian Kent - 1:5.0.5-1 +- update source to latest upstream version. + - this is essentially a consolidation of the patches already in this rpm. +- add dist tag to match latest RHEL-5 package tag format. + +* Thu Sep 3 2009 Ian Kent - 1:5.0.4-39 +- fix libxml2 non-thread-safe calls. +- fix direct map cache locking. +- fix patch "dont umount existing direct mount on reread" deadlock. + +* Fri Jul 24 2009 Fedora Release Engineering - 1:5.0.4-37 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri Jul 17 2009 Ian Kent - 1:5.0.4-34 +- fix typo in patch to allow dumping core. + +* Wed Jul 15 2009 Ian Kent - 1:5.0.4-32 +- fix an RPC fd leak. +- don't block signals we expect to dump core. +- fix pthread push order in expire_proc_direct(). + +* Fri Jun 12 2009 Ian Kent - 1:5.0.4-30 +- fix incorrect dclist free. +- srv lookup handle endianness. +- fix bug introduced by library reload changes which causes autofs to + not release mount thread resources when using submounts. +- fix notify mount message path. +- try harder to work out if we created mount point at remount. +- fix double free in do_sasl_bind(). +- manual umount recovery fixes. +- fix map type info parse error. + +* Mon May 18 2009 Ian Kent - 1:5.0.4-28 +- use intr option as hosts mount default. +- sync kernel includes with upstream kernel. +- dont umount existing direct mount on master re-read. +- fix incorrect shutdown introduced by library relaod fixes. +- improve manual umount recovery. +- dont fail on ipv6 address when adding host. +- always read file maps multi map fix. +- always read file maps key lookup fixes. +- add support for LDAP_URI="ldap:///" SRV RR lookup. + +* Thu Apr 16 2009 Ian Kent - 1:5.0.4-26 +- fix lsb init script header. +- fix memory leak reading ldap master map. +- fix st_remove_tasks() locking. +- reset flex scanner when setting buffer. +- zero s_magic is valid. + +* Mon Mar 30 2009 Ian Kent - 1:5.0.4-24 +- clear rpc client on lookup fail. + +* Fri Mar 20 2009 Ian Kent - 1:5.0.4-23 +- fix call restorecon when misc device file doesn't exist. + +* Wed Mar 18 2009 Ian Kent - 1:5.0.4-22 +- use misc device ioctl interface by default, if available. + +* Tue Mar 17 2009 Ian Kent - 1:5.0.4-21 +- fix file map lookup when reading included or nsswitch sources. + - a regression introduced by file map lookup optimisation in rev 9. + +* Fri Mar 13 2009 Ian Kent - 1:5.0.4-20 +- add LSB init script parameter block. + +* Fri Mar 13 2009 Ian Kent - 1:5.0.4-19 +- another easy alloca replacements fix. + +* Thu Mar 12 2009 Ian Kent - 1:5.0.4-18 +- fix return start status on fail. +- fix double free in expire_proc(). + +* Wed Feb 25 2009 Ian Kent - 1:5.0.4-17 +- fix bad token declaration in master map parser. + +* Wed Feb 25 2009 Ian Kent - 1:5.0.4-16 +- correct mkdir command in %%install section, bz481132. + +* Tue Feb 24 2009 Ian Kent - 1:5.0.4-15 +- fix array out of bounds accesses and cleanup couple of other alloca() calls. +- Undo mistake in copy order for submount path introduced by rev 11 patch. +- add check for alternate libxml2 library for libxml2 tsd workaround. +- add check for alternate libtirpc library for libtirpc tsd workaround. +- cleanup configure defines for libtirpc. +- add WITH_LIBTIRPC to -V status report. +- add libtirpc-devel to BuildRequires. +- add nfs mount protocol default configuration option. + +* Mon Feb 23 2009 Fedora Release Engineering - 1:5.0.4-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 19 2009 Ian Kent - 5.0.4-10 +- fix mntent.h not included before use of setmntent_r(). + +* Mon Feb 16 2009 Ian Kent - 5.0.4-9 +- fix hosts map use after free. +- fix uri list locking (again). +- check for stale SASL credentials upon connect fail. +- add "forcestart" and "forcerestart" init script options to allow + use of 5.0.3 strartup behavior if required. +- always read entire file map into cache to speed lookups. +- make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit. +- make some easy alloca replacements. +- update to configure libtirpc if present. +- update to provide ipv6 name and address support. +- update to provide ipv6 address parsing. + +* Thu Feb 5 2009 Ian Kent - 5.0.4-8 +- rename program map parsing bug fix patch. +- use CLOEXEC flag functionality for setmntent also, if present. + +* Wed Jan 21 2009 Jeff Moyer - 5.0.4-6 +- fix a bug in the program map parsing routine + +* Thu Jan 15 2009 Ian Kent - 5.0.4-5 +- fix negative caching of non-existent keys. +- fix ldap library detection in configure. +- use CLOEXEC flag functionality if present. +- fix select(2) fd limit. +- make hash table scale to thousands of entries. + +* Wed Dec 3 2008 Ian Kent - 5.0.4-4 +- fix nested submount expire deadlock. + +* Wed Nov 19 2008 Ian Kent - 5.0.4-3 +- fix libxml2 version check for deciding whether to use workaround. + +* Tue Nov 11 2008 Ian Kent - 5.0.4-2 +- Fix tag confusion. + +* Tue Nov 11 2008 Ian Kent - 5.0.4-1 +- Upstream source version 5.0.4. + +* Tue Nov 11 2008 Ian Kent - 5.0.3-32 +- correct buffer length setting in autofs-5.0.3-fix-ifc-buff-size-fix.patch. + +* Sun Nov 2 2008 Ian Kent - 5.0.3-30 +- fix segv during library re-open. +- fix incorrect pthreads condition handling for expire requests. +- fix master map lexer eval order. +- fix bad alloca usage. + +* Thu Oct 23 2008 Ian Kent - 5.0.3-28 +- don't close file handle for rootless direct mounti-mount at mount. +- wait submount expire thread completion when expire successful. +- add inadvertantly ommitted server list locking in LDAP module. + +* Fri Oct 10 2008 Ian Kent - 5.0.3-26 +- add map-type-in-map-name fix patch to sync with upstream and RHEL. +- don't readmap on HUP for new mount. +- add NIS_PARTIAL to map entry not found check and fix use after free bug. + +* Fri Sep 26 2008 Ian Kent - 5.0.3-25 +- fix fd leak at multi-mount non-fatal mount fail. +- fix incorrect multi-mount mountpoint calcualtion. + +* Fri Sep 19 2008 Ian Kent - 5.0.3-23 +- add upstream bug fixes + - bug fix for mtab check. + - bug fix for zero length nis key. + - update for ifc buffer handling. + - bug fix for kernel automount handling. +- warning: I found a bunch of patches that were present but not + being applied. + +* Mon Aug 25 2008 Ian Kent - 5.0.3-21 +- add upstream bug fix patches + - add command line option to override is running check. + - don't use proc fs for is running check. + - fix fail on included browse map not found. + - fix incorrect multi source messages. + - clear stale flag on map read. + - fix proximity other rpc ping timeout. + - refactor mount request vars code. + - make handle_mounts startup condition distinct. + - fix submount shutdown handling. + - try not to block on expire. + - add configuration paramter UMOUNT_WAIT. + - fix multi mount race. + - fix nfs4 colon escape handling. + - check replicated list after probe. + - 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. + - fix interface config buffer size. + - fix percent hack heap corruption. + +* Mon Jul 14 2008 Tom "spot" Callaway - 5.0.3-19 +- change conflicts to requires +- fix license tag + +* Mon Jun 30 2008 Ian Kent - 5.0.3-18 +- don't abuse the ap->ghost field on NFS mount. +- multi-map doesn't pickup NIS updates automatically. +- eliminate redundant DNS name lookups. +- mount thread create condition handling fix. +- allow directory create on NFS root. +- check direct mount path length. +- fix incorrect in check in get user info. +- fix a couple of memory leaks. + +* Wed May 14 2008 Ian Kent - 5.0.3-16 +- update patches, documentation and comments only change. +- rename patch and add to CVS. + +* Mon May 12 2008 Ian Kent - 5.0.3-14 +- check for nohide mounts (bz 442618). +- ignore nsswitch sources that aren't supported (bz 445880). + +* Thu Apr 17 2008 Ian Kent - 5.0.3-13 +- fix typo in patch for incorrect pthreads condition handling patch. + +* Mon Apr 14 2008 Ian Kent - 5.0.3-12 +- fix incorrect pthreads condition handling for mount requests. + +* Tue Apr 1 2008 Ian Kent - 5.0.3-11 +- and another try at fixing lexer matching map type in map name. + +* Sun Mar 30 2008 Ian Kent - 5.0.3-10 +- another try a fixing lexer matching map type in map name. + +* Wed Mar 26 2008 Ian Kent - 5.0.3-9 +- fix lexer ambiguity in match when map type name is included in map name. + +* Mon Mar 24 2008 Ian Kent - 5.0.3-8 +- revert miscellaneous device node related patches. +- add missing check for zero length NIS key. +- fix incorrect match of map type name when included in map name. +- update rev 7 sasl callbacks patch. + +* Thu Mar 20 2008 Ian Kent - 5.0.3-7 +- add patch to initialize sasl callbacks unconditionally on autofs + LDAP lookup library load. + +* Mon Feb 25 2008 Ian Kent - 5.0.3-6 +- fix expire calling kernel more often 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. +- device node and active restart fixes. +- update is_mounted to use device node ioctl, if available. + +* Fri Feb 1 2008 Ian Kent - 5.0.3-5 +- another fix for don't fail on empty master map. + +* Fri Jan 25 2008 Ian Kent - 5.0.3-4 +- correction to the correction for handling of LDAP base dns with spaces. +- avoid using UDP for probing NFSv4 mount requests. +- use libldap instead of libldap_r. + +* Mon Jan 21 2008 Ian Kent - 5.0.3-3 +- catch "-xfn" map type and issue "no supported" message. +- another correction for handling of LDAP base dns with spaces. + +* Mon Jan 14 2008 Ian Kent - 5.0.3-2 +- correct configure test for ldap page control functions. + +* Mon Jan 14 2008 Ian Kent - 5.0.3-1 +- update source to version 5.0.3. + +* Fri Dec 21 2007 Ian Kent - 5.0.2-25 +- Bug 426401: CVE-2007-6285 autofs default doesn't set nodev in /net [rawhide] + - use mount option "nodev" for "-hosts" map unless "dev" is explicily specified. + +* Tue Dec 18 2007 Ian Kent - 5.0.2-23 +- Bug 397591 SELinux is preventing /sbin/rpc.statd (rpcd_t) "search" to (sysctl_fs_t). + - prevent fork between fd open and setting of FD_CLOEXEC. + +* Thu Dec 13 2007 Ian Kent - 5.0.2-21 +- Bug 421371: CVE-2007-5964 autofs defaults don't restrict suid in /net [rawhide] + - use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified. + +* Thu Dec 6 2007 Jeremy Katz - 1:5.0.2-19 +- rebuild for new ldap + +* Tue Nov 20 2007 Ian Kent - 5.0.2-18 +- fix schema selection in LDAP schema discovery. +- check for "*" when looking up wildcard in LDAP. +- fix couple of edge case parse fails of timeout option. +- add SEARCH_BASE configuration option. +- add random selection as a master map entry option. +- re-read config on HUP signal. +- add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options. +- fix deadlock in submount mount module. +- fix lack of ferror() checking when reading files. +- fix typo in autofs(5) man page. +- fix map entry expansion when undefined macro is present. +- remove unused export validation code. +- add dynamic logging (adapted from v4 patch from Jeff Moyer). +- fix recursive loopback mounts (Matthias Koenig). +- add map re-load to verbose logging. +- fix handling of LDAP base dns with spaces. +- handle MTAB_NOTUPDATED status return from mount. +- when default master map, auto.master, is used also check for auto_master. +- update negative mount timeout handling. +- fix large group handling (Ryan Thomas). +- fix for dynamic logging breaking non-sasl build (Guillaume Rousse). +- eliminate NULL proc ping for singleton host or local mounts. + +* Mon Sep 24 2007 Ian Kent - 5.0.2-16 +- add descriptive comments to config about LDAP schema discovery. +- work around segfault at exit caused by libxml2. +- fix foreground logging (also fixes shutdown needing extra signal bug). + +* Wed Sep 5 2007 Ian Kent - 5.0.2-15 +- fix LDAP schema discovery. + +* Tue Aug 28 2007 Ian Kent - 5.0.2-14 +- update patch to prevent failure on empty master map. +- if there's no "automount" entry in nsswitch.conf use "files" source. +- add LDAP schema discovery if no schema is configured. + +* Wed Aug 22 2007 Ian Kent - 5.0.2-13 +- fix "nosymlink" option handling and add desription to man page. + +* Tue Aug 21 2007 Ian Kent - 5.0.2-12 +- change random multiple server selection option name to be consistent + with upstream naming. + +* Tue Aug 21 2007 Ian Kent - 5.0.2-11 +- don't fail on empty master map. +- add support for the "%%" hack for case insensitive attribute schemas. + +* Mon Jul 30 2007 Ian Kent - 5.0.2-10 +- mark map instances stale so they aren't "cleaned" during updates. +- fix large file compile time option. + +* Fri Jul 27 2007 Ian Kent - 5.0.2-9 +- fix version passed to get_supported_ver_and_cost (bz 249574). + +* Tue Jul 24 2007 Ian Kent - 5.0.2-8 +- fix parse confusion between attribute and attribute value. + +* Fri Jul 20 2007 Ian Kent - 5.0.2-7 +- fix handling of quoted slash alone (bz 248943). + +* Wed Jul 18 2007 Ian Kent - 5.0.2-6 +- fix wait time resolution in alarm and state queue handlers (bz 247711). + +* Mon Jul 16 2007 Ian Kent - 5.0.2-5 +- fix mount point directory creation for bind mounts. +- add quoting for exports gathered by hosts map. + +* Mon Jun 25 2007 Ian Kent - 5.0.2-4 +- update multi map nsswitch patch. + +* Mon Jun 25 2007 Ian Kent - 5.0.2-3 +- add missing "multi" map support. +- add multi map nsswitch lookup. + +* Wed Jun 20 2007 Ian Kent - 5.0.2-2 +- include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it). +- correct initialization of local var in parse_server_string. + +* Mon Jun 18 2007 Ian Kent - 5.0.2-1 +- Update to upstream release 5.0.2. + +* Tue Jun 12 2007 Ian Kent - 5.0.1-16 +- add ldaps support. + - note: it's no longer possible to have multiple hosts in an ldap map spec. + - note: to do this you need to rely on the ldap client config. + +* Thu Jun 7 2007 Ian Kent - 5.0.1-14 +- fix deadlock in alarm manager module. + +* Sun Jun 3 2007 Ian Kent - 5.0.1-12 +- correct mistake in logic test in wildcard lookup. + +* Mon May 7 2007 Ian Kent - 5.0.1-10 +- fix master map lexer to admit "." in macro values. + +* Tue Apr 17 2007 Ian Kent - 5.0.1-9 +- upstream fix for filesystem is local check. +- disable exports access control check (bz 203277). +- fix patch to add command option for set a global mount options (bz 214684). + +* Mon Apr 16 2007 Ian Kent - 5.0.1-8 +- add configuration variable to control appending of global options (bz 214684). +- add command option to set a global mount options string (bz 214684). + +* Tue Apr 3 2007 Ian Kent - 5.0.1-7 +- fix "null" domain netgroup match for "-hosts" map. + +* Thu Mar 29 2007 Ian Kent - 5.0.1-6 +- fix directory creation for browse mounts. +- fix wildcard map handling and improve nsswitch source map update. + +* Fri Mar 16 2007 Ian Kent - 5.0.1-5 +- drop "DEFAULT_" prefix from configuration names. +- add option to select replicated server at random (instead of + ping response time) (bz 227604). +- fix incorrect cast in directory cleanup routines (bz 231864). + +* Thu Mar 8 2007 Ian Kent - 5.0.1-4 +- fixed numeric export match (bz 231188). + +* Thu Mar 1 2007 Ian Kent - 5.0.1-3 +- change file map lexer to allow white-space only blank lines (bz 229434). + +* Fri Feb 23 2007 Ian Kent - 5.0.1-2 +- update "@network" matching patch. + +* Thu Feb 22 2007 Ian Kent - 5.0.1-1 +- update to release tar. +- fix return check for getpwuid_r and getgrgid_r. +- patch to give up trying to update exports list while host is mounted. +- fix to "@network" matching. +- patch to check for fstab update and retry if not updated. + +* Tue Feb 20 2007 Ian Kent - 5.0.1-0.rc3.24 +- add "condrestart" to init script (bz 228860). +- add "@network" and .domain.name export check. +- fix display map name in mount entry for "-hosts" map. + +* Fri Feb 16 2007 Ian Kent - 5.0.1-0.rc3.22 +- fix localhost replicated mounts not working (bz 208757). + +* Wed Feb 14 2007 Ian Kent - 5.0.1-0.rc3.20 +- correct return status from do_mkdir (bz 223480). + +* Sat Feb 10 2007 Ian Kent - 5.0.1-0.rc3.18 +- update the "task done race" patch to fix a deadlock. +- added URL tag. +- removed obsoletes autofs-ldap. +- replaced init directory paths with %%{_initrddir} macro. + +* Fri Feb 9 2007 Ian Kent - 5.0.1-0.rc3.17 +- make use of spaces and tabs in spec file consistent. +- escape embedded macro text in %%changelog. +- eliminate redundant %%version and %%release. +- remove redundant conditional check from %%clean. +- remove redundant exit from %%preun. +- correct %%defattr spec. +- remove empty %%doc and redundant %%dir misc lines. +- combine program module spec lines into simpler one line form. + +* Tue Feb 6 2007 Ian Kent - 5.0.1-0.rc3.15 +- fix race when setting task done (bz 227268). + +* Mon Jan 29 2007 Ian Kent - 5.0.1-0.rc3.13 +- make double quote handing consistent (at least as much as we can). +- fix handling of trailing white space in wildcard lookup (forward port bz 199720). +- check fqdn of each interface when matching export access list (bz 213700). + +* Thu Jan 18 2007 Ian Kent - 5.0.1-0.rc3.11 +- correct check for busy offset mounts before offset umount (bz 222872). + +* Wed Jan 17 2007 Ian Kent - 5.0.1-0.rc3.9 +- fix another expire regression introduced in the "mitigate manual umount" + patch (bz 222872). + +* Mon Jan 15 2007 Ian Kent - 5.0.1-0.rc3.7 +- ignore "winbind" if it appears in "automount" nsswitch.conf (bz 214632). + +* Wed Jan 10 2007 Ian Kent - 5.0.1-0.rc3.5 +- remove fullstop from Summary tag. +- change Buildroot to recommended form. +- replace Prereq with Requires. + +* Tue Jan 9 2007 Ian Kent - 5.0.1-0.rc3.3 +- remove redundant rpath link option (prep for move to Extras). + +* Tue Jan 9 2007 Ian Kent - 5.0.1-0.rc3.1 +- consolidate to rc3. +- fix typo in Fix typo in var when removing temp directory (bz 221847). + +* Wed Dec 27 2006 Ian Kent - 5.0.1-0.rc2.41 +- fix nonstrict multi-mount handling (bz 219383). +- correct detection of duplicate indirect mount entries (bz 220799). + +* Thu Dec 14 2006 Ian Kent - 5.0.1-0.rc2.38 +- update master map tokenizer to admit "slasify-colons" option. +- update location validation to accept "_" (bz 219445). +- set close-on-exec flag on open sockets (bz 215757). + +* Mon Dec 11 2006 Ian Kent - 5.0.1-0.rc2.35 +- update "replace-tempnam" patch to create temp files in sane location. + +* Mon Dec 11 2006 Ian Kent - 5.0.1-0.rc2.34 +- change mount "device" from "automount" to the map name. +- check for buffer overflow in mount_afs.c. +- replace tempnam with mkdtemp. + +* Sun Dec 10 2006 Ian Kent - 5.0.1-0.rc2.33 +- expand export access checks to include missing syntax options. +- make "-hosts" module try to be sensitive to exports list changes. + +* Thu Dec 7 2006 Ian Kent - 5.0.1-0.rc2.32 +- remove ability to use multiple indirect mount entries in master + map (bz 218616). + +* Wed Dec 6 2006 Ian Kent - 5.0.1-0.rc2.29 +- alter nfs4 host probing to not use portmap lookup and add options + check for "port=" parameter (bz 208757). +- correct semantics of "-null" map handling (bzs 214800, 208091). + +* Sat Nov 25 2006 Ian Kent - 5.0.1-0.rc2.26 +- fix parsing of bad mount mount point in master map (bz 215620). +- fix use after free memory access in cache.c and lookup_yp.c (bz 208091). +- eliminate use of pthread_kill to detect task completion (bz 208091). + +* Sun Nov 12 2006 Ian Kent - 5.0.1-0.rc2.23 +- fix tokenizer to distinguish between global option and dn string (bz 214684). +- fix incorrect return from spawn. + +* Wed Nov 8 2006 Ian Kent - 5.0.1-0.rc2.21 +- mitigate manual umount of automounts where possible. +- fix multiply recursive bind mounts. +- check kernel module version and require 5.00 or above. +- fix expire regression introduced in the "mitigate manual umount" patch. +- still more on multiply recursive bind mounts. + +* Mon Oct 30 2006 Ian Kent - 5.0.1-0.rc2.20 +- Update patch for changed semantics of mkdir in recent kernels. +- fix macro table locking (bz 208091). +- fix nsswitch parser locking (bz 208091). +- allow only one master map read task at a time. +- fix misc memory leaks. + +* Wed Oct 25 2006 Ian Kent - 5.0.1-0.rc2.19 +- deal with changed semantics of mkdir in recent kernels. + +* Fri Oct 20 2006 Ian Kent - 5.0.1-0.rc2.16 +- fix get_query_dn not looking in subtree for LDAP search (missed + econd occurance). +- allow additional common LDAP attributes in map dn. +- Resolves: rhbz#205997 + +* Mon Oct 16 2006 Ian Kent - 5.0.1-0.rc2.13 +- fix parsing of numeric host names in LDAP map specs (bz 205997). + +* Mon Oct 16 2006 Ian Kent - 5.0.1-0.rc2.12 +- fix "-fstype=nfs4" server probing (part 2 of bz 208757). +- set close-on-exec flag on open files where possible (bz 207678). + +* Fri Oct 13 2006 Ian Kent - 5.0.1-0.rc2.11 +- fix file handle leak in nsswitch parser (bz 207678). +- fix memory leak in mount and expire request processing (bz 207678). +- add additional check to prevent running of cancelled tasks. +- fix potential file handle leakage in rpc_subs.c for some failure + cases (bz 207678). +- fix file handle leak in included map lookup (bz 207678). + +* Sat Oct 7 2006 Ian Kent - 5.0.1-0.rc2.10 +- fix get_query_dn not looking in subtree for LDAP search. +- allow syntax "--timeout " for backward compatibility + (bz 193948). +- make masked_match independent of hostname for exports comparison + (bz 209638). + +* Thu Oct 5 2006 Ian Kent - 5.0.1-0.rc2.9 +- fix "-fstype=nfs4" handling (bz 208757). + +* Wed Sep 27 2006 Ian Kent - 5.0.1-0.rc2.8 +- review and fix master map options update for map reload. + +* Wed Sep 27 2006 Ian Kent - 5.0.1-0.rc2.7 +- make default installed master map for /net use "-hosts" instead + of auto.net. +- fix included map recursive map key lookup. + +* Mon Sep 25 2006 Ian Kent - 5.0.1-0.rc2.6 +- remove unused option UNDERSCORETODOT from default config files. + +* Mon Sep 25 2006 Ian Kent - 5.0.1-0.rc2.5 +- fix LDAP lookup delete cache entry only if entry doesn't exist. +- add missing socket close in replicated host check (Jeff Moyer). + +* Wed Sep 20 2006 Ian Kent - 5.0.1-0.rc2.4 +- fix cache entrys not being cleaned up on submount expire. + +* Sun Sep 17 2006 Ian Kent - 5.0.1-0.rc2.3 +- fix include check full patch for file map of same name. + +* Wed Sep 13 2006 Ian Kent - 5.0.1-0.rc2.2 +- fix handling of autofs specific mount options (bz 199777). + +* Fri Sep 1 2006 Ian Kent - 5.0.1-0.rc2.1 +- consolidate to rc2. +- fix colon escape handling. +- fix recusively referenced bind automounts. +- update kernel patches. + +* Fri Aug 25 2006 Ian Kent - 5.0.1-0.rc1.17 +- fix task cancelation at shutdown (more) +- fix concurrent mount and expire race with nested submounts. + +* Sun Aug 20 2006 Ian Kent - 5.0.1-0.rc1.16 +- fix included map lookup. +- fix directory cleanup on expire. +- fix task cancelation at shutdown. +- fix included map wild card key lookup. + +* Wed Aug 16 2006 Ian Kent - 5.0.1-0.rc1.15 +- expire individual submounts. +- add ino_index locking. +- fix nested submount expiring away when pwd is base of submount. +- more expire re-work to cope better with shutdown following cthon tests. +- allow hostname to start with numeric when validating. + +* Mon Aug 7 2006 Ian Kent - 5.0.1-0.rc1.14 +- remove SIGCHLD handler because it is no longer needed and was + causing expire problems. +- alter expire locking of multi-mounts to lock sub-tree instead of + entire tree. +- review verbose message feedback and update. +- correction for expire of multi-mounts. +- spelling corrections to release notes (Jeff Moyer). +- add back sloppy mount option, removed for Connectathon testing. +- disable mtab locking again. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.13 +- tidy up directory cleanup and add validation check to rmdir_path. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.12 +- enable mtab locking until I can resolve the race with it. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.11 +- cthon fix expire of wildcard and program mounts broken by recent + patches. + +* Thu Aug 3 2006 Ian Kent - 5.0.1-0.rc1.10 +- cthon corrections for shutdown patch below and fix shutdown expire. + +* Wed Aug 2 2006 Ian Kent - 5.0.1-0.rc1.9 +- cthon fix some shutdown races. + +* Thu Jul 27 2006 Ian Kent - 5.0.1-0.rc1.8 +- Fix compile error. + +* Thu Jul 27 2006 Ian Kent - 5.0.1-0.rc1.7 +- cthon fix expire of various forms of nested mounts. + +* Mon Jul 24 2006 Ian Kent - 5.0.1-0.rc1.6 +- cthon more parser corrections and attempt to fix multi-mounts + with various combinations of submounts (still not right). + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.5 +- Add conflicts kernel < 2.6.17. +- Fix submount operation broken by connectathon updates. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.4 +- Correction to host name validation test for connectathon tests. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.3 +- More code cleanup and corrections for connectathon tests. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.2 +- Code cleanup and fixes for connectathon tests. + +* Thu Jul 13 2006 Ian Kent - 5.0.1-0.rc1.1 +- Update version label to avoid package update problems. + +* Thu Jul 13 2006 Ian Kent - 5.0.0_beta6-8 +- add cacheing of negative lookups to reduce unneeded map + lookups (bz 197746 part 2). + +* Wed Jul 12 2006 Jesse Keating - 1:5.0.0_beta6-7.1 +- rebuild + +* Tue Jul 11 2006 Ian Kent - 5.0.0_beta6-7 +- correct directory cleanup in mount modules. +- merge key and wildcard LDAP query for lookups (bz 197746). + +* Sat Jul 8 2006 Ian Kent - 5.0.0_beta6-6 +- correct test for libhesiod. + +* Fri Jul 7 2006 Ian Kent - 5.0.0_beta6-5 +- correct auto.net installed as auto.smb. +- update LDAP auth - add autodectect option. + +* Wed Jul 5 2006 Ian Kent - 5.0.0_beta6-4 +- correct shutdown log message print. +- correct auth init test when no credentials required. + +* Tue Jul 4 2006 Ian Kent - 5.0.0_beta6-3 +- correct test for existence of auth config file. + +* Mon Jul 3 2006 Ian Kent - 5.0.0_beta6-2 +- merge LDAP authentication update for GSSAPI (Jeff Moyer). +- update default auth config to add options documenetation (Jeff Moyer). +- workaround segfaults at exit after using GSSAPI library. +- fix not checking return in init_ldap_connection (jeff Moyer). + +* Thu Jun 29 2006 Ian Kent - 5.0.0_beta6-1 +- consolidate to beta6, including: + - mode change update for config file. + - correction to get_query_dn fix from beta5-4. + +* Wed Jun 28 2006 Ian Kent - 5.0.0_beta5-6 +- cleanup defaults_read_config (Jeff Moyer). + +* Tue Jun 27 2006 Ian Kent - 5.0.0_beta5-5 +- allow global macro defines to override system macros. +- correct spelling error in default config files missed by + previous update. +- misc correctness and a memory leak fix. + +* Mon Jun 26 2006 Ian Kent - 5.0.0_beta5-4 +- correct spelling error in default config. +- fix default auth config not being installed. +- change LDAP query method as my test db was incorrect. +- change ldap defaults code to handle missing auth config. +- fix mistake in parsing old style LDAP specs. +- update LDAP so that new query method also works for old syntax. + +* Fri Jun 23 2006 Ian Kent - 5.0.0_beta5-3 +- lookup_init cleanup and fix missed memory leak. +- use nis map order to check if update is needed. +- fix couple of memory leaks in lookup_yp.c. +- fix pasre error in replicated server module. + +* Wed Jun 21 2006 Ian Kent - 5.0.0_beta5-2 +- Add openssl-devel to the BuildRequires, as it is needed for the LDAP + authentication bitsi also. + +* Tue Jun 20 2006 Ian Kent - 5.0.0_beta5-1 +- promote to beta5. + +* Tue Jun 20 2006 Ian Kent - 5.0.0_beta4-14 +- fix directory cleanup at exit. + +* Mon Jun 19 2006 Ian Kent - 5.0.0_beta4-13 +- Change LDAP message severity from crit to degug (bz# 183893). +- Corrections to INSTALL and README.v5.release. +- Add patch to fix segv on overlength map keys in file maps (Jeff Moter). +- Add patch to restrict scanning of /proc to pid directories only (Jeff Moyer). + +* Thu Jun 15 2006 Jeff Moyer - 5.0.0_beta4-12 +- Change BuildPrereq to BuildRequires as per the package guidelines. +- Add libxml2-devel to the BuildRequires, as it is needed for the LDAP + authentication bits. + +* Wed Jun 14 2006 Ian Kent - 5.0.0_beta4-11 +- add export access list matching to "hosts" lookup module (bz # 193585). + +* Tue Jun 13 2006 Jeff Moyer - 5.0.0_beta4-10 +- Add a BuildPrereq for cyrus-sasl-devel + +* Tue Jun 13 2006 Ian Kent - 5.0.0_beta4-9 +- move autofs4 module loading back to init script (part bz # 194061). + +* Mon Jun 12 2006 Ian Kent - 5.0.0_beta4-8 +- fix handling of master map entry update (bz # 193718). +- fix program map handling of invalid multi-mount offsets. + +* Sat Jun 10 2006 Ian Kent - 5.0.0_beta4-7 +- fix context init error (introduced by memory leak patch). + +* Fri Jun 9 2006 Ian Kent - 5.0.0_beta4-6 +- add free for working var in get_default_logging. +- add inialisation for kver in autofs_point struct. +- fix sources list corruption in check_update_map_sources. +- fix memory leak in walk_tree. +- fix memory leak in rpc_portmap_getport and rpc_ping_proto. +- fix memory leak in initialisation of lookup modules. + +* Thu Jun 8 2006 Ian Kent - 5.0.0_beta4-5 +- misc fixes for things found while investigating map re-read problem. + +* Wed Jun 7 2006 Ian Kent - 5.0.0_beta4-4 +- check base of offset mount tree is not a mount before umounting + its offsets. +- fix replicated mount parse for case where last name in list + fails lookup. +- correct indirect mount expire broken by the wildcard lookup fix. +- fix up multi-mount handling when wildcard map entry present. + +* Mon Jun 5 2006 Ian Kent - 5.0.0_beta4-3 +- correct config names in default.c (jpro@bas.ac.uk). + +* Mon Jun 5 2006 Ian Kent - 5.0.0_beta4-2 +- re-instate v4 directory cleanup (bz# 193832 again). +- backout master map lookup changes made to beta3. +- change default master map from /etc/auto.master to auto.master + so that we always use nsswitch to locate master map. +- change default installed master map to include "+auto.master" + to pickup NIS master map (all bz# 193831 again). + +* Fri Jun 2 2006 Ian Kent - 5.0.0_beta4-1 +- update to beta4. +- should address at least bzs 193798, 193770, 193831 and + possibly 193832. + +* Mon May 29 2006 Ian Kent - 5.0.0_beta3-6 +- add back test for nested mount in program map lookup. + - I must have commented this out for a reason. I guess we'll + find out soon enough. + +* Mon May 29 2006 Ian Kent - 5.0.0_beta3-5 +- fix handling of autofs filesystem mount fail on init. + +* Sat May 27 2006 Ian Kent - 5.0.0_beta3-4 +- updated hesiod patch. + +* Sat May 27 2006 Ian Kent - 5.0.0_beta3-3 +- update hesiod module (Jeff Moyer). + - add mutex to protect against overlapping mount requests. + - update return from mount request to give more sensible NSS_* + values. + +* Fri May 26 2006 Jeff Moyer - 1:5.0.0_beta3-2 +- Fix the install permissions for auto.master and auto.misc. + +* Thu May 25 2006 Ian Kent - 5.0.0_beta3-1 +- update source to version 5.0.0_beta3. +- add patch to remove extra debug print. +- add patch to + - fix memory alloc error in nis lookup module. + - add "_" to "." mapname translation to nis lookup module. +- add patch to add owner pid to mount list struct. +- add patch to disable NFSv4 when probing hosts (at least foe now). +- add patch to fix white space handling in replicated server selection code. +- add patch to prevent striping of debug info macro patch (Jeff Moyer). +- add patch to add sanity checks on rmdir_path and unlink (Jeff Moyer). +- add patch to fix e2fsck error code check (Jeff Moyer). + +* Tue May 16 2006 Ian Kent - 1:4.1.4-23 +- add patch to ignore the "bg" and "fg" mount options as they + aren't relevant for autofs mounts (bz #184386). + +* Tue May 2 2006 Ian Kent - 1:4.1.4-20 +- add patch to use "cifs" instead of smbfs and escape speces + in share names (bz #163999, #187732). + +* Tue Apr 11 2006 Ian Kent - 1:4.1.4-18 +- Add patch to allow customization of arguments to the + autofs-ldap-auto-master program (bz #187525). +- Add patch to escap "#" characters in exports from auto.net + program mount (bz#178304). + +* Fri Feb 10 2006 Jesse Keating - 1:4.1.4-16.2.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 1:4.1.4-16.2.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Wed Feb 1 2006 Ian Kent - 1:4.1.4-16.2 +- Add more general patch to translate "_" to "." in map names. (bz #147765) + +* Wed Jan 25 2006 Ian Kent - 1:4.1.4-16.1 +- Add patch to use LDAP_DEPRICATED compile option. (bz #173833) + +* Tue Jan 17 2006 Ian Kent - 1:4.1.4-16 +- Replace check-is-multi with more general multi-parse-fix. +- Add fix for premature return when waiting for lock file. +- Update copyright declaration for reentrant-syslog source. +- Add patch for configure option to disable locking during mount. + But don't disable locking by default. +- Add ability to handle automount schema used in Sun directory server. +- Quell compiler warning about getsockopt parameter. +- Quell compiler warning about yp_order parameter. + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Nov 17 2005 Jeff Moyer - 1:4.1.4-14 +- Removed the /misc entry from the default auto.master. auto.misc has + an entry for the cdrom device, and the preferred method of mounting the + cd is via udev/hal. + +* Mon Nov 7 2005 Jeff Moyer - 1:4.1.4-13 +- Changed to sort -k 1, since that should be the same as +0. + +* Thu Nov 3 2005 Jeff Moyer - 1:4.1.4-12 +- The sort command no longer accepts options of the form "+0". This broke + auto.net, so the option was removed. Fixes bz #172111. + +* Wed Oct 26 2005 - 1:4.1.4-11 +- Check the return code of is_local_addr in get_best_mount. (bz #169523) + +* Wed Oct 26 2005 - 1:4.1.4-10 +- Fix some bugs in the parser +- allow -net instead of /etc/auto.net +- Fix a buffer overflow with large key lengths +- Don't allow autofs to unlink files, only to remove directories +- change to the upstream reentrant syslog patch from the band-aid deferred + syslog patch. +- Get rid of the init script patch that hard-coded the release to redhat. + This should be handled properly by all red hat distros. + +* Wed May 4 2005 Jeff Moyer - 1:4.1.4-8 +- Add in the deferred syslog patch. This fixes a hung automounter issue + related to unsafe calls to syslog in signal handler context. + +* Tue May 3 2005 Jeff Moyer - 1:4.1.4-7 +- I reversed the checking for multimount entries, breaking those configs! + This update puts the code back the way it was before I broke it. + +* Tue Apr 26 2005 Jeff Moyer - 1:4.1.4-6 +- Fix a race between mounting a share and updating the cache in the parent + process. If the mount completed first, the parent would not expire the + stale entry, leaving it first on the list. This causes map updates to not + be recognized (well, worse, they are recognized after the first expire, but + not subsequent ones). Fixes a regression, bug #137026 (rhel3 bug). + +* Fri Apr 15 2005 Chris Feist - 1:4.1.4-5 +- Fixed regression with -browse not taking effect. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-4 +- Finish up with the merge breakage. +- Temporary fix for the multimount detection code. It seems half-baked. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-3 +- Fix up the one-auto-master patch. My "improvements" had side-effects. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-2 +- Import 4.1.4 and merge. + +* Mon Apr 4 2005 Jeff Moyer - 1:4.1.3-123 +- Add in an error case that was omitted in the multi-over patch. +- Update our auto.net to reflect the changes that went into 4.1.4_beta2. + This fixes a problem seen by at least one customer where a malformed entry + appeared first in the multimount list, thus causing the entire multimount + to be ignored. This new auto.net places that entry at the end, purely by + luck, but it fixes the problem in this one case. + +* Thu Mar 31 2005 Jeff Moyer - 1:4.1.3-119 +- Merge in the multi-over patch. This resolves an issue whereby multimounts + (such as those used for /net) could be processed in the wrong order, + resulting in directories not showing up in a multimount tree. The fix + is to process these directories in order, shortest to longer path. + +* Wed Mar 23 2005 Chris Feist - 1:4.1.3-115 +- Fixed regression causing any entries after a wildcard in an + indirect map to be ignored. (bz #151668). +- Fixed regression which caused local hosts to be mount instead + of --bind local directories. (bz #146887) + +* Thu Mar 17 2005 Chris Feist - 1:4.1.3-111 +- Fixed one off bug in the submount-variable-propagation patch. + (bz #143074) +- Fixed a bug in the init script which wouldn't find the -browse + option if it was preceded by another option. (fz #113494) + +* Mon Feb 28 2005 Chris Feist - 1:4.1.3-100 +- When using ldap if auto.master doesn't exist we now check for auto_master. + Addresses bz #130079 +- When using an auto.smb map we now remove the leading ':' from the path which + caused mount to fail in the past. Addresses bz #147492 +- Autofs now checks /etc/nsswitch.conf to determine in what order files & nis + are checked when looking up autofs submount maps which don't specify a + maptype. Addresses IT #57612. + +* Mon Feb 14 2005 Jeff Moyer - 1:4.1.3-99 +- Change Copyright to License in the spec file so it will build. + +* Fri Feb 11 2005 Jeff Moyer - 1:4.1.3-98 +- Program maps can repeat the last character of output. Fix this. + Addresses bz #138606 +- Return first entry when there are duplicate keys in a map. Addresses + bz #140108. +- Propagate custom map variables to submounts. Fixes bz #143074. +- Create a sysconfig variable to control whether we source only one master + map (the way sun does), or source all maps found (which is the default for + backwards compatibility). Addresses bz #143126. +- Revised version of the get_best_mount patch. (#146887) cfeist@redhat.com + The previous patch introduced a regression. Non-replicated mounts would + not have the white space stripped from the entry and the mount would fail. +- Handle comment characters in the middle of the automount line in + /etc/nsswitch.conf. Addresses bz #127457. + +* Wed Feb 2 2005 Chris Feist - 1:4.1.3-94 +- Stop automount from pinging hosts if there is only one host (#146887) + +* Wed Feb 2 2005 Jeff Moyer - 1:4.1.3-90 +- Fix potential double free in cache_release. This bug showed up in a + multi-map setup. Two calls to cache_release would result in a SIGSEGV, + and the automount process would never exit. + +* Mon Jan 24 2005 Chris Feist - 1:4.3-82 +- Fixed documentation so users know that any local mounts override + any other weighted mount. + +* Mon Jan 24 2005 Chris Feist - 1:4.3-80 +- Added a variable to determine if we created the directory or not + so we don't accidently remove a directory that we didn't create when + we stop autofs. (bz #134399) + +* Tue Jan 11 2005 Jeff Moyer - 1:4.1.3-76 +- Fix the large program map patch. + +* Tue Jan 11 2005 Jeff Moyer - 1:4.1.3-75 +- Fix some merging breakages that caused the package not to build. + +* Thu Jan 6 2005 - 1:4.1.3-74 +- Add in the map expiry patch +- Bring in other patches that have been committed to other branches. This + version should now contain all fixes we have to date +- Merge conflicts due to map expiry changes + +* Fri Nov 19 2004 Jeff Moyer - 1:4.1.3-57 +- Pass a socket into clntudp_bufcreate so that we don't use up additional + reserved ports. This patch, along with the socket leak fix, addresses + bz #128966. + +* Wed Nov 17 2004 - 1:4.1.3-56 +- Somehow the -browse patch either didn't get committed or got reverted. + Fixed. + +* Tue Nov 16 2004 Jeff Moyer - 1:4.1.3-55 +- Fix program maps so that they can have gt 4k characters. (Neil Horman) + Addresses bz #138994. +- Add a space after the colon here "Starting automounter:" in init script. + Fixes bz #138513. + +* Mon Nov 15 2004 Jeff Moyer - 1:4.1.3-53 +- Make autofs understand -[no]browse. Addresses fz #113494. + +* Thu Nov 11 2004 Jeff Moyer - 1:4.1.3-48 +- Fix the umount loop device function in the init script. + +* Wed Oct 27 2004 Chris Feist - 1:4.1.3-34 +- Added a patch to fix the automounter failing on ldap maps + when it couldn't get the whole map. (ie. when the search + limit was lower than the number of results) + +* Thu Oct 21 2004 Chris Feist - 1:4.1.3-32 +- Fixed the use of +ypmapname so the maps included with +ypmapname + are used in the correct order. (In the past the '+' entries + were always processed after local entries.) + +* Thu Oct 21 2004 Chris Feist - 1:4.1.3-31 +- Fixed the duplicate map detection code to detect if maps try + to mount on top of existing maps. + +* Wed Oct 20 2004 Chris Feist - 1:4.1.3-29 +- Fixed a problem with backwards compatability. Specifying local + maps without '/etc/' prepended to them now works. (bz #136038) + +* Fri Oct 15 2004 Chris Feist - 1:4.1.3-28 +- Fixed a bug which caused directories to never be unmounted. (bz #134403) + +* Thu Oct 14 2004 Chris Feist - 1:4.1.3-27 +- Fixed an error in the init script which caused duplicate entries to be + displayed when asking for autofs status. + +* Fri Oct 1 2004 Jeff Moyer - 1:4.1.3-22 +- Comment out map expiry (and related) patch for an FC3 build. + +* Thu Sep 23 2004 Jeff Moyer - 1:4.1.3-21 +- Make local options apply to all maps in a multi-map entry. + +* Tue Sep 21 2004 Jeff Moyer - 1:4.1.3-20 +- Merged my and Ian's socket leak fixes into one, smaller patch. Only + partially addresses bz #128966. +- Fix some more echo lines for internationalization. bz #77820 +- Revert the only one auto.master patch until we implement the +auto_master + syntax. Temporarily addresses bz #133055. + +* Thu Sep 2 2004 Jeff Moyer - 1:4.1.3-18 +- Umount loopback filesystems under automount points when stopping the + automounter. +- Uncomment the map expiry patch. +- change a close to an fclose in lookup_file.c + +* Tue Aug 31 2004 Jeff Moyer - 1:4.1.3-17 +- Add patch to support parsing nsswitch.conf to determine map sources. +- Disable this patch, and Ian's map expiry patch for a FC build. + +* Tue Aug 24 2004 Jeff Moyer - 1:4.1.3-16 +- Version 3 of Ian's map expiry changes. + +* Wed Aug 18 2004 Jeff Moyer - 1:4.1.3-15 +- Fix a socket leak in the rpc_subs, causing mounts to fail since we are + running out of port space fairly quickly. + +* Wed Aug 18 2004 Jeff Moyer - 1:4.1.3-14 +- New map expiry patch from Ian. +- Fix a couple signal races. No known problem reports of these, but they + are holes, none-the-less. + +* Tue Aug 10 2004 Jeff Moyer - 1:4.1.3-13 +- Only read one auto.master map (instead of concatenating all found sources). +- Uncomment Ian's experimental mount expiry patch. + +* Fri Aug 6 2004 Jeff Moyer - 1:4.1.3-12 +- Add a sysconfig entry to disable direct map support, and set this to + 1 by default. +- Disable the beta map expiry logic so I can build into a stable distro. +- Add defaults for all of the sysconfig variables to the init script so + we don't trip over user errors (i.e. deleting /etc/sysconfig/autofs). + +* Wed Aug 4 2004 Jeff Moyer - 1:4.1.3-11 +- Add beta map expiry code for wider testing. (Ian Kent) +- Fix check for ghosting option. I forgot to check for it in DAEMONOPTIONS. +- Remove STRIPDASH from /etc/sysconfig/autofs + +* Mon Jul 12 2004 Jeff Moyer - 1:4.1.3-10 +- Add bad chdir patch from Ian Kent. +- Add a typo fix for the mtab lock file. +- Nuke the stripdash patch. It didn't solve a problem. + +* Tue Jun 22 2004 Jeff Moyer - 1:4.1.3-9 +- Bump revison for inclusion in RHEL 3. + +* Mon Jun 21 2004 Jeff Moyer - 1:4.1.3-8 +- Change icmp ping to an rpc ping. (Ian Kent) +- Fix i18n patch + o Remove the extra \" from one echo line. + o Use echo -e if we are going to do a \n in the echo string. + +* Mon Jun 21 2004 Alan Cox +- Fixed i18n bug #107463 + +* Mon Jun 21 2004 Alan Cox +- Fixed i18n bug #107461 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Sat Jun 5 2004 Jeff Moyer - 1:4.1.3-4 +- Perform an icmp ping request before rpc_pings, since the rpc clnt_create + function has a builtin default timeout of 60 seconds. This could result + in a long delay when a server in a replicated mount setup is down. +- For non-replicated server entries, ping a host before attempting to mount. + (Ian Kent) +- Change to %%configure. +- Put version-release into .version to allow for automount --version to + print exact info. +- Nuke my get-best-mount patch which always uses the long timeout. This + should no longer be needed. +- Put name into changelog entries to make them consistent. Add e:n-v-r + into Florian's entry. +- Stop autofs before uninstalling + +* Sat Jun 05 2004 Florian La Roche - 1:4.1.3-3 +- add a preun script to remove autofs + +* Tue Jun 1 2004 Jeff Moyer - 1:4.1.3-2 +- Incorporate patch from Ian which fixes an infinite loop seen by those + running older versions of the kernel patches (triggered by non-strict mounts + being the default). + +* Tue Jun 1 2004 Jeff Moyer - 1:4.1.3-1 +- Update to upstream 4.1.3. + +* Thu May 6 2004 Jeff Moyer - 1:4.1.2-6 +- The lookup_yp module only dealt with YPERR_KEY, all other errors were + treated as success. As a result, if the ypdomain was not bound, the + subprocess that starts mounts would SIGSEGV. This is now fixed. +- Option parsing in the init script was not precise enough, sometimes matching + filesystem options to one of --ghost, --timeout, --verbose, or --debug. + The option-parsing patch addresses this issue by making the regexp's much + more precise. +- Ian has rolled a third version of the replicated mount fixes. + +* Tue May 4 2004 Jeff Moyer - 1:4.1.2-5 +- Ian has a new fix for replicated server and multi-mounts. Updated the + patch for testing. Still beta. (Ian Kent) + +* Mon May 3 2004 Jeff Moyer - 1:4.1.2-4 +- Fix broken multi-mounts. test patch. (Ian Kent) + +* Tue Apr 20 2004 Jeff Moyer - 1:4.1.2-3 +- Fix a call to spawnl which forgot to specify a lock file. (nphilipp) + +* Wed Apr 14 2004 - 1:4.1.2-2 +- Pass --libdir= to ./configure so we get this right on 64 bit platforms that + support backwards compat. + +* Wed Apr 14 2004 Jeff Moyer - 1:4.1.2-1 +- Change hard-coded paths in the spec file to the %%{_xxx} variety. +- Update to upstream 4.1.2. +- Add a STRIPDASH option to /etc/sysconfig/autofs which allows for + compatibility with the Sun automounter options specification syntax in + auto.master. See /etc/sysconfig/autofs for more information. Addresses + bug 113950. + +* Tue Apr 6 2004 Jeff Moyer - 1:4.1.1-6 +- Add the /etc/sysconfig/autofs file, and supporting infrastructure in + the init script. +- Add support for UNDERSCORE_TO_DOT for those who want it. +- We no longer own /net. Move it to the filesystem package. + +* Tue Mar 30 2004 Jeff Moyer - 1:4.1.1-5 +- Clarify documentation on direct maps. +- Send automount daemons a HUP signal during reload. This tells them to + re-read maps (otherwise they use a cached version. Patch from the autofs + maintainer. + +* Mon Mar 22 2004 Jeff Moyer - 1:4.1.1-4 +- Fix init script to print out failures where appropriate. +- Build the automount daemon as a PIE. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-3 +- Fix bug in get_best_mount, whereby if there is only one option, we + choose nothing. This is primarily due to the fact that we pass 0 in to + the get_best_mount function for the long timeout parameter. So, we + timeout trying to contact our first and only server, and never retry. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-2 +- Prevent startup if a mountpoint is already mounted. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-1 +- Update to 4.1.1, as it fixes problems with wildcards that people are + seeing quite a bit. + +* Wed Mar 17 2004 Jeff Moyer - 1:4.1.0-8 +- Fix ldap init code to parse server name and options correctly. + +* Tue Mar 16 2004 Jeff Moyer - 1:4.1.0-7 +- Moved the freeing of ap.path to cleanup_exit, as we would otherwise + reference an already-freed variable. + +* Mon Mar 15 2004 Jeff Moyer - 1:4.1.0-6 +- add %%config(noreplace) for auto.* config files. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-5 +- make the init script only recognize redhat systems. Nalin seems to remember + some arcane build system error that can be caused if we don't do this. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-4 +- comment out /net and /misc from the default auto.master. /net is important + since in a default shipping install, we can neatly co-exist with amd. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-3 +- Ported forward Red Hat's patches from 3.1.7 that were not already present + in 4.1.0. +- Moving autofs from version 3.1.7 to 4.1.0 + +* Mon Sep 29 2003 Ian Kent +- Added work around for O(1) patch oddity. + +* Sat Aug 16 2003 Ian Kent +- Fixed tree mounts. +- Corrected transciption error in autofs4-2.4.18 kernel module + +* Sun Aug 10 2003 Ian Kent +- Checked and merged most of the RedHat v3 patches +- Fixed kernel module handling wu-ftpd login problem (again) + +* Thu Aug 7 2003 Ian Kent +- Removed ineffective lock stuff +- Added -n to bind mount to prevent mtab update error +- Added retry to autofs umount to clean matb after fail +- Redirected messages from above to debug log and added info message +- Fixed autofs4 module reentrancy, pwd and chroot handling + +* Wed Jul 30 2003 Ian Kent +- Fixed autofs4 ghosting patch for 2.4.19 and above (again) +- Fixed autofs directory removal on failure of autofs mount +- Fixed lock file wait function overlapping calls to (u)mount + +* Sun Jul 27 2003 Ian Kent +- Implemented LDAP direct map handling for nisMap and automountMap schema +- Fixed autofs4 ghosting patch for 2.4.19 and above (again) +- Added locking to fix overlapping internal calls to (u)mount +- Added wait for mtab~ to improve tolerance of overlapping external calls to (u)mount +- Fixed ghosted directory removal after failed mount attempt + +* Wed May 28 2003 Ian Kent +- Cleaned up an restructured my added code +- Corrected ghosting problem with 2.4.19 and above +- Added autofs4 ghosting patch for 2.4.19 and above +- Implemented HUP signal to force update of ghosted maps + +* Sat Mar 23 2002 Ian Kent +- Add patch to implement directory ghosting and direct mounts +- Add patch to for autofs4 module to support ghosting + +* Wed Jan 17 2001 Nalin Dahyabhai +- use -fPIC instead of -fpic for modules and honor other RPM_OPT_FLAGS + +* Tue Feb 29 2000 Nalin Dahyabhai +- enable hesiod support over libbind + +* Fri Aug 13 1999 Cristian Gafton +- add patch from rth to avoid an infinite loop diff --git a/sources b/sources new file mode 100644 index 0000000..431c7d7 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (autofs-5.1.4.tar.gz) = f9d388ba2dad6ec66dc57b347615c610782c8fb73fce3895da40d13f0987c1f402d1406e1a7c3f5e36d63a329b2f8c72c5fbad8e5e684c45393ce45a3f103eb1