Browse Source

- autofs: bump version to 5.1.8; rework build; add script to keep patches up-to-date

master
vanhofen 2 years ago
parent
commit
8fedd5260e
  1. 19
      package/autofs/autofs-update-patches.sh
  2. 34
      package/autofs/autofs.mk
  3. 139
      package/autofs/patches/0001-autofs-5.1.8-fix-kernel-mount-status-notification.patch
  4. 41
      package/autofs/patches/0002-autofs-5.1.8-fix-fedfs-build-flags.patch
  5. 60
      package/autofs/patches/0003-autofs-5.1.8-fix-set-open-file-limit.patch
  6. 175
      package/autofs/patches/0004-autofs-5.1.8-improve-descriptor-open-error-reporting.patch
  7. 91
      package/autofs/patches/0005-autofs-5.1.8-fix-root-offset-error-handling.patch
  8. 38
      package/autofs/patches/0006-autofs-5.1.8-fix-fix-root-offset-error-handling.patch
  9. 42
      package/autofs/patches/0007-autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch
  10. 50
      package/autofs/patches/0008-autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch
  11. 40
      package/autofs/patches/0009-autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch
  12. 38
      package/autofs/patches/0010-autofs-5.1.8-bailout-on-rpc-systemerror.patch
  13. 102
      package/autofs/patches/0011-autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch
  14. 48
      package/autofs/patches/0012-autofs-5.1.8-simplify-cache_add-a-little.patch
  15. 59
      package/autofs/patches/0013-autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch
  16. 44
      package/autofs/patches/0014-autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch
  17. 39
      package/autofs/patches/0015-autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch
  18. 68
      package/autofs/patches/0016-autofs-5.1.8-fix-sysconf-return-handling.patch
  19. 85
      package/autofs/patches/0017-autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch
  20. 116
      package/autofs/patches/0018-autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch
  21. 135
      package/autofs/patches/0019-autofs-5.1.8-dont-use-initgroups-at-spawn.patch
  22. 60
      package/autofs/patches/0020-autofs-5.1.8-fix-bashism-in-configure.patch
  23. 46
      package/autofs/patches/0021-autofs-5.1.8-fix-missing-include-in-hash_h.patch
  24. 48
      package/autofs/patches/0022-autofs-5.1.8-define-fallback-dummy-NSS-config-path.patch
  25. 77
      package/autofs/patches/0023-autofs-5.1.8-avoid-internal-stat.h-definitions.patch
  26. 46
      package/autofs/patches/0024-autofs-5.1.8-add-missing-include-to-hash.h-for-_WORDSIZE.patch
  27. 47
      package/autofs/patches/0025-autofs-5.1.8-add-missing-include-to-log.h-for-pid_t.patch
  28. 56
      package/autofs/patches/0026-autofs-5.1.8-define-_SWORD_TYPE-for-musl.patch
  29. 62
      package/autofs/patches/0027-autofs-5.1.8-add-strerror_r-helper-for-musl.patch
  30. 104
      package/autofs/patches/0028-autofs-5.1.8-update-configure.patch
  31. 113
      package/autofs/patches/0029-autofs-5.1.8-handle-innetgr-not-present-in-musl.patch
  32. 48
      package/autofs/patches/autofs-5.1.7-Fix-option-for-master_read_wait.patch
  33. 136
      package/autofs/patches/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch
  34. 51
      package/autofs/patches/autofs-5.1.7-add-buffer-length-check-to-rmdir_path.patch
  35. 108
      package/autofs/patches/autofs-5.1.7-add-buffer-length-checks-to-autofs-mount_mount.patch
  36. 51
      package/autofs/patches/autofs-5.1.7-add-copy-length-check-in-umount_autofs_indirect.patch
  37. 104
      package/autofs/patches/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch
  38. 42
      package/autofs/patches/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch
  39. 60
      package/autofs/patches/autofs-5.1.7-add-mapent-path-length-check-in-handle_packet_expire_direct.patch
  40. 177
      package/autofs/patches/autofs-5.1.7-add-mapent-tree-implementation.patch
  41. 55
      package/autofs/patches/autofs-5.1.7-add-missing-description-of-null-map-option.patch
  42. 42
      package/autofs/patches/autofs-5.1.7-add-missing-free-in-handle_mounts.patch
  43. 310
      package/autofs/patches/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch
  44. 50
      package/autofs/patches/autofs-5.1.7-add-set_offset_tree_catatonic.patch
  45. 257
      package/autofs/patches/autofs-5.1.7-add-some-buffer-length-checks-to-master-map-parser.patch
  46. 552
      package/autofs/patches/autofs-5.1.7-add-some-multi-mount-macros.patch
  47. 133
      package/autofs/patches/autofs-5.1.7-add-tree_mapent_add_node.patch
  48. 94
      package/autofs/patches/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch
  49. 119
      package/autofs/patches/autofs-5.1.7-add-tree_mapent_delete_offsets.patch
  50. 83
      package/autofs/patches/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch
  51. 335
      package/autofs/patches/autofs-5.1.7-add-xdr_exports.patch
  52. 38
      package/autofs/patches/autofs-5.1.7-also-require-TCP_REQUESTED-when-setting-NFS-port.patch
  53. 44
      package/autofs/patches/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch
  54. 50
      package/autofs/patches/autofs-5.1.7-check-for-offset-with-no-mount-location.patch
  55. 64
      package/autofs/patches/autofs-5.1.7-cleanup-cache_delete-a-little.patch
  56. 207
      package/autofs/patches/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch
  57. 64
      package/autofs/patches/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch
  58. 45
      package/autofs/patches/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch
  59. 47
      package/autofs/patches/autofs-5.1.7-dont-use-AUTOFS_DEV_IOCTL_CLOSEMOUNT.patch
  60. 112
      package/autofs/patches/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch
  61. 86
      package/autofs/patches/autofs-5.1.7-eliminate-buffer-usage-from-handle_mounts_cleanup.patch
  62. 378
      package/autofs/patches/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch
  63. 290
      package/autofs/patches/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch
  64. 140
      package/autofs/patches/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch
  65. 90
      package/autofs/patches/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch
  66. 216
      package/autofs/patches/autofs-5.1.7-eliminate-some-more-alloca-usage.patch
  67. 128
      package/autofs/patches/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch
  68. 52
      package/autofs/patches/autofs-5.1.7-fix-amd-hosts-mount-expire.patch
  69. 124
      package/autofs/patches/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch
  70. 40
      package/autofs/patches/autofs-5.1.7-fix-arg-not-used-in-print.patch
  71. 124
      package/autofs/patches/autofs-5.1.7-fix-concat_options-error-handling.patch
  72. 39
      package/autofs/patches/autofs-5.1.7-fix-dandling-symlink-creation-if-nis-support-is-not-available.patch
  73. 55
      package/autofs/patches/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch
  74. 135
      package/autofs/patches/autofs-5.1.7-fix-direct-mount-deadlock.patch
  75. 39
      package/autofs/patches/autofs-5.1.7-fix-double-free-in-parse_mapent.patch
  76. 37
      package/autofs/patches/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch
  77. 38
      package/autofs/patches/autofs-5.1.7-fix-flag-check-in-umount_multi.patch
  78. 300
      package/autofs/patches/autofs-5.1.7-fix-hosts-map-offset-order.patch
  79. 251
      package/autofs/patches/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch
  80. 135
      package/autofs/patches/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch
  81. 44
      package/autofs/patches/autofs-5.1.7-fix-incorrect-print-format-specifiers.patch
  82. 64
      package/autofs/patches/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch
  83. 60
      package/autofs/patches/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch
  84. 36
      package/autofs/patches/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch
  85. 40
      package/autofs/patches/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch
  86. 38
      package/autofs/patches/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch
  87. 67
      package/autofs/patches/autofs-5.1.7-fix-mount_fullpath.patch
  88. 60
      package/autofs/patches/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch
  89. 207
      package/autofs/patches/autofs-5.1.7-fix-offset-entries-order.patch
  90. 38
      package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch
  91. 58
      package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch
  92. 44
      package/autofs/patches/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch
  93. 43
      package/autofs/patches/autofs-5.1.7-fix-use-of-possibly-NULL-var-in-lookup_program_c-match_key.patch
  94. 69
      package/autofs/patches/autofs-5.1.7-make-NFS-version-check-flags-consistent.patch
  95. 352
      package/autofs/patches/autofs-5.1.7-make-tree-implementation-data-independent.patch
  96. 118
      package/autofs/patches/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch
  97. 72
      package/autofs/patches/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch
  98. 171
      package/autofs/patches/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch
  99. 83
      package/autofs/patches/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch
  100. 206
      package/autofs/patches/autofs-5.1.7-refactor-get_nfs_info.patch

19
package/autofs/autofs-update-patches.sh

@ -0,0 +1,19 @@
#!/bin/bash
version=5.1.8
url=https://mirrors.edge.kernel.org/pub/linux/daemons/autofs/v5/patches-5.1.9
cd patches
wget -N $url/patch_order_$version
i=0
cat patch_order_$version | while read p; do
case "$p" in
*.patch)
i=$((i+1))
t=$(printf "%04d\n" $i)-$p
if [ ! -f $t ]; then
wget -O $t $url/$p
fi
;;
esac
done

34
package/autofs/autofs.mk

@ -4,21 +4,11 @@
#
################################################################################
AUTOFS_VERSION = 5.1.7
AUTOFS_VERSION = 5.1.8
AUTOFS_DIR = autofs-$(AUTOFS_VERSION)
AUTOFS_SOURCE = autofs-$(AUTOFS_VERSION).tar.xz
AUTOFS_SITE = $(KERNEL_MIRROR)/linux/daemons/autofs/v5
$(DL_DIR)/$(AUTOFS_SOURCE):
$(download) $(AUTOFS_SITE)/$(AUTOFS_SOURCE)
# cd package/autofs/patches
# wget -N https://mirrors.edge.kernel.org/pub/linux/daemons/autofs/v5/patches-5.1.8/patch_order_5.1.7
# for p in $(cat patch_order_5.1.7); do test -f $p || wget https://mirrors.edge.kernel.org/pub/linux/daemons/autofs/v5/patches-5.1.8/$p; done
AUTOFS_PATCH = 0000-force-STRIP-to-emtpy.patch
AUTOFS_PATCH += $(shell cat $(PKG_PATCHES_DIR)/patch_order_$(AUTOFS_VERSION))
AUTOFS_DEPENDENCIES = libtirpc
AUTOFS_AUTORECONF = YES
@ -48,24 +38,20 @@ AUTOFS_CONF_OPTS = \
--with-fifodir=/var/run \
--with-flagdir=/var/run
AUTOFS_MAKE_ENV = \
DONTSTRIP=1
# We're patching Makefile.rules, so there's no need to set DONTSTRIP
#AUTOFS_MAKE_ENV = \
# DONTSTRIP=1
define AUTOFS_PATCH_RPC_SUBS_H
$(SED) "s|nfs/nfs.h|linux/nfs.h|" $(PKG_BUILD_DIR)/include/rpc_subs.h
endef
AUTOFS_POST_PATCH_HOOKS += AUTOFS_PATCH_RPC_SUBS_H
autofs: $(AUTOFS_DEPENDENCIES) $(DL_DIR)/$(AUTOFS_SOURCE) | $(TARGET_DIR)
$(REMOVE)/$(PKG_DIR)
$(UNTAR)/$(PKG_SOURCE)
$(call APPLY_PATCHES,$($(PKG)_PATCH))
$(call TARGET_CONFIGURE)
$(CHDIR)/$(PKG_DIR); \
$($(PKG)_MAKE_ENV) \
$(MAKE); \
$(MAKE) install DESTDIR=$(TARGET_DIR)
define AUTOFS_INSTALL_FILES
$(INSTALL_COPY) $(PKG_FILES_DIR)-skel/* $(TARGET_DIR)/
$(UPDATE-RC.D) autofs defaults 75 25
$(REMOVE)/$(PKG_DIR)
$(TOUCH)
endef
AUTOFS_TARGET_FINALIZE_HOOKS += AUTOFS_INSTALL_FILES
autofs: | $(TARGET_DIR)
$(call autotools-package)

139
package/autofs/patches/0001-autofs-5.1.8-fix-kernel-mount-status-notification.patch

@ -0,0 +1,139 @@
autofs-5.1.8 - fix kernel mount status notification
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 2 ++
daemon/direct.c | 19 +++++++++++--------
daemon/indirect.c | 19 +++++++++++--------
3 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3be6119a..18a2f29c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,5 @@
+- fix kernel mount status notification.
+
19/10/2021 autofs-5.1.8
- add xdr_exports().
- remove mount.x and rpcgen dependencies.
diff --git a/daemon/direct.c b/daemon/direct.c
index 4a56486b..c2331155 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1147,12 +1147,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
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);
}
@@ -1181,7 +1187,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);
@@ -1195,9 +1202,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);
}
@@ -1207,8 +1212,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);
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index b73c2781..23ef9f41 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -683,13 +683,18 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
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)
@@ -718,7 +723,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);
@@ -731,9 +737,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);
}
@@ -742,7 +746,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);
}

41
package/autofs/patches/0002-autofs-5.1.8-fix-fedfs-build-flags.patch

@ -0,0 +1,41 @@
autofs-5.1.8 - fix fedfs build flags
From: Ian Kent <raven@themaw.net>
Dynamic executables should be compiled with -fPIE and linked with -pie.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
fedfs/Makefile | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 18a2f29c..61090a99 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,5 @@
- fix kernel mount status notification.
+- fix fedfs build flags.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/fedfs/Makefile b/fedfs/Makefile
index dff749e4..65b2a2f5 100644
--- a/fedfs/Makefile
+++ b/fedfs/Makefile
@@ -23,12 +23,12 @@ LDFLAGS += -rdynamic
all: mount.fedfs fedfs-map-nfs4
mount.fedfs: $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS)
- $(CC) -o mount.fedfs \
+ $(CC) $(DAEMON_LDFLAGS) -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 \
+ $(CC) $(DAEMON_LDFLAGS) -o fedfs-map-nfs4 \
$(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) \
$(LDFLAGS) $(LIBRESOLV) $(LIBS)

60
package/autofs/patches/0003-autofs-5.1.8-fix-set-open-file-limit.patch

@ -0,0 +1,60 @@
autofs-5.1.8 - fix set open file limit
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 61090a99..0cbfbe87 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
- fix kernel mount status notification.
- fix fedfs build flags.
+- fix set open file limit.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/automount.c b/daemon/automount.c
index cc286892..b8cbdc1b 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -94,7 +94,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);
@@ -2486,9 +2486,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)

175
package/autofs/patches/0004-autofs-5.1.8-improve-descriptor-open-error-reporting.patch

@ -0,0 +1,175 @@
autofs-5.1.8 - improve descriptor open error reporting
From: Ian Kent <raven@themaw.net>
Add error message reporting to the descriptor open functions.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0cbfbe87..870fd8f3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
- fix kernel mount status notification.
- fix fedfs build flags.
- fix set open file limit.
+- improve descriptor open error reporting.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/automount.c b/daemon/automount.c
index b8cbdc1b..b47c485b 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -868,9 +868,6 @@ static int create_logpri_fifo(struct autofs_point *ap)
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;
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 7992c5ab..914e5288 100644
--- a/daemon/spawn.c
+++ b/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 flags, int mode)
#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 flags, int mode)
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 protocol)
#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));
diff --git a/lib/mounts.c b/lib/mounts.c
index 4c866885..39b7fe81 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2169,11 +2169,8 @@ struct mnt_list *get_mnt_list(const char *path, int include)
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 *mp, unsigned int type)
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);
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 691abedb..b5eb1117 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -214,11 +214,8 @@ static char *lookup_one(struct autofs_point *ap,
* 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]);

91
package/autofs/patches/0005-autofs-5.1.8-fix-root-offset-error-handling.patch

@ -0,0 +1,91 @@
autofs-5.1.8 - fix root offset error handling
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 10 +++++++++-
modules/parse_sun.c | 6 ++++++
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 870fd8f3..6f18a0bb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@
- fix fedfs build flags.
- fix set open file limit.
- improve descriptor open error reporting.
+- fix root offset error handling.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/direct.c b/daemon/direct.c
index c2331155..8810900c 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1167,6 +1167,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;
@@ -1230,7 +1231,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;
@@ -1271,6 +1271,14 @@ 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.
+ */
+ 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);
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index d9ac0c94..56fe4161 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1142,6 +1142,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
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] = '/';
@@ -1186,6 +1189,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
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;
}
}

