diff --git a/autofs-5.0.3-check-for-kernel-automount.patch b/autofs-5.0.3-check-for-kernel-automount.patch new file mode 100644 index 0000000..df6e2c3 --- /dev/null +++ b/autofs-5.0.3-check-for-kernel-automount.patch @@ -0,0 +1,200 @@ +autofs 5.0.3 - check for exported mounts automatically mounted by kernel + +From: Ian Kent + +If a server exports file systems that are automatically mounted by +the kernel client autofs will mistakenly over mount them when it +constructs and mounts its multi-mount triggers. + +This patch makes autofs check for this case and ignores them if the +kernel mounts them while it mounts multi-mount triggers. + +We don't want to fight with NFS over mounting these because it +confuses autofs and they magically go away when the owner mount is +umounted. This isn't ideal because autofs will mount these mounts +while constructing its multi-mount triggers but it is unavoidable +at the moment. +--- + + CHANGELOG | 1 + + daemon/direct.c | 26 ++++++++++++++++++-------- + include/automount.h | 4 ++++ + lib/parse_subs.c | 26 ++++++++++++++++++-------- + 4 files changed, 41 insertions(+), 16 deletions(-) + + +--- autofs-5.0.3.orig/CHANGELOG ++++ autofs-5.0.3/CHANGELOG +@@ -12,6 +12,7 @@ + - init SASL callbacks on every ldap lookup library load. + - fix incorrect match of map type name when included in map name. + - fix incorrect pthreads condition handling for mount requests. ++- add check for exports automatically mounted by NFS kernel client. + + 14/01/2008 autofs-5.0.3 + ----------------------- +--- autofs-5.0.3.orig/daemon/direct.c ++++ autofs-5.0.3/daemon/direct.c +@@ -664,12 +664,12 @@ int mount_autofs_offset(struct autofs_po + if (ap->state != ST_READMAP) + warn(ap->logopt, + "trigger %s already mounted", me->key); +- return 0; ++ return MOUNT_OFFSET_OK; + } + + if (me->ioctlfd != -1) { + error(ap->logopt, "active offset mount %s", me->key); +- return -1; ++ return MOUNT_OFFSET_FAIL; + } + + status = pthread_once(&key_mnt_params_once, key_mnt_params_init); +@@ -683,7 +683,7 @@ int mount_autofs_offset(struct autofs_po + crit(ap->logopt, + "mnt_params value create failed for offset mount %s", + me->key); +- return 0; ++ return MOUNT_OFFSET_OK; + } + mp->options = NULL; + +@@ -697,12 +697,22 @@ int mount_autofs_offset(struct autofs_po + if (!mp->options) { + mp->options = make_options_string(ap->path, ap->kpipefd, "offset"); + if (!mp->options) +- return 0; ++ return MOUNT_OFFSET_OK; + } + + /* In case the directory doesn't exist, try to mkdir it */ + if (mkdir_path(me->key, 0555) < 0) { + if (errno == EEXIST) { ++ /* ++ * If the mount point directory is a real mount ++ * and it isn't the root offset then it must be ++ * a mount that has been automatically mounted by ++ * the kernel NFS client. ++ */ ++ if (me->multi != me && ++ is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) ++ return MOUNT_OFFSET_IGNORE; ++ + /* + * If we recieve an error, and it's EEXIST + * we know the directory was not created. +@@ -721,13 +731,13 @@ int mount_autofs_offset(struct autofs_po + debug(ap->logopt, + "can't create mount directory: %s, %s", + me->key, estr); +- return -1; ++ return MOUNT_OFFSET_FAIL; + } else { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + crit(ap->logopt, + "failed to create mount directory: %s, %s", + me->key, estr); +- return -1; ++ return MOUNT_OFFSET_FAIL; + } + } else { + /* No errors so the directory was successfully created */ +@@ -787,7 +797,7 @@ int mount_autofs_offset(struct autofs_po + + debug(ap->logopt, "mounted trigger %s", me->key); + +- return 0; ++ return MOUNT_OFFSET_OK; + + out_close: + close(ioctlfd); +@@ -797,7 +807,7 @@ out_err: + if (stat(me->key, &st) == 0 && me->dir_created) + rmdir_path(ap, me->key, st.st_dev); + +- return -1; ++ return MOUNT_OFFSET_FAIL; + } + + static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt) +--- autofs-5.0.3.orig/include/automount.h ++++ autofs-5.0.3/include/automount.h +@@ -468,6 +468,10 @@ struct autofs_point { + + /* Standard functions used by daemon or modules */ + ++#define MOUNT_OFFSET_OK 0 ++#define MOUNT_OFFSET_FAIL -1 ++#define MOUNT_OFFSET_IGNORE -2 ++ + void *handle_mounts(void *arg); + int umount_multi(struct autofs_point *ap, const char *path, int incl); + int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token); +--- autofs-5.0.3.orig/lib/parse_subs.c ++++ autofs-5.0.3/lib/parse_subs.c +@@ -390,7 +390,7 @@ int mount_multi_triggers(struct autofs_p + struct list_head *pos = NULL; + unsigned int fs_path_len; + unsigned int mounted; +- int start; ++ int ret, start; + + fs_path_len = strlen(root) + strlen(base); + if (fs_path_len > PATH_MAX) +@@ -411,15 +411,25 @@ int mount_multi_triggers(struct autofs_p + } + + oe = cache_lookup_offset(base, offset, start, &me->multi_list); +- if (!oe) ++ if (!oe || !oe->mapent) + goto cont; + + debug(ap->logopt, "mount offset %s", oe->key); + +- if (mount_autofs_offset(ap, oe) < 0) +- warn(ap->logopt, "failed to mount offset"); +- else ++ ret = mount_autofs_offset(ap, oe); ++ if (ret >= MOUNT_OFFSET_OK) + mounted++; ++ else { ++ if (ret != MOUNT_OFFSET_IGNORE) ++ warn(ap->logopt, "failed to mount offset"); ++ else { ++ debug(ap->logopt, ++ "ignoring \"nohide\" trigger %s", ++ oe->key); ++ free(oe->mapent); ++ oe->mapent = NULL; ++ } ++ } + cont: + offset = cache_get_offset(base, + offset, start, &me->multi_list, &pos); +@@ -457,7 +467,7 @@ int umount_multi_triggers(struct autofs_ + + oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); + /* root offset is a special case */ +- if (!oe || (strlen(oe->key) - start) == 1) ++ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) + continue; + + /* +@@ -481,7 +491,7 @@ int umount_multi_triggers(struct autofs_ + while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { + oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); + /* root offset is a special case */ +- if (!oe || (strlen(oe->key) - start) == 1) ++ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) + continue; + + debug(ap->logopt, "umount offset %s", oe->key); +@@ -505,7 +515,7 @@ int umount_multi_triggers(struct autofs_ + if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { + info(ap->logopt, "unmounting dir = %s", root); + if (umount_ent(ap, root)) { +- if (!mount_multi_triggers(ap, root, me, "/")) ++ if (mount_multi_triggers(ap, root, me, "/") < 0) + warn(ap->logopt, + "failed to remount offset triggers"); + return left++; diff --git a/autofs-5.0.3-nfs4-nohide-check.patch b/autofs-5.0.3-nfs4-nohide-check.patch deleted file mode 100644 index 7ed8f41..0000000 --- a/autofs-5.0.3-nfs4-nohide-check.patch +++ /dev/null @@ -1,196 +0,0 @@ -autofs 5.0.3 - check for nohide mounts - -From: Ian Kent - -If a server exports file systems with the nohide option -autofs will mistakenly over mount them when it constructs -and mounts its multi-mount triggers. - -This patch makes autofs check for nohide mounts and ignores -them if the kernel mounts them while it mounts multi-mount -triggers. - -We don't want to fight with NFS over mounting these because -it confuses autofs and they magically go away when the owner -mount is umounted. This isn't ideal because autofs will mount -the nohide exports while constructing its multi-mount triggers -but it is unavoidable at the moment. ---- - - daemon/direct.c | 26 ++++++++++++++++++-------- - include/automount.h | 4 ++++ - lib/parse_subs.c | 26 ++++++++++++++++++-------- - 3 files changed, 40 insertions(+), 16 deletions(-) - - -diff --git a/daemon/direct.c b/daemon/direct.c -index a9dda87..c67f38a 100644 ---- a/daemon/direct.c -+++ b/daemon/direct.c -@@ -664,12 +664,12 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - if (ap->state != ST_READMAP) - warn(ap->logopt, - "trigger %s already mounted", me->key); -- return 0; -+ return MOUNT_OFFSET_OK; - } - - if (me->ioctlfd != -1) { - error(ap->logopt, "active offset mount %s", me->key); -- return -1; -+ return MOUNT_OFFSET_FAIL; - } - - status = pthread_once(&key_mnt_params_once, key_mnt_params_init); -@@ -683,7 +683,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - crit(ap->logopt, - "mnt_params value create failed for offset mount %s", - me->key); -- return 0; -+ return MOUNT_OFFSET_OK; - } - mp->options = NULL; - -@@ -697,12 +697,22 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - if (!mp->options) { - mp->options = make_options_string(ap->path, ap->kpipefd, "offset"); - if (!mp->options) -- return 0; -+ return MOUNT_OFFSET_OK; - } - - /* In case the directory doesn't exist, try to mkdir it */ - if (mkdir_path(me->key, 0555) < 0) { - if (errno == EEXIST) { -+ /* -+ * If the mount point directory is a real mount -+ * and it isn't the root offset then it must be -+ * a "nohide" mount, automounted by the kernel NFS -+ * client. -+ */ -+ if (me->multi != me && -+ is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) -+ return MOUNT_OFFSET_IGNORE; -+ - /* - * If we recieve an error, and it's EEXIST - * we know the directory was not created. -@@ -721,13 +731,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - debug(ap->logopt, - "can't create mount directory: %s, %s", - me->key, estr); -- return -1; -+ return MOUNT_OFFSET_FAIL; - } else { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - crit(ap->logopt, - "failed to create mount directory: %s, %s", - me->key, estr); -- return -1; -+ return MOUNT_OFFSET_FAIL; - } - } else { - /* No errors so the directory was successfully created */ -@@ -787,7 +797,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) - - debug(ap->logopt, "mounted trigger %s", me->key); - -- return 0; -+ return MOUNT_OFFSET_OK; - - out_close: - close(ioctlfd); -@@ -797,7 +807,7 @@ out_err: - if (stat(me->key, &st) == 0 && me->dir_created) - rmdir_path(ap, me->key, st.st_dev); - -- return -1; -+ return MOUNT_OFFSET_FAIL; - } - - static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt) -diff --git a/include/automount.h b/include/automount.h -index cd8ce7b..d59be77 100644 ---- a/include/automount.h -+++ b/include/automount.h -@@ -468,6 +468,10 @@ struct autofs_point { - - /* Standard functions used by daemon or modules */ - -+#define MOUNT_OFFSET_OK 0 -+#define MOUNT_OFFSET_FAIL -1 -+#define MOUNT_OFFSET_IGNORE -2 -+ - void *handle_mounts(void *arg); - int umount_multi(struct autofs_point *ap, const char *path, int incl); - int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token); -diff --git a/lib/parse_subs.c b/lib/parse_subs.c -index 5422fef..27cb0fc 100644 ---- a/lib/parse_subs.c -+++ b/lib/parse_subs.c -@@ -390,7 +390,7 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, - struct list_head *pos = NULL; - unsigned int fs_path_len; - unsigned int mounted; -- int start; -+ int ret, start; - - fs_path_len = strlen(root) + strlen(base); - if (fs_path_len > PATH_MAX) -@@ -411,15 +411,25 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, - } - - oe = cache_lookup_offset(base, offset, start, &me->multi_list); -- if (!oe) -+ if (!oe || !oe->mapent) - goto cont; - - debug(ap->logopt, "mount offset %s", oe->key); - -- if (mount_autofs_offset(ap, oe) < 0) -- warn(ap->logopt, "failed to mount offset"); -- else -+ ret = mount_autofs_offset(ap, oe); -+ if (ret >= MOUNT_OFFSET_OK) - mounted++; -+ else { -+ if (ret != MOUNT_OFFSET_IGNORE) -+ warn(ap->logopt, "failed to mount offset"); -+ else { -+ debug(ap->logopt, -+ "ignoring \"nohide\" trigger %s", -+ oe->key); -+ free(oe->mapent); -+ oe->mapent = NULL; -+ } -+ } - cont: - offset = cache_get_offset(base, - offset, start, &me->multi_list, &pos); -@@ -457,7 +467,7 @@ int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me - - oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); - /* root offset is a special case */ -- if (!oe || (strlen(oe->key) - start) == 1) -+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) - continue; - - /* -@@ -481,7 +491,7 @@ int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me - while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { - oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); - /* root offset is a special case */ -- if (!oe || (strlen(oe->key) - start) == 1) -+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) - continue; - - debug(ap->logopt, "umount offset %s", oe->key); -@@ -505,7 +515,7 @@ int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me - if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { - info(ap->logopt, "unmounting dir = %s", root); - if (umount_ent(ap, root)) { -- if (!mount_multi_triggers(ap, root, me, "/")) -+ if (mount_multi_triggers(ap, root, me, "/") < 0) - warn(ap->logopt, - "failed to remount offset triggers"); - return left++; diff --git a/autofs.spec b/autofs.spec index 21ebf05..2429b4d 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.3 -Release: 16 +Release: 17 Epoch: 1 License: GPL Group: System Environment/Daemons @@ -131,8 +131,9 @@ fi %{_libdir}/autofs/ %changelog -* Mon May 12 2008 Ian Kent - 5.0.3-16 +* Wed May 14 2008 Ian Kent - 5.0.3-16 - update patches, documentation and comments only change. +- rename patch and add to CVS. * Mon May 12 2008 Ian Kent - 5.0.3-14 - check for nohide mounts (bz 442618).