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.
219 lines
6.1 KiB
219 lines
6.1 KiB
autofs-5.1.2 - make set_direct_mount_catatonic() more general |
|
|
|
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. |
|
|
|
Start by making set_direct_mount_catatonic() able to handle the |
|
different types of autofs mounts and move it to the mounts function |
|
library. |
|
--- |
|
CHANGELOG | 1 |
|
daemon/direct.c | 69 +++---------------------------------------------------- |
|
include/mounts.h | 1 |
|
lib/mounts.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
4 files changed, 71 insertions(+), 64 deletions(-) |
|
|
|
--- autofs-5.0.7.orig/CHANGELOG |
|
+++ autofs-5.0.7/CHANGELOG |
|
@@ -213,6 +213,7 @@ |
|
- set sane default master read wait timeout. |
|
- don't return until after master map retry read. |
|
- make lookup_nss_read_master() return nss status. |
|
+- make set_direct_mount_catatonic() more general. |
|
|
|
25/07/2012 autofs-5.0.7 |
|
======================= |
|
--- autofs-5.0.7.orig/daemon/direct.c |
|
+++ autofs-5.0.7/daemon/direct.c |
|
@@ -82,65 +82,6 @@ static void mnts_cleanup(void *arg) |
|
return; |
|
} |
|
|
|
-/* When exiting direct mount triggers must be set catatonic, regardless |
|
- * of whether they are busy on not, to avoid a hang on access once the |
|
- * daemon has gone away. |
|
- */ |
|
-static int set_direct_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd) |
|
-{ |
|
- struct ioctl_ops *ops = get_ioctl_ops(); |
|
- unsigned int opened = 0; |
|
- char buf[MAX_ERR_BUF]; |
|
- int fd = -1; |
|
- int error; |
|
- |
|
- /* In case the miscellaneous device isn't being used try |
|
- * and use an existing ioctl control fd. In this case if |
|
- * we don't already have an ioctl fd the mount can't be |
|
- * set catatonic if it's covered. |
|
- */ |
|
- if (ioctlfd >= 0) |
|
- fd = ioctlfd; |
|
- else if (me->ioctlfd >= 0) |
|
- fd = me->ioctlfd; |
|
- else { |
|
- error = ops->open(ap->logopt, &fd, me->dev, me->key); |
|
- if (error == -1) { |
|
- int err = errno; |
|
- char *estr; |
|
- |
|
- estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|
- error(ap->logopt, |
|
- "failed to open ioctlfd for %s, error: %s", |
|
- me->key, estr); |
|
- return err; |
|
- } |
|
- opened = 1; |
|
- } |
|
- |
|
- if (fd >= 0) { |
|
- error = ops->catatonic(ap->logopt, fd); |
|
- if (error == -1) { |
|
- int err = errno; |
|
- char *estr; |
|
- |
|
- estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|
- error(ap->logopt, |
|
- "failed to set %s catatonic, error: %s", |
|
- me->key, estr); |
|
- if (opened) |
|
- ops->close(ap->logopt, fd); |
|
- return err; |
|
- } |
|
- if (opened) |
|
- ops->close(ap->logopt, fd); |
|
- } |
|
- |
|
- debug(ap->logopt, "set %s catatonic", me->key); |
|
- |
|
- return 0; |
|
-} |
|
- |
|
int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) |
|
{ |
|
struct ioctl_ops *ops = get_ioctl_ops(); |
|
@@ -190,19 +131,19 @@ int do_umount_autofs_direct(struct autof |
|
"ask umount returned busy for %s", |
|
me->key); |
|
if (ap->state != ST_READMAP) |
|
- set_direct_mount_catatonic(ap, me, ioctlfd); |
|
+ set_mount_catatonic(ap, me, ioctlfd); |
|
if (opened) |
|
ops->close(ap->logopt, ioctlfd); |
|
return 1; |
|
} else { |
|
me->ioctlfd = -1; |
|
- set_direct_mount_catatonic(ap, me, ioctlfd); |
|
+ set_mount_catatonic(ap, me, ioctlfd); |
|
ops->close(ap->logopt, ioctlfd); |
|
goto force_umount; |
|
} |
|
} |
|
me->ioctlfd = -1; |
|
- set_direct_mount_catatonic(ap, me, ioctlfd); |
|
+ set_mount_catatonic(ap, me, ioctlfd); |
|
ops->close(ap->logopt, ioctlfd); |
|
} else { |
|
error(ap->logopt, |
|
@@ -297,12 +238,12 @@ int umount_autofs_direct(struct autofs_p |
|
if (!error) |
|
goto done; |
|
|
|
- error = set_direct_mount_catatonic(ap, me, me->ioctlfd); |
|
+ error = set_mount_catatonic(ap, me, me->ioctlfd); |
|
if (!error) |
|
goto done; |
|
|
|
/* We really need to set this, last ditch attempt */ |
|
- set_direct_mount_catatonic(ap, me, -1); |
|
+ set_mount_catatonic(ap, me, -1); |
|
done: |
|
me = cache_enumerate(mc, me); |
|
} |
|
--- autofs-5.0.7.orig/include/mounts.h |
|
+++ autofs-5.0.7/include/mounts.h |
|
@@ -114,6 +114,7 @@ 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); |
|
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 |
|
@@ -1894,6 +1894,70 @@ int try_remount(struct autofs_point *ap, |
|
return 0; |
|
} |
|
|
|
+/* |
|
+ * When exiting mounts need be set catatonic, regardless of whether they |
|
+ * 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) |
|
+{ |
|
+ struct ioctl_ops *ops = get_ioctl_ops(); |
|
+ unsigned int opened = 0; |
|
+ char buf[MAX_ERR_BUF]; |
|
+ char *path; |
|
+ int fd = -1; |
|
+ int error; |
|
+ dev_t dev; |
|
+ |
|
+ path = ap->path; |
|
+ dev = ap->dev; |
|
+ if (me && (ap->type == LKP_DIRECT || *me->key == '/')) { |
|
+ path = me->key; |
|
+ dev = me->dev; |
|
+ } |
|
+ |
|
+ if (ioctlfd >= 0) |
|
+ fd = ioctlfd; |
|
+ else if (me && me->ioctlfd >= 0) |
|
+ fd = me->ioctlfd; |
|
+ else { |
|
+ error = ops->open(ap->logopt, &fd, dev, path); |
|
+ if (error == -1) { |
|
+ int err = errno; |
|
+ char *estr; |
|
+ |
|
+ estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|
+ error(ap->logopt, |
|
+ "failed to open ioctlfd for %s, error: %s", |
|
+ path, estr); |
|
+ return err; |
|
+ } |
|
+ opened = 1; |
|
+ } |
|
+ |
|
+ if (fd >= 0) { |
|
+ error = ops->catatonic(ap->logopt, fd); |
|
+ if (error == -1) { |
|
+ int err = errno; |
|
+ char *estr; |
|
+ |
|
+ estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|
+ error(ap->logopt, |
|
+ "failed to set %s catatonic, error: %s", |
|
+ path, estr); |
|
+ if (opened) |
|
+ ops->close(ap->logopt, fd); |
|
+ return err; |
|
+ } |
|
+ if (opened) |
|
+ ops->close(ap->logopt, fd); |
|
+ } |
|
+ |
|
+ debug(ap->logopt, "set %s catatonic", path); |
|
+ |
|
+ return 0; |
|
+} |
|
+ |
|
int umount_ent(struct autofs_point *ap, const char *path) |
|
{ |
|
int rv;
|
|
|