38
package/autofs/patches/0006-autofs-5.1.8-fix-fix-root-offset-error-handling.patch

@ -0,0 +1,38 @@
autofs-5.1.8 - fix fix root offset error handling
From: Ian Kent <raven@themaw.net>
The change to fix root offset error handlling is missing a cache read
lock prior to the key lookup, the following unmatched unlock then
causes a hang.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 6f18a0bb..f81b0259 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@
- fix set open file limit.
- improve descriptor open error reporting.
- fix root offset error handling.
+- fix fix root offset error handling.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/direct.c b/daemon/direct.c
index 8810900c..cf3f24d7 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1275,6 +1275,7 @@ static void *do_mount_direct(void *arg)
/* 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);

42
package/autofs/patches/0007-autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch

@ -0,0 +1,42 @@
autofs-5.1.8 - fix nonstrict fail handling of last offset mount
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index f81b0259..bd1f672c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
- improve descriptor open error reporting.
- fix root offset error handling.
- fix fix root offset error handling.
+- fix nonstrict fail handling of last offset mount.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/mounts.c b/lib/mounts.c
index 39b7fe81..b4229908 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1940,7 +1940,7 @@ static int tree_mapent_mount_offsets_work(struct tree_node *n, void *ptr)
tree_mapent_mount_offsets(oe, !ctxt->strict);
}
- return ret;
+ return (ctxt->strict ? ret : 1);
}
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict)

50
package/autofs/patches/0008-autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch

@ -0,0 +1,50 @@
autofs-5.1.8 - dont fail on duplicate host export entry
From: Ian Kent <raven@themaw.net>
If we encounter a duplicate host export entry don't fail, just ignore
it and return the duplicate.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index bd1f672c..aaf20cd6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
- fix root offset error handling.
- fix fix root offset error handling.
- fix nonstrict fail handling of last offset mount.
+- dont fail on duplicate offset entry tree add.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/mounts.c b/lib/mounts.c
index b4229908..451849a6 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1341,7 +1341,7 @@ static struct tree_node *tree_add_node(struct tree_node *root, void *ptr)
}
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_node *n, void *ptr)
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;
}

40
package/autofs/patches/0009-autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch

@ -0,0 +1,40 @@
autofs-5.1.8 - fix loop under run in cache_get_offset_parent()
From: Frank Sorenson <sorenson@redhat.com>
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 <sorenson@redhat.com>
---
CHANGELOG | 1 +
lib/cache.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index aaf20cd6..b4b064ff 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
- fix 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().
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/cache.c b/lib/cache.c
index 66dda5d9..8aed28ea 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -710,7 +710,7 @@ struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key)
*tail = 0;
tail--;
- if (tail == parent)
+ if (tail <= parent)
break;
me = cache_lookup_distinct(mc, parent);

38
package/autofs/patches/0010-autofs-5.1.8-bailout-on-rpc-systemerror.patch

@ -0,0 +1,38 @@
autofs-5.1.8 - bailout on rpc systemerror
From: Ian Kent <raven@themaw.net>
If there's a system error (eg. oversize packet received) just give up
since redoing the call would likely end up with the same error.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/rpc_subs.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index b4b064ff..575f186d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,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().
+- bailout on rpc systemerror.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 7b8162b4..ee7f94b9 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -1195,6 +1195,8 @@ static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exp
info->timeout);
if (status == RPC_SUCCESS)
break;
+ if (status == RPC_SYSTEMERROR)
+ break;
if (++vers_entry > 2)
break;
CLNT_CONTROL(client, CLSET_VERS,

102
package/autofs/patches/0011-autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch

@ -0,0 +1,102 @@
autofs-5.1.8 - fix nfsv4 only mounts should not use rpcbind
From: Ian Kent <raven@themaw.net>
Commit 606795ecfaa1 ("autofs-5.1.7 - also require TCP_REQUESTED when
setting NFS port" together with commit 26fb6b5408be) caused NFSv4 only
mounts to also use rpcbind to probe availability which breaks the
requirememt that this type of mount not use rpcbind at all.
Fix this by treating fstype=nfs4 mounts as a special case which doesn't
use rpcbind.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/replicated.h | 2 ++
modules/mount_nfs.c | 13 +++++++------
modules/replicated.c | 4 ++--
4 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 575f186d..4e5e82d0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,7 @@
- dont fail on duplicate offset entry tree add.
- fix loop under run in cache_get_offset_parent().
- bailout on rpc systemerror.
+- fix nfsv4 only mounts should not use rpcbind.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/include/replicated.h b/include/replicated.h
index 95ff1f0d..f889a56a 100644
--- a/include/replicated.h
+++ b/include/replicated.h
@@ -35,6 +35,8 @@
#define NFS3_REQUESTED NFS3_SUPPORTED
#define NFS4_REQUESTED NFS4_SUPPORTED
+#define NFS4_ONLY_REQUESTED 0x0800
+
#define TCP_SUPPORTED 0x0001
#define UDP_SUPPORTED 0x0002
#define TCP_REQUESTED TCP_SUPPORTED
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 0ab87dcf..feb5afcd 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -92,7 +92,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
mount_default_proto = defaults_get_mount_nfs_default_proto();
vers = NFS_VERS_DEFAULT | NFS_PROTO_DEFAULT;
if (strcmp(fstype, "nfs4") == 0)
- vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED;
+ vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED | NFS4_ONLY_REQUESTED;
else if (mount_default_proto == 4)
vers = vers | NFS4_VERS_DEFAULT;
@@ -157,15 +157,16 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
} else {
/* Is any version of NFSv4 in the options */
if (_strncmp("vers=4", cp, 6) == 0 ||
- _strncmp("nfsvers=4", cp, 9) == 0)
- vers = NFS4_VERS_MASK | TCP_SUPPORTED;
- else if (_strncmp("vers=3", cp, o_len) == 0 ||
+ _strncmp("nfsvers=4", cp, 9) == 0) {
+ vers &= ~(NFS_VERS_MASK);
+ vers |= NFS4_VERS_MASK | TCP_SUPPORTED | NFS4_ONLY_REQUESTED;
+ } else if (_strncmp("vers=3", cp, o_len) == 0 ||
_strncmp("nfsvers=3", cp, o_len) == 0) {
- vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK);
+ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK | NFS4_ONLY_REQUESTED);
vers |= NFS3_REQUESTED;
} else if (_strncmp("vers=2", cp, o_len) == 0 ||
_strncmp("nfsvers=2", cp, o_len) == 0) {
- vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK);
+ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK | NFS4_ONLY_REQUESTED);
vers |= NFS2_REQUESTED;
} else if (strstr(cp, "port=") == cp &&
o_len - 5 < 25) {
diff --git a/modules/replicated.c b/modules/replicated.c
index 09075dd0..cdb7c617 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -291,7 +291,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
rpc_info->proto = proto;
if (port < 0) {
- if ((version & NFS4_REQUESTED) && (version & TCP_REQUESTED))
+ if (version & NFS4_REQUESTED && (version & NFS4_ONLY_REQUESTED))
rpc_info->port = NFS_PORT;
else
port = 0;
@@ -525,7 +525,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
{
struct conn_info pm_info, rpc_info;
time_t timeout = RPC_TIMEOUT;
- unsigned int supported, vers = (NFS_VERS_MASK | NFS4_VERS_MASK);
+ unsigned int supported, vers = (NFS_VERS_MASK | NFS4_VERS_MASK | NFS4_ONLY_REQUESTED);
int ret = 0;
if (!check_address_proto(logopt, host, version))

48
package/autofs/patches/0012-autofs-5.1.8-simplify-cache_add-a-little.patch

@ -0,0 +1,48 @@
autofs-5.1.8 - simplify cache_add() a little
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4e5e82d0..5b37460f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@
- fix loop under run in cache_get_offset_parent().
- bailout on rpc systemerror.
- fix nfsv4 only mounts should not use rpcbind.
+- simplify cache_add() a little.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/cache.c b/lib/cache.c
index 8aed28ea..4f908daf 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -564,6 +564,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
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, struct map_source *ms, const char *key, c
existing = next;
}
- me->next = existing->next;
existing->next = me;
}
return CHE_OK;

59
package/autofs/patches/0013-autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch

@ -0,0 +1,59 @@
autofs-5.1.8 - fix use after free in tree_mapent_delete_offset_tree()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 16 +++++++++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5b37460f..f05c9c6b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,7 @@
- bailout on rpc systemerror.
- fix nfsv4 only mounts should not use rpcbind.
- simplify cache_add() a little.
+- fix use after free in tree_mapent_delete_offset_tree().
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/mounts.c b/lib/mounts.c
index 451849a6..c731f464 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1666,16 +1666,26 @@ static int tree_mapent_delete_offset_tree(struct tree_node *root)
*/
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);

44
package/autofs/patches/0014-autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch

@ -0,0 +1,44 @@
autofs-5.1.8 - fix memory leak in xdr_exports()
From: Ian Kent <raven@themaw.net>
Converting xdr_exports() to not be recursive introduced a memory leak
if an error is encountered, fix it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/rpc_subs.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index f05c9c6b..9d57a21b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@
- fix nfsv4 only mounts should not use rpcbind.
- simplify cache_add() a little.
- fix use after free in tree_mapent_delete_offset_tree().
+- fix memory leak in xdr_exports().
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index ee7f94b9..0c833af0 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -1151,8 +1151,13 @@ bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports)
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;

39
package/autofs/patches/0015-autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch

@ -0,0 +1,39 @@
autofs-5.1.8 - avoid calling pthread_getspecific() with NULL key_thread_attempt_id
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/log.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 9d57a21b..dacc2fa0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,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.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/log.c b/lib/log.c
index 0cb47d7e..d1edef28 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -38,6 +38,9 @@ static char *prepare_attempt_prefix(const char *msg)
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;

68
package/autofs/patches/0016-autofs-5.1.8-fix-sysconf-return-handling.patch

@ -0,0 +1,68 @@
autofs-5.1.8 - fix sysconf(3) return handling
From: Fabian Groffen <grobian@gentoo.org>
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 <grobian@gentoo.org>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 13 +++++++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index dacc2fa0..a063a126 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -13,6 +13,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.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/lib/mounts.c b/lib/mounts.c
index c731f464..ad8f3de4 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2385,11 +2385,17 @@ void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid)
/* 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 logopt, uid_t uid, gid_t gid)
/* 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;

85
package/autofs/patches/0017-autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch

@ -0,0 +1,85 @@
autofs-5.1.8 - remove nonstrict parameter from tree_mapent_umount_offsets()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 2 +-
include/mounts.h | 2 +-
lib/mounts.c | 6 +++---
4 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a063a126..5402b88d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,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().
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/automount.c b/daemon/automount.c
index b47c485b..353e4f54 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -558,7 +558,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
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);
diff --git a/include/mounts.h b/include/mounts.h
index ddb7e4c5..23c7ba1c 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -182,7 +182,7 @@ int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct
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);
diff --git a/lib/mounts.c b/lib/mounts.c
index ad8f3de4..617c1d54 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1843,7 +1843,7 @@ static int tree_mapent_umount_offset(struct mapent *oe, void *ptr)
* 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_work(struct tree_node *n, void *ptr)
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;

116
package/autofs/patches/0018-autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch

@ -0,0 +1,116 @@
autofs-5.1.8 - fix handling of incorrect return from umount_ent()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 3 +--
lib/mounts.c | 19 ++++++++++---------
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5402b88d..72a5aa59 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,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().
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/automount.c b/daemon/automount.c
index 353e4f54..85847edf 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -609,8 +609,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
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;
diff --git a/lib/mounts.c b/lib/mounts.c
index 617c1d54..a3f9dfd7 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1869,8 +1869,7 @@ static int tree_mapent_umount_offset(struct mapent *oe, void *ptr)
*/
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 mapent *oe)
*/
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(struct autofs_point *ap, struct mapent *me)
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, const char *path)
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, const char *path)
* 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)

135
package/autofs/patches/0019-autofs-5.1.8-dont-use-initgroups-at-spawn.patch

