diff --git a/autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch b/autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch new file mode 100644 index 0000000..dc111ac --- /dev/null +++ b/autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch @@ -0,0 +1,60 @@ +autofs-5.1.9 - add flags argument to amd do_program_mount() + +From: Ian Kent + +Most of the amd mount functions take a flags argument that allows them +to alter their function based on configuration. + +For example the amd option autofs_use_lofs will use bind mounts instead +of symlinks in some cases which might be preferred. + +The program mount function was not being passed this parameter but the +design of all the amd mount functions is quite similar and adding the +flag works as expected.. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -11,6 +11,7 @@ + - don't free ext mount if mounted. + - refactor amd function do_program_mount(). + - refactor umount_amd_ext_mount(). ++- add flags argument to amd do_program_mount(). + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/parse_amd.c ++++ autofs-5.1.9/modules/parse_amd.c +@@ -1412,7 +1412,8 @@ out: + } + + static int do_program_mount(struct autofs_point *ap, +- struct amd_entry *entry, const char *name) ++ struct amd_entry *entry, const char *name, ++ unsigned int flags) + { + int rv = 1; + +@@ -1486,7 +1487,7 @@ static int do_program_mount(struct autof + goto out; + } + done: +- rv = do_link_mount(ap, name, entry, 0); ++ rv = do_link_mount(ap, name, entry, flags); + if (rv) { + if (!umount_amd_ext_mount(ap, entry->fs, 1)) { + debug(ap->logopt, MODPREFIX +@@ -1715,7 +1716,7 @@ static int amd_mount(struct autofs_point + case AMD_MOUNT_TYPE_PROGRAM: + if (!validate_program_options(ap->logopt, entry)) + return 1; +- ret = do_program_mount(ap, entry, name); ++ ret = do_program_mount(ap, entry, name, flags); + break; + + default: diff --git a/autofs-5.1.9-add-some-unimplemented-amd-map-options.patch b/autofs-5.1.9-add-some-unimplemented-amd-map-options.patch new file mode 100644 index 0000000..4c01399 --- /dev/null +++ b/autofs-5.1.9-add-some-unimplemented-amd-map-options.patch @@ -0,0 +1,221 @@ +commit 6cbb6e9a3b8b223babf723e0f56cdd7b7eb90455 +Author: Ian Kent +Date: Mon Jul 8 11:04:11 2024 +0800 + + autofs-5.1.9 - add some unimplemented amd map options + + Add handling for amd per-mount options "utimeout", "unmount" and "nounmount" + if the kernel supports it. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + include/mounts.h | 2 ++ + include/parse_amd.h | 6 ++++++ + lib/mounts.c | 4 ++++ + modules/amd_parse.y | 38 +++++++++++++++++++++++++++++++------- + modules/parse_amd.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 94 insertions(+), 7 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -16,6 +16,7 @@ + - seperate amd mount and entry flags. + - make iocl ops ->timeout() handle per-dentry expire. + - refactor amd mount options handling. ++- add some unimplemented amd map options. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/include/mounts.h ++++ autofs-5.1.9/include/mounts.h +@@ -113,6 +113,8 @@ struct mnt_list { + char *amd_pref; + char *amd_type; + char *amd_opts; ++ unsigned long amd_flags; ++ unsigned int amd_utimeout; + unsigned int amd_cache_opts; + struct list_head amdmount; + +--- autofs-5.1.9.orig/include/parse_amd.h ++++ autofs-5.1.9/include/parse_amd.h +@@ -33,6 +33,11 @@ + #define AMD_MOUNT_TYPE_PROGRAM 0x00004000 + #define AMD_MOUNT_TYPE_MASK 0x0000ffff + ++#define AMD_MOUNT_OPT_UNMOUNT 0x00010000 ++#define AMD_MOUNT_OPT_NOUNMOUNT 0x00020000 ++#define AMD_MOUNT_OPT_UTIMEOUT 0x00040000 ++#define AMD_MOUNT_OPT_MASK 0x00ff0000 ++ + #define AMD_DEFAULTS_MERGE 0x0001 + #define AMD_DEFAULTS_RESET 0x0002 + #define AMD_DEFAULTS_MASK 0x00ff +@@ -49,6 +54,7 @@ + struct amd_entry { + char *path; + unsigned long flags; ++ unsigned int utimeout; + unsigned int cache_opts; + unsigned int entry_flags; + char *type; +--- autofs-5.1.9.orig/lib/mounts.c ++++ autofs-5.1.9/lib/mounts.c +@@ -1193,6 +1193,8 @@ struct mnt_list *mnts_add_amdmount(struc + this->amd_pref = pref; + this->amd_type = type; + this->amd_opts = opts; ++ this->amd_flags = entry->flags; ++ this->amd_utimeout = entry->utimeout; + this->amd_cache_opts = entry->cache_opts; + this->flags |= MNTS_AMD_MOUNT; + if (list_empty(&this->amdmount)) +@@ -1237,6 +1239,8 @@ static void __mnts_remove_amdmount(const + free(this->amd_opts); + this->amd_opts = NULL; + } ++ this->amd_flags = AMD_MOUNT_OPT_UNMOUNT; ++ this->amd_utimeout = -1; + this->amd_cache_opts = 0; + __mnts_put_mount(this); + } +--- autofs-5.1.9.orig/modules/amd_parse.y ++++ autofs-5.1.9/modules/amd_parse.y +@@ -647,8 +647,7 @@ static int match_mnt_option(char *option + { + int ret = 0; + +- if (!strcmp(option, "fullybrowsable") || +- !strcmp(option, "nounmount")) { ++ if (!strcmp(option, "fullybrowsable")) { + sprintf(msg_buf, "option %s is not currently " + "implemented, ignored", option); + amd_info(msg_buf); +@@ -660,15 +659,37 @@ static int match_mnt_option(char *option + sprintf(msg_buf, "option %s is not used by " + "autofs, ignored", option); + amd_info(msg_buf); ++ } else if (!strcmp(option, "umount")) { ++ entry.flags &= ~AMD_MOUNT_OPT_NOUNMOUNT; ++ entry.flags |= AMD_MOUNT_OPT_UNMOUNT; ++ } else if (!strcmp(option, "nounmount")) { ++ if (entry.flags & AMD_MOUNT_TYPE_AUTO) ++ prepend_opt(opts, "timeout=0"); ++ else { ++ entry.flags &= ~AMD_MOUNT_OPT_UNMOUNT; ++ entry.flags |= AMD_MOUNT_OPT_NOUNMOUNT; ++ entry.utimeout = 0; ++ } + } else if (!strncmp(option, "utimeout=", 9)) { ++ /* ++ * amd type "auto" mounts map to autofs fstype=autofs ++ * mounts so a distinct autofs mount is present at the ++ * the root so there's no need for special handling, ++ * just pass the timeout= autofs option. ++ */ + if (entry.flags & AMD_MOUNT_TYPE_AUTO) + prepend_opt(options, ++option); + else { +- sprintf(msg_buf, "umount timeout can't be " +- "used for other than type " +- "\"auto\" with autofs, " +- "ignored"); +- amd_info(msg_buf); ++ if (strchr(option, '=')) { ++ unsigned long tout; ++ int ret; ++ ++ ret = sscanf(option, "utimeout=%lu", &tout); ++ if (ret) { ++ entry.flags |= AMD_MOUNT_OPT_UTIMEOUT; ++ entry.utimeout = tout; ++ } ++ } + } + } else + ret = 1; +@@ -791,6 +812,8 @@ static void local_init_vars(void) + { + memset(&entry, 0, sizeof(entry)); + entry.cache_opts = AMD_CACHE_OPTION_NONE; ++ entry.flags = AMD_MOUNT_OPT_UNMOUNT; ++ entry.utimeout = -1; + memset(opts, 0, sizeof(opts)); + } + +@@ -900,6 +923,7 @@ static int add_location(void) + new->path = entry.path; + } + new->flags = entry.flags; ++ new->utimeout = entry.utimeout; + new->cache_opts = entry.cache_opts; + new->entry_flags = entry.entry_flags; + new->type = entry.type; +--- autofs-5.1.9.orig/modules/parse_amd.c ++++ autofs-5.1.9/modules/parse_amd.c +@@ -1654,6 +1654,7 @@ static int amd_mount(struct autofs_point + struct parse_context *ctxt) + { + unsigned long fstype = entry->flags & AMD_MOUNT_TYPE_MASK; ++ unsigned long per_mnt_flags = entry->flags & AMD_MOUNT_OPT_MASK; + int ret = 1; + + switch (fstype) { +@@ -1725,6 +1726,55 @@ static int amd_mount(struct autofs_point + break; + } + ++ if (!ret) { ++ struct ioctl_ops *ops; ++ ++ if (!(per_mnt_flags & AMD_MOUNT_OPT_MASK)) ++ goto done; ++ ++ /* The mount succeeded, make sure there's no path component ++ * seperator in "name" as it must be the last component of ++ * the mount point alone for the per-mount options. ++ */ ++ if (strchr(name, '/')) { ++ warn(ap->logopt, "path component seperator not valid here"); ++ goto done; ++ } ++ ++ ops = get_ioctl_ops(); ++ ++ /* The default in autofs is to always expire mounts according to ++ * a timeout set in the autofs mount super block information ++ * structure. But amd allows for differing expire timeouts on a ++ * per-mount basis. It also has (context sensitive) options "unmount" ++ * to say expire this mount and "nounmount" to say don't expire this ++ * mount. In amd mounts these options are set by default according ++ * to whether a mount should expire or not, for example a cd mount ++ * is set "nounmount". Setting defaults like this is not used in the ++ * autofs amd implementation because there's only one, little used, ++ * removable file system available. ++ * ++ * But the "nounmount" and "utimeout" options can be useful. ++ */ ++ if (per_mnt_flags & AMD_MOUNT_OPT_NOUNMOUNT) { ++ if (entry->utimeout) ++ warn(ap->logopt, ++ "non-zero timeout set, possible conflicting options"); ++ ++ /* "nounmount" option, don't expire this mount. */ ++ if (ops) ++ ops->timeout(ap->logopt, ap->ioctlfd, name, 0); ++ } else if (per_mnt_flags & AMD_MOUNT_OPT_UTIMEOUT) { ++ if (!entry->utimeout) ++ warn(ap->logopt, ++ "zero timeout set, possible conflicting options"); ++ ++ /* "utimeout" option, expire this mount according to a timeout. */ ++ if (ops) ++ ops->timeout(ap->logopt, ap->ioctlfd, name, entry->utimeout); ++ } ++ } ++done: + return ret; + } + diff --git a/autofs-5.1.9-dont-free-ext-mount-if-mounted.patch b/autofs-5.1.9-dont-free-ext-mount-if-mounted.patch new file mode 100644 index 0000000..37caffe --- /dev/null +++ b/autofs-5.1.9-dont-free-ext-mount-if-mounted.patch @@ -0,0 +1,53 @@ +autofs-5.1.9 - don't free ext mount if mounted + +From: Ian Kent + +If an external mount is in use when a umount is attempted don't free +it just let the reference count go to zero. + +This will leave the mount in place and it won't get umounted. But if +another automount uses it it's reference count will become no zero +allowing for it to be umounted as normal if it isn't in use during +automount expire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -8,6 +8,7 @@ + - fix deadlock in remount. + - fix amd external mount error handling. + - fix amd external mount mount handling. ++- don't free ext mount if mounted. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/lib/mounts.c ++++ autofs-5.1.9/lib/mounts.c +@@ -889,10 +889,10 @@ int ext_mount_remove(const char *path) + if (!em) + goto done; + +- em->ref--; + if (em->ref) +- goto done; +- else { ++ em->ref--; ++ ++ if (!em->ref && !is_mounted(path, MNTS_REAL)) { + hlist_del_init(&em->mount); + free(em->mp); + if (em->umount) +@@ -914,7 +914,7 @@ int ext_mount_inuse(const char *path) + em = ext_mount_lookup(path); + if (!em) + goto done; +- ret = em->ref; ++ ret = 1; + done: + ext_mount_hash_mutex_unlock(); + return ret; diff --git a/autofs-5.1.9-fix-always-recreate-credential-cache.patch b/autofs-5.1.9-fix-always-recreate-credential-cache.patch new file mode 100644 index 0000000..0bbfc18 --- /dev/null +++ b/autofs-5.1.9-fix-always-recreate-credential-cache.patch @@ -0,0 +1,36 @@ +autofs-5.1.9 - fix always recreate credential cache + +From: Ian Kent + +When I aplied the original patch from Ian Collier for this I changed +the credential end time comparison to be against the time returned from +monotomic_time(). But this isn't the same as the calander time returned +from time() which Ian used in his original patch. + +Signed-off-by: Ian Kent < raven@themaw.net> +--- + CHANGELOG | 1 + + modules/cyrus-sasl.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -3,6 +3,7 @@ + - fix ldap_parse_page_control() check. + - fix crash in make_options_string(). + - Fix incompatible function pointer types in cyrus-sasl module. ++- fix always recreate credential cache. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/cyrus-sasl.c ++++ autofs-5.1.9/modules/cyrus-sasl.c +@@ -676,7 +676,7 @@ sasl_do_kinit(unsigned logopt, struct lo + } + else { + krb5_creds match_creds, out_creds; +- time_t now = monotonic_time(NULL); ++ time_t now = time(NULL); + + /* even if the cache is in use, we will clear it if it + * contains an expired credential for our principal, diff --git a/autofs-5.1.9-fix-amd-cache-options-not-copied.patch b/autofs-5.1.9-fix-amd-cache-options-not-copied.patch new file mode 100644 index 0000000..523cc10 --- /dev/null +++ b/autofs-5.1.9-fix-amd-cache-options-not-copied.patch @@ -0,0 +1,36 @@ +commit abf2030556dfe694dc19ed2d73f84f7e5046b660 +Author: Ian Kent +Date: Thu Jul 11 13:56:15 2024 +0800 + + autofs-5.1.9 - fix amd cache options not copied + + The cache options set when parsing the amd map entry are not copied to + the list entry that gets processed by the caller. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + modules/amd_parse.y | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -12,6 +12,7 @@ + - refactor amd function do_program_mount(). + - refactor umount_amd_ext_mount(). + - add flags argument to amd do_program_mount(). ++- fix amd cache options not copied. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/amd_parse.y ++++ autofs-5.1.9/modules/amd_parse.y +@@ -888,6 +888,7 @@ static int add_location(void) + new->path = entry.path; + } + new->flags = entry.flags; ++ new->cache_opts = entry.cache_opts; + new->type = entry.type; + new->map_type = entry.map_type; + new->pref = entry.pref; diff --git a/autofs-5.1.9-fix-amd-external-mount-error-handling.patch b/autofs-5.1.9-fix-amd-external-mount-error-handling.patch new file mode 100644 index 0000000..7402d80 --- /dev/null +++ b/autofs-5.1.9-fix-amd-external-mount-error-handling.patch @@ -0,0 +1,55 @@ +autofs-5.1.9 - fix amd external mount error handling + +From: Ian Kent + +An amd program mount might have defined its own umount program to be used +for external mounts. + +In mount failure cases where the mount needs to be umounted be sure to +use the custom umount if there is one. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -6,6 +6,7 @@ + - fix always recreate credential cache. + - fix get parent multi-mount check in try_remount(). + - fix deadlock in remount. ++- fix amd external mount error handling. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/parse_amd.c ++++ autofs-5.1.9/modules/parse_amd.c +@@ -1190,7 +1190,7 @@ static int do_generic_mount(struct autof + } + /* If we have an external mount add it to the list */ + if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_ent(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", + entry->fs); +@@ -1240,7 +1240,7 @@ static int do_nfs_mount(struct autofs_po + } + /* We might be using an external mount */ + if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_ent(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", entry->fs); + ret = 1; +@@ -1469,7 +1469,7 @@ static int do_program_mount(struct autof + "%s: mounted %s", entry->type, entry->fs); + goto do_free; + } +- umount_ent(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs); + } + + if (!ext_mount_inuse(entry->fs)) diff --git a/autofs-5.1.9-fix-amd-external-mount-mount-handling.patch b/autofs-5.1.9-fix-amd-external-mount-mount-handling.patch new file mode 100644 index 0000000..835ffac --- /dev/null +++ b/autofs-5.1.9-fix-amd-external-mount-mount-handling.patch @@ -0,0 +1,71 @@ +autofs-5.1.9 - fix amd external mount mount handling + +From: Ian Kent + +Amd external mounts exist outside of the autofs file system and need +extra effort to try and keep track of them so they are mounted and +umounted when they should be. + +Cleanup cases where an external mount is already mounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 21 ++++++++++++--------- + 2 files changed, 13 insertions(+), 9 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -7,6 +7,7 @@ + - fix get parent multi-mount check in try_remount(). + - fix deadlock in remount. + - fix amd external mount error handling. ++- fix amd external mount mount handling. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/parse_amd.c ++++ autofs-5.1.9/modules/parse_amd.c +@@ -1189,8 +1189,9 @@ static int do_generic_mount(struct autof + umount = 1; + } + /* If we have an external mount add it to the list */ +- if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_amd_ext_mount(ap, entry->fs); ++ if (!ext_mount_add(entry->fs, entry->umount)) { ++ if (umount) ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", + entry->fs); +@@ -1239,8 +1240,9 @@ static int do_nfs_mount(struct autofs_po + umount = 1; + } + /* We might be using an external mount */ +- if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_amd_ext_mount(ap, entry->fs); ++ if (!ext_mount_add(entry->fs, entry->umount)) { ++ if (umount) ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", entry->fs); + ret = 1; +@@ -1442,12 +1444,13 @@ static int do_program_mount(struct autof + * before executing the mount command and removing it at + * umount. + */ +- if (ext_mount_inuse(entry->fs)) { ++ if (is_mounted(entry->fs, MNTS_REAL)) { ++ if (!ext_mount_add(entry->fs, entry->umount)) { ++ error(ap->logopt, MODPREFIX ++ "error: could not add external mount %s", entry->fs); ++ goto out; ++ } + rv = 0; +- /* An external mount with path entry->fs exists +- * so ext_mount_add() won't fail. +- */ +- ext_mount_add(entry->fs, entry->umount); + } else { + rv = mkdir_path(entry->fs, mp_mode); + if (rv && errno != EEXIST) { diff --git a/autofs-5.1.9-fix-deadlock-in-remount.patch b/autofs-5.1.9-fix-deadlock-in-remount.patch new file mode 100644 index 0000000..7c28cb2 --- /dev/null +++ b/autofs-5.1.9-fix-deadlock-in-remount.patch @@ -0,0 +1,68 @@ +autofs-5.1.9 - fix deadlock in remount + +From: Ian Kent + +If we're starting up or trying to re-connect to an existing direct mount +we could be iterating through the map entries with the cache readlock +held so we can't just take the writelock for direct mounts. But when +trying to re-connect to an existing mount at startup there won't be any +other process updating the map entry cache. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 26 ++++++++++++++++++++++++-- + 2 files changed, 25 insertions(+), 2 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -5,6 +5,7 @@ + - Fix incompatible function pointer types in cyrus-sasl module. + - fix always recreate credential cache. + - fix get parent multi-mount check in try_remount(). ++- fix deadlock in remount. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/parse_sun.c ++++ autofs-5.1.9/modules/parse_sun.c +@@ -889,7 +889,18 @@ update_offset_entry(struct autofs_point + strcpy(m_mapent, loc); + } + +- cache_writelock(mc); ++ /* ++ * If we're starting up or trying to re-connect to an existing ++ * direct mount we could be iterating through the map entries ++ * with the readlock held so we can't just take the writelock ++ * for direct mounts. But at when trying to re-connect to an ++ * existing mount at startup there won't be any other process ++ * updating the map entry cache. ++ */ ++ if (ap->state == ST_INIT && ap->flags & MOUNT_FLAG_REMOUNT) ++ cache_readlock(mc); ++ else ++ cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + + me = cache_lookup_distinct(mc, m_key); +@@ -1581,7 +1592,18 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + +- cache_writelock(mc); ++ /* ++ * If we're starting up or trying to re-connect to an existing ++ * direct mount we could be iterating through the map entries ++ * with the readlock held so we can't just take the writelock ++ * for direct mounts. But at when trying to re-connect to an ++ * existing mount at startup there won't be any other process ++ * updating the map entry cache. ++ */ ++ if (ap->state == ST_INIT && ap->flags & MOUNT_FLAG_REMOUNT) ++ cache_readlock(mc); ++ else ++ cache_writelock(mc); + me = cache_lookup_distinct(mc, name); + if (!me) { + cache_unlock(mc); diff --git a/autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch b/autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch new file mode 100644 index 0000000..1f48ad4 --- /dev/null +++ b/autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch @@ -0,0 +1,43 @@ +autofs-5.1.9 - fix get parent multi-mount check in try_remount() + +From: Ian Kent + +In commit 635b90ecc (autofs-5.1.8 - fix mount tree startup reconnect) +when getting the parent the check for a multi-mount should include a +check for the root of the multi-mount as well since the root does not +set its parent (it remains NULL). + +We could set the root parent to itself but that may have side effects +because the convention has always been the parent is NULL for the +multi-mount root. + +Reported-by: Roberto Bergantinos Corpas +Suggested-by: Roberto Bergantinos Corpas + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -4,6 +4,7 @@ + - fix crash in make_options_string(). + - Fix incompatible function pointer types in cyrus-sasl module. + - fix always recreate credential cache. ++- fix get parent multi-mount check in try_remount(). + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/lib/mounts.c ++++ autofs-5.1.9/lib/mounts.c +@@ -2861,7 +2861,7 @@ int try_remount(struct autofs_point *ap, + } + + me->flags &= ~MOUNT_FLAG_DIR_CREATED; +- mapent = IS_MM(me) ? MM_PARENT(me) : me; ++ mapent = IS_MM(me) && !IS_MM_ROOT(me) ? MM_PARENT(me) : me; + /* Direct or offset mount, key is full path */ + if (mapent->key[0] == '/') { + if (!is_mounted(mapent->key, MNTS_REAL)) diff --git a/autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch b/autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch new file mode 100644 index 0000000..1b077d3 --- /dev/null +++ b/autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch @@ -0,0 +1,193 @@ +commit 6fdfbcd65fd845e968a68cbdf475a6dd0ee0ee66 +Author: Ian Kent +Date: Tue Jul 9 16:18:19 2024 +0800 + + autofs-5.1.9 - make ioctl ops ->timeout() handle per-dentry expire + + Update the ioctl ops ->timeout() function to handle setting of per-dentry + expire timeout if the kernel supports it. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + daemon/direct.c | 6 +++--- + daemon/indirect.c | 2 +- + daemon/state.c | 4 ++-- + include/dev-ioctl-lib.h | 2 +- + lib/dev-ioctl-lib.c | 42 +++++++++++++++++++++++++++++++----------- + lib/mounts.c | 4 ++-- + 7 files changed, 41 insertions(+), 20 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -14,6 +14,7 @@ + - add flags argument to amd do_program_mount(). + - fix amd cache options not copied. + - seperate amd mount and entry flags. ++- make iocl ops ->timeout() handle per-dentry expire. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/daemon/direct.c ++++ autofs-5.1.9/daemon/direct.c +@@ -328,7 +328,7 @@ int do_mount_autofs_direct(struct autofs + return 0; + } + +- ops->timeout(ap->logopt, ioctlfd, tout); ++ ops->timeout(ap->logopt, ioctlfd, NULL, tout); + + if (save_ioctlfd == -1) + ops->close(ap->logopt, ioctlfd); +@@ -423,7 +423,7 @@ int do_mount_autofs_direct(struct autofs + goto out_umount; + } + +- ops->timeout(ap->logopt, ioctlfd, timeout); ++ ops->timeout(ap->logopt, ioctlfd, NULL, timeout); + notify_mount_result(ap, me->key, timeout, str_direct); + cache_set_ino_index(me->mc, me); + ops->close(ap->logopt, ioctlfd); +@@ -779,7 +779,7 @@ int mount_autofs_offset(struct autofs_po + if (ioctlfd < 0) + goto out_umount; + +- ops->timeout(ap->logopt, ioctlfd, timeout); ++ ops->timeout(ap->logopt, ioctlfd, NULL, timeout); + cache_set_ino_index(me->mc, me); + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); +--- autofs-5.1.9.orig/daemon/indirect.c ++++ autofs-5.1.9/daemon/indirect.c +@@ -136,7 +136,7 @@ static int do_mount_autofs_indirect(stru + goto out_umount; + } + +- ops->timeout(ap->logopt, ap->ioctlfd, timeout); ++ ops->timeout(ap->logopt, ap->ioctlfd, NULL, timeout); + notify_mount_result(ap, ap->path, timeout, str_indirect); + + return 0; +--- autofs-5.1.9.orig/daemon/state.c ++++ autofs-5.1.9/daemon/state.c +@@ -370,7 +370,7 @@ static int do_readmap_mount(struct autof + cache_unlock(vmc); + /* Set timeout and calculate the expire run frequency */ + timeout = get_exp_timeout(ap, map); +- ops->timeout(ap->logopt, valid->ioctlfd, timeout); ++ ops->timeout(ap->logopt, valid->ioctlfd, NULL, timeout); + if (timeout) { + runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + if (ap->exp_runfreq) +@@ -431,7 +431,7 @@ static void *do_readmap(void *arg) + struct ioctl_ops *ops = get_ioctl_ops(); + time_t timeout = get_exp_timeout(ap, ap->entry->maps); + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; +- ops->timeout(ap->logopt, ap->ioctlfd, timeout); ++ ops->timeout(ap->logopt, ap->ioctlfd, NULL, timeout); + lookup_prune_cache(ap, now); + status = lookup_ghost(ap); + } else { +--- autofs-5.1.9.orig/include/dev-ioctl-lib.h ++++ autofs-5.1.9/include/dev-ioctl-lib.h +@@ -45,7 +45,7 @@ struct ioctl_ops { + int (*send_fail)(unsigned int, int, unsigned int, int); + int (*setpipefd)(unsigned int, int, int); + int (*catatonic)(unsigned int, int); +- int (*timeout)(unsigned int, int, time_t); ++ int (*timeout)(unsigned int, int, const char *, time_t); + int (*requester)(unsigned int, int, const char *, uid_t *, gid_t *); + int (*expire)(unsigned int, int, const char *, unsigned int); + int (*askumount)(unsigned int, int, unsigned int *); +--- autofs-5.1.9.orig/lib/dev-ioctl-lib.c ++++ autofs-5.1.9/lib/dev-ioctl-lib.c +@@ -55,7 +55,7 @@ static int dev_ioctl_send_ready(unsigned + static int dev_ioctl_send_fail(unsigned int, int, unsigned int, int); + static int dev_ioctl_setpipefd(unsigned int, int, int); + static int dev_ioctl_catatonic(unsigned int, int); +-static int dev_ioctl_timeout(unsigned int, int, time_t); ++static int dev_ioctl_timeout(unsigned int, int, const char *, time_t); + static int dev_ioctl_requester(unsigned int, int, const char *, uid_t *, gid_t *); + static int dev_ioctl_expire(unsigned int, int, const char *, unsigned int); + static int dev_ioctl_askumount(unsigned int, int, unsigned int *); +@@ -69,7 +69,7 @@ static int ioctl_close(unsigned int, int + static int ioctl_send_ready(unsigned int, int, unsigned int); + static int ioctl_send_fail(unsigned int, int, unsigned int, int); + static int ioctl_catatonic(unsigned int, int); +-static int ioctl_timeout(unsigned int, int, time_t); ++static int ioctl_timeout(unsigned int, int, const char *, time_t); + static int ioctl_expire(unsigned int, int, const char *, unsigned int); + static int ioctl_askumount(unsigned int, int, unsigned int *); + +@@ -571,21 +571,41 @@ static int ioctl_catatonic(unsigned int + } + + /* Set the autofs mount timeout */ +-static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout) ++static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, const char *mp, time_t timeout) + { +- struct autofs_dev_ioctl param; +- +- init_autofs_dev_ioctl(¶m); +- param.ioctlfd = ioctlfd; +- param.timeout.timeout = timeout; ++ if (!mp) { ++ struct autofs_dev_ioctl param; + +- if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) == -1) +- return -1; ++ init_autofs_dev_ioctl(¶m); ++ param.ioctlfd = ioctlfd; ++ param.timeout.timeout = timeout; ++ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) == -1) ++ return -1; ++ } else { ++ unsigned int kver_major = get_kver_major(); ++ unsigned int kver_minor = get_kver_minor(); ++ struct autofs_dev_ioctl *param; ++ ++ if (kver_major < 5 || ++ (kver_major == 5 && kver_minor < 6)) { ++ error(logopt, "per-mount expire timeout not supported by kernel."); ++ return -1; ++ } + ++ param = alloc_dev_ioctl_path(ioctlfd, mp); ++ if (!param) ++ return -1; ++ param->timeout.timeout = timeout; ++ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, param) == -1) { ++ free_dev_ioctl_path(param); ++ return -1; ++ } ++ free_dev_ioctl_path(param); ++ } + return 0; + } + +-static int ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout) ++static int ioctl_timeout(unsigned int logopt, int ioctlfd, const char *mp, time_t timeout) + { + time_t tout = timeout; + return ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout); +--- autofs-5.1.9.orig/lib/mounts.c ++++ autofs-5.1.9/lib/mounts.c +@@ -2740,7 +2740,7 @@ static int remount_active_mount(struct a + /* Re-reading the map, set timeout and return */ + if (ap->state == ST_READMAP) { + debug(ap->logopt, "already mounted, update timeout"); +- ops->timeout(ap->logopt, fd, timeout); ++ ops->timeout(ap->logopt, fd, NULL, timeout); + ops->close(ap->logopt, fd); + return REMOUNT_READ_MAP; + } +@@ -2762,7 +2762,7 @@ static int remount_active_mount(struct a + ops->close(ap->logopt, fd); + return REMOUNT_OPEN_FAIL; + } +- ops->timeout(ap->logopt, fd, timeout); ++ ops->timeout(ap->logopt, fd, NULL, timeout); + if (fstat(fd, &st) == -1) { + error(ap->logopt, + "failed to stat %s mount %s", str_type, path); diff --git a/autofs-5.1.9-refactor-amd-function-do_program_mount.patch b/autofs-5.1.9-refactor-amd-function-do_program_mount.patch new file mode 100644 index 0000000..ca1d710 --- /dev/null +++ b/autofs-5.1.9-refactor-amd-function-do_program_mount.patch @@ -0,0 +1,138 @@ +autofs-5.1.9 - refactor amd function do_program_mount() + +From: Ian Kent + +The amd mounts function do_program_mount() is particularly untidy. + +Refactor it to make it a little simpler and to take advantage of the +coming refactoring of the funtion umount_amd_ext_mount(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/parse_amd.c | 74 ++++++++++++++++++++++++---------------------------- + 2 files changed, 36 insertions(+), 39 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -9,6 +9,7 @@ + - fix amd external mount error handling. + - fix amd external mount mount handling. + - don't free ext mount if mounted. ++- refactor amd function do_program_mount(). + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/parse_amd.c ++++ autofs-5.1.9/modules/parse_amd.c +@@ -1414,26 +1414,8 @@ out: + static int do_program_mount(struct autofs_point *ap, + struct amd_entry *entry, const char *name) + { +- char *prog, *str; +- char **argv; +- int argc = -1; + int rv = 1; + +- str = strdup(entry->mount); +- if (!str) +- goto out; +- +- prog = NULL; +- argv = NULL; +- +- argc = construct_argv(str, &prog, &argv); +- if (argc == -1) { +- error(ap->logopt, MODPREFIX +- "%s: error creating mount arguments", entry->type); +- free(str); +- goto out; +- } +- + /* The am-utils documentation doesn't actually say that the + * mount (and umount, if given) command need to use ${fs} as + * the mount point in the command. +@@ -1452,6 +1434,25 @@ static int do_program_mount(struct autof + } + rv = 0; + } else { ++ char *prog, *str; ++ char **argv; ++ int argc = -1; ++ ++ str = strdup(entry->mount); ++ if (!str) ++ goto out; ++ ++ prog = NULL; ++ argv = NULL; ++ ++ argc = construct_argv(str, &prog, &argv); ++ if (argc == -1) { ++ error(ap->logopt, MODPREFIX ++ "%s: error creating mount arguments", entry->type); ++ free(str); ++ goto out; ++ } ++ + rv = mkdir_path(entry->fs, mp_mode); + if (rv && errno != EEXIST) { + char buf[MAX_ERR_BUF]; +@@ -1461,7 +1462,9 @@ static int do_program_mount(struct autof + error(ap->logopt, + MODPREFIX "%s: mkdir_path %s failed: %s", + entry->type, entry->fs, estr); +- goto do_free; ++ free_argv(argc, (const char **) argv); ++ free(str); ++ goto out; + } + + rv = spawnv(ap->logopt, prog, (const char * const *) argv); +@@ -1470,33 +1473,26 @@ static int do_program_mount(struct autof + rv = 0; + debug(ap->logopt, MODPREFIX + "%s: mounted %s", entry->type, entry->fs); +- goto do_free; ++ free_argv(argc, (const char **) argv); ++ free(str); ++ goto done; + } + umount_amd_ext_mount(ap, entry->fs); + } +- +- if (!ext_mount_inuse(entry->fs)) +- rmdir_path(ap, entry->fs, ap->dev); + error(ap->logopt, MODPREFIX + "%s: failed to mount using %s", entry->type, entry->mount); +- } +-do_free: +- free_argv(argc, (const char **) argv); +- free(str); +- +- if (rv) ++ free_argv(argc, (const char **) argv); ++ free(str); + goto out; +- ++ } ++done: + rv = do_link_mount(ap, name, entry, 0); +- if (!rv) +- goto out; +- +- if (umount_amd_ext_mount(ap, entry->fs)) { +- if (!ext_mount_inuse(entry->fs)) +- rmdir_path(ap, entry->fs, ap->dev); +- debug(ap->logopt, MODPREFIX +- "%s: failed to umount external mount at %s", +- entry->type, entry->fs); ++ if (rv) { ++ if (umount_amd_ext_mount(ap, entry->fs)) { ++ debug(ap->logopt, MODPREFIX ++ "%s: failed to cleanup external mount at %s", ++ entry->type, entry->fs); ++ } + } + out: + return rv; diff --git a/autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch b/autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch new file mode 100644 index 0000000..d81c4a5 --- /dev/null +++ b/autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch @@ -0,0 +1,242 @@ +autofs-5.1.9 - refactor amd function umount_amd_ext_mount() + +From: Ian Kent + +The amd mounts function umount_amd_ext_mount() needs some improvement. + +Make sure the function returns true for success and false for failure +and add a parameter to control if the expternal mount reference should +be decremented on successful umount. + +If the reference count of the external mount is greater than 1 there's +some other mount using (symlink pointing to) it so don't try to umount +it just return success. + +Also check for the case where the mount is already mounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 4 +- + include/mounts.h | 2 - + lib/mounts.c | 80 ++++++++++++++++++++++++++++++---------------------- + modules/parse_amd.c | 10 +++--- + 5 files changed, 56 insertions(+), 41 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -10,6 +10,7 @@ + - fix amd external mount mount handling. + - don't free ext mount if mounted. + - refactor amd function do_program_mount(). ++- refactor umount_amd_ext_mount(). + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/daemon/automount.c ++++ autofs-5.1.9/daemon/automount.c +@@ -633,7 +633,7 @@ static int umount_subtree_mounts(struct + /* Check for an external mount and umount if possible */ + mnt = mnts_find_amdmount(path); + if (mnt) { +- umount_amd_ext_mount(ap, mnt->ext_mp); ++ umount_amd_ext_mount(ap, mnt->ext_mp, 1); + mnts_remove_amdmount(path); + mnts_put_mount(mnt); + } +@@ -699,7 +699,7 @@ int umount_multi(struct autofs_point *ap + /* Check for an external mount and attempt umount if needed */ + mnt = mnts_find_amdmount(path); + if (mnt) { +- umount_amd_ext_mount(ap, mnt->ext_mp); ++ umount_amd_ext_mount(ap, mnt->ext_mp, 1); + mnts_remove_amdmount(path); + mnts_put_mount(mnt); + } +--- autofs-5.1.9.orig/include/mounts.h ++++ autofs-5.1.9/include/mounts.h +@@ -199,7 +199,7 @@ int try_remount(struct autofs_point *, s + void set_indirect_mount_tree_catatonic(struct autofs_point *); + void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); + int umount_ent(struct autofs_point *, const char *); +-int umount_amd_ext_mount(struct autofs_point *, const char *); ++int umount_amd_ext_mount(struct autofs_point *, const char *, int remove); + int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); + + #endif +--- autofs-5.1.9.orig/lib/mounts.c ++++ autofs-5.1.9/lib/mounts.c +@@ -3078,37 +3078,62 @@ int umount_ent(struct autofs_point *ap, + return mounted; + } + +-int umount_amd_ext_mount(struct autofs_point *ap, const char *path) ++int umount_amd_ext_mount(struct autofs_point *ap, const char *path, int remove) + { + struct ext_mount *em; + char *umount = NULL; +- char *mp; ++ char *mp = NULL; + int rv = 1; ++ int ret; + + pthread_mutex_lock(&ext_mount_hash_mutex); +- + em = ext_mount_lookup(path); + if (!em) { + pthread_mutex_unlock(&ext_mount_hash_mutex); ++ rv = 0; + goto out; + } + mp = strdup(em->mp); + if (!mp) { + pthread_mutex_unlock(&ext_mount_hash_mutex); ++ rv = 0; + goto out; + } + if (em->umount) { + umount = strdup(em->umount); + if (!umount) { + pthread_mutex_unlock(&ext_mount_hash_mutex); +- free(mp); ++ rv = 0; + goto out; + } + } +- ++ /* Don't try and umount if there's more than one ++ * user of the external mount. ++ */ ++ if (em->ref > 1) { ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ if (!remove) ++ error(ap->logopt, ++ "reference count mismatch, called with remove false"); ++ else ++ ext_mount_remove(mp); ++ goto out; ++ } ++ /* This shouldn't happen ... */ ++ if (!is_mounted(mp, MNTS_REAL)) { ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ error(ap->logopt, "failed to umount program mount at %s", mp); ++ if (remove) ++ ext_mount_remove(mp); ++ goto out; ++ } + pthread_mutex_unlock(&ext_mount_hash_mutex); + +- if (umount) { ++ if (!umount) { ++ ret = umount_ent(ap, mp); ++ if (ret) ++ rv = 0; ++ } else { + char *prog; + char **argv; + int argc = -1; +@@ -3117,41 +3142,30 @@ int umount_amd_ext_mount(struct autofs_p + argv = NULL; + + argc = construct_argv(umount, &prog, &argv); +- if (argc == -1) +- goto done; +- +- if (!ext_mount_remove(mp)) { +- rv =0; +- goto out_free; +- } +- +- rv = spawnv(ap->logopt, prog, (const char * const *) argv); +- if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv))) ++ if (argc == -1) { + error(ap->logopt, +- "failed to umount program mount at %s", mp); +- else { ++ "failed to allocate args for umount of %s", mp); + rv = 0; +- debug(ap->logopt, "umounted program mount at %s", mp); +- rmdir_path(ap, mp, ap->dev); ++ goto out; + } +-out_free: ++ ret = spawnv(ap->logopt, prog, (const char * const *) argv); ++ rv = WIFEXITED(ret) && !WEXITSTATUS(ret); + free_argv(argc, (const char **) argv); +- +- goto done; + } + +- if (ext_mount_remove(mp)) { +- rv = umount_ent(ap, mp); +- if (rv) +- error(ap->logopt, +- "failed to umount external mount %s", mp); +- else +- debug(ap->logopt, "umounted external mount %s", mp); ++ if (is_mounted(mp, MNTS_REAL)) ++ error(ap->logopt, ++ "failed to umount external mount %s", mp); ++ else { ++ info(ap->logopt, "umounted external mount %s", mp); ++ rmdir_path(ap, mp, ap->dev); + } +-done: ++ if (remove) ++ ext_mount_remove(mp); ++out: + if (umount) + free(umount); +- free(mp); +-out: ++ if (mp) ++ free(mp); + return rv; + } +--- autofs-5.1.9.orig/modules/parse_amd.c ++++ autofs-5.1.9/modules/parse_amd.c +@@ -1140,7 +1140,7 @@ symlink: + + if (entry->sublink) { + /* failed to complete sublink mount */ +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 1); + } + out: + return ret; +@@ -1191,7 +1191,7 @@ static int do_generic_mount(struct autof + /* If we have an external mount add it to the list */ + if (!ext_mount_add(entry->fs, entry->umount)) { + if (umount) +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 0); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", + entry->fs); +@@ -1242,7 +1242,7 @@ static int do_nfs_mount(struct autofs_po + /* We might be using an external mount */ + if (!ext_mount_add(entry->fs, entry->umount)) { + if (umount) +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 0); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", entry->fs); + ret = 1; +@@ -1477,7 +1477,7 @@ static int do_program_mount(struct autof + free(str); + goto done; + } +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 0); + } + error(ap->logopt, MODPREFIX + "%s: failed to mount using %s", entry->type, entry->mount); +@@ -1488,7 +1488,7 @@ static int do_program_mount(struct autof + done: + rv = do_link_mount(ap, name, entry, 0); + if (rv) { +- if (umount_amd_ext_mount(ap, entry->fs)) { ++ if (!umount_amd_ext_mount(ap, entry->fs, 1)) { + debug(ap->logopt, MODPREFIX + "%s: failed to cleanup external mount at %s", + entry->type, entry->fs); diff --git a/autofs-5.1.9-refactor-amd-mount-options-handling.patch b/autofs-5.1.9-refactor-amd-mount-options-handling.patch new file mode 100644 index 0000000..b3c9c63 --- /dev/null +++ b/autofs-5.1.9-refactor-amd-mount-options-handling.patch @@ -0,0 +1,121 @@ +commit b48aab92dd3f47411a8ccd67ff4370cbfee64581 +Author: Ian Kent +Date: Thu Jul 11 13:35:04 2024 +0800 + + autofs-5.1.9 - refactor amd mount options handling + + Refactor handling of entry options opts, addopts, remopts. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + modules/amd_parse.y | 66 ++++++++++++++++++++++++++++++---------------------- + 2 files changed, 40 insertions(+), 27 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -15,6 +15,7 @@ + - fix amd cache options not copied. + - seperate amd mount and entry flags. + - make iocl ops ->timeout() handle per-dentry expire. ++- refactor amd mount options handling. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/amd_parse.y ++++ autofs-5.1.9/modules/amd_parse.y +@@ -60,6 +60,7 @@ static int match_map_option_fs_type(char + static int match_map_option_map_type(char *map_option, char *type); + static int match_map_option_cache_option(char *type); + static int match_mnt_option_options(char *mnt_option, char *options); ++static int match_mnt_option(char *option, char *options); + + static struct amd_entry entry; + static struct list_head *entries; +@@ -437,40 +438,18 @@ option_assignment: MAP_OPTION OPTION_ASS + + options: OPTION + { +- if (!strcmp($1, "fullybrowsable") || +- !strcmp($1, "nounmount")) { +- sprintf(msg_buf, "option %s is not currently " +- "implemented, ignored", $1); +- amd_info(msg_buf); +- } else if (!strncmp($1, "ping=", 5) || +- !strncmp($1, "retry=", 6) || +- !strcmp($1, "public") || +- !strcmp($1, "softlookup") || +- !strcmp($1, "xlatecookie")) { +- sprintf(msg_buf, "option %s is not used by " +- "autofs, ignored", $1); +- amd_info(msg_buf); +- } else if (!strncmp($1, "utimeout=", 9)) { +- if (entry.flags & AMD_MOUNT_TYPE_AUTO) { +- char *opt = $1; +- prepend_opt(opts, ++opt); +- } else { +- sprintf(msg_buf, "umount timeout can't be " +- "used for other than type " +- "\"auto\" with autofs, " +- "ignored"); +- amd_info(msg_buf); +- } +- } else ++ if (match_mnt_option($1, opts)) + prepend_opt(opts, $1); + } + | OPTION COMMA options + { +- prepend_opt(opts, $1); ++ if (match_mnt_option($1, opts)) ++ prepend_opt(opts, $1); + } + | OPTION COMMA + { +- prepend_opt(opts, $1); ++ if (match_mnt_option($1, opts)) ++ prepend_opt(opts, $1); + } + ; + +@@ -664,6 +643,39 @@ static int match_mnt_option_options(char + return 1; + } + ++static int match_mnt_option(char *option, char *options) ++{ ++ int ret = 0; ++ ++ if (!strcmp(option, "fullybrowsable") || ++ !strcmp(option, "nounmount")) { ++ sprintf(msg_buf, "option %s is not currently " ++ "implemented, ignored", option); ++ amd_info(msg_buf); ++ } else if (!strncmp(option, "ping=", 5) || ++ !strncmp(option, "retry=", 6) || ++ !strcmp(option, "public") || ++ !strcmp(option, "softlookup") || ++ !strcmp(option, "xlatecookie")) { ++ sprintf(msg_buf, "option %s is not used by " ++ "autofs, ignored", option); ++ amd_info(msg_buf); ++ } else if (!strncmp(option, "utimeout=", 9)) { ++ if (entry.flags & AMD_MOUNT_TYPE_AUTO) ++ prepend_opt(options, ++option); ++ else { ++ sprintf(msg_buf, "umount timeout can't be " ++ "used for other than type " ++ "\"auto\" with autofs, " ++ "ignored"); ++ amd_info(msg_buf); ++ } ++ } else ++ ret = 1; ++ ++ return ret; ++} ++ + static void prepend_opt(char *dest, char *opt) + { + char new[MAX_OPTS_LEN]; diff --git a/autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch b/autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch new file mode 100644 index 0000000..87d18f4 --- /dev/null +++ b/autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch @@ -0,0 +1,133 @@ +commit a2002247e16ef60efe049e04119a9c92694cbfe1 +Author: Ian Kent +Date: Tue Jul 9 14:59:40 2024 +0800 + + autofs-5.1.9 - seperate amd mount and entry flags + + We are running out of flags for amd mounts, seperate the mount flags + from the defaults and entry flags and add a new amd entry flags field. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + include/parse_amd.h | 11 ++++++----- + modules/amd_parse.y | 7 ++++--- + modules/parse_amd.c | 10 +++++----- + 4 files changed, 16 insertions(+), 13 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -13,6 +13,7 @@ + - refactor umount_amd_ext_mount(). + - add flags argument to amd do_program_mount(). + - fix amd cache options not copied. ++- seperate amd mount and entry flags. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/include/parse_amd.h ++++ autofs-5.1.9/include/parse_amd.h +@@ -33,12 +33,12 @@ + #define AMD_MOUNT_TYPE_PROGRAM 0x00004000 + #define AMD_MOUNT_TYPE_MASK 0x0000ffff + +-#define AMD_ENTRY_CUT 0x00010000 +-#define AMD_ENTRY_MASK 0x00ff0000 ++#define AMD_DEFAULTS_MERGE 0x0001 ++#define AMD_DEFAULTS_RESET 0x0002 ++#define AMD_DEFAULTS_MASK 0x00ff + +-#define AMD_DEFAULTS_MERGE 0x01000000 +-#define AMD_DEFAULTS_RESET 0x02000000 +-#define AMD_DEFAULTS_MASK 0xff000000 ++#define AMD_ENTRY_CUT 0x0100 ++#define AMD_ENTRY_MASK 0xff00 + + #define AMD_CACHE_OPTION_NONE 0x0000 + #define AMD_CACHE_OPTION_INC 0x0001 +@@ -50,6 +50,7 @@ struct amd_entry { + char *path; + unsigned long flags; + unsigned int cache_opts; ++ unsigned int entry_flags; + char *type; + char *map_type; + char *pref; +--- autofs-5.1.9.orig/modules/amd_parse.y ++++ autofs-5.1.9/modules/amd_parse.y +@@ -155,7 +155,7 @@ location_selection_list: location + } + | location_selection_list SPACE CUT SPACE location + { +- entry.flags |= AMD_ENTRY_CUT; ++ entry.entry_flags |= AMD_ENTRY_CUT; + if (!add_location()) { + amd_msg("failed to allocate new location"); + YYABORT; +@@ -168,11 +168,11 @@ location: location_entry + } + | HYPHEN location_entry + { +- entry.flags |= AMD_DEFAULTS_MERGE; ++ entry.entry_flags |= AMD_DEFAULTS_MERGE; + } + | HYPHEN + { +- entry.flags |= AMD_DEFAULTS_RESET; ++ entry.entry_flags |= AMD_DEFAULTS_RESET; + } + ; + +@@ -889,6 +889,7 @@ static int add_location(void) + } + new->flags = entry.flags; + new->cache_opts = entry.cache_opts; ++ new->entry_flags = entry.entry_flags; + new->type = entry.type; + new->map_type = entry.map_type; + new->pref = entry.pref; +--- autofs-5.1.9.orig/modules/parse_amd.c ++++ autofs-5.1.9/modules/parse_amd.c +@@ -2029,13 +2029,13 @@ static struct amd_entry *select_default_ + + p = p->next; + +- if (this->flags & AMD_DEFAULTS_MERGE) { ++ if (this->entry_flags & AMD_DEFAULTS_MERGE) { + if (entry_default) + free_amd_entry(entry_default); + list_del_init(&this->list); + entry_default = this; + continue; +- } else if (this->flags & AMD_DEFAULTS_RESET) { ++ } else if (this->entry_flags & AMD_DEFAULTS_RESET) { + struct amd_entry *new; + new = dup_defaults_entry(defaults_entry); + if (new) { +@@ -2266,14 +2266,14 @@ int parse_mount(struct autofs_point *ap, + struct amd_entry *this = list_entry(p, struct amd_entry, list); + p = p->next; + +- if (this->flags & AMD_DEFAULTS_MERGE) { ++ if (this->entry_flags & AMD_DEFAULTS_MERGE) { + free_amd_entry(cur_defaults); + list_del_init(&this->list); + cur_defaults = this; + update_with_defaults(defaults_entry, cur_defaults, sv); + debug(ap->logopt, "merged /defaults entry with defaults"); + continue; +- } else if (this->flags & AMD_DEFAULTS_RESET) { ++ } else if (this->entry_flags & AMD_DEFAULTS_RESET) { + struct amd_entry *nd, *new; + struct substvar *nsv = NULL; + +@@ -2298,7 +2298,7 @@ int parse_mount(struct autofs_point *ap, + debug(ap->logopt, "expand defaults entry"); + sv = expand_entry(ap, cur_defaults, flags, sv); + +- if (this->flags & AMD_ENTRY_CUT && at_least_one) { ++ if (this->entry_flags & AMD_ENTRY_CUT && at_least_one) { + info(ap->logopt, MODPREFIX + "at least one entry tried before cut selector, " + "not continuing"); diff --git a/autofs.spec b/autofs.spec index 1005cac..6e9143d 100644 --- a/autofs.spec +++ b/autofs.spec @@ -12,7 +12,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.9 -Release: 9%{?dist} +Release: 10%{?dist} Epoch: 1 License: GPL-2.0-or-later Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.gz @@ -20,6 +20,20 @@ Patch0: autofs-5.1.9-update-configure.patch Patch1: autofs-5.1.9-fix-ldap_parse_page_control-check.patch Patch2: autofs-5.1.9-fix-crash-in-make_options_string.patch Patch3: autofs-5.1.9-Fix-incompatible-function-pointer-types-in-cyrus-sasl-module.patch +Patch4: autofs-5.1.9-fix-always-recreate-credential-cache.patch +Patch5: autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch +Patch6: autofs-5.1.9-fix-deadlock-in-remount.patch +Patch7: autofs-5.1.9-fix-amd-external-mount-error-handling.patch +Patch8: autofs-5.1.9-fix-amd-external-mount-mount-handling.patch +Patch9: autofs-5.1.9-dont-free-ext-mount-if-mounted.patch +Patch10: autofs-5.1.9-refactor-amd-function-do_program_mount.patch +Patch11: autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch +Patch12: autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch +Patch13: autofs-5.1.9-fix-amd-cache-options-not-copied.patch +Patch14: autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch +Patch15: autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch +Patch16: autofs-5.1.9-refactor-amd-mount-options-handling.patch +Patch17: autofs-5.1.9-add-some-unimplemented-amd-map-options.patch %if %{with_systemd} BuildRequires: systemd-units @@ -192,6 +206,23 @@ fi %dir /etc/auto.master.d %changelog +* Mon Jul 22 2024 Ian Kent - 1:5.1.9-10 +- Upstream bug fix sync. + - fix always recreate credential cache. + - fix get parent multi-mount check in try_remount(). + - fix deadlock in remount. + - fix amd external mount error handling. + - fix amd external mount mount handling. + - don't free ext mount if mounted. + - refactor amd function do_program_mount(). + - refactor umount_amd_ext_mount(). + - add flags argument to amd do_program_mount(). + - fix amd cache options not copied. + - seperate amd mount and entry flags. + - make iocl ops ->timeout() handle per-dentry expire. + - refactor amd mount options handling. + - add some unimplemented amd map options. + * Mon Jul 22 2024 Ian Kent - 1:5.1.9-9 - RHEL-32639 - [10.0-beta] starting autofs leads to core dump - bring the existing patches up to date with upstream.