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.
207 lines
6.1 KiB
207 lines
6.1 KiB
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;
|
|
|