@ -0,0 +1,135 @@
autofs-5.1.8 - dont use initgroups() at spawn
From: Ian Kent <raven@themaw.net>
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 <rbergant@redhat.com>.
Reported-by: Roberto Bergantinos <rbergant@redhat.com>
Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()")
Signed-off-by: Roberto Bergantinos <rbergant@redhat.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 72a5aa59..e1214323 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,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.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 914e5288..6f8856a9 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -26,6 +26,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mount.h>
+#include <pwd.h>
#include "automount.h"
@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, unsigned int wait,
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, unsigned int wait,
}
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, unsigned int wait,
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, unsigned int wait,
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) {

60
package/autofs/patches/0020-autofs-5.1.8-fix-bashism-in-configure.patch

@ -0,0 +1,60 @@
autofs-5.1.8 - fix bashism in configure
From: Sam James <sam@gentoo.org>
configure scripts need to work with a POSIX-compliant shell,
so let's not use a bashism here.
```
checking for res_query in -lresolv... yes
checking for libhesiod... no
./configure: 4880: test: 0: unexpected operator
checking how to run the C preprocessor... gcc -E
```
Tested-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
---
CHANGELOG | 1 +
configure.in | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e1214323..dd76b02f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,7 @@
- remove nonstrict parameter from tree_mapent_umount_offsets().
- fix handling of incorrect return from umount_ent().
- dont use initgroups() at spawn.
+- fix bashism in configure.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/configure.in b/configure.in
index 750ffb48..723bb30d 100644
--- a/configure.in
+++ b/configure.in
@@ -262,7 +262,7 @@ if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0"
then
HAVE_HESIOD=0
AF_CHECK_LIBHESIOD()
- if test "$HAVE_HESIOD" == "1"; then
+ if test "$HAVE_HESIOD" = "1"; then
AC_DEFINE(WITH_HESIOD,1,
[Define if using Hesiod as a source of automount maps])
fi
@@ -337,11 +337,11 @@ AC_ARG_WITH(sasl,
SASL_FLAGS="-I${withval}/include"
fi
)
-if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" = "1"
then
HAVE_SASL=0
AC_CHECK_LIB(sasl2, sasl_client_start, HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2", , -lsasl2 $LIBS)
- if test "$HAVE_SASL" == "1"; then
+ if test "$HAVE_SASL" = "1"; then
AC_DEFINE(WITH_SASL,1,
[Define if using SASL authentication with the LDAP module])
fi

46
package/autofs/patches/0021-autofs-5.1.8-fix-missing-include-in-hash_h.patch

@ -0,0 +1,46 @@
autofs-5.1.8 - fix missing include in hash.h
From: Sam James <sam@gentoo.org>
Fixes a build failure with the musl libc:
```
../include/hash.h:74:8: error: unknown type name '__always_inline'
74 | static __always_inline uint32_t hash_64(uint64_t val, unsigned int bits)
| ^~~~~~~~~~~~~~~
```
We need to include stddef.h from linux-headers to ensure _always_inline
is always defined.
Bug: https://bugs.gentoo.org/828918
Tested-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
---
CHANGELOG | 1 +
include/hash.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index dd76b02f..53b487eb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,7 @@
- fix handling of incorrect return from umount_ent().
- dont use initgroups() at spawn.
- fix bashism in configure.
+- musl: fix missing include in hash.h.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/include/hash.h b/include/hash.h
index 2447f293..010acd7e 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -3,6 +3,7 @@
/* Fast hashing routine for ints, longs and pointers.
(C) 2002 Nadia Yvette Chambers, IBM */
+#include <linux/stddef.h>
#include <sys/types.h>
#include <stdint.h>

48
package/autofs/patches/0022-autofs-5.1.8-define-fallback-dummy-NSS-config-path.patch

@ -0,0 +1,48 @@
autofs-5.1.8 - define fallback dummy NSS config path
From: Sam James <sam@gentoo.org>
On musl, _PATH_NSSWITCH_CONF won't be defined (it doesn't support NSS),
so let's give it a dummy path when it's not defined by glibc.
Fixes build failures like:
```
../include/nsswitch.h:27:23: error: '_PATH_NSSWITCH_CONF' undeclared (first use in this function)
27 | #define NSSWITCH_FILE _PATH_NSSWITCH_CONF
| ^~~~~~~~~~~~~~~~~~~
```
Tested-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
---
CHANGELOG | 1 +
include/nsswitch.h | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 53b487eb..0627db48 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@
- dont use initgroups() at spawn.
- fix bashism in configure.
- musl: fix missing include in hash.h.
+- musl: define fallback dummy NSS config path
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/include/nsswitch.h b/include/nsswitch.h
index d3e40277..8376113e 100644
--- a/include/nsswitch.h
+++ b/include/nsswitch.h
@@ -24,6 +24,10 @@
#include <netdb.h>
#include "list.h"
+#ifndef _PATH_NSSWITCH_CONF
+#define _PATH_NSSWITCH_CONF "/dev/null"
+#endif
+
#define NSSWITCH_FILE _PATH_NSSWITCH_CONF
enum nsswitch_status {

77
package/autofs/patches/0023-autofs-5.1.8-avoid-internal-stat.h-definitions.patch

@ -0,0 +1,77 @@
autofs-5.1.8 - avoid internal stat.h definitions
From: Sam James <sam@gentoo.org>
Tested-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
---
CHANGELOG | 1 +
daemon/lookup.c | 6 +++---
modules/lookup_multi.c | 4 ++--
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0627db48..98c8da8d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@
- fix bashism in configure.
- musl: fix missing include in hash.h.
- musl: define fallback dummy NSS config path
+- musl: avoid internal stat.h definitions.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 0b281f83..4a286d6b 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -397,7 +397,7 @@ static int read_file_source_instance(struct autofs_point *ap, struct map_source
return NSS_STATUS_NOTFOUND;
}
- if (st.st_mode & __S_IEXEC)
+ if (st.st_mode & S_IEXEC)
type = src_prog;
else
type = src_file;
@@ -930,7 +930,7 @@ static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_
return NSS_STATUS_NOTFOUND;
}
- if (st.st_mode & __S_IEXEC)
+ if (st.st_mode & S_IEXEC)
type = src_prog;
else
type = src_file;
@@ -1077,7 +1077,7 @@ static struct map_source *lookup_get_map_source(struct master_mapent *entry)
if (!S_ISREG(st.st_mode))
return NULL;
- if (st.st_mode & __S_IEXEC)
+ if (st.st_mode & S_IEXEC)
type = "program";
else
type = "file";
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index fadd2ea6..cf109de9 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -247,7 +247,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
continue;
}
- if (st.st_mode & __S_IEXEC)
+ if (st.st_mode & S_IEXEC)
type = src_prog;
else
type = src_file;
@@ -452,7 +452,7 @@ int lookup_reinit(const char *my_mapfmt,
continue;
}
- if (st.st_mode & __S_IEXEC)
+ if (st.st_mode & S_IEXEC)
type = src_prog;
else
type = src_file;

46
package/autofs/patches/0024-autofs-5.1.8-add-missing-include-to-hash.h-for-_WORDSIZE.patch

@ -0,0 +1,46 @@
autofs-5.1.8 - add missing include to hash.h for _WORDSIZE
From: Sam James <sam@gentoo.org>
Fixes build failure on musl like:
```
../include/hash.h:22:2: error: #error Wordsize not 32 or 64
22 | #error Wordsize not 32 or 64
| ^~~~~
```
Tested-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
---
CHANGELOG | 1 +
include/hash.h | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 98c8da8d..02f8ef5f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,7 @@
- musl: fix missing include in hash.h.
- musl: define fallback dummy NSS config path
- musl: avoid internal stat.h definitions.
+- musl: add missing include to hash.h for _WORDSIZE.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/include/hash.h b/include/hash.h
index 010acd7e..0f1d7b5d 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -3,6 +3,11 @@
/* Fast hashing routine for ints, longs and pointers.
(C) 2002 Nadia Yvette Chambers, IBM */
+#ifdef __GLIBC__
+#include <bits/wordsize.h>
+#else
+#include <bits/reg.h>
+#endif
#include <linux/stddef.h>
#include <sys/types.h>
#include <stdint.h>

47
package/autofs/patches/0025-autofs-5.1.8-add-missing-include-to-log.h-for-pid_t.patch

@ -0,0 +1,47 @@
autofs-5.1.8 - add missing include to log.h for pid_t
From: Sam James <sam@gentoo.org>
Fixes build failures on musl like:
```
../include/log.h:49:8: error: unknown type name 'pid_t'
49 | extern pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label);
| ^~~~~
../include/log.h:49:51: error: unknown type name 'pid_t'; did you mean 'gid_t'?
49 | extern pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label);
| ^~~~~
| gid_t
```
Tested-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
---
CHANGELOG | 1 +
include/log.h | 2 ++
2 files changed, 3 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 02f8ef5f..794cd04b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,6 +22,7 @@
- musl: define fallback dummy NSS config path
- musl: avoid internal stat.h definitions.
- musl: add missing include to hash.h for _WORDSIZE.
+- musl: add missing include to log.h for pid_t.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/include/log.h b/include/log.h
index 69eed96b..a7b09f92 100644
--- a/include/log.h
+++ b/include/log.h
@@ -17,6 +17,8 @@
#ifndef LOG_H
#define LOG_H
+#include <unistd.h>
+
/* Define logging functions */
#define LOGOPT_NONE 0x0000

56
package/autofs/patches/0026-autofs-5.1.8-define-_SWORD_TYPE-for-musl.patch

@ -0,0 +1,56 @@
autofs-5.1.8 - define _SWORD_TYPE for musl
From: Sam James <sam@gentoo.org>
Copy the definition from glibc. Fixes build failures like:
```
automount.c:280:35: error: '__SWORD_TYPE' undeclared (first use in this function)
280 | if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) {
| ^~~~~~~~~~~~
automount.c:280:35: note: each undeclared identifier is reported only once for each function it appears in
automount.c:280:48: error: expected ')' before numeric constant
280 | if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) {
| ~ ^
| )
```
Tested-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
---
CHANGELOG | 1 +
daemon/automount.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 794cd04b..2e84b954 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,6 +23,7 @@
- musl: avoid internal stat.h definitions.
- musl: add missing include to hash.h for _WORDSIZE.
- musl: add missing include to log.h for pid_t.
+- musl: define _SWORD_TYPE.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/automount.c b/daemon/automount.c
index 85847edf..32f95a53 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -48,6 +48,16 @@
#endif
#endif
+#ifndef __SWORD_TYPE
+#if __WORDSIZE == 32
+# define __SWORD_TYPE int
+#elif __WORDSIZE == 64
+# define __SWORD_TYPE long int
+#else
+#error
+#endif
+#endif
+
const char *program; /* Initialized with argv[0] */
const char *version = VERSION_STRING; /* Program version */
const char *libdir = AUTOFS_LIB_DIR; /* Location of library modules */

62
package/autofs/patches/0027-autofs-5.1.8-add-strerror_r-helper-for-musl.patch

@ -0,0 +1,62 @@
autofs-5.1.8 - add autofs_strerror_r() helper for musl
From: Fabian Groffen <grobian@gentoo.org>
If using musl libc the XSI-compliant variant strerror_r() which returns
an integer instead of a pointer so add a helper function to handle this
case.
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 5 +++++
lib/log.c | 10 ++++++++++
3 files changed, 16 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 2e84b954..4f4ee181 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,7 @@
- musl: add missing include to hash.h for _WORDSIZE.
- musl: add missing include to log.h for pid_t.
- musl: define _SWORD_TYPE.
+- add autofs_strerror_r() helper for musl.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/include/automount.h b/include/automount.h
index 947ed16d..d2d05d89 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -43,6 +43,11 @@
#define ENABLE_CORES 1
+#ifndef __GLIBC__
+# define strerror_r(N,B,S) autofs_strerror_r(N,B,S)
+char *autofs_strerror_r(int errnum, char *buf, size_t buflen); /* GNU */
+#endif
+
/* We MUST have the paths to mount(8) and umount(8) */
#ifndef HAVE_MOUNT
#error Failed to locate mount(8)!
diff --git a/lib/log.c b/lib/log.c
index d1edef28..43eccc07 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -367,3 +367,13 @@ pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label) {
return ppid;
}
+
+#ifndef __GLIBC__
+# undef strerror_r
+char *autofs_strerror_r(int errnum, char *buf, size_t buflen) {
+ int s = strerror_r(errnum, buf, buflen);
+ if (s)
+ return NULL;
+ return buf;
+}
+#endif

104
package/autofs/patches/0028-autofs-5.1.8-update-configure.patch

@ -0,0 +1,104 @@
autofs-5.1.8 - update configure
From: Ian Kent <raven@themaw.net>
Update generated configure with autoconf and autoheader.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
configure | 20 ++++++++++++++++----
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4f4ee181..2b4ddeb9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@
- musl: add missing include to log.h for pid_t.
- musl: define _SWORD_TYPE.
- add autofs_strerror_r() helper for musl.
+- update configure.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/configure b/configure
index 394a8d55..dc1c62db 100755
--- a/configure
+++ b/configure
@@ -710,6 +710,7 @@ infodir
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -810,6 +811,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
@@ -1062,6 +1064,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1199,7 +1210,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1352,6 +1363,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -4877,7 +4889,7 @@ rm -f core conftest.err conftest.$ac_objext \
# restore libs
LIBS="$af_check_hesiod_save_libs"
- if test "$HAVE_HESIOD" == "1"; then
+ if test "$HAVE_HESIOD" = "1"; then
$as_echo "#define WITH_HESIOD 1" >>confdefs.h
@@ -5521,7 +5533,7 @@ if test "${with_sasl+set}" = set; then :
fi
-if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" = "1"
then
HAVE_SASL=0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sasl_client_start in -lsasl2" >&5
@@ -5564,7 +5576,7 @@ if test "x$ac_cv_lib_sasl2_sasl_client_start" = xyes; then :
HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2"
fi
- if test "$HAVE_SASL" == "1"; then
+ if test "$HAVE_SASL" = "1"; then
$as_echo "#define WITH_SASL 1" >>confdefs.h

113
package/autofs/patches/0029-autofs-5.1.8-handle-innetgr-not-present-in-musl.patch

@ -0,0 +1,113 @@
autofs-5.1.8 - handle innetgr() not present in musl
From: Fabian Groffen <grobian@gentoo.org>
The function innetgr(3) may not be present in musl libc, add a check
for this.
Originally contributed by Fabian, modified by me.
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
configure | 9 +++++----
configure.in | 2 +-
include/config.h.in | 3 +++
modules/parse_amd.c | 7 +++++++
5 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2b4ddeb9..1f7c93ab 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,7 @@
- musl: define _SWORD_TYPE.
- add autofs_strerror_r() helper for musl.
- update configure.
+- handle innetgr() not present in musl.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/configure b/configure
index dc1c62db..90ce6e0e 100755
--- a/configure
+++ b/configure
@@ -4239,12 +4239,13 @@ fi
-for ac_func in pipe2
+for ac_func in pipe2 innetgr
do :
- ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
-if test "x$ac_cv_func_pipe2" = xyes; then :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define HAVE_PIPE2 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
diff --git a/configure.in b/configure.in
index 723bb30d..68cbd44a 100644
--- a/configure.in
+++ b/configure.in
@@ -169,7 +169,7 @@ AF_CHECK_SSS_LIB(SSS_AUTOFS, libsss_autofs.so)
AC_SUBST(HAVE_SSS_AUTOFS)
AC_SUBST(sssldir)
-AC_CHECK_FUNCS(pipe2)
+AC_CHECK_FUNCS(pipe2 innetgr)
#
# Newer mounts have the -s (sloppy) option to ignore unknown options,
diff --git a/include/config.h.in b/include/config.h.in
index 4e36b390..4f8daa86 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -30,6 +30,9 @@
/* Define to 1 if you have the `getservbyname' function. */
#undef HAVE_GETSERVBYNAME
+/* Define to 1 if you have the `innetgr' function. */
+#undef HAVE_INNETGR
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index 163174cd..5090060d 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -425,6 +425,7 @@ static int sel_in_network(struct autofs_point *ap,
return ret;
}
+#ifdef HAVE_INNETGR
static int sel_netgrp(struct autofs_point *ap,
struct selector *s, struct substvar *sv)
{
@@ -489,6 +490,7 @@ out:
return ret;
}
+#endif
static int eval_selector(struct autofs_point *ap,
struct amd_entry *this, struct substvar *sv)
@@ -628,7 +630,12 @@ static int eval_selector(struct autofs_point *ap,
switch (s->sel->selector) {
case SEL_NETGRP:
case SEL_NETGRPD:
+#ifndef HAVE_INNETGR
+ error(logopt, MODPREFIX
+ "netgroups not available, function innetgr(3) not available");
+#else
ret = sel_netgrp(ap, s, sv);
+#endif
break;
default:

48
package/autofs/patches/autofs-5.1.7-Fix-option-for-master_read_wait.patch

@ -1,48 +0,0 @@
autofs-5.1.7 - Fix option for master read wait
From: Goldwyn Rodrigues <rgoldwyn@suse.de>
The master-wait program option expects a value, and if provided
automount crashes with the following trace:
#0 __GI_____strtoul_l_internal (nptr=0x0, endptr=0x7fffffffe120, base=0, group=<optimized out>,
loc=0x7ffff77a63a0 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
#1 0x0000555555562c52 in getnumopt ()
#2 0x0000555555564ec0 in main ()
This is because the options string is not correct and does not expect
an argument for master-wait (M), which sets optarg to NULL.
Fixes: e68f07f ("autofs-5.1.2 - add master read wait option")
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index fe49740e..0b577909 100644
--- a/CHANGELOG
+++ b/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.
+- Fix option for master read wait.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index e476f6b2..7fa92877 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -2274,7 +2274,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:CFUM";
+ 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'},

136
package/autofs/patches/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch

@ -1,136 +0,0 @@
autofs-5.1.7 - add a len field to struct autofs_point
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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(-)
diff --git a/CHANGELOG b/CHANGELOG
index 60924b3f..0dae6761 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -30,6 +30,7 @@
- rename tree implementation functions.
- add some multi-mount macros.
- remove unused functions cache_dump_multi() and cache_dump_cache().
+- add a len field to struct autofs_point.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 8c9a82b5..5116b927 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -843,7 +843,7 @@ static int lookup_amd_instance(struct autofs_point *ap,
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");
diff --git a/daemon/master.c b/daemon/master.c
index da527a61..022fb9dd 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -86,6 +86,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
free(ap);
return 0;
}
+ ap->len = strlen(ap->path);
ap->pref = NULL;
ap->entry = entry;
diff --git a/include/automount.h b/include/automount.h
index e917515b..34485859 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -548,6 +548,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 */
diff --git a/lib/mounts.c b/lib/mounts.c
index f6f20fc0..b478ecb4 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1158,7 +1158,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
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)
@@ -2495,9 +2495,9 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
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];
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index d3e8a450..5a9079d6 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -147,7 +147,7 @@ static struct substvar *add_lookup_vars(struct autofs_point *ap,
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_point *ap, const char *name,
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
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index b11c6693..b1f64ca0 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1154,7 +1154,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
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, "/");
@@ -1477,7 +1477,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);

