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.
220 lines
6.1 KiB
220 lines
6.1 KiB
7 years ago
|
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;
|