201 lines
6.3 KiB
Diff
201 lines
6.3 KiB
Diff
autofs 5.0.3 - check for exported mounts automatically mounted by kernel
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
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++;
|