51
package/autofs/patches/autofs-5.1.7-add-buffer-length-check-to-rmdir_path.patch

@ -1,51 +0,0 @@
autofs-5.1.7 - add buffer length check to rmdir_path()
From: Ian Kent <raven@themaw.net>
Add a length check before copying the incoming path string to the work
buffer.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 8 ++++++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ded0f00f..38304720 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -86,6 +86,7 @@
- add mapent path length check in handle_packet_expire_direct().
- add copy length check in umount_autofs_indirect().
- add some buffer length checks to master map parser.
+- add buffer length check to rmdir_path().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 45e0833f..114b013a 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -241,15 +241,19 @@ int mkdir_path(const char *path, mode_t mode)
int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev)
{
int len = strlen(path);
- char buf[PATH_MAX];
+ char buf[PATH_MAX + 1];
char *cp;
int first = 1;
struct stat st;
struct statfs fs;
+ if (len > PATH_MAX) {
+ error(ap->logopt, "path longer than maximum length");
+ return -1;
+ }
strcpy(buf, path);
- cp = buf + len;
+ cp = buf + len;
do {
*cp = '\0';

108
package/autofs/patches/autofs-5.1.7-add-buffer-length-checks-to-autofs-mount_mount.patch

@ -1,108 +0,0 @@
autofs-5.1.7 - add buffer length checks to autofs mount_mount()
From: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/mount_autofs.c | 59 +++++++++++++++++++++++++++++++++---------------
2 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 6ab4813d..17926916 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -88,6 +88,7 @@
- add some buffer length checks to master map parser.
- add buffer length check to rmdir_path().
- eliminate buffer usage from handle_mounts_cleanup().
+- add buffer length checks to autofs mount_mount().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 0bcbb343..b2233573 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -50,8 +50,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
{
struct startup_cond suc;
pthread_t thid;
- char realpath[PATH_MAX];
- char mountpoint[PATH_MAX];
+ char realpath[PATH_MAX + 1];
+ char mountpoint[PATH_MAX + 1];
const char **argv;
int argc, status;
int nobind = ap->flags & MOUNT_FLAG_NOBIND;
@@ -68,32 +68,53 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
struct mnt_list *mnt;
char buf[MAX_ERR_BUF];
char *options, *p;
- int len, ret;
+ int err, ret;
int hosts = 0;
/* Root offset of multi-mount */
- len = strlen(root);
- if (root[len - 1] == '/') {
- strcpy(realpath, ap->path);
- strcat(realpath, "/");
- strcat(realpath, name);
- len--;
- strncpy(mountpoint, root, len);
- mountpoint[len] = '\0';
+ if (root[strlen(root) - 1] == '/') {
+ err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for realpath");
+ return 1;
+ }
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
+ mountpoint[err - 1] = 0;
} else if (*name == '/') {
if (ap->flags & MOUNT_FLAG_REMOUNT) {
- strcpy(mountpoint, name);
- strcpy(realpath, name);
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
+ err = snprintf(realpath, PATH_MAX + 1, "%s", name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for realpath");
+ return 1;
+ }
} else {
- strcpy(mountpoint, root);
- strcpy(realpath, name);
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
+ err = snprintf(realpath, PATH_MAX + 1, "%s", name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for realpath");
+ return 1;
+ }
}
} else {
- strcpy(mountpoint, root);
- strcat(mountpoint, "/");
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
strcpy(realpath, mountpoint);
- strcat(mountpoint, name);
- strcat(realpath, name);
}
options = NULL;

51
package/autofs/patches/autofs-5.1.7-add-copy-length-check-in-umount_autofs_indirect.patch

@ -1,51 +0,0 @@
autofs-5.1.7 - add copy length check in umount_autofs_indirect()
From: Ian Kent <raven@themaw.net>
Add a source length check before copying to a work buffer in
umount_autofs_indirect().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/indirect.c | 13 +++++++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5fdb4c0a..be0b9d85 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -84,6 +84,7 @@
- fix use of possibly NULL var in lookup_program.c:match_key().
- fix incorrect print format specifiers in get_pkt().
- add mapent path length check in handle_packet_expire_direct().
+- add copy length check in umount_autofs_indirect().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 9f2ca6a0..b73c2781 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -238,10 +238,19 @@ int umount_autofs_indirect(struct autofs_point *ap, const char *root)
int rv, retries;
unsigned int unused;
- if (root)
+ if (root) {
+ if (strlen(root) > PATH_MAX) {
+ error(ap->logopt, "mountpoint path too long");
+ return 1;
+ }
strcpy(mountpoint, root);
- else
+ } else {
+ if (ap->len > PATH_MAX) {
+ error(ap->logopt, "mountpoint path too long");
+ return 1;
+ }
strcpy(mountpoint, ap->path);
+ }
/* If we are trying to shutdown make sure we can umount */
rv = ops->askumount(ap->logopt, ap->ioctlfd, &unused);

104
package/autofs/patches/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch

@ -1,104 +0,0 @@
autofs-5.1.7 - add ext_mount_hash_mutex lock helpers
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 26 ++++++++++++++++++++------
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b1b28888..ff44ac25 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 3996eb5e..c24d1a88 100644
--- a/lib/mounts.c
+++ b/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, const char *umount)
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, const char *umount)
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;
}

42
package/autofs/patches/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch

@ -1,42 +0,0 @@
autofs-5.1.7 - add length check in umount_subtree_mounts()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 224f58d6..9e385ba9 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 48472d5f..70506d83 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
left++;
}
+ if (me->len > PATH_MAX) {
+ crit(ap->logopt, "me->key too long for buffer");
+ return 1;
+ }
+
strcpy(key, me->key);
cache_unlock(mc);

60
package/autofs/patches/autofs-5.1.7-add-mapent-path-length-check-in-handle_packet_expire_direct.patch

@ -1,60 +0,0 @@
autofs-5.1.7 - add mapent path length check in handle_packet_expire_direct()
From: Ian Kent <raven@themaw.net>
Since direct mount expire requests from the kernel need to look up their
map entry and copy the path to a request processing struct fix length
char array the copy length should be checked.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0dac7318..5fdb4c0a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -83,6 +83,7 @@
- use default stack size for threads.
- fix use of possibly NULL var in lookup_program.c:match_key().
- fix incorrect print format specifiers in get_pkt().
+- add mapent path length check in handle_packet_expire_direct().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/direct.c b/daemon/direct.c
index d37dd676..4a56486b 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1039,13 +1039,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
map = map->next;
}
- if (!me) {
+ if (!me || me->len >= PATH_MAX) {
/*
* Shouldn't happen as we have been sent this following
* successful thread creation and lookup.
*/
- crit(ap->logopt, "can't find map entry for (%lu,%lu)",
- (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+ if (!me)
+ crit(ap->logopt, "can't find map entry for (%lu,%lu)",
+ (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+ else {
+ cache_unlock(mc);
+ crit(ap->logopt, "lookup key is too long");
+ }
master_source_unlock(ap->entry);
pthread_setcancelstate(state, NULL);
return 1;
@@ -1091,7 +1096,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
mt->ap = ap;
mt->ioctlfd = me->ioctlfd;
mt->mc = mc;
- /* TODO: check length here */
strcpy(mt->name, me->key);
mt->dev = me->dev;
mt->type = NFY_EXPIRE;

177
package/autofs/patches/autofs-5.1.7-add-mapent-tree-implementation.patch

@ -1,177 +0,0 @@
autofs-5.1.7 - add mapent tree implementation
From: Ian Kent <raven@themaw.net>
Add a struct mapent basic tree implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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(-)
diff --git a/CHANGELOG b/CHANGELOG
index 74571570..8841f72f 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/automount.h b/include/automount.h
index 34485859..ebc2007f 100644
--- a/include/automount.h
+++ b/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;
diff --git a/include/mounts.h b/include/mounts.h
index 71d29566..fd7c6183 100644
--- a/include/mounts.h
+++ b/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(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, 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);
diff --git a/lib/cache.c b/lib/cache.c
index 629c4d0a..6dfaeff5 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -546,17 +546,21 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
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, struct map_source *ms, const char *key, c
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;
diff --git a/lib/mounts.c b/lib/mounts.c
index a6d1c5a7..40ebf9cf 100644
--- a/lib/mounts.c
+++ b/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_head *mnts)
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

55
package/autofs/patches/autofs-5.1.7-add-missing-description-of-null-map-option.patch

@ -1,55 +0,0 @@
autofs-5.1.7 - add missing desciption of null map option
From: Ian Kent <raven@themaw.net>
The description of how the -null master map option behaves is
mising from auto.master(5).
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
man/auto.master.5.in | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index b29d2ed8..f5f0da76 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -76,6 +76,7 @@
- eliminate redundant cache lookup in tree_mapent_add_node().
- fix hosts map offset order.
- fix direct mount deadlock.
+- add missing description of null map option.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
index 72fbfd23..16717015 100644
--- a/man/auto.master.5.in
+++ b/man/auto.master.5.in
@@ -265,6 +265,25 @@ accessing /net/myserver will mount exports from myserver on directories below
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
+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

42
package/autofs/patches/autofs-5.1.7-add-missing-free-in-handle_mounts.patch

@ -1,42 +0,0 @@
autofs-5.1.7 - add missing free in handle_mounts()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 9c3ede45..62a918a9 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 28c4d1ee..48472d5f 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1922,6 +1922,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);
}

310
package/autofs/patches/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch

@ -1,310 +0,0 @@
autofs-5.1.7 - add mount and umount offsets functions
From: Ian Kent <raven@themaw.net>
Add tree_mapent_mount_offsets() and tree_mapent_umount_offsets() to
the mapent tree handling implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 2
lib/mounts.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 0bd6f181..892f7581 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -39,6 +39,7 @@
- fix mount_fullpath().
- add tree_mapent_cleanup_offsets().
- add set_offset_tree_catatonic().
+- add mount and umount offsets functions.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/mounts.h b/include/mounts.h
index 5441ee0e..e56f80ba 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -172,6 +172,8 @@ 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 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);
diff --git a/lib/mounts.c b/lib/mounts.c
index f075a27e..f7c29475 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1692,6 +1692,266 @@ void tree_mapent_cleanup_offsets(struct mapent *oe)
}
}
+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

50
package/autofs/patches/autofs-5.1.7-add-set_offset_tree_catatonic.patch

