src/host_id.c | 7 ++++---
src/main.c | 23 +++++++++++++++++------
src/sanlock_internal.h | 2 ++
src/token_manager.c | 13 ++++++++-----
tests/devcount.c | 4 ++--
tests/devcountn | 1 +
6 files changed, 34 insertions(+), 16 deletions(-)
New commits:
commit 795995ae43f325dd791aeb274488f1da1ff607a1
Author: David Teigland <teigland(a)redhat.com>
Date: Thu Jun 2 10:44:16 2011 -0500
sanlock: don't release tokens in dead lockspace
diff --git a/src/host_id.c b/src/host_id.c
index a523242..52b0054 100644
--- a/src/host_id.c
+++ b/src/host_id.c
@@ -42,6 +42,7 @@ int print_space_state(struct space *sp, char *str)
snprintf(str, SANLK_STATE_MAXSTR-1,
"space_id=%u "
"host_generation=%llu "
+ "space_dead=%d "
"killing_pids=%d "
"acquire_last_result=%d "
"renewal_last_result=%d "
@@ -51,6 +52,7 @@ int print_space_state(struct space *sp, char *str)
"renewal_last_success=%llu",
sp->space_id,
(unsigned long long)sp->host_generation,
+ sp->space_dead,
sp->killing_pids,
sp->lease_status.acquire_last_result,
sp->lease_status.renewal_last_result,
@@ -59,7 +61,7 @@ int print_space_state(struct space *sp, char *str)
(unsigned long long)sp->lease_status.renewal_last_attempt,
(unsigned long long)sp->lease_status.renewal_last_success);
- return strlen(str);
+ return strlen(str) + 1;
}
static struct space *_search_space(char *name, struct sync_disk *disk,
@@ -423,8 +425,6 @@ static int finish_space(struct space *sp, int wait)
return -EINVAL;
}
- log_space(sp, "finish_space");
-
if (wait)
rv = pthread_join(sp->thread, NULL);
else
@@ -442,6 +442,7 @@ void clear_spaces(int wait)
list_for_each_entry_safe(sp, safe, &spaces_remove, list) {
rv = finish_space(sp, wait);
if (!rv) {
+ log_space(sp, "free sp");
list_del(&sp->list);
free(sp);
}
diff --git a/src/main.c b/src/main.c
index c12ac7b..31df837 100644
--- a/src/main.c
+++ b/src/main.c
@@ -415,9 +415,14 @@ static int client_using_space(struct client *cl, struct space *sp)
continue;
if (strncmp(token->r.lockspace_name, sp->space_name, NAME_ID_SIZE))
continue;
- rv = 1;
+
log_spoke(sp, token, "client_using_space pid %d", cl->pid);
- break;
+ token->space_dead = sp->space_dead;
+ rv = 1;
+
+ /* we could break here after finding one if we didn't care
+ * about setting token->space_dead which isn't really
+ * necessary; it just avoids trying to release the token */
}
return rv;
}
@@ -536,7 +541,7 @@ static int main_loop(void)
struct timeval now, last_check;
int poll_timeout, check_interval;
unsigned int ms;
- int i, rv, empty;
+ int i, rv, empty, space_dead;
gettimeofday(&last_check, NULL);
poll_timeout = STANDARD_CHECK_INTERVAL;
@@ -588,9 +593,15 @@ static int main_loop(void)
}
check_interval = RECOVERY_CHECK_INTERVAL;
} else {
- if (external_shutdown || sp->external_remove ||
- !host_id_check(&main_task, sp)) {
- log_space(sp, "set killing_pids");
+ space_dead = !host_id_check(&main_task, sp);
+
+ if (space_dead || external_shutdown ||
+ sp->external_remove) {
+ log_space(sp, "set killing_pids dead %d "
+ "shutdown %d remove %d",
+ space_dead, external_shutdown,
+ sp->external_remove);
+ sp->space_dead = space_dead;
sp->killing_pids = 1;
kill_pids(sp);
check_interval = RECOVERY_CHECK_INTERVAL;
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h
index 2729f6d..62b3f68 100644
--- a/src/sanlock_internal.h
+++ b/src/sanlock_internal.h
@@ -84,6 +84,7 @@ struct token {
/* internal */
int token_id; /* used to refer to this token instance in log messages */
+ int space_dead; /* don't bother trying to release if ls is dead */
int acquire_result;
int release_result;
struct leader_record leader; /* copy of last leader_record we wrote */
@@ -108,6 +109,7 @@ struct space {
struct sync_disk host_id_disk;
struct list_head list;
int space_id; /* used to refer to this space instance in log messages */
+ int space_dead;
int killing_pids;
int external_remove;
int thread_stop;
diff --git a/src/token_manager.c b/src/token_manager.c
index abb2eb5..c0fc485 100644
--- a/src/token_manager.c
+++ b/src/token_manager.c
@@ -210,9 +210,7 @@ static void *async_release_thread(void *arg GNUC_UNUSED)
pthread_mutex_unlock(&resource_mutex);
token = r->token;
-
- if (token->acquire_result == 1)
- release_token(&task, token);
+ release_token(&task, token);
/* we don't want to remove r from dispose_list until after the
lease is released because we don't want a new token for
@@ -237,8 +235,13 @@ void release_token_async(struct token *token)
r = find_resource(token, &resources);
if (r) {
/* assert r->token == token ? */
- list_move(&r->list, &dispose_resources);
- pthread_cond_signal(&resource_cond);
+ if (token->space_dead || (token->acquire_result != SANLK_OK)) {
+ _del_resource(r);
+ free(token);
+ } else {
+ list_move(&r->list, &dispose_resources);
+ pthread_cond_signal(&resource_cond);
+ }
}
pthread_mutex_unlock(&resource_mutex);
}
diff --git a/tests/devcount.c b/tests/devcount.c
index 817927c..f897f74 100644
--- a/tests/devcount.c
+++ b/tests/devcount.c
@@ -580,9 +580,9 @@ static int do_relock(int argc, char *argv[])
}
run_more:
- /* let the child run for 20 seconds before stopping it */
+ /* let the child run for 30 seconds before stopping it */
- for (i = 0; i < 20; i++) {
+ for (i = 0; i < 30; i++) {
rv = waitpid(pid, &status, WNOHANG);
if (rv == pid)
break;
diff --git a/tests/devcountn b/tests/devcountn
index 625eb33..8ef1b7a 100755
--- a/tests/devcountn
+++ b/tests/devcountn
@@ -10,6 +10,7 @@ if [ $# -le 3 ]; then
echo "devcountn N relock LOCKDEV_BASE rw COUNTDEV_BASE SEC1 SEC2 HOSTID"
echo "devcountn N wrap LOCKDEV_BASE rw COUNTDEV_BASE SEC1 SEC2 HOSTID"
echo "devcountn N migrate LOCKDEV_BASE rw COUNTDEV_BASE SEC1 SEC2 HOSTID
MAXID"
+ echo "devcountn N expire LOCKDEV_BASE rw COUNTDEV_BASE SEC1 SEC2 HOSTID"
echo ""
echo "devcount <cmd> LOCKDEV1 rw COUNTDEV1 ..."
echo "devcount <cmd> LOCKDEV2 rw COUNTDEV2 ..."