|
Ian Kent |
3685ec |
autofs-5.0.3 - try not to block on expire
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
From: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
When a server is not available umount and any stat statfs and related
|
|
Ian Kent |
3685ec |
function calls may block for a significant amount of time. This effects
|
|
Ian Kent |
3685ec |
expire timeouts a lot due to their synchronous nature. This patch limits
|
|
Ian Kent |
3685ec |
the time we wait on spawned umounts and elininates calls to functions
|
|
Ian Kent |
3685ec |
that would block. This allows us to retry the umount on the next expire
|
|
Ian Kent |
3685ec |
event and continue the expire of remaining mounts.
|
|
Ian Kent |
3685ec |
---
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
CHANGELOG | 2 ++
|
|
Ian Kent |
3685ec |
daemon/automount.c | 34 ++++++++++++++++++------------
|
|
Ian Kent |
3685ec |
daemon/direct.c | 29 +++++---------------------
|
|
Ian Kent |
3685ec |
daemon/indirect.c | 26 +++++++++--------------
|
|
Ian Kent |
3685ec |
daemon/spawn.c | 59 ++++++++++++++++++++++++++++++++++++++++++----------
|
|
Ian Kent |
3685ec |
include/master.h | 1 +
|
|
Ian Kent |
3685ec |
lib/master.c | 23 ++++++++++++++++++++
|
|
Ian Kent |
3685ec |
lib/mounts.c | 48 ++----------------------------------------
|
|
Ian Kent |
3685ec |
8 files changed, 112 insertions(+), 110 deletions(-)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
diff --git a/CHANGELOG b/CHANGELOG
|
|
Ian Kent |
3685ec |
index ff04985..ff44cc7 100644
|
|
Ian Kent |
3685ec |
--- a/CHANGELOG
|
|
Ian Kent |
3685ec |
+++ b/CHANGELOG
|
|
Ian Kent |
3685ec |
@@ -27,6 +27,8 @@
|
|
Ian Kent |
3685ec |
- don't use proc file system when checking if the daemon is running.
|
|
Ian Kent |
3685ec |
- make handle_mounts startup condition distinct.
|
|
Ian Kent |
3685ec |
- fix submount shutdown recovery handling.
|
|
Ian Kent |
3685ec |
+- avoid stat of possibly dead mount points and limit time to wait for
|
|
Ian Kent |
3685ec |
+ umount during expire.
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
14/01/2008 autofs-5.0.3
|
|
Ian Kent |
3685ec |
-----------------------
|
|
Ian Kent |
3685ec |
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
Ian Kent |
3685ec |
index 68bf1d3..5bd5f6d 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/automount.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/automount.c
|
|
Ian Kent |
3685ec |
@@ -247,9 +247,17 @@ static int walk_tree(const char *base, int (*fn) (unsigned logopt,
|
|
Ian Kent |
3685ec |
int, void *), int incl, unsigned logopt, void *arg)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
char buf[PATH_MAX + 1];
|
|
Ian Kent |
3685ec |
- struct stat st;
|
|
Ian Kent |
3685ec |
+ struct stat st, *pst = &st;
|
|
Ian Kent |
3685ec |
+ int ret;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (!is_mounted(_PATH_MOUNTED, base, MNTS_REAL))
|
|
Ian Kent |
3685ec |
+ ret = lstat(base, pst);
|
|
Ian Kent |
3685ec |
+ else {
|
|
Ian Kent |
3685ec |
+ pst = NULL;
|
|
Ian Kent |
3685ec |
+ ret = 0;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- if (lstat(base, &st) != -1 && (fn) (logopt, base, &st, 0, arg)) {
|
|
Ian Kent |
3685ec |
+ if (ret != -1 && (fn) (logopt, base, pst, 0, arg)) {
|
|
Ian Kent |
3685ec |
if (S_ISDIR(st.st_mode)) {
|
|
Ian Kent |
3685ec |
struct dirent **de;
|
|
Ian Kent |
3685ec |
int n;
|
|
Ian Kent |
3685ec |
@@ -283,7 +291,7 @@ static int walk_tree(const char *base, int (*fn) (unsigned logopt,
|
|
Ian Kent |
3685ec |
free(de);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
if (incl)
|
|
Ian Kent |
3685ec |
- (fn) (logopt, base, &st, 1, arg);
|
|
Ian Kent |
3685ec |
+ (fn) (logopt, base, pst, 1, arg);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -294,6 +302,9 @@ static int rm_unwanted_fn(unsigned logopt, const char *file, const struct stat *
|
|
Ian Kent |
3685ec |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
struct stat newst;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ if (!st)
|
|
Ian Kent |
3685ec |
+ return 0;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
if (when == 0) {
|
|
Ian Kent |
3685ec |
if (st->st_dev != dev)
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
@@ -344,8 +355,8 @@ static int counter_fn(unsigned logopt, const char *file, const struct stat *st,
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct counter_args *counter = (struct counter_args *) arg;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- if (S_ISLNK(st->st_mode) || (S_ISDIR(st->st_mode)
|
|
Ian Kent |
3685ec |
- && st->st_dev != counter->dev)) {
|
|
Ian Kent |
3685ec |
+ if (!st || (S_ISLNK(st->st_mode) || (S_ISDIR(st->st_mode)
|
|
Ian Kent |
3685ec |
+ && st->st_dev != counter->dev))) {
|
|
Ian Kent |
3685ec |
counter->count++;
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -512,9 +523,8 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|
Ian Kent |
3685ec |
int umount_multi(struct autofs_point *ap, const char *path, int incl)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct mapent_cache *nc;
|
|
Ian Kent |
3685ec |
- struct statfs fs;
|
|
Ian Kent |
3685ec |
int is_autofs_fs;
|
|
Ian Kent |
3685ec |
- int ret, left;
|
|
Ian Kent |
3685ec |
+ int left;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
debug(ap->logopt, "path %s incl %d", path, incl);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -526,13 +536,9 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl)
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
cache_unlock(nc);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- ret = statfs(path, &fs);
|
|
Ian Kent |
3685ec |
- if (ret == -1) {
|
|
Ian Kent |
3685ec |
- error(ap->logopt, "could not stat fs of %s", path);
|
|
Ian Kent |
3685ec |
- return 1;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- is_autofs_fs = fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC ? 1 : 0;
|
|
Ian Kent |
3685ec |
+ is_autofs_fs = 0;
|
|
Ian Kent |
3685ec |
+ if (master_find_submount(ap, path))
|
|
Ian Kent |
3685ec |
+ is_autofs_fs = 1;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
left = 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
diff --git a/daemon/direct.c b/daemon/direct.c
|
|
Ian Kent |
3685ec |
index 334a4b6..7fb78a3 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/direct.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/direct.c
|
|
Ian Kent |
3685ec |
@@ -152,7 +152,7 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
retries = UMOUNT_RETRIES;
|
|
Ian Kent |
3685ec |
while ((rv = umount(me->key)) == -1 && retries--) {
|
|
Ian Kent |
3685ec |
- struct timespec tm = {0, 100000000};
|
|
Ian Kent |
3685ec |
+ struct timespec tm = {0, 200000000};
|
|
Ian Kent |
3685ec |
if (errno != EBUSY)
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
nanosleep(&tm, NULL);
|
|
Ian Kent |
3685ec |
@@ -604,7 +604,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
retries = UMOUNT_RETRIES;
|
|
Ian Kent |
3685ec |
while ((rv = umount(me->key)) == -1 && retries--) {
|
|
Ian Kent |
3685ec |
- struct timespec tm = {0, 100000000};
|
|
Ian Kent |
3685ec |
+ struct timespec tm = {0, 200000000};
|
|
Ian Kent |
3685ec |
if (errno != EBUSY)
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
nanosleep(&tm, NULL);
|
|
Ian Kent |
3685ec |
@@ -705,7 +705,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
Ian Kent |
3685ec |
* the kernel NFS client.
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
if (me->multi != me &&
|
|
Ian Kent |
3685ec |
- is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL))
|
|
Ian Kent |
3685ec |
+ is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL))
|
|
Ian Kent |
3685ec |
return MOUNT_OFFSET_IGNORE;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
@@ -807,17 +807,7 @@ out_err:
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
- char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
- int ret, retries;
|
|
Ian Kent |
3685ec |
- struct stat st;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (fstat(ioctlfd, &st) == -1) {
|
|
Ian Kent |
3685ec |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
3685ec |
- debug(logopt, "fstat failed: %s", estr);
|
|
Ian Kent |
3685ec |
- return 0;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
|
|
Ian Kent |
3685ec |
+ int ret, retries = EXPIRE_RETRIES;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (retries--) {
|
|
Ian Kent |
3685ec |
struct timespec tm = {0, 100000000};
|
|
Ian Kent |
3685ec |
@@ -911,7 +901,6 @@ void *expire_proc_direct(void *arg)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (!strcmp(next->fs_type, "autofs")) {
|
|
Ian Kent |
3685ec |
struct stat st;
|
|
Ian Kent |
3685ec |
- struct statfs fs;
|
|
Ian Kent |
3685ec |
int ioctlfd;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
cache_unlock(me->mc);
|
|
Ian Kent |
3685ec |
@@ -932,14 +921,8 @@ void *expire_proc_direct(void *arg)
|
|
Ian Kent |
3685ec |
continue;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- if (statfs(next->path, &fs) == -1) {
|
|
Ian Kent |
3685ec |
- pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
3685ec |
- warn(ap->logopt,
|
|
Ian Kent |
3685ec |
- "fstatfs failed for %s", next->path);
|
|
Ian Kent |
3685ec |
- continue;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) {
|
|
Ian Kent |
3685ec |
+ /* It's got a mount, deal with in the outer loop */
|
|
Ian Kent |
3685ec |
+ if (tree_is_mounted(mnts, me->key, MNTS_REAL)) {
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
3685ec |
continue;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|
Ian Kent |
3685ec |
index 17bed3e..e832cd4 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/indirect.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/indirect.c
|
|
Ian Kent |
3685ec |
@@ -285,7 +285,7 @@ int umount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
retries = UMOUNT_RETRIES;
|
|
Ian Kent |
3685ec |
while ((rv = umount(ap->path)) == -1 && retries--) {
|
|
Ian Kent |
3685ec |
- struct timespec tm = {0, 100000000};
|
|
Ian Kent |
3685ec |
+ struct timespec tm = {0, 200000000};
|
|
Ian Kent |
3685ec |
if (errno != EBUSY)
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
nanosleep(&tm, NULL);
|
|
Ian Kent |
3685ec |
@@ -368,17 +368,7 @@ force_umount:
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *path, unsigned int when)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
- char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
- int ret, retries;
|
|
Ian Kent |
3685ec |
- struct stat st;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (fstat(ioctlfd, &st) == -1) {
|
|
Ian Kent |
3685ec |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
3685ec |
- debug(ap->logopt, "fstat failed: %s", estr);
|
|
Ian Kent |
3685ec |
- return 0;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- retries = (count_mounts(ap->logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
|
|
Ian Kent |
3685ec |
+ int ret, retries = EXPIRE_RETRIES;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (retries--) {
|
|
Ian Kent |
3685ec |
struct timespec tm = {0, 100000000};
|
|
Ian Kent |
3685ec |
@@ -512,7 +502,6 @@ void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
3685ec |
left++;
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
* If there are no more real mounts left we could still
|
|
Ian Kent |
3685ec |
@@ -520,12 +509,17 @@ void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
3685ec |
* umount them here.
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
if (mnts) {
|
|
Ian Kent |
3685ec |
+ int retries;
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
Ian Kent |
3685ec |
- ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
|
|
Ian Kent |
3685ec |
- if (!ret)
|
|
Ian Kent |
3685ec |
- left++;
|
|
Ian Kent |
3685ec |
+ retries = (count_mounts(ap->logopt, ap->path, ap->dev) + 1);
|
|
Ian Kent |
3685ec |
+ while (retries--) {
|
|
Ian Kent |
3685ec |
+ ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
|
|
Ian Kent |
3685ec |
+ if (!ret)
|
|
Ian Kent |
3685ec |
+ left++;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
+ pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
count = offsets = submnts = 0;
|
|
Ian Kent |
3685ec |
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
|
|
Ian Kent |
3685ec |
diff --git a/daemon/spawn.c b/daemon/spawn.c
|
|
Ian Kent |
3685ec |
index 78d69c6..e3c355e 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/spawn.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/spawn.c
|
|
Ian Kent |
3685ec |
@@ -89,13 +89,43 @@ void reset_signals(void)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
#define ERRBUFSIZ 2047 /* Max length of error string excl \0 */
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-static int do_spawn(unsigned logopt, unsigned int options, const char *prog, const char *const *argv)
|
|
Ian Kent |
3685ec |
+static int timed_read(int pipe, char *buf, size_t len, int time)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ struct timeval timeout = { 0, 0 };
|
|
Ian Kent |
3685ec |
+ struct timeval *tout = NULL;
|
|
Ian Kent |
3685ec |
+ fd_set wset, rset;
|
|
Ian Kent |
3685ec |
+ int ret;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ FD_ZERO(&rset);
|
|
Ian Kent |
3685ec |
+ FD_SET(pipe, &rset);
|
|
Ian Kent |
3685ec |
+ wset = rset;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (time != -1) {
|
|
Ian Kent |
3685ec |
+ timeout.tv_sec = time;
|
|
Ian Kent |
3685ec |
+ tout = &timeout;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ ret = select(pipe + 1, &rset, &wset, NULL, tout);
|
|
Ian Kent |
3685ec |
+ if (ret <= 0) {
|
|
Ian Kent |
3685ec |
+ if (ret == 0)
|
|
Ian Kent |
3685ec |
+ ret = -ETIMEDOUT;
|
|
Ian Kent |
3685ec |
+ return ret;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ while ((ret = read(pipe, buf, len)) == -1 && errno == EINTR);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ return ret;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+static int do_spawn(unsigned logopt, unsigned int wait,
|
|
Ian Kent |
3685ec |
+ unsigned int options, const char *prog,
|
|
Ian Kent |
3685ec |
+ const char *const *argv)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
pid_t f;
|
|
Ian Kent |
3685ec |
int ret, status, pipefd[2];
|
|
Ian Kent |
3685ec |
char errbuf[ERRBUFSIZ + 1], *p, *sp;
|
|
Ian Kent |
3685ec |
int errp, errn;
|
|
Ian Kent |
3685ec |
- int cancel_state;
|
|
Ian Kent |
3685ec |
+ int flags, cancel_state;
|
|
Ian Kent |
3685ec |
unsigned int use_lock = options & SPAWN_OPT_LOCK;
|
|
Ian Kent |
3685ec |
unsigned int use_access = options & SPAWN_OPT_ACCESS;
|
|
Ian Kent |
3685ec |
sigset_t allsigs, tmpsig, oldsig;
|
|
Ian Kent |
3685ec |
@@ -183,12 +213,15 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
|
|
Ian Kent |
3685ec |
return -1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ if ((flags = fcntl(pipefd[0], F_GETFD, 0)) != -1) {
|
|
Ian Kent |
3685ec |
+ flags |= FD_CLOEXEC;
|
|
Ian Kent |
3685ec |
+ fcntl(pipefd[0], F_SETFD, flags);
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
errp = 0;
|
|
Ian Kent |
3685ec |
do {
|
|
Ian Kent |
3685ec |
- while ((errn =
|
|
Ian Kent |
3685ec |
- read(pipefd[0], errbuf + errp, ERRBUFSIZ - errp)) == -1
|
|
Ian Kent |
3685ec |
- && errno == EINTR);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
+ errn = timed_read(pipefd[0],
|
|
Ian Kent |
3685ec |
+ errbuf + errp, ERRBUFSIZ - errp, wait);
|
|
Ian Kent |
3685ec |
if (errn > 0) {
|
|
Ian Kent |
3685ec |
errp += errn;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -213,6 +246,9 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
} while (errn > 0);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ if (errn == -ETIMEDOUT)
|
|
Ian Kent |
3685ec |
+ kill(f, SIGTERM);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
close(pipefd[0]);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (errp > 0) {
|
|
Ian Kent |
3685ec |
@@ -238,7 +274,7 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
int spawnv(unsigned logopt, const char *prog, const char *const *argv)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
- return do_spawn(logopt, SPAWN_OPT_NONE, prog, argv);
|
|
Ian Kent |
3685ec |
+ return do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, argv);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
int spawnl(unsigned logopt, const char *prog, ...)
|
|
Ian Kent |
3685ec |
@@ -259,7 +295,7 @@ int spawnl(unsigned logopt, const char *prog, ...)
|
|
Ian Kent |
3685ec |
while ((*p++ = va_arg(arg, char *)));
|
|
Ian Kent |
3685ec |
va_end(arg);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- return do_spawn(logopt, SPAWN_OPT_NONE, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
+ return do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
int spawn_mount(unsigned logopt, ...)
|
|
Ian Kent |
3685ec |
@@ -307,7 +343,7 @@ int spawn_mount(unsigned logopt, ...)
|
|
Ian Kent |
3685ec |
va_end(arg);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (retries--) {
|
|
Ian Kent |
3685ec |
- ret = do_spawn(logopt, options, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
+ ret = do_spawn(logopt, -1, options, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
if (ret & MTAB_NOTUPDATED) {
|
|
Ian Kent |
3685ec |
struct timespec tm = {3, 0};
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -406,7 +442,7 @@ int spawn_bind_mount(unsigned logopt, ...)
|
|
Ian Kent |
3685ec |
va_end(arg);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (retries--) {
|
|
Ian Kent |
3685ec |
- ret = do_spawn(logopt, options, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
+ ret = do_spawn(logopt, -1, options, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
if (ret & MTAB_NOTUPDATED) {
|
|
Ian Kent |
3685ec |
struct timespec tm = {3, 0};
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -466,6 +502,7 @@ int spawn_umount(unsigned logopt, ...)
|
|
Ian Kent |
3685ec |
unsigned int options;
|
|
Ian Kent |
3685ec |
unsigned int retries = MTAB_LOCK_RETRIES;
|
|
Ian Kent |
3685ec |
int ret, printed = 0;
|
|
Ian Kent |
3685ec |
+ unsigned int wait = 12;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
#ifdef ENABLE_MOUNT_LOCKING
|
|
Ian Kent |
3685ec |
options = SPAWN_OPT_LOCK;
|
|
Ian Kent |
3685ec |
@@ -488,7 +525,7 @@ int spawn_umount(unsigned logopt, ...)
|
|
Ian Kent |
3685ec |
va_end(arg);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (retries--) {
|
|
Ian Kent |
3685ec |
- ret = do_spawn(logopt, options, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
+ ret = do_spawn(logopt, wait, options, prog, (const char **) argv);
|
|
Ian Kent |
3685ec |
if (ret & MTAB_NOTUPDATED) {
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
* If the mount succeeded but the mtab was not
|
|
Ian Kent |
3685ec |
diff --git a/include/master.h b/include/master.h
|
|
Ian Kent |
3685ec |
index 86ae045..a397a75 100644
|
|
Ian Kent |
3685ec |
--- a/include/master.h
|
|
Ian Kent |
3685ec |
+++ b/include/master.h
|
|
Ian Kent |
3685ec |
@@ -91,6 +91,7 @@ void master_source_lock_cleanup(void *);
|
|
Ian Kent |
3685ec |
void master_source_current_wait(struct master_mapent *);
|
|
Ian Kent |
3685ec |
void master_source_current_signal(struct master_mapent *);
|
|
Ian Kent |
3685ec |
struct master_mapent *master_find_mapent(struct master *, const char *);
|
|
Ian Kent |
3685ec |
+struct autofs_point *master_find_submount(struct autofs_point *, const char *);
|
|
Ian Kent |
3685ec |
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
|
|
Ian Kent |
3685ec |
void master_add_mapent(struct master *, struct master_mapent *);
|
|
Ian Kent |
3685ec |
void master_remove_mapent(struct master_mapent *);
|
|
Ian Kent |
3685ec |
diff --git a/lib/master.c b/lib/master.c
|
|
Ian Kent |
3685ec |
index 522b919..71ba04a 100644
|
|
Ian Kent |
3685ec |
--- a/lib/master.c
|
|
Ian Kent |
3685ec |
+++ b/lib/master.c
|
|
Ian Kent |
3685ec |
@@ -602,6 +602,29 @@ struct master_mapent *master_find_mapent(struct master *master, const char *path
|
|
Ian Kent |
3685ec |
return NULL;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+struct autofs_point *master_find_submount(struct autofs_point *ap, const char *path)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ struct list_head *head, *p;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ mounts_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ head = &ap->submounts;
|
|
Ian Kent |
3685ec |
+ list_for_each(p, head) {
|
|
Ian Kent |
3685ec |
+ struct autofs_point *submount;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ submount = list_entry(p, struct autofs_point, mounts);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (!strcmp(submount->path, path)) {
|
|
Ian Kent |
3685ec |
+ mounts_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ return submount;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ mounts_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ return NULL;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct master_mapent *entry;
|
|
Ian Kent |
3685ec |
diff --git a/lib/mounts.c b/lib/mounts.c
|
|
Ian Kent |
3685ec |
index a4bf86c..d77a6b0 100644
|
|
Ian Kent |
3685ec |
--- a/lib/mounts.c
|
|
Ian Kent |
3685ec |
+++ b/lib/mounts.c
|
|
Ian Kent |
3685ec |
@@ -1073,55 +1073,11 @@ free_tsv:
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
int umount_ent(struct autofs_point *ap, const char *path)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
- struct stat st;
|
|
Ian Kent |
3685ec |
- struct statfs fs;
|
|
Ian Kent |
3685ec |
- int sav_errno;
|
|
Ian Kent |
3685ec |
- int status, is_smbfs = 0;
|
|
Ian Kent |
3685ec |
- int ret, rv = 1;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- ret = statfs(path, &fs);
|
|
Ian Kent |
3685ec |
- if (ret == -1) {
|
|
Ian Kent |
3685ec |
- warn(ap->logopt, "could not stat fs of %s", path);
|
|
Ian Kent |
3685ec |
- is_smbfs = 0;
|
|
Ian Kent |
3685ec |
- } else {
|
|
Ian Kent |
3685ec |
- int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER;
|
|
Ian Kent |
3685ec |
- int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC;
|
|
Ian Kent |
3685ec |
- is_smbfs = (cifsfs | smbfs) ? 1 : 0;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- status = lstat(path, &st);
|
|
Ian Kent |
3685ec |
- sav_errno = errno;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (status < 0)
|
|
Ian Kent |
3685ec |
- warn(ap->logopt, "lstat of %s failed with %d", path, status);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- /*
|
|
Ian Kent |
3685ec |
- * lstat failed and we're an smbfs fs returning an error that is not
|
|
Ian Kent |
3685ec |
- * EIO or EBADSLT or the lstat failed so it's a bad path. Return
|
|
Ian Kent |
3685ec |
- * a fail.
|
|
Ian Kent |
3685ec |
- *
|
|
Ian Kent |
3685ec |
- * EIO appears to correspond to an smb mount that has gone away
|
|
Ian Kent |
3685ec |
- * and EBADSLT relates to CD changer not responding.
|
|
Ian Kent |
3685ec |
- */
|
|
Ian Kent |
3685ec |
- if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) {
|
|
Ian Kent |
3685ec |
- rv = spawn_umount(ap->logopt, path, NULL);
|
|
Ian Kent |
3685ec |
- } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) {
|
|
Ian Kent |
3685ec |
- rv = spawn_umount(ap->logopt, path, NULL);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
+ int rv;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ rv = spawn_umount(ap->logopt, path, NULL);
|
|
Ian Kent |
3685ec |
/* We are doing a forced shutcwdown down so unlink busy mounts */
|
|
Ian Kent |
3685ec |
if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
|
|
Ian Kent |
3685ec |
- ret = stat(path, &st);
|
|
Ian Kent |
3685ec |
- if (ret == -1 && errno == ENOENT) {
|
|
Ian Kent |
3685ec |
- warn(ap->logopt, "mount point does not exist");
|
|
Ian Kent |
3685ec |
- return 0;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (ret == 0 && !S_ISDIR(st.st_mode)) {
|
|
Ian Kent |
3685ec |
- warn(ap->logopt, "mount point is not a directory");
|
|
Ian Kent |
3685ec |
- return 0;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
if (ap->state == ST_SHUTDOWN_FORCE) {
|
|
Ian Kent |
3685ec |
info(ap->logopt, "forcing umount of %s", path);
|
|
Ian Kent |
3685ec |
rv = spawn_umount(ap->logopt, "-l", path, NULL);
|