@ -1,50 +0,0 @@
autofs-5.1.7 - add set_offset_tree_catatonic()
From: Ian Kent <raven@themaw.net>
Add tree mapent support function set_offset_tree_catatonic().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 89d4cfa0..0bd6f181 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -38,6 +38,7 @@
- add tree_mapent_traverse_subtree().
- fix mount_fullpath().
- add tree_mapent_cleanup_offsets().
+- add set_offset_tree_catatonic().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index ba573b9a..f075a27e 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2578,6 +2578,21 @@ static int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int i
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)) {

257
package/autofs/patches/autofs-5.1.7-add-some-buffer-length-checks-to-master-map-parser.patch

@ -1,257 +0,0 @@
autofs-5.1.7 - add some buffer length checks to master map parser
From: Ian Kent <raven@themaw.net>
Add some checks for buffer overflow to the master map parser.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master_parse.y | 38 +++++++++++++++-----------
daemon/master_tok.l | 73 ++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 88 insertions(+), 24 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index be0b9d85..ded0f00f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -85,6 +85,7 @@
- fix incorrect print format specifiers in get_pkt().
- add mapent path length check in handle_packet_expire_direct().
- add copy length check in umount_autofs_indirect().
+- add some buffer length checks to master map parser.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/master_parse.y b/daemon/master_parse.y
index 7480c36a..2d78f082 100644
--- a/daemon/master_parse.y
+++ b/daemon/master_parse.y
@@ -29,6 +29,7 @@
#include "master.h"
#define MAX_ERR_LEN 512
+#define STRTYPE_LEN 2048
extern struct master *master_list;
@@ -79,6 +80,7 @@ static int local_argc;
static unsigned int propagation;
static char errstr[MAX_ERR_LEN];
+static int errlen;
static unsigned int verbose;
static unsigned int debug;
@@ -521,10 +523,11 @@ dnattrs: DNATTR EQUAL DNNAME
strcasecmp($1, "ou") &&
strcasecmp($1, "automountMapName") &&
strcasecmp($1, "nisMapName")) {
- strcpy(errstr, $1);
- strcat(errstr, "=");
- strcat(errstr, $3);
- master_notify(errstr);
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
+ if (errlen < MAX_ERR_LEN)
+ master_notify(errstr);
+ else
+ master_notify("error string too long");
YYABORT;
}
strcpy($$, $1);
@@ -537,10 +540,11 @@ dnattrs: DNATTR EQUAL DNNAME
strcasecmp($1, "ou") &&
strcasecmp($1, "automountMapName") &&
strcasecmp($1, "nisMapName")) {
- strcpy(errstr, $1);
- strcat(errstr, "=");
- strcat(errstr, $3);
- master_notify(errstr);
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
+ if (errlen < MAX_ERR_LEN)
+ master_notify(errstr);
+ else
+ master_notify("error string too long");
YYABORT;
}
strcpy($$, $1);
@@ -565,10 +569,11 @@ dnattr: DNATTR EQUAL DNNAME
{
if (!strcasecmp($1, "automountMapName") ||
!strcasecmp($1, "nisMapName")) {
- strcpy(errstr, $1);
- strcat(errstr, "=");
- strcat(errstr, $3);
- master_notify(errstr);
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
+ if (errlen < MAX_ERR_LEN)
+ master_notify(errstr);
+ else
+ master_notify("error string too long");
YYABORT;
}
strcpy($$, $1);
@@ -579,10 +584,11 @@ dnattr: DNATTR EQUAL DNNAME
{
if (!strcasecmp($1, "automountMapName") ||
!strcasecmp($1, "nisMapName")) {
- strcpy(errstr, $1);
- strcat(errstr, "=");
- strcat(errstr, $3);
- master_notify(errstr);
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
+ if (errlen < MAX_ERR_LEN)
+ master_notify(errstr);
+ else
+ master_notify("error string too long");
YYABORT;
}
strcpy($$, $1);
diff --git a/daemon/master_tok.l b/daemon/master_tok.l
index 87a6b958..e2d15bce 100644
--- a/daemon/master_tok.l
+++ b/daemon/master_tok.l
@@ -23,6 +23,7 @@
#endif /* ECHO */
static void master_echo(void); /* forward definition */
#define ECHO master_echo()
+static void master_error(char *s);
#include <stdio.h>
#include <stdlib.h>
@@ -80,6 +81,8 @@ char *bptr;
char *optr = buff;
unsigned int tlen;
+#define STRTYPE_LEN 2048
+
%}
%option nounput
@@ -217,7 +220,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
bptr += tlen;
yyless(tlen);
} else {
- strcpy(master_lval.strtype, master_text);
+ if (tlen <= STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("MULTITYPE: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return(MULTITYPE);
}
}
@@ -239,7 +248,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
bptr += tlen;
yyless(tlen);
} else {
- strcpy(master_lval.strtype, master_text);
+ if (tlen <= STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("MAPTYPE: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return(MAPTYPE);
}
}
@@ -327,12 +342,24 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
{OPTWS}\\\n{OPTWS} {}
{DNSERVERSTR} {
- strcpy(master_lval.strtype, master_text);
+ if (master_leng < STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("DNSERVER: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return DNSERVER;
}
{DNATTRSTR}/"=" {
- strcpy(master_lval.strtype, master_text);
+ if (master_leng < STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("DNATTR: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return DNATTR;
}
@@ -341,12 +368,24 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
}
{DNNAMESTR1}/","{DNATTRSTR}"=" {
- strcpy(master_lval.strtype, master_text);
+ if (master_leng < STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("DNNAME: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return DNNAME;
}
{DNNAMESTR2} {
- strcpy(master_lval.strtype, master_text);
+ if (master_leng < STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("DNNAME: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return DNNAME;
}
@@ -357,7 +396,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
{WS}"=" |
"="{WS} {
BEGIN(INITIAL);
- strcpy(master_lval.strtype, master_text);
+ if (master_leng < STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("SPACE: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return SPACE;
}
@@ -419,7 +464,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
}
{OPTIONSTR} {
- strcpy(master_lval.strtype, master_text);
+ if (master_leng < STRTYPE_LEN)
+ strcpy(master_lval.strtype, master_text);
+ else {
+ master_error("OPTION: value too large, truncated");
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
+ }
return(OPTION);
}
@@ -459,6 +510,12 @@ static void master_echo(void)
return;
}
+static void master_error(char *s)
+{
+ logmsg("%s");
+ return;
+}
+
#ifdef FLEX_SCANNER
void master_set_scan_buffer(const char *buffer)

552
package/autofs/patches/autofs-5.1.7-add-some-multi-mount-macros.patch

@ -1,552 +0,0 @@
autofs-5.1.7 - add some multi-mount macros
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1bf20699..3ba748d7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,6 +28,7 @@
- rename path to m_offset in update_offset_entry().
- don't pass root to do_mount_autofs_offset().
- rename tree implementation functions.
+- add some multi-mount macros.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 62530b6b..f4608fc9 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -545,27 +545,27 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
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 autofs_point *ap, const char *path, unsi
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");
diff --git a/daemon/direct.c b/daemon/direct.c
index 5c1146a7..3f4f5704 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -686,7 +686,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
* 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);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 2fea0c0b..8c9a82b5 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -748,7 +748,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root)
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;
@@ -838,12 +838,12 @@ static int lookup_amd_instance(struct autofs_point *ap,
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");
@@ -852,7 +852,7 @@ static int lookup_amd_instance(struct autofs_point *ap,
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);
@@ -1355,7 +1355,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
* 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;
}
diff --git a/include/automount.h b/include/automount.h
index fa6f5d63..e917515b 100644
--- a/include/automount.h
+++ b/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);
diff --git a/lib/cache.c b/lib/cache.c
index a90bbb1d..1d9f5cc7 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -374,7 +374,7 @@ struct mapent *cache_lookup_first(struct mapent_cache *mc)
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 mapent_cache *mc, struct mapent *me)
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 mapent_cache *mc, struct mapent *me)
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(struct mapent *me)
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_cache *mc, const char *mkey, const char *k
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;
@@ -814,14 +814,14 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
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;
}
@@ -879,7 +879,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key)
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;
@@ -889,7 +889,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key)
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;
@@ -927,7 +927,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
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;
}
@@ -956,7 +956,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
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;
}
@@ -995,7 +995,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
return CHE_FAIL;
/* Not offset list owner */
- if (me->multi != me)
+ if (!IS_MM_ROOT(me))
return CHE_FAIL;
head = &me->multi_list;
@@ -1016,13 +1016,13 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
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++;
}
@@ -1030,7 +1030,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
if (!remain) {
list_del_init(&me->multi_list);
- me->multi = NULL;
+ MM_ROOT(me) = NULL;
}
if (remain)
diff --git a/lib/mounts.c b/lib/mounts.c
index f5b905a6..f6f20fc0 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2163,7 +2163,7 @@ int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
} 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;
}
}
@@ -2310,7 +2310,7 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
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);
@@ -2330,7 +2330,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);
}
@@ -2490,12 +2490,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
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);
@@ -2690,7 +2690,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
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;
@@ -2724,7 +2724,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
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
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index f46a04f0..6afc5587 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1199,8 +1199,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
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 {
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index c1ebb7f6..7e101ddb 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -177,7 +177,7 @@ static void update_hosts_mounts(struct autofs_point *ap,
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
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 3624dd86..3e43fc01 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -3700,8 +3700,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
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 {
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index cbd03cdb..6e9a85d1 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -722,8 +722,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
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 {
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index ca209488..70f27545 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -646,7 +646,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
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"
@@ -657,7 +657,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
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);
}
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index ccd605af..ad834626 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -1055,8 +1055,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
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);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 38f75497..8bccb72f 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -826,8 +826,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
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 {
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 34d4441e..b11c6693 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1148,7 +1148,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
rv = 0;
- mm_key = me->multi->key;
+ mm_key = MM_ROOT(me)->key;
if (*mm_key == '/') {
mm_root = mm_key;
@@ -1162,7 +1162,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
}
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) {
@@ -1179,7 +1179,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
/* 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;
@@ -1350,7 +1350,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
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);
@@ -1505,7 +1505,7 @@ dont_expand:
}
/* So we know we're the multi-mount root */
- if (!me->multi)
+ if (!IS_MM(me))
me->multi = me;
else {
/*
@@ -1630,7 +1630,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) {

133
package/autofs/patches/autofs-5.1.7-add-tree_mapent_add_node.patch

@ -1,133 +0,0 @@
autofs-5.1.7 - add tree_mapent_add_node()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_add_node() to the mapent tree handling
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8841f72f..85730eda 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/automount.h b/include/automount.h
index ebc2007f..f6023e27 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -216,6 +216,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
int cache_lookup_negative(struct mapent *me, const char *key);
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);
diff --git a/include/mounts.h b/include/mounts.h
index fd7c6183..a0e60e24 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -169,6 +169,7 @@ 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 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);
diff --git a/lib/cache.c b/lib/cache.c
index 6dfaeff5..7c409a56 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -749,8 +749,7 @@ void cache_update_negative(struct mapent_cache *mc,
}
-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;
@@ -796,7 +795,7 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
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
diff --git a/lib/mounts.c b/lib/mounts.c
index 40ebf9cf..a0bf3d52 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1481,6 +1481,53 @@ static void tree_mapent_free(struct tree_node *n)
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

94
package/autofs/patches/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch

@ -1,94 +0,0 @@
autofs-5.1.7 - add tree_mapent_cleanup_offsets()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_cleanup_offsets() to the mapent tree handling
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 1 +
lib/mounts.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index e2fd532c..89d4cfa0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -37,6 +37,7 @@
- add tree_mapent_delete_offsets().
- add tree_mapent_traverse_subtree().
- fix mount_fullpath().
+- add tree_mapent_cleanup_offsets().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/mounts.h b/include/mounts.h
index b5a1193b..5441ee0e 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -171,6 +171,7 @@ void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned
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);
diff --git a/lib/mounts.c b/lib/mounts.c
index 497c28c9..ba573b9a 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1647,6 +1647,51 @@ int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key)
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

119
package/autofs/patches/autofs-5.1.7-add-tree_mapent_delete_offsets.patch

@ -1,119 +0,0 @@
autofs-5.1.7 - add tree_mapent_delete_offsets()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_delete_offsets() to the mapent tree handling
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 1 +
lib/mounts.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 85730eda..488b4996 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -34,6 +34,7 @@
- make tree implementation data independent.
- add mapent tree implementation.
- add tree_mapent_add_node().
+- add tree_mapent_delete_offsets().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/mounts.h b/include/mounts.h
index a0e60e24..b5a1193b 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -170,6 +170,7 @@ 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_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);
diff --git a/lib/mounts.c b/lib/mounts.c
index a0bf3d52..eb700c79 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1528,6 +1528,76 @@ int tree_mapent_add_node(struct mapent_cache *mc,
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

83
package/autofs/patches/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch

@ -1,83 +0,0 @@
autofs-5.1.7 - add tree_mapent_traverse_subtree()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_traverse_subtree() that enumerates offsets from
a given base node bounded by subtree nesting points.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 488b4996..390028ac 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -35,6 +35,7 @@
- add mapent tree implementation.
- add tree_mapent_add_node().
- add tree_mapent_delete_offsets().
+- add tree_mapent_traverse_subtree().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index eb700c79..fded4c09 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1528,6 +1528,53 @@ int tree_mapent_add_node(struct mapent_cache *mc,
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);

335
package/autofs/patches/autofs-5.1.7-add-xdr_exports.patch

@ -1,335 +0,0 @@
autofs-5.1.7 - add xdr_exports()
From: Ian Kent <raven@themaw.net>
Add an xdr_exports() function to get NFS exports from a server.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 3 +
include/rpc_subs.h | 14 ++++++
lib/rpc_subs.c | 120 +++++++++++++++++++++++++++++++++++-------------
modules/lookup_hosts.c | 25 +++-------
4 files changed, 112 insertions(+), 50 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2c48484b..84050e91 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+
+- add xdr_exports().
+
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
- update ldap READMEs and schema definitions.
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
index 7ba4b93f..080f19d9 100644
--- a/include/rpc_subs.h
+++ b/include/rpc_subs.h
@@ -17,6 +17,7 @@
#define _RPC_SUBS_H
#include <rpc/rpc.h>
+#include <rpc/types.h>
#include <rpc/pmap_prot.h>
#include <linux/nfs.h>
#include <linux/nfs2.h>
@@ -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 *, struct pmap *, unsigned short *);
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
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 643b7687..7b8162b4 100644
--- a/lib/rpc_subs.c
+++ b/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 start, struct timespec end)
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 conn_info *info, exports *exp)
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 conn_info *info, exports *exp)
return 1;
}
-static void rpc_export_free(exports item)
+static void rpc_export_free(struct exportinfo *export)
{
- groups grp;
- groups tmp;
-
- if (item->ex_dir)
- free(item->ex_dir);
-
- grp = item->ex_groups;
- while (grp) {
- if (grp->gr_name)
- free(grp->gr_name);
- tmp = grp;
- grp = grp->gr_next;
+ struct hostinfo *host, *tmp;
+
+ if (export->dir)
+ free(export->dir);
+
+ 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, long seconds, long micros, unsigned in
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)
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 744062e2..81a4eb18 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -20,14 +20,6 @@
#include <sys/stat.h>
#include <netdb.h>
-/*
- * 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_point *ap, const char *host)
{
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_point *ap, const char *host)
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_point *ap, const char *host)
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_point *ap, const char *host)
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);

38
package/autofs/patches/autofs-5.1.7-also-require-TCP_REQUESTED-when-setting-NFS-port.patch

@ -1,38 +0,0 @@
autofs-5.1.7 - also require TCP_REQUESTED when setting NFS port
From: Ian Kent <raven@themaw.net>
Set the NFS service port to the default (2049) only if tcp protocol is
being used and not alternate port has been given.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/replicated.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5d2c2c88..fd5b800a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -91,6 +91,7 @@
- add buffer length checks to autofs mount_mount().
- make NFS version check flags consistent.
- refactor get_nfs_info().
+- also require TCP_REQUESTED when setting NFS port.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/replicated.c b/modules/replicated.c
index e03c9d25..09075dd0 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -291,7 +291,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
rpc_info->proto = proto;
if (port < 0) {
- if (version & NFS4_REQUESTED)
+ if ((version & NFS4_REQUESTED) && (version & TCP_REQUESTED))
rpc_info->port = NFS_PORT;
else
port = 0;

44
package/autofs/patches/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch

@ -1,44 +0,0 @@
autofs-5.1.7 - cater for empty mounts list in mnts_get_expire_list()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b79aebc8..b1b28888 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 883e3743..3996eb5e 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
}
}
- 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();
}

50
package/autofs/patches/autofs-5.1.7-check-for-offset-with-no-mount-location.patch

@ -1,50 +0,0 @@
autofs-5.1.7 - check for offset with no mount location
From: Ian Kent <raven@themaw.net>
Offsets need to have a mount location, check for it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index a9209755..42914160 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index b1c2611c..a81d4028 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -801,7 +801,20 @@ update_offset_entry(struct autofs_point *ap,
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);

64
package/autofs/patches/autofs-5.1.7-cleanup-cache_delete-a-little.patch

@ -1,64 +0,0 @@
autofs-5.1.7 - cleanup cache_delete() a little
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 11 +++--------
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 6419052d..e822efec 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/cache.c b/lib/cache.c
index 03d0499a..a90bbb1d 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -917,20 +917,15 @@ int cache_delete(struct mapent_cache *mc, const char *key)
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;
@@ -959,7 +954,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
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;

207
package/autofs/patches/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch

@ -1,207 +0,0 @@
autofs-5.1.7 - don't add offset mounts to mounted mounts table
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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(-)
diff --git a/CHANGELOG b/CHANGELOG
index cb709773..b144f6aa 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,6 +22,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/direct.c b/daemon/direct.c
index 311a98ba..fbfebbdd 100644
--- a/daemon/direct.c
+++ b/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_point *ap, struct mapent *me)
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 {
diff --git a/daemon/indirect.c b/daemon/indirect.c
index b259ebdc..eddcfff7 100644
--- a/daemon/indirect.c
+++ b/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 {
diff --git a/include/mounts.h b/include/mounts.h
index e3022b23..ac480c06 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -131,7 +131,7 @@ 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);
+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);
diff --git a/lib/mounts.c b/lib/mounts.c
index 04fe3d00..25ae2e1d 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1172,7 +1172,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
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, unsigned int flags)
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)
@@ -1947,17 +1928,13 @@ static int do_remount_direct(struct autofs_point *ap,
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);
@@ -2032,7 +2009,9 @@ static int do_remount_indirect(struct autofs_point *ap, const unsigned int type,
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);

64
package/autofs/patches/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch

@ -1,64 +0,0 @@
autofs-5.1.7 - don't pass root to do_mount_autofs_offset()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 9 ++++-----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0e9ca94f..2a07bd45 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 25ae2e1d..289500da 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2453,13 +2453,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)
@@ -2651,7 +2650,7 @@ static int do_umount_offset(struct autofs_point *ap,
*/
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 */
@@ -2697,7 +2696,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
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

45
package/autofs/patches/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch

@ -1,45 +0,0 @@
autofs-5.1.7 - dont try umount after stat() ENOENT fail
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 7add6c55..c7bc0c39 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/direct.c b/daemon/direct.c
index a33f9f91..3bd714e6 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
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);

47
package/autofs/patches/autofs-5.1.7-dont-use-AUTOFS_DEV_IOCTL_CLOSEMOUNT.patch

@ -1,47 +0,0 @@
autofs-5.1.7 - dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT
From: Ian Kent <raven@themaw.net>
Using an ioctl (AUTOFS_DEV_IOCTL_CLOSEMOUNT) to close an autofs mount
file handle can race with copy_to_user() so the file handle needs to
be closed using close(2) instead.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/dev-ioctl-lib.c | 10 +---------
2 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 06bf24b8..51e7767e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -68,6 +68,7 @@
- add ext_mount_hash_mutex lock helpers.
- fix amd section mounts map reload.
- fix dandling symlink creation if nis support is not available.
+- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index e7a1b42a..6b549d73 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -404,15 +404,7 @@ err:
/* Close */
static int dev_ioctl_close(unsigned int logopt, int ioctlfd)
{
- struct autofs_dev_ioctl param;
-
- init_autofs_dev_ioctl(&param);
- param.ioctlfd = ioctlfd;
-
- if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_CLOSEMOUNT, &param) == -1)
- return -1;
-
- return 0;
+ return close(ioctlfd);
}
static int ioctl_close(unsigned int logopt, int ioctlfd)

112
package/autofs/patches/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch

@ -1,112 +0,0 @@
autofs-5.1.7 - dont use realloc in host exports list processing
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 59 +++++++++++++++++++++---------------------------
2 files changed, 27 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 19af245e..1bd6ac7f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
- add xdr_exports().
- remove mount.x and rpcgen dependencies.
+- dont use realloc in host exports list processing.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 81a4eb18..e3ee0ab8 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_point *ap, const char *host)
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;
-
- 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_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
+ this = this->next;
+ }
+
+ 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_point *ap, const char *host)
}
rpc_exports_free(exp);
- if (!mapent)
- error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
-
return mapent;
}

86
package/autofs/patches/autofs-5.1.7-eliminate-buffer-usage-from-handle_mounts_cleanup.patch

