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