- add command line option to override is running check. - don't use proc fs for is running check. - fix fail on included browse map not found. - fix incorrect multi source messages. - clear stale flag on map read. - fix proximity other rpc ping timeout. - refactor mount request vars code. - make handle_mounts startup condition distinct. - fix submount shutdown handling. - try not to block on expire. - add configuration paramter UMOUNT_WAIT. - fix multi mount race. - fix nfs4 colon escape handling. - check replicated list after probe. - add replicated server selection debug logging. - update replicated server selection documentation. - use /dev/urandom instead of /dev/random. - check for mtab pointing to /proc/mounts. - fix interface config buffer size. - fix percent hack heap corruption.
310 lines
8.3 KiB
Diff
310 lines
8.3 KiB
Diff
autofs-5.0.3 - make handle_mounts startup condition distinct
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
When starting a number of mounts we can get contention for the startup
|
|
condition used to synchronize the handle_mounts thread completion. This
|
|
patch makes the condition used distinct for each thread creation.
|
|
---
|
|
|
|
CHANGELOG | 1 +
|
|
daemon/automount.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----
|
|
include/automount.h | 4 +++
|
|
lib/master.c | 29 +++++++++++-----------
|
|
modules/mount_autofs.c | 35 +++++++++++++--------------
|
|
5 files changed, 93 insertions(+), 38 deletions(-)
|
|
|
|
|
|
diff --git a/CHANGELOG b/CHANGELOG
|
|
index 3921552..9da7be3 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -25,6 +25,7 @@
|
|
- fix couple of memory leaks.
|
|
- add command line option to override check for daemon already running.
|
|
- don't use proc file system when checking if the daemon is running.
|
|
+- make handle_mounts startup condition distinct.
|
|
|
|
14/01/2008 autofs-5.0.3
|
|
-----------------------
|
|
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
index dbf267c..086affb 100644
|
|
--- a/daemon/automount.c
|
|
+++ b/daemon/automount.c
|
|
@@ -1461,6 +1461,55 @@ static void mutex_operation_wait(pthread_mutex_t *mutex)
|
|
return;
|
|
}
|
|
|
|
+int handle_mounts_startup_cond_init(struct startup_cond *suc)
|
|
+{
|
|
+ int status;
|
|
+
|
|
+ status = pthread_mutex_init(&suc->mutex, NULL);
|
|
+ if (status)
|
|
+ return status;
|
|
+
|
|
+ status = pthread_cond_init(&suc->cond, NULL);
|
|
+ if (status) {
|
|
+ status = pthread_mutex_destroy(&suc->mutex);
|
|
+ if (status)
|
|
+ fatal(status);
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ status = pthread_mutex_lock(&suc->mutex);
|
|
+ if (status) {
|
|
+ status = pthread_mutex_destroy(&suc->mutex);
|
|
+ if (status)
|
|
+ fatal(status);
|
|
+ status = pthread_cond_destroy(&suc->cond);
|
|
+ if (status)
|
|
+ fatal(status);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void handle_mounts_startup_cond_destroy(void *arg)
|
|
+{
|
|
+ struct startup_cond *suc = (struct startup_cond *) arg;
|
|
+ int status;
|
|
+
|
|
+ status = pthread_mutex_unlock(&suc->mutex);
|
|
+ if (status)
|
|
+ fatal(status);
|
|
+
|
|
+ status = pthread_mutex_destroy(&suc->mutex);
|
|
+ if (status)
|
|
+ fatal(status);
|
|
+
|
|
+ status = pthread_cond_destroy(&suc->cond);
|
|
+ if (status)
|
|
+ fatal(status);
|
|
+
|
|
+ return;
|
|
+}
|
|
+
|
|
static void handle_mounts_cleanup(void *arg)
|
|
{
|
|
struct autofs_point *ap;
|
|
@@ -1512,17 +1561,20 @@ static void handle_mounts_cleanup(void *arg)
|
|
|
|
void *handle_mounts(void *arg)
|
|
{
|
|
+ struct startup_cond *suc;
|
|
struct autofs_point *ap;
|
|
int cancel_state, status = 0;
|
|
|
|
- ap = (struct autofs_point *) arg;
|
|
+ suc = (struct startup_cond *) arg;
|
|
+
|
|
+ ap = suc->ap;
|
|
|
|
- pthread_cleanup_push(return_start_status, &suc);
|
|
+ pthread_cleanup_push(return_start_status, suc);
|
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
|
|
|
|
state_mutex_lock(ap);
|
|
|
|
- status = pthread_mutex_lock(&suc.mutex);
|
|
+ status = pthread_mutex_lock(&suc->mutex);
|
|
if (status) {
|
|
logerr("failed to lock startup condition mutex!");
|
|
fatal(status);
|
|
@@ -1530,7 +1582,7 @@ void *handle_mounts(void *arg)
|
|
|
|
if (mount_autofs(ap) < 0) {
|
|
crit(ap->logopt, "mount of %s failed!", ap->path);
|
|
- suc.status = 1;
|
|
+ suc->status = 1;
|
|
state_mutex_unlock(ap);
|
|
umount_autofs(ap, 1);
|
|
pthread_setcancelstate(cancel_state, NULL);
|
|
@@ -1540,7 +1592,7 @@ void *handle_mounts(void *arg)
|
|
if (ap->ghost && ap->type != LKP_DIRECT)
|
|
info(ap->logopt, "ghosting enabled");
|
|
|
|
- suc.status = 0;
|
|
+ suc->status = 0;
|
|
pthread_cleanup_pop(1);
|
|
|
|
/* We often start several automounters at the same time. Add some
|
|
diff --git a/include/automount.h b/include/automount.h
|
|
index da1bf8f..1a20cd9 100644
|
|
--- a/include/automount.h
|
|
+++ b/include/automount.h
|
|
@@ -331,10 +331,14 @@ int ncat_path(char *buf, size_t len,
|
|
struct startup_cond {
|
|
pthread_mutex_t mutex;
|
|
pthread_cond_t cond;
|
|
+ struct autofs_point *ap;
|
|
unsigned int done;
|
|
unsigned int status;
|
|
};
|
|
|
|
+int handle_mounts_startup_cond_init(struct startup_cond *suc);
|
|
+void handle_mounts_startup_cond_destroy(void *arg);
|
|
+
|
|
struct master_readmap_cond {
|
|
pthread_mutex_t mutex;
|
|
pthread_cond_t cond;
|
|
diff --git a/lib/master.c b/lib/master.c
|
|
index 4a34dd4..edd3bdc 100644
|
|
--- a/lib/master.c
|
|
+++ b/lib/master.c
|
|
@@ -997,28 +997,31 @@ next:
|
|
|
|
static int master_do_mount(struct master_mapent *entry)
|
|
{
|
|
+ struct startup_cond suc;
|
|
struct autofs_point *ap;
|
|
pthread_t thid;
|
|
int status;
|
|
|
|
- status = pthread_mutex_lock(&suc.mutex);
|
|
- if (status)
|
|
- fatal(status);
|
|
+ ap = entry->ap;
|
|
+
|
|
+ if (handle_mounts_startup_cond_init(&suc)) {
|
|
+ crit(ap->logopt,
|
|
+ "failed to init startup cond for mount %s", entry->path);
|
|
+ return 0;
|
|
+ }
|
|
|
|
+ suc.ap = ap;
|
|
suc.done = 0;
|
|
suc.status = 0;
|
|
|
|
- ap = entry->ap;
|
|
-
|
|
debug(ap->logopt, "mounting %s", entry->path);
|
|
|
|
- if (pthread_create(&thid, &thread_attr, handle_mounts, ap)) {
|
|
+ status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
|
|
+ if (status) {
|
|
crit(ap->logopt,
|
|
"failed to create mount handler thread for %s",
|
|
entry->path);
|
|
- status = pthread_mutex_unlock(&suc.mutex);
|
|
- if (status)
|
|
- fatal(status);
|
|
+ handle_mounts_startup_cond_destroy(&suc);
|
|
return 0;
|
|
}
|
|
entry->thid = thid;
|
|
@@ -1031,15 +1034,11 @@ static int master_do_mount(struct master_mapent *entry)
|
|
|
|
if (suc.status) {
|
|
error(ap->logopt, "failed to startup mount");
|
|
- status = pthread_mutex_unlock(&suc.mutex);
|
|
- if (status)
|
|
- fatal(status);
|
|
+ handle_mounts_startup_cond_destroy(&suc);
|
|
return 0;
|
|
}
|
|
|
|
- status = pthread_mutex_unlock(&suc.mutex);
|
|
- if (status)
|
|
- fatal(status);
|
|
+ handle_mounts_startup_cond_destroy(&suc);
|
|
|
|
return 1;
|
|
}
|
|
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
|
|
index 356fb14..6f66564 100644
|
|
--- a/modules/mount_autofs.c
|
|
+++ b/modules/mount_autofs.c
|
|
@@ -46,6 +46,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
int name_len, const char *what, const char *fstype,
|
|
const char *c_options, void *context)
|
|
{
|
|
+ struct startup_cond suc;
|
|
pthread_t thid;
|
|
char *fullpath;
|
|
const char **argv;
|
|
@@ -210,34 +211,34 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
source->mc = cache_init(entry->ap, source);
|
|
if (!source->mc) {
|
|
error(ap->logopt, MODPREFIX "failed to init source cache");
|
|
+ master_free_map_source(source, 0);
|
|
master_free_mapent(entry);
|
|
return 1;
|
|
}
|
|
|
|
mounts_mutex_lock(ap);
|
|
|
|
- status = pthread_mutex_lock(&suc.mutex);
|
|
- if (status) {
|
|
- crit(ap->logopt,
|
|
- MODPREFIX "failed to lock startup condition mutex!");
|
|
- cache_release(source);
|
|
+ if (handle_mounts_startup_cond_init(&suc)) {
|
|
+ crit(ap->logopt, MODPREFIX
|
|
+ "failed to init startup cond for mount %s", entry->path);
|
|
+ mounts_mutex_unlock(ap);
|
|
+ master_free_map_source(source, 1);
|
|
master_free_mapent(entry);
|
|
return 1;
|
|
}
|
|
|
|
+ suc.ap = nap;
|
|
suc.done = 0;
|
|
suc.status = 0;
|
|
|
|
- if (pthread_create(&thid, NULL, handle_mounts, nap)) {
|
|
+ if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) {
|
|
crit(ap->logopt,
|
|
MODPREFIX
|
|
"failed to create mount handler thread for %s",
|
|
fullpath);
|
|
+ handle_mounts_startup_cond_destroy(&suc);
|
|
mounts_mutex_unlock(ap);
|
|
- status = pthread_mutex_unlock(&suc.mutex);
|
|
- if (status)
|
|
- fatal(status);
|
|
- cache_release(source);
|
|
+ master_free_map_source(source, 1);
|
|
master_free_mapent(entry);
|
|
return 1;
|
|
}
|
|
@@ -246,8 +247,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
while (!suc.done) {
|
|
status = pthread_cond_wait(&suc.cond, &suc.mutex);
|
|
if (status) {
|
|
+ handle_mounts_startup_cond_destroy(&suc);
|
|
mounts_mutex_unlock(ap);
|
|
- pthread_mutex_unlock(&suc.mutex);
|
|
+ master_free_map_source(source, 1);
|
|
+ master_free_mapent(entry);
|
|
fatal(status);
|
|
}
|
|
}
|
|
@@ -255,10 +258,9 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
if (suc.status) {
|
|
crit(ap->logopt,
|
|
MODPREFIX "failed to create submount for %s", fullpath);
|
|
+ handle_mounts_startup_cond_destroy(&suc);
|
|
mounts_mutex_unlock(ap);
|
|
- status = pthread_mutex_unlock(&suc.mutex);
|
|
- if (status)
|
|
- fatal(status);
|
|
+ master_free_map_source(source, 1);
|
|
master_free_mapent(entry);
|
|
return 1;
|
|
}
|
|
@@ -266,12 +268,9 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
ap->submnt_count++;
|
|
list_add(&nap->mounts, &ap->submounts);
|
|
|
|
+ handle_mounts_startup_cond_destroy(&suc);
|
|
mounts_mutex_unlock(ap);
|
|
|
|
- status = pthread_mutex_unlock(&suc.mutex);
|
|
- if (status)
|
|
- fatal(status);
|
|
-
|
|
return 0;
|
|
}
|
|
|