@ -1,86 +0,0 @@
autofs-5.1.7 - eliminate buffer usage from handle_mounts_cleanup()
From: Ian Kent <raven@themaw.net>
This buffer was originally added because a SEGV was seen accessing
the ap->path field on shutdown.
But this was actually caused by calling master_remove_mapent() too
early which adds the map entry to the master map join list that leads
to freeing the autofs_point (ap in the code) which also frees ap->path.
But the master map join list is protected by the master map mutex which
is held until after all the accesses are completed. So whatever the
problem was it doesn't appear to be present any more.
Nevertheless, to be sure, delay the call to master_remove_mapent() until
after all accesses to ap->path are completed.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 13 ++++++-------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 38304720..6ab4813d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -87,6 +87,7 @@
- add copy length check in umount_autofs_indirect().
- add some buffer length checks to master map parser.
- add buffer length check to rmdir_path().
+- eliminate buffer usage from handle_mounts_cleanup().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 114b013a..cc286892 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1716,7 +1716,6 @@ void handle_mounts_startup_cond_destroy(void *arg)
static void handle_mounts_cleanup(void *arg)
{
struct autofs_point *ap;
- char path[PATH_MAX + 1];
char buf[MAX_ERR_BUF];
unsigned int clean = 0, submount, logopt;
unsigned int pending = 0;
@@ -1726,7 +1725,6 @@ static void handle_mounts_cleanup(void *arg)
logopt = ap->logopt;
submount = ap->submount;
- strcpy(path, ap->path);
if (!submount && strcmp(ap->path, "/-") &&
ap->flags & MOUNT_FLAG_DIR_CREATED)
clean = 1;
@@ -1751,8 +1749,8 @@ static void handle_mounts_cleanup(void *arg)
/* Don't signal the handler if we have already done so */
if (!list_empty(&master_list->completed))
pending = 1;
- master_remove_mapent(ap->entry);
- master_source_unlock(ap->entry);
+
+ info(logopt, "shut down path %s", ap->path);
destroy_logpri_fifo(ap);
@@ -1768,14 +1766,15 @@ static void handle_mounts_cleanup(void *arg)
}
if (clean) {
- if (rmdir(path) == -1) {
+ if (rmdir(ap->path) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
warn(logopt, "failed to remove dir %s: %s",
- path, estr);
+ ap->path, estr);
}
}
- info(logopt, "shut down path %s", path);
+ master_remove_mapent(ap->entry);
+ master_source_unlock(ap->entry);
/*
* If we are not a submount send a signal to the signal handler

378
package/autofs/patches/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch

@ -1,378 +0,0 @@
autofs-5.1.7 - eliminate cache_lookup_offset() usage
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 82 +++++++++++++++++++++++++++++++++------------------
modules/parse_sun.c | 77 ++++++++++++++++++++++++++++++------------------
3 files changed, 102 insertions(+), 58 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0b577909..484bd866 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
- use sprintf() when constructing hosts mapent.
- fix mnts_remove_amdmount() uses wrong list.
- Fix option for master read wait.
+- eliminate cache_lookup_offset() usage.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index ccbd52e0..42e8ef07 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2495,24 +2495,27 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
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;
@@ -2525,12 +2528,8 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
*/
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,
@@ -2584,6 +2583,8 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
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);
@@ -2597,11 +2598,28 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
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;
@@ -2686,13 +2704,14 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
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)
@@ -2720,14 +2739,30 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
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;
@@ -2778,14 +2813,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
}
}
- 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)) {
@@ -2800,7 +2827,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
error(ap->logopt,
"failed to delete offset key %s", key);
- free(key);
continue;
}
@@ -2816,7 +2842,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
left++;
/* But we did origianlly create this */
oe->flags |= MOUNT_FLAG_DIR_CREATED;
- free(key);
continue;
}
/*
@@ -2834,7 +2859,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
error(ap->logopt,
"failed to delete offset key %s", key);
}
- free(key);
}
return left;
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 4b137f99..819d6adc 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1086,6 +1086,8 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
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;
@@ -1095,16 +1097,31 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
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);
@@ -1117,17 +1134,14 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
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;
@@ -1141,20 +1155,26 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
}
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;
@@ -1172,13 +1192,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
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)
@@ -1186,11 +1200,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
}
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) {
@@ -1206,24 +1220,29 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
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);

290
package/autofs/patches/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch

@ -1,290 +0,0 @@
autofs-5.1.7 - eliminate clean_stale_multi_triggers()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1
lib/mounts.c | 209 ++++++++++-----------------------------------------
modules/parse_sun.c | 10 --
3 files changed, 43 insertions(+), 177 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5a3bedc1..b1ce7b69 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 5268ba5b..a9abbebf 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2601,10 +2601,44 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
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);
@@ -2666,6 +2700,11 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
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);
@@ -2725,169 +2764,3 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
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;
-}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index f42af7b7..f4d5125c 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1176,7 +1176,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
/* 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;
@@ -1610,14 +1610,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);

140
package/autofs/patches/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch

@ -1,140 +0,0 @@
autofs-5.1.7 - eliminate count_mounts() from expire_proc_indirect()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 4 ++--
daemon/indirect.c | 10 +++++-----
lib/dev-ioctl-lib.c | 21 +++++++++++++--------
4 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c5619d2e..0b78eb62 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/direct.c b/daemon/direct.c
index c41c680f..311a98ba 100644
--- a/daemon/direct.c
+++ b/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);
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 65cfe4e3..b259ebdc 100644
--- a/daemon/indirect.c
+++ b/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);
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index 7040c3da..e7a1b42a 100644
--- a/lib/dev-ioctl-lib.c
+++ b/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,

90
package/autofs/patches/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch

@ -1,90 +0,0 @@
autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 2 +-
lib/mounts.c | 13 ++-----------
modules/parse_sun.c | 2 +-
4 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5a767360..81b6ce6a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -73,6 +73,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/mounts.h b/include/mounts.h
index f7768ce5..5a7a0b89 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -170,7 +170,7 @@ 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 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);
diff --git a/lib/mounts.c b/lib/mounts.c
index 9ec547ea..6b24a6c2 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree_node *n)
}
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_cache *mc,
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
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index c75bcc8e..12844a30 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1546,7 +1546,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);
}

216
package/autofs/patches/autofs-5.1.7-eliminate-some-more-alloca-usage.patch

@ -1,216 +0,0 @@
autofs-5.1.7 - eliminate some more alloca usage
From: Ian Kent <raven@themaw.net>
Quite a bit of the alloca(3) usage has been eliminated over time.
Use malloc(3) for some more cases that might need to allocate a largish
amount of storage.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_program.c | 11 ++++++++++-
modules/lookup_yp.c | 22 +++++++++++++++++++---
modules/parse_sun.c | 18 ++++++++++++++----
modules/replicated.c | 19 ++++++-------------
5 files changed, 50 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8d050552..2b7cfaa0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -79,6 +79,7 @@
- add missing description of null map option.
- fix nonstrict offset mount fail handling.
- fix concat_options() error handling.
+- eliminate some more alloca usage.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 6cab52c8..028580e5 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -636,7 +636,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
char *ent = NULL;
if (me->mapent) {
- ent = alloca(strlen(me->mapent) + 1);
+ ent = malloc(strlen(me->mapent) + 1);
+ if (!ent) {
+ char buf[MAX_ERR_BUF];
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ cache_unlock(mc);
+ goto out_free;
+ }
strcpy(ent, me->mapent);
}
cache_unlock(mc);
@@ -644,6 +651,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
ap->entry->current = source;
ret = ctxt->parse->parse_mount(ap, name,
name_len, ent, ctxt->parse->context);
+ if (ent)
+ free(ent);
goto out_free;
} else {
if (IS_MM(me) && !IS_MM_ROOT(me)) {
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 8bccb72f..d2a4b5a5 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -254,7 +254,7 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
len = ypkeylen + 1 + vallen + 2;
- buffer = alloca(len);
+ buffer = malloc(len);
if (!buffer) {
error(logopt, MODPREFIX "could not malloc parse buffer");
return 0;
@@ -267,6 +267,8 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
master_parse_entry(buffer, timeout, logging, age);
+ free(buffer);
+
return 0;
}
@@ -368,7 +370,12 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen,
return 0;
}
- mapent = alloca(vallen + 1);
+ mapent = malloc(vallen + 1);
+ if (!mapent) {
+ error(logopt, MODPREFIX "could not malloc mapent buffer");
+ free(key);
+ return 0;
+ }
strncpy(mapent, val, vallen);
*(mapent + vallen) = '\0';
@@ -377,6 +384,7 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen,
cache_unlock(mc);
free(key);
+ free(mapent);
if (ret == CHE_FAIL)
return -1;
@@ -904,7 +912,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
}
if (me && (me->source == source || *me->key == '/')) {
mapent_len = strlen(me->mapent);
- mapent = alloca(mapent_len + 1);
+ mapent = malloc(mapent_len + 1);
+ if (!mapent) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ cache_unlock(mc);
+ free(lkp_key);
+ return NSS_STATUS_TRYAGAIN;
+ }
strcpy(mapent, me->mapent);
}
}
@@ -929,6 +944,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
ret = ctxt->parse->parse_mount(ap, key, key_len,
mapent, ctxt->parse->context);
+ free(mapent);
if (ret) {
/* Don't update negative cache when re-connecting */
if (ap->flags & MOUNT_FLAG_REMOUNT)
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 9190165d..d9ac0c94 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -668,9 +668,16 @@ static int sun_mount(struct autofs_point *ap, const char *root,
}
}
+ what = malloc(loclen + 1);
+ if (!what) {
+ char buf[MAX_ERR_BUF];
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
if (!strcmp(fstype, "nfs") || !strcmp(fstype, "nfs4")) {
- what = alloca(loclen + 1);
memcpy(what, loc, loclen);
what[loclen] = '\0';
@@ -706,10 +713,10 @@ static int sun_mount(struct autofs_point *ap, const char *root,
rv = mount_nfs->mount_mount(ap, root, name, namelen,
what, fstype, options, mount_nfs->context);
} else {
- if (!loclen)
+ if (!loclen) {
+ free(what);
what = NULL;
- else {
- what = alloca(loclen + 1);
+ } else {
if (*loc == ':') {
loclen--;
memcpy(what, loc + 1, loclen);
@@ -728,6 +735,9 @@ static int sun_mount(struct autofs_point *ap, const char *root,
/* Generic mount routine */
rv = do_mount(ap, root, name, namelen, what, fstype, options);
}
+ if (what)
+ free(what);
+
pthread_setcancelstate(cur_state, NULL);
if (nonstrict && rv)
diff --git a/modules/replicated.c b/modules/replicated.c
index 03d4ba1e..ffaf519f 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -1041,25 +1041,18 @@ done:
return ret;
}
-static int add_path(struct host *hosts, const char *path, int len)
+static int add_path(struct host *hosts, const char *path)
{
struct host *this;
- char *tmp, *tmp2;
-
- tmp = alloca(len + 1);
- if (!tmp)
- return 0;
-
- strncpy(tmp, path, len);
- tmp[len] = '\0';
+ char *tmp;
this = hosts;
while (this) {
if (!this->path) {
- tmp2 = strdup(tmp);
- if (!tmp2)
+ tmp = strdup(path);
+ if (!tmp)
return 0;
- this->path = tmp2;
+ this->path = tmp;
}
this = this->next;
}
@@ -1188,7 +1181,7 @@ int parse_location(unsigned logopt, struct host **hosts,
}
}
- if (!add_path(*hosts, path, strlen(path))) {
+ if (!add_path(*hosts, path)) {
free_host_list(hosts);
free(str);
return 0;

128
package/autofs/patches/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch

@ -1,128 +0,0 @@
autofs-5.1.7 - eliminate some strlen calls in offset handling
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 30 +++++++++++++++++-------------
2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0b78eb62..cb709773 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 0fcd4087..04fe3d00 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2540,10 +2540,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
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;
@@ -2551,12 +2553,11 @@ static int do_umount_multi_triggers(struct autofs_point *ap,
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;
@@ -2592,13 +2593,14 @@ static int do_umount_multi_triggers(struct autofs_point *ap,
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;
@@ -2607,8 +2609,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
* 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
@@ -2712,7 +2714,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
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;
}
@@ -2726,7 +2728,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
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,
@@ -2738,9 +2740,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) {
/*
@@ -2753,7 +2757,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
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;

52
package/autofs/patches/autofs-5.1.7-fix-amd-hosts-mount-expire.patch

@ -1,52 +0,0 @@
autofs-5.1.7 - fix amd hosts mount expire
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 9 +++++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 698cc27a..94eb6a2c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -70,6 +70,7 @@
- fix dandling symlink creation if nis support is not available.
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT.
- fix lookup_prune_one_cache() refactoring change.
+- fix amd hosts mount expire.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index 64c1ce63..163174cd 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap, const char *name,
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 */

124
package/autofs/patches/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch

@ -1,124 +0,0 @@
autofs-5.1.7 - fix amd section mounts map reload
From: Ian Kent <raven@themaw.net>
Master map section mounts (amd format mounts) get umounted on reload.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index ff44ac25..ddc07912 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/master.c b/daemon/master.c
index 84743f80..f99359c5 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -882,6 +882,83 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int f
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_mounts(struct master *master, time_t ag
* 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);

40
package/autofs/patches/autofs-5.1.7-fix-arg-not-used-in-print.patch

@ -1,40 +0,0 @@
autofs-5.1.7 - fix arg not used in error print
From: Ian Kent <raven@themaw.net>
Coverity: extra_argument: This argument was not used by the format
string: "key".
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 4 +---
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f11aa1c7..1d56c96f 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 018b9c80..883e3743 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_cache *mc,
}
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);

124
package/autofs/patches/autofs-5.1.7-fix-concat_options-error-handling.patch

@ -1,124 +0,0 @@
autofs-5.1.7 - fix concat_options() error handling
From: Ian Kent <raven@themaw.net>
There's a possibility of a memory leak in the mount options processing
when calling concat_options() in parse_mount() of the Sun format map
entry parsing.
There's also a case in do_init() of the Sun map format parsing where
a previously freed value is used in a logging statement without being
set to MULL.
So ensure concat_options() always frees it's arguments so that the
handling can be consistent in all places.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 24 +++++++++++-------------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ecffa933..8d050552 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -78,6 +78,7 @@
- fix direct mount deadlock.
- add missing description of null map option.
- fix nonstrict offset mount fail handling.
+- fix concat_options() error handling.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index cdf515c6..9190165d 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -380,7 +380,8 @@ static int do_init(int argc, const char *const *argv, struct parse_context *ctxt
if (!tmp) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr(MODPREFIX "concat_options: %s", estr);
- free(gbl_options);
+ /* freed in concat_options */
+ ctxt->optstr = NULL;
} else
ctxt->optstr = tmp;
} else {
@@ -492,12 +493,16 @@ static char *concat_options(char *left, char *right)
char *ret;
if (left == NULL || *left == '\0') {
+ if (!right || *right == '\0')
+ return NULL;
ret = strdup(right);
free(right);
return ret;
}
if (right == NULL || *right == '\0') {
+ if (left == NULL || *left == '\0')
+ return NULL;
ret = strdup(left);
free(left);
return ret;
@@ -508,6 +513,8 @@ static char *concat_options(char *left, char *right)
if (ret == NULL) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr(MODPREFIX "malloc: %s", estr);
+ free(left);
+ free(right);
return NULL;
}
@@ -989,14 +996,13 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
if (newopt && strstr(newopt, myoptions)) {
free(myoptions);
myoptions = newopt;
- } else {
+ } else if (newopt) {
tmp = concat_options(myoptions, newopt);
if (!tmp) {
char *estr;
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(logopt, MODPREFIX
"concat_options: %s", estr);
- free(myoptions);
return 0;
}
myoptions = tmp;
@@ -1358,16 +1364,12 @@ dont_expand:
if (mnt_options && noptions && strstr(noptions, mnt_options)) {
free(mnt_options);
mnt_options = noptions;
- } else {
+ } else if (noptions) {
tmp = concat_options(mnt_options, noptions);
if (!tmp) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
MODPREFIX "concat_options: %s", estr);
- if (noptions)
- free(noptions);
- if (mnt_options)
- free(mnt_options);
free(options);
free(pmapent);
return 1;
@@ -1387,15 +1389,11 @@ dont_expand:
if (options && mnt_options && strstr(mnt_options, options)) {
free(options);
options = mnt_options;
- } else {
+ } else if (mnt_options) {
tmp = concat_options(options, mnt_options);
if (!tmp) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt, MODPREFIX "concat_options: %s", estr);
- if (options)
- free(options);
- if (mnt_options)
- free(mnt_options);
free(pmapent);
return 1;
}

39
package/autofs/patches/autofs-5.1.7-fix-dandling-symlink-creation-if-nis-support-is-not-available.patch

@ -1,39 +0,0 @@
autofs-5.1.7 - fix dandling symlink creation if nis support is not available
From: Ian Kent <raven@themaw.net>
If NIS support is not available a dangling symlink is created pointing
from lookup_nis.so to (a non-existent) lookup_yp.so.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/Makefile | 2 ++
2 files changed, 3 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index ddc07912..06bf24b8 100644
--- a/CHANGELOG
+++ b/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 dandling symlink creation if nis support is not available.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/Makefile b/modules/Makefile
index 91dc20ab..6908da06 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -77,7 +77,9 @@ install: all
install -c $(MODS) -m 755 $(INSTALLROOT)$(autofslibdir)
-rm -f $(INSTALLROOT)$(autofslibdir)/mount_smbfs.so
ln -fs lookup_file.so $(INSTALLROOT)$(autofslibdir)/lookup_files.so
+ifeq ($(YPCLNT), 1)
ln -fs lookup_yp.so $(INSTALLROOT)$(autofslibdir)/lookup_nis.so
+endif
ifeq ($(LDAP), 1)
ln -fs lookup_ldap.so $(INSTALLROOT)$(autofslibdir)/lookup_ldaps.so
endif

55
package/autofs/patches/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch

@ -1,55 +0,0 @@
autofs-5.1.7 - fix dead code in mnts_add_mount()
From: Ian Kent <raven@themaw.net>
Coverity: dead_error_line: Execution cannot reach this statement: "free(mp);".
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 8 ++------
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f95b1aa6..f11aa1c7 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index ef69cec1..018b9c80 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
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 autofs_point *ap,
free(mp);
return this;
-fail:
- if (mp)
- free(mp);
- return NULL;
}
void mnts_remove_mount(const char *mp, unsigned int flags)

135
package/autofs/patches/autofs-5.1.7-fix-direct-mount-deadlock.patch

@ -1,135 +0,0 @@
autofs-5.1.7 - fix direct mount deadlock
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 22 +++++++++++++++++++++-
daemon/state.c | 14 +++++++++-----
3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 9e341e06..b29d2ed8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -75,6 +75,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/direct.c b/daemon/direct.c
index 3bd714e6..d37dd676 100644
--- a/daemon/direct.c
+++ b/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_point *ap)
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_point *ap)
* failed umount.
*/
error = do_umount_autofs_direct(ap, me);
+ /* cache became invalid, restart */
+ if (error == -1)
+ goto restart;
if (!error)
goto done;
diff --git a/daemon/state.c b/daemon/state.c
index 091210a5..5156bb21 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -324,11 +324,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;
@@ -387,7 +388,7 @@ static void do_readmap_mount(struct autofs_point *ap,
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;
@@ -406,14 +407,14 @@ static void do_readmap_mount(struct autofs_point *ap,
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)
@@ -480,9 +481,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);

39
package/autofs/patches/autofs-5.1.7-fix-double-free-in-parse_mapent.patch

@ -1,39 +0,0 @@
autofs-5.1.7 - fix double free in parse_mapent()
From: Ian Kent <raven@themaw.net>
Coverity:
in parse_mapent(): double_free: Calling "free" frees pointer "newopt"
which has already been freed.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ff3d88eb..81461978 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 5d15f892..03a63290 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -974,8 +974,6 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(logopt, MODPREFIX
"concat_options: %s", estr);
- if (newopt)
- free(newopt);
free(myoptions);
return 0;
}

37
package/autofs/patches/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch

@ -1,37 +0,0 @@
autofs-5.1.7 - fix double unlock in parse_mount()
From: Ian Kent <raven@themaw.net>
Coverity: double_unlock: "cache_unlock" unlocks "mc->rwlock" while it
is unlocked.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2e3b9fd7..224f58d6 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index a81d4028..05f53fc2 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1526,7 +1526,6 @@ dont_expand:
if (!loc) {
free(options);
free(pmapent);
- cache_unlock(mc);
warn(ap->logopt, MODPREFIX "out of memory");
return 1;
}

38
package/autofs/patches/autofs-5.1.7-fix-flag-check-in-umount_multi.patch

@ -1,38 +0,0 @@
autofs-5.1.7 - fix flags check in umount_multi()
From: Ian Kent <raven@themaw.net>
Coverity: operator_confusion: "ap->flags | 1" is always 1/true
regardless of the values of its operand.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 9e385ba9..7add6c55 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 70506d83..23235a7d 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -662,7 +662,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl)
/* 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

300
package/autofs/patches/autofs-5.1.7-fix-hosts-map-offset-order.patch

@ -1,300 +0,0 @@
autofs-5.1.7 - fix hosts map offset order
From: Ian Kent <raven@themaw.net>
Map entry offset paths need 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 used to mount the offset during parsing
since the path length of exports can vary 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 <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 2 +
include/mounts.h | 8 ++++++
include/rpc_subs.h | 3 ++
lib/mounts.c | 57 ++++++++++++++++++++++++++++++++++++++--
modules/lookup_hosts.c | 69 ++++++++++++++++++++++++++++++++++++++----------
6 files changed, 123 insertions(+), 17 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 81b6ce6a..9e341e06 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -74,6 +74,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/automount.h b/include/automount.h
index d279744d..947ed16d 100644
--- a/include/automount.h
+++ b/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"
diff --git a/include/mounts.h b/include/mounts.h
index 5a7a0b89..ddb7e4c5 100644
--- a/include/mounts.h
+++ b/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 autofs_point *ap, const char *name, unsig
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);
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
index 080f19d9..debf2df0 100644
--- a/include/rpc_subs.h
+++ b/include/rpc_subs.h
@@ -23,6 +23,8 @@
#include <linux/nfs2.h>
#include <linux/nfs3.h>
+#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 {
diff --git a/lib/mounts.c b/lib/mounts.c
index 6b24a6c2..5a4602e3 100644
--- a/lib/mounts.c
+++ b/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(struct tree_node *root, void *ptr)
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 *root)
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_head *mnts)
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);
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 24edf00c..26c224f6 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *master, time_t age, void *context)
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_point *ap, const char *host)
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_point *ap, const char *host)
}
*mapent = 0;
- pos = 0;
- this = exp;
- if (this) {
- len = sprintf(mapent, "\"%s\" \"%s:%s\"",
- this->dir, host, this->dir);
- pos += len;
- this = this->next;
- }
+ wi.mapent = mapent;
+ wi.host = host;
+ wi.pos = 0;
- while (this) {
- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
- this->dir, host, this->dir);
- pos += len;
- this = this->next;
+ if (!tree) {
+ free(mapent);
+ mapent = NULL;
+ } else {
+ tree_traverse_inorder(tree, tree_host_work, &wi);
+ tree_free(tree);
}
rpc_exports_free(exp);

251
package/autofs/patches/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch

@ -1,251 +0,0 @@
autofs-5.1.7 - fix inconsistent locking in parse_mount()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 9 ++++++++-
modules/parse_sun.c | 53 ++++++++++++++++++++++++++++++++-------------------
3 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c60a9ed3..d25b19c8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 5ebfe5fd..0fcd4087 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2491,6 +2491,12 @@ static int do_mount_autofs_offset(struct autofs_point *ap,
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;
}
@@ -2634,7 +2640,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
/*
* 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);
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 95251bee..a6630a76 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -851,10 +851,12 @@ update_offset_entry(struct autofs_point *ap,
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
@@ -1128,14 +1130,22 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
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;
@@ -1180,9 +1190,12 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
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;
@@ -1199,9 +1212,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
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;
}
}
@@ -1217,9 +1231,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
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) {
@@ -1227,8 +1242,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
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;
}
@@ -1237,13 +1255,15 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
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)
@@ -1484,7 +1504,6 @@ dont_expand:
return 1;
}
- cache_multi_writelock(me);
/* So we know we're the multi-mount root */
if (!me->multi)
me->multi = me;
@@ -1509,14 +1528,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 {
@@ -1537,8 +1555,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);
@@ -1554,8 +1572,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);
@@ -1573,8 +1591,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);
@@ -1592,10 +1610,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);
@@ -1616,6 +1631,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);
@@ -1624,10 +1640,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);

