You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.1 KiB
208 lines
6.1 KiB
7 years ago
|
autofs-5.1.2 - set autofs mounts catatonic at exit
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
Setting direct mounts catatonic at exit doesn't go far enough.
|
||
|
|
||
|
To avoid possible hang on access of automount managed paths when
|
||
|
the daemon has exited all mounted autofs file systems must be set
|
||
|
catatonic when the daemon exits.
|
||
|
|
||
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
||
|
---
|
||
|
CHANGELOG | 1
|
||
|
daemon/automount.c | 1
|
||
|
daemon/direct.c | 17 ++++---------
|
||
|
daemon/indirect.c | 3 --
|
||
|
include/mounts.h | 3 +-
|
||
|
lib/mounts.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||
|
6 files changed, 78 insertions(+), 16 deletions(-)
|
||
|
|
||
|
--- autofs-5.0.7.orig/CHANGELOG
|
||
|
+++ autofs-5.0.7/CHANGELOG
|
||
|
@@ -214,6 +214,7 @@
|
||
|
- don't return until after master map retry read.
|
||
|
- make lookup_nss_read_master() return nss status.
|
||
|
- make set_direct_mount_catatonic() more general.
|
||
|
+- set autofs mounts catatonic at exit.
|
||
|
|
||
|
25/07/2012 autofs-5.0.7
|
||
|
=======================
|
||
|
--- autofs-5.0.7.orig/daemon/automount.c
|
||
|
+++ autofs-5.0.7/daemon/automount.c
|
||
|
@@ -1732,6 +1732,7 @@ int handle_mounts_exit(struct autofs_poi
|
||
|
*/
|
||
|
ret = umount_autofs(ap, NULL, 1);
|
||
|
if (!ret) {
|
||
|
+ set_indirect_mount_tree_catatonic(ap);
|
||
|
handle_mounts_cleanup(ap);
|
||
|
return 1;
|
||
|
}
|
||
|
--- autofs-5.0.7.orig/daemon/direct.c
|
||
|
+++ autofs-5.0.7/daemon/direct.c
|
||
|
@@ -130,20 +130,16 @@ int do_umount_autofs_direct(struct autof
|
||
|
error(ap->logopt,
|
||
|
"ask umount returned busy for %s",
|
||
|
me->key);
|
||
|
- if (ap->state != ST_READMAP)
|
||
|
- set_mount_catatonic(ap, me, ioctlfd);
|
||
|
if (opened)
|
||
|
ops->close(ap->logopt, ioctlfd);
|
||
|
return 1;
|
||
|
} else {
|
||
|
me->ioctlfd = -1;
|
||
|
- set_mount_catatonic(ap, me, ioctlfd);
|
||
|
ops->close(ap->logopt, ioctlfd);
|
||
|
goto force_umount;
|
||
|
}
|
||
|
}
|
||
|
me->ioctlfd = -1;
|
||
|
- set_mount_catatonic(ap, me, ioctlfd);
|
||
|
ops->close(ap->logopt, ioctlfd);
|
||
|
} else {
|
||
|
error(ap->logopt,
|
||
|
@@ -173,8 +169,11 @@ int do_umount_autofs_direct(struct autof
|
||
|
warn(ap->logopt, "mount point %s is in use", me->key);
|
||
|
if (ap->state == ST_SHUTDOWN_FORCE)
|
||
|
goto force_umount;
|
||
|
- else
|
||
|
+ else {
|
||
|
+ if (ap->state != ST_READMAP)
|
||
|
+ set_direct_mount_tree_catatonic(ap, me);
|
||
|
return 0;
|
||
|
+ }
|
||
|
break;
|
||
|
case ENOTDIR:
|
||
|
error(ap->logopt, "mount point is not a directory");
|
||
|
@@ -238,12 +237,8 @@ int umount_autofs_direct(struct autofs_p
|
||
|
if (!error)
|
||
|
goto done;
|
||
|
|
||
|
- error = set_mount_catatonic(ap, me, me->ioctlfd);
|
||
|
- if (!error)
|
||
|
- goto done;
|
||
|
-
|
||
|
- /* We really need to set this, last ditch attempt */
|
||
|
- set_mount_catatonic(ap, me, -1);
|
||
|
+ if (ap->state != ST_READMAP)
|
||
|
+ set_direct_mount_tree_catatonic(ap, me);
|
||
|
done:
|
||
|
me = cache_enumerate(mc, me);
|
||
|
}
|
||
|
--- autofs-5.0.7.orig/daemon/indirect.c
|
||
|
+++ autofs-5.0.7/daemon/indirect.c
|
||
|
@@ -286,9 +286,6 @@ int umount_autofs_indirect(struct autofs
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
- if (ap->shutdown)
|
||
|
- ops->catatonic(ap->logopt, ap->ioctlfd);
|
||
|
-
|
||
|
ops->close(ap->logopt, ap->ioctlfd);
|
||
|
ap->ioctlfd = -1;
|
||
|
sched_yield();
|
||
|
--- autofs-5.0.7.orig/include/mounts.h
|
||
|
+++ autofs-5.0.7/include/mounts.h
|
||
|
@@ -114,7 +114,8 @@ void set_tsd_user_vars(unsigned int, uid
|
||
|
const char *mount_type_str(unsigned int);
|
||
|
void notify_mount_result(struct autofs_point *, const char *, time_t, const char *);
|
||
|
int try_remount(struct autofs_point *, struct mapent *, unsigned int);
|
||
|
-int set_mount_catatonic(struct autofs_point *, struct mapent *, int);
|
||
|
+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 mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
|
||
|
int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
|
||
|
--- autofs-5.0.7.orig/lib/mounts.c
|
||
|
+++ autofs-5.0.7/lib/mounts.c
|
||
|
@@ -1899,7 +1899,7 @@ int try_remount(struct autofs_point *ap,
|
||
|
* are busy on not, to avoid a hang on access once the daemon has gone
|
||
|
* away.
|
||
|
*/
|
||
|
-int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd)
|
||
|
+static int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd)
|
||
|
{
|
||
|
struct ioctl_ops *ops = get_ioctl_ops();
|
||
|
unsigned int opened = 0;
|
||
|
@@ -1926,6 +1926,9 @@ int set_mount_catatonic(struct autofs_po
|
||
|
int err = errno;
|
||
|
char *estr;
|
||
|
|
||
|
+ if (errno == ENOENT)
|
||
|
+ return 0;
|
||
|
+
|
||
|
estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||
|
error(ap->logopt,
|
||
|
"failed to open ioctlfd for %s, error: %s",
|
||
|
@@ -1958,6 +1961,70 @@ int set_mount_catatonic(struct autofs_po
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
|
||
|
+{
|
||
|
+ if (!list_empty(&me->multi_list)) {
|
||
|
+ struct list_head *head = &me->multi_list;
|
||
|
+ struct list_head *p;
|
||
|
+
|
||
|
+ list_for_each(p, head) {
|
||
|
+ struct mapent *this;
|
||
|
+
|
||
|
+ this = list_entry(p, struct mapent, multi_list);
|
||
|
+ set_mount_catatonic(ap, this, this->ioctlfd);
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
|
||
|
+{
|
||
|
+ struct master_mapent *entry = ap->entry;
|
||
|
+ struct map_source *map;
|
||
|
+ struct mapent_cache *mc;
|
||
|
+ struct mapent *me;
|
||
|
+
|
||
|
+ if (!is_mounted(_PROC_MOUNTS, ap->path, MNTS_AUTOFS))
|
||
|
+ return;
|
||
|
+
|
||
|
+ map = entry->maps;
|
||
|
+ while (map) {
|
||
|
+ mc = map->mc;
|
||
|
+ cache_readlock(mc);
|
||
|
+ me = cache_enumerate(mc, NULL);
|
||
|
+ while (me) {
|
||
|
+ /* Skip negative map entries and wildcard entries */
|
||
|
+ if (!me->mapent)
|
||
|
+ goto next;
|
||
|
+
|
||
|
+ if (!strcmp(me->key, "*"))
|
||
|
+ goto next;
|
||
|
+
|
||
|
+ /* Only need to set offset mounts catatonic */
|
||
|
+ if (me->multi && me->multi == me)
|
||
|
+ set_multi_mount_tree_catatonic(ap, me);
|
||
|
+next:
|
||
|
+ me = cache_enumerate(mc, me);
|
||
|
+ }
|
||
|
+ cache_unlock(mc);
|
||
|
+ map = map->next;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* By the time this function is called ap->ioctlfd will have
|
||
|
+ * been closed so don't try and use it.
|
||
|
+ */
|
||
|
+ set_mount_catatonic(ap, NULL, -1);
|
||
|
+
|
||
|
+ return;
|
||
|
+}
|
||
|
+
|
||
|
+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)
|
||
|
+ set_multi_mount_tree_catatonic(ap, me);
|
||
|
+ set_mount_catatonic(ap, me, me->ioctlfd);
|
||
|
+}
|
||
|
+
|
||
|
int umount_ent(struct autofs_point *ap, const char *path)
|
||
|
{
|
||
|
int rv;
|