135
package/autofs/patches/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch

@ -1,135 +0,0 @@
autofs-5.1.7 - fix inconsistent locking in umount_subtree_mounts()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 42 ++++++++++++++++++++++++++++++------------
lib/mounts.c | 8 --------
3 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1dded118..64e619ec 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 7fa92877..93bd8556 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -527,8 +527,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
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 autofs_point *ap, const char *path, unsi
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 autofs_point *ap, const char *path, unsi
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;
diff --git a/lib/mounts.c b/lib/mounts.c
index 87813b16..5ebfe5fd 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2736,9 +2736,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
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
@@ -2756,11 +2753,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
}
}
- /* 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);
}

44
package/autofs/patches/autofs-5.1.7-fix-incorrect-print-format-specifiers.patch

@ -1,44 +0,0 @@
autofs-5.1.7 - fix incorrect print format specifiers in get_pkt()
From: Ian Kent <raven@themaw.net>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 680dbbd7..0dac7318 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -82,6 +82,7 @@
- eliminate some more alloca usage.
- use default stack size for threads.
- fix use of possibly NULL var in lookup_program.c:match_key().
+- fix incorrect print format specifiers in get_pkt().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index d7432350..45e0833f 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1116,7 +1116,7 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt)
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
"read error on state pipe, "
- "read %u, error %s",
+ "read %lu, error %s",
read, estr);
st_mutex_unlock();
continue;
@@ -1134,7 +1134,7 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt)
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
"read error on request pipe, "
- "read %u, expected %u error %s",
+ "read %lu, expected %lu error %s",
read, kpkt_len, estr);
}
return read;

64
package/autofs/patches/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch

@ -1,64 +0,0 @@
autofs-5.1.7 - fix is mounted check on non existent path
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/dev-ioctl-lib.c | 3 +++
lib/mounts.c | 12 +++++++++++-
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 484bd866..e55fd66a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
- fix mnts_remove_amdmount() uses wrong list.
- Fix option for master read wait.
- eliminate cache_lookup_offset() usage.
+- fix is mounted check on non existent path.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index e8519236..7040c3da 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -759,6 +759,9 @@ static int dev_ioctl_ismountpoint(unsigned int logopt,
int save_errno = errno;
free_dev_ioctl_path(param);
errno = save_errno;
+ /* Path doesn't exist */
+ if (errno == ENOENT)
+ return 0;
return -1;
}
diff --git a/lib/mounts.c b/lib/mounts.c
index 42e8ef07..fe931b20 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1649,8 +1649,18 @@ static int table_is_mounted(const char *mp, unsigned int type)
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;

60
package/autofs/patches/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch

@ -1,60 +0,0 @@
autofs-5.1.7 - fix lookup_prune_one_cache() refactoring change
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 51e7767e..698cc27a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -69,6 +69,7 @@
- fix amd section mounts map reload.
- fix dandling symlink creation if nis support is not available.
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT.
+- fix lookup_prune_one_cache() refactoring change.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 3e9722e4..0b281f83 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -1379,6 +1379,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
if (!key || strchr(key, '*')) {
if (key)
free(key);
+ me = cache_enumerate(mc, me);
continue;
}
@@ -1386,6 +1387,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
if (!path) {
warn(ap->logopt, "can't malloc storage for path");
free(key);
+ me = cache_enumerate(mc, me);
continue;
}
@@ -1413,9 +1415,10 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
}
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)

36
package/autofs/patches/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch

@ -1,36 +0,0 @@
autofs-5.1.7 - fix missing lock release in mount_subtree()
From: Ian Kent <raven@themaw.net>
Covarity: missing_unlock: Returning without unlocking "mc->rwlock".
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 1d56c96f..ff3d88eb 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 05f53fc2..5d15f892 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1105,6 +1105,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
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] = '/';

40
package/autofs/patches/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch

@ -1,40 +0,0 @@
autofs-5.1.7 - fix mnts_get_expire_list() expire list construction
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index f5c5641a..1dded118 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,7 @@
- refactor umount_multi_triggers().
- eliminate clean_stale_multi_triggers().
- simplify mount_subtree() mount check.
+- fix mnts_get_expire_list() expire list construction.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index a9abbebf..87813b16 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1364,6 +1364,9 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
list_for_each_entry(mnt, &ap->mounts, mount) {
struct node *n;
+ if (!(mnt->flags & MNTS_MOUNTED))
+ continue;
+
__mnts_get_mount(mnt);
if (!tree) {

38
package/autofs/patches/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch

@ -1,38 +0,0 @@
autofs-5.1.7 - fix mnts_remove_amdmount() uses wrong list
From: Ian Kent <raven@themaw.net>
Function mnts_remove_amdmount() uses the wrong list when removing an
amd mount.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index d613e5ca..fe49740e 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index dbeb77b5..ccbd52e0 100644
--- a/lib/mounts.c
+++ b/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;

67
package/autofs/patches/autofs-5.1.7-fix-mount_fullpath.patch

@ -1,67 +0,0 @@
autofs-5.1.7 - fix mount_fullpath()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 4 +++-
modules/parse_amd.c | 6 ++++--
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 390028ac..e2fd532c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -36,6 +36,7 @@
- add tree_mapent_add_node().
- add tree_mapent_delete_offsets().
- add tree_mapent_traverse_subtree().
+- fix mount_fullpath().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index fded4c09..497c28c9 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -371,8 +371,10 @@ int mount_fullpath(char *fullpath, size_t max_len,
/* 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);
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index 5a9079d6..64c1ce63 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -1177,7 +1177,8 @@ static int do_generic_mount(struct autofs_point *ap, const char *name,
* 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_point *ap, const char *name,
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)

60
package/autofs/patches/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch

@ -1,60 +0,0 @@
autofs-5.1.7 - fix nonstrict offset mount fail handling
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 2 +-
modules/parse_sun.c | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f5f0da76..ecffa933 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -77,6 +77,7 @@
- fix hosts map offset order.
- fix direct mount deadlock.
- add missing description of null map option.
+- fix nonstrict offset mount fail handling.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 5a4602e3..4c866885 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work
{
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);
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 12844a30..cdf515c6 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1181,7 +1181,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
* 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);

207
package/autofs/patches/autofs-5.1.7-fix-offset-entries-order.patch

@ -1,207 +0,0 @@
autofs-5.1.7 - fix offset entries order
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 1 +
lib/cache.c | 1 +
modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++----------
4 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 94eb6a2c..7b360f52 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -71,6 +71,7 @@
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT.
- fix lookup_prune_one_cache() refactoring change.
- fix amd hosts mount expire.
+- fix offset entries order.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/automount.h b/include/automount.h
index 51a0bf0e..d279744d 100644
--- a/include/automount.h
+++ b/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;
diff --git a/lib/cache.c b/lib/cache.c
index ef761739..66dda5d9 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
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;
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 03a63290..b206a326 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -789,14 +789,15 @@ static int check_is_multi(const char *mapent)
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);
@@ -862,8 +863,29 @@ update_offset_entry(struct autofs_point *ap,
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) {
@@ -1209,6 +1231,25 @@ static char *do_expandsunent(const char *src, const char *key,
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] ...
@@ -1228,7 +1269,8 @@ int parse_mount(struct autofs_point *ap, const char *name,
char buf[MAX_ERR_BUF];
struct map_source *source;
struct mapent_cache *mc;
- struct mapent *me;
+ struct mapent *me, *oe, *tmp;
+ LIST_HEAD(offsets);
char *pmapent, *options;
const char *p;
int mapent_len, rv = 0;
@@ -1444,9 +1486,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);
@@ -1461,9 +1501,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);
@@ -1474,15 +1512,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);
@@ -1499,6 +1535,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);

38
package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch

@ -1,38 +0,0 @@
autofs-5.1.7 - fix possible memory leak in master_parse()
From: Ian Kent <raven@themaw.net>
Coverity: Overwriting "path" in "path = master_strdup(yyvsp[-1].strtype)"
leaks the storage that "path" points to.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master_parse.y | 2 ++
2 files changed, 3 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 2186cbe3..b797f6dc 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/master_parse.y b/daemon/master_parse.y
index 08e44b57..7480c36a 100644
--- a/daemon/master_parse.y
+++ b/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();

58
package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch

@ -1,58 +0,0 @@
autofs-5.1.7 - fix possible memory leak in mnts_add_amdmount()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 20 ++++++++++----------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b797f6dc..2e3b9fd7 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index c8a7bf00..ef69cec1 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *en
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;

44
package/autofs/patches/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch

@ -1,44 +0,0 @@
autofs-5.1.7 - fix return from umount_subtree_mounts() on offset list delete
From: Ian Kent <raven@themaw.net>
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 that
the umount of the subtree has not succeeded).
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 5 +++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 64e619ec..6e0edd74 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/automount.c b/daemon/automount.c
index 93bd8556..62530b6b 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -590,9 +590,10 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
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 &&

43
package/autofs/patches/autofs-5.1.7-fix-use-of-possibly-NULL-var-in-lookup_program_c-match_key.patch

@ -1,43 +0,0 @@
autofs-5.1.7 - fix use of possibly NULL var in lookup_program.c:match_key()
From: Ian Kent <raven@themaw.net>
The lookup key used in match_key() should not be NULL.
A check for a malloc() failure of the lookup key is missing in one of
the two cases in match_key() so add it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_program.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 61f3547a..680dbbd7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -81,6 +81,7 @@
- fix concat_options() error handling.
- eliminate some more alloca usage.
- use default stack size for threads.
+- fix use of possibly NULL var in lookup_program.c:match_key().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 028580e5..691abedb 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -468,6 +468,11 @@ static int match_key(struct autofs_point *ap,
if (!is_amd_format) {
lkp_key = strdup(name);
+ if (!lkp_key) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ return NSS_STATUS_UNAVAIL;
+ }
lkp_len = name_len;
} else {
size_t len;

69
package/autofs/patches/autofs-5.1.7-make-NFS-version-check-flags-consistent.patch

@ -1,69 +0,0 @@
autofs-5.1.7 - make NFS version check flags consistent
From: Ian Kent <raven@themaw.net>
Several of the NFS connection macros have the same value so that they
can be used as internal code documentation of what is being done.
Adjust the protocol macro naming to be consistent in a few places.
Also make sure the correct flags are set for the function they indicate.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/mount_nfs.c | 16 +++++++++-------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 17926916..c27973bb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -89,6 +89,7 @@
- add buffer length check to rmdir_path().
- eliminate buffer usage from handle_mounts_cleanup().
- add buffer length checks to autofs mount_mount().
+- make NFS version check flags consistent.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 0314a78f..0ab87dcf 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -178,18 +178,20 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
port = 0;
} else if (_strncmp("proto=udp", cp, o_len) == 0 ||
_strncmp("udp", cp, o_len) == 0) {
- vers &= ~TCP_SUPPORTED;
+ vers &= ~TCP_REQUESTED;
+ vers |= UDP_REQUESTED;
} else if (_strncmp("proto=udp6", cp, o_len) == 0 ||
_strncmp("udp6", cp, o_len) == 0) {
- vers &= ~TCP_SUPPORTED;
- vers |= UDP6_REQUESTED;
+ vers &= ~(TCP_REQUESTED|TCP6_REQUESTED);
+ vers |= (UDP_REQUESTED|UDP6_REQUESTED);
} else if (_strncmp("proto=tcp", cp, o_len) == 0 ||
_strncmp("tcp", cp, o_len) == 0) {
- vers &= ~UDP_SUPPORTED;
+ vers &= ~UDP_REQUESTED;
+ vers |= TCP_REQUESTED;
} else if (_strncmp("proto=tcp6", cp, o_len) == 0 ||
_strncmp("tcp6", cp, o_len) == 0) {
- vers &= ~UDP_SUPPORTED;
- vers |= TCP6_REQUESTED;
+ vers &= ~(UDP_REQUESTED|UDP6_REQUESTED);
+ vers |= TCP_REQUESTED|TCP6_REQUESTED;
}
/* Check for options that also make sense
with bind mounts */
@@ -246,7 +248,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
mount_default_proto == 4 &&
(vers & NFS_VERS_MASK) != 0 &&
(vers & NFS4_VERS_MASK) != 0 &&
- !(vers & UDP6_REQUESTED)) {
+ !(vers & (UDP_REQUESTED|UDP6_REQUESTED))) {
unsigned int v4_probe_ok = 0;
struct host *tmp = new_host(hosts->name, 0,
hosts->addr, hosts->addr_len,

352
package/autofs/patches/autofs-5.1.7-make-tree-implementation-data-independent.patch

@ -1,352 +0,0 @@
autofs-5.1.7 - make tree implementation data independent
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 29 +++++++++
lib/mounts.c | 174 ++++++++++++++++++++++++++++++++++--------------------
3 files changed, 140 insertions(+), 64 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0dae6761..74571570 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/mounts.h b/include/mounts.h
index ac480c06..71d29566 100644
--- a/include/mounts.h
+++ b/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.
*/
diff --git a/lib/mounts.c b/lib/mounts.c
index b478ecb4..a6d1c5a7 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -68,6 +68,17 @@ static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
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(const char *mp)
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(const char *mp)
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)
+static inline struct tree_node *tree_root(struct tree_ops *ops, void *ptr)
{
- 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)
-{
- 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(struct tree_node *root, struct mnt_list *
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 void tree_traverse(struct tree_node *n, struct list_head *mnts)
+static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, 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);
+ 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 int tree_mnt_expire_list_work(struct tree_node *n, void *ptr)
+{
+ 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_head *mnts, struct autofs_point *ap)
__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_head *mnts, struct autofs_point *ap)
}
}
- tree_traverse(tree, mnts);
+ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
tree_free(tree);
done:
mnts_hash_mutex_unlock();

118
package/autofs/patches/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch

@ -1,118 +0,0 @@
autofs-5.1.7 - move amd mounts removal into lib/mounts.c
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 12 +-----------
include/mounts.h | 1 +
lib/mounts.c | 28 ++++++++++++++++++++++++----
4 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 002da042..a9209755 100644
--- a/CHANGELOG
+++ b/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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/master.c b/daemon/master.c
index af9cd79f..b288e070 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -143,22 +143,12 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
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)
diff --git a/include/mounts.h b/include/mounts.h
index d7980976..1b376b3d 100644
--- a/include/mounts.h
+++ b/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);
diff --git a/lib/mounts.c b/lib/mounts.c
index 6b8e4c92..c8a7bf00 100644
--- a/lib/mounts.c
+++ b/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();
}

72
package/autofs/patches/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch

@ -1,72 +0,0 @@
autofs-5.1.7 - pass mapent_cache to update_offset_entry()
From: Ian Kent <raven@themaw.net>
Pass mapent_cache to update_offset_entry() rather than use the wait/signal
mechanism, it isn't needed here.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 22 ++++++----------------
2 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 6e0edd74..c60a9ed3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 1142e8a3..95251bee 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -793,24 +793,17 @@ static int check_is_multi(const char *mapent)
}
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 */
@@ -1574,11 +1567,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) {

171
package/autofs/patches/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch

@ -1,171 +0,0 @@
autofs-5.1.7 - pass root length to mount_fullpath()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8494f0dc..1c9e2a2d 100644
--- a/CHANGELOG
+++ b/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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/include/mounts.h b/include/mounts.h
index ec895e1c..d7980976 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -131,7 +131,7 @@ 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);
+ const char *root, size_t root_len, const char *name);
struct amd_entry;
diff --git a/lib/mounts.c b/lib/mounts.c
index c120d2a8..6b8e4c92 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -362,11 +362,14 @@ int check_nfs_mount_version(struct nfs_mount_vers *vers,
#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 mapent *oe)
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 mapent *oe, int nonstrict)
* 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;
}
diff --git a/modules/mount_bind.c b/modules/mount_bind.c
index c17c6f18..7f64332b 100644
--- a/modules/mount_bind.c
+++ b/modules/mount_bind.c
@@ -122,7 +122,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
}
}
- 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");
diff --git a/modules/mount_changer.c b/modules/mount_changer.c
index d02b5f45..8adb9f9a 100644
--- a/modules/mount_changer.c
+++ b/modules/mount_changer.c
@@ -59,7 +59,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
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");
diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c
index 53e6ee10..f4002e58 100644
--- a/modules/mount_ext2.c
+++ b/modules/mount_ext2.c
@@ -55,7 +55,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
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");
diff --git a/modules/mount_generic.c b/modules/mount_generic.c
index c9deb7ae..8cd0f4ab 100644
--- a/modules/mount_generic.c
+++ b/modules/mount_generic.c
@@ -54,7 +54,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
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");
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index c70210f4..0314a78f 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -213,7 +213,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
}
/* 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");
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index d3fc6c7f..b1c2611c 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1089,7 +1089,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
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;
@@ -1359,7 +1359,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");

83
package/autofs/patches/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch

@ -1,83 +0,0 @@
autofs-5.1.7 - reduce umount EBUSY check delay
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 4 ++--
daemon/indirect.c | 2 +-
include/automount.h | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b144f6aa..6419052d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,6 +23,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/daemon/direct.c b/daemon/direct.c
index fbfebbdd..5c1146a7 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -150,7 +150,7 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me)
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_point *ap, struct mapent *me)
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);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index eddcfff7..9f2ca6a0 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -265,7 +265,7 @@ int umount_autofs_indirect(struct autofs_point *ap, const char *root)
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);
diff --git a/include/automount.h b/include/automount.h
index 69445b92..fa6f5d63 100644
--- a/include/automount.h
+++ b/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 {

206
package/autofs/patches/autofs-5.1.7-refactor-get_nfs_info.patch

@ -1,206 +0,0 @@
autofs-5.1.7 - refactor get_nfs_info()
From: Ian Kent <raven@themaw.net>
Make getting a portmap client and getting a service port from portmap
helper functions and simplify the return handling.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
modules/replicated.c | 135 ++++++++++++++++++++++++++++----------------------
2 files changed, 76 insertions(+), 60 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c27973bb..5d2c2c88 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -90,6 +90,7 @@
- eliminate buffer usage from handle_mounts_cleanup().
- add buffer length checks to autofs mount_mount().
- make NFS version check flags consistent.
+- refactor get_nfs_info().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/replicated.c b/modules/replicated.c
index ffaf519f..e03c9d25 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -223,6 +223,49 @@ void free_host_list(struct host **list)
*list = NULL;
}
+static unsigned int get_portmap_client(unsigned logopt,
+ struct conn_info *pm_info, struct host *host,
+ int proto)
+{
+ unsigned int status;
+
+ /* On success client is stored in pm_info->client */
+ status = rpc_portmap_getclient(pm_info,
+ host->name, host->addr, host->addr_len,
+ proto, RPC_CLOSE_DEFAULT);
+ if (status == -EHOSTUNREACH)
+ debug(logopt,
+ "host not reachable getting portmap client");
+ else if (status)
+ debug(logopt, "error 0x%d getting portmap client");
+
+ return status;
+}
+
+static unsigned int get_portmap_port(unsigned logopt,
+ struct conn_info *pm_info, struct pmap *parms,
+ unsigned long vers, unsigned int version,
+ short unsigned int *port)
+{
+ unsigned int status;
+ short unsigned int nfs_port;
+
+ parms->pm_vers = vers;
+ status = rpc_portmap_getport(pm_info, parms, &nfs_port);
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
+ debug(logopt,
+ "host not reachable or timed out getting service port");
+ } else if (status < 0) {
+ if (!(version & NFS_VERS_MASK))
+ debug(logopt, "error 0x%d getting service port");
+ }
+
+ if (!status)
+ *port = nfs_port;
+
+ return status;
+}
+
static unsigned int get_nfs_info(unsigned logopt, struct host *host,
struct conn_info *pm_info, struct conn_info *rpc_info,
int proto, unsigned int version, int port)
@@ -263,33 +306,20 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
goto v3_ver;
if (!port) {
- status = rpc_portmap_getclient(pm_info,
- host->name, host->addr, host->addr_len,
- proto, RPC_CLOSE_DEFAULT);
- if (status == -EHOSTUNREACH) {
- debug(logopt,
- "host not reachable getting portmap client");
- supported = status;
- goto done_ver;
- } else if (status) {
- debug(logopt, "error 0x%d getting portmap client");
+ status = get_portmap_client(logopt, pm_info, host, proto);
+ if (status) {
+ if (status == -EHOSTUNREACH)
+ supported = status;
goto done_ver;
}
- parms.pm_vers = NFS4_VERSION;
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
- debug(logopt,
- "host not reachable or timed out getting service port");
- supported = status;
- goto done_ver;
- } else if (status < 0) {
- if (version & NFS_VERS_MASK)
+ status = get_portmap_port(logopt, pm_info, &parms,
+ NFS4_VERSION, version, &rpc_info->port);
+ if (status) {
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
+ supported = status;
+ if (status < 0 && version & NFS_VERS_MASK)
goto v3_ver; /* MOUNT_NFS_DEFAULT_PROTOCOL=4 */
- else {
- debug(logopt,
- "error 0x%d getting service port");
- goto done_ver;
- }
+ goto done_ver;
}
}
@@ -334,31 +364,22 @@ v3_ver:
goto v2_ver;
if (!port && !pm_info->client) {
- status = rpc_portmap_getclient(pm_info,
- host->name, host->addr, host->addr_len,
- proto, RPC_CLOSE_DEFAULT);
- if (status == -EHOSTUNREACH) {
- debug(logopt,
- "host not reachable getting portmap client");
- supported = status;
- goto done_ver;
- } else if (status) {
- debug(logopt,
- "error 0x%d getting getting portmap client");
+ status = get_portmap_client(logopt, pm_info, host, proto);
+ if (status) {
+ if (status == -EHOSTUNREACH)
+ supported = status;
goto done_ver;
}
}
if (!port) {
- parms.pm_vers = NFS3_VERSION;
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
- debug(logopt,
- "host not reachable or timed out getting service port");
- supported = status;
+ status = get_portmap_port(logopt, pm_info, &parms,
+ NFS3_VERSION, version, &rpc_info->port);
+ if (status) {
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
+ supported = status;
goto done_ver;
- } else if (status < 0)
- goto v2_ver;
+ }
}
if (rpc_info->proto == IPPROTO_UDP)
@@ -399,28 +420,22 @@ v2_ver:
goto done_ver;
if (!port && !pm_info->client) {
- status = rpc_portmap_getclient(pm_info,
- host->name, host->addr, host->addr_len,
- proto, RPC_CLOSE_DEFAULT);
- if (status == -EHOSTUNREACH) {
- debug(logopt,
- "host not reachable getting portmap client");
- supported = status;
- goto done_ver;
- } else if (status)
+ status = get_portmap_client(logopt, pm_info, host, proto);
+ if (status) {
+ if (status == -EHOSTUNREACH)
+ supported = status;
goto done_ver;
+ }
}
if (!port) {
- parms.pm_vers = NFS2_VERSION;
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
- debug(logopt,
- "host not reachable or timed out getting service port");
- supported = status;
- goto done_ver;
- } else if (status < 0)
+ status = get_portmap_port(logopt, pm_info, &parms,
+ NFS2_VERSION, version, &rpc_info->port);
+ if (status) {
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
+ supported = status;
goto done_ver;
+ }
}
if (rpc_info->proto == IPPROTO_UDP)

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save