src/main.c | 34 +++++++++++++------
tests/sanlk_load.c | 91 ++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 97 insertions(+), 28 deletions(-)
New commits:
commit 021048e33e4c260c85ba6ab50645523725c385b0
Author: David Teigland <teigland(a)redhat.com>
Date: Mon Jun 20 16:29:25 2011 -0500
sanlock: initial pid_dead check in acquire
If cmd_acquire has been queued for a while waiting for
the thread pool, the pid may already be dead by the time
cmd_acquire begins. In that case don't go to the trouble
of acquiring leases before checking if the pid is dead.
diff --git a/src/main.c b/src/main.c
index 3d407fb..0b531bf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -761,6 +761,12 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca)
}
pthread_mutex_lock(&cl->mutex);
+ if (cl->pid_dead) {
+ result = -ESTALE;
+ pthread_mutex_unlock(&cl->mutex);
+ goto done;
+ }
+
empty_slots = 0;
for (i = 0; i < SANLK_MAX_RESOURCES; i++) {
if (!cl->tokens[i])
commit 0d8078864b74173a181d65dcf217549639bd81db
Author: David Teigland <teigland(a)redhat.com>
Date: Mon Jun 20 15:32:42 2011 -0500
sanlock: fix recv and inquire
- recv correct number of remaining bytes after aborting cmd_acquire
- don't return partial/bogus string from cmd_inquire when the
pid has no resources
diff --git a/src/main.c b/src/main.c
index fec794e..3d407fb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -635,22 +635,25 @@ static void client_recv_all(int ci, struct sm_header *h_recv, int
pos)
{
char trash[64];
int rem = h_recv->length - sizeof(struct sm_header) - pos;
- int rv, total = 0;
+ int rv, error = 0, total = 0;
if (!rem)
return;
while (1) {
rv = recv(client[ci].fd, trash, sizeof(trash), MSG_DONTWAIT);
+ if (rv == -1)
+ error = errno;
if (rv <= 0)
break;
total += rv;
- if (total > MAX_CLIENT_MSG)
+ if (total >= rem)
break;
}
- log_debug("recv_all ci %d rem %d total %d", ci, rem, total);
+ log_error("recv_all %d,%d,%d pos %d rv %d error %d rem %d total %d",
+ ci, client[ci].fd, client[ci].pid, pos, rv, error, rem, total);
}
static void release_cl_tokens(struct task *task, struct client *cl)
@@ -1060,15 +1063,15 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca)
}
reply:
+ if (!recv_done)
+ client_recv_all(ca->ci_in, &ca->header, pos);
+
memcpy(&h, &ca->header, sizeof(struct sm_header));
h.length = sizeof(h);
h.data = result;
h.data2 = 0;
send(fd, &h, sizeof(h), MSG_NOSIGNAL);
- if (!recv_done)
- client_recv_all(ca->ci_in, &ca->header, pos);
-
client_resume(ca->ci_in);
}
@@ -1214,6 +1217,11 @@ static void cmd_inquire(struct task *task, struct cmd_args *ca)
res_count++;
}
+ if (!res_count) {
+ result = 0;
+ goto done;
+ }
+
state_maxlen = res_count * (SANLK_MAX_RES_STR + 1);
state = malloc(state_maxlen);
@@ -1282,8 +1290,8 @@ static void cmd_inquire(struct task *task, struct cmd_args *ca)
cl->cmd_active = 0;
pthread_mutex_unlock(&cl->mutex);
- log_debug("cmd_inquire %d,%d,%d result %d pid_dead %d count %d strlen %d",
- cl_ci, cl_fd, cl_pid, result, pid_dead, res_count, state_strlen);
+ log_debug("cmd_inquire %d,%d,%d result %d pid_dead %d res_count %d cat_count %d
strlen %d",
+ cl_ci, cl_fd, cl_pid, result, pid_dead, res_count, cat_count, state_strlen);
if (pid_dead) {
release_cl_tokens(task, cl);
@@ -1888,14 +1896,14 @@ static void process_cmd_thread_resource(int ci_in, struct
sm_header *h_recv)
return;
fail:
+ client_recv_all(ci_in, h_recv, 0);
+
memcpy(&h, h_recv, sizeof(struct sm_header));
h.length = sizeof(h);
h.data = result;
h.data2 = 0;
send(client[ci_in].fd, &h, sizeof(h), MSG_NOSIGNAL);
- client_recv_all(ci_in, h_recv, 0);
-
client_resume(ci_in);
if (ca)
free(ca);
diff --git a/tests/sanlk_load.c b/tests/sanlk_load.c
index 27d2221..6c55ffb 100644
--- a/tests/sanlk_load.c
+++ b/tests/sanlk_load.c
@@ -15,6 +15,7 @@
#include <limits.h>
#include <time.h>
#include <signal.h>
+#include <syslog.h>
#include "sanlock.h"
#include "sanlock_admin.h"
@@ -25,12 +26,15 @@
#define LEASE_SIZE ONEMB
#define MAX_LS_COUNT 64
-#define MAX_RES_COUNT 64
+#define MAX_RES_COUNT 512
+#define MAX_PID_COUNT 256
#define DEFAULT_LS_COUNT 4
#define DEFAULT_RES_COUNT 4
#define DEFAULT_PID_COUNT 4
#define MAX_RV 300
+int debug = 0;
+char error_buf[4096];
char lock_disk_base[PATH_MAX];
int lock_state[MAX_LS_COUNT][MAX_RES_COUNT];
int ls_count = DEFAULT_LS_COUNT;
@@ -39,17 +43,19 @@ int pid_count = DEFAULT_PID_COUNT;
int our_hostid;
int acquire_rv[MAX_RV];
int release_rv[MAX_RV];
-int debug = 0;
#define log_debug(fmt, args...) \
do { \
- if (debug) printf("%llu " fmt "\n", (unsigned long long)time(NULL),
##args); \
+ if (debug) printf("%lu " fmt "\n", time(NULL), ##args); \
} while (0)
#define log_error(fmt, args...) \
do { \
- printf("ERROR %llu " fmt "\n", (unsigned long long)time(NULL),
##args); \
+ memset(error_buf, 0, sizeof(error_buf)); \
+ snprintf(error_buf, 4095, "%ld " fmt "\n", time(NULL), ##args); \
+ printf("ERROR: %s\n", error_buf); \
+ syslog(LOG_ERR, "%s", error_buf); \
} while (0)
@@ -58,7 +64,7 @@ static int get_rand(int a, int b)
return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0));
}
-static void save_rv(int rv, int acquire)
+static void save_rv(int pid, int rv, int acquire)
{
if (rv > 0)
goto fail;
@@ -79,16 +85,18 @@ static void save_rv(int rv, int acquire)
return;
fail:
- log_error("save_rv %d %d", rv, acquire);
- while (1)
+ log_error("%d save_rv %d %d", pid, rv, acquire);
+ while (1) {
sleep(10);
+ printf("%lu %d ERROR save_rv %d %d", time(NULL), pid, rv, acquire);
+ }
}
static void display_rv(int pid)
{
int i;
- printf("%llu %d results acquire ", (unsigned long long)time(NULL), pid);
+ printf("%lu %d results acquire ", time(NULL), pid);
for (i = 0; i < MAX_RV; i++) {
if (acquire_rv[i])
printf("%d:%d ", i, acquire_rv[i]);
@@ -118,15 +126,36 @@ static void dump_lock_state(int pid)
static int check_lock_state(int pid, int result, int count, char *res_state)
{
char buf[128];
- char *found;
+ char *found = NULL;
int found_count = 0;
int none_count = 0;
int bad_count = 0;
int i, j;
+ memset(buf, 0, sizeof(buf));
+
if (result < 0)
goto fail;
+ if (!count) {
+ if (res_state) {
+ log_error("%d check_lock_state zero count res_state %s",
+ pid, res_state);
+ }
+ for (i = 0; i < ls_count; i++) {
+ for (j = 0; j < res_count; j++) {
+ if (lock_state[i][j]) {
+ bad_count++;
+ log_error("%d check_lock_state zero count %d %d lock", pid, i, j);
+ }
+ }
+ }
+
+ if (bad_count)
+ goto fail;
+ return 0;
+ }
+
for (i = 0; i < ls_count; i++) {
for (j = 0; j < res_count; j++) {
memset(buf, 0, sizeof(buf));
@@ -140,7 +169,6 @@ static int check_lock_state(int pid, int result, int count, char
*res_state)
none_count++;
} else {
bad_count++;
-
log_error("%d check_lock_state %s lock_state %d res_state %s",
pid, buf, lock_state[i][j], res_state);
}
@@ -163,8 +191,11 @@ static int check_lock_state(int pid, int result, int count, char
*res_state)
dump_lock_state(pid);
- while (1)
+ while (1) {
sleep(10);
+ printf("%lu %d ERROR check_lock_state result %d count %d found %d bad %d res_state
%s",
+ time(NULL), pid, result, count, found_count, bad_count, res_state);
+ }
}
static int add_lockspaces(void)
@@ -172,6 +203,8 @@ static int add_lockspaces(void)
struct sanlk_lockspace ls;
int i, rv;
+ printf("adding %d lockspaces...\n", ls_count);
+
for (i = 0; i < ls_count; i++) {
memset(&ls, 0, sizeof(ls));
sprintf(ls.host_id_disk.path, "%s%d", lock_disk_base, i);
@@ -185,9 +218,9 @@ static int add_lockspaces(void)
return -1;
}
- log_debug("add lockspace %s:%llu:%s:%d",
- ls.name, (unsigned long long)ls.host_id,
- ls.host_id_disk.path, 0);
+ printf("add lockspace %s:%llu:%s:%d\n",
+ ls.name, (unsigned long long)ls.host_id,
+ ls.host_id_disk.path, 0);
}
return 0;
@@ -220,7 +253,7 @@ static int do_one(int pid, int fd, int ls1, int res1, int *full, int
acquire)
log_debug("%d %s %d,%d = %d",
pid, acquire ? "acquire" : "release", ls1, res1, rv);
- save_rv(rv, acquire);
+ save_rv(pid, rv, acquire);
return rv;
}
@@ -269,7 +302,7 @@ static int do_two(int pid, int fd, int ls1, int res1, int ls2, int
res2, int *fu
log_debug("%d %s %d,%d %d,%d = %d",
pid, acquire ? "acquire" : "release", ls1, res1, ls2, res2, rv);
- save_rv(rv, acquire);
+ save_rv(pid, rv, acquire);
free(res_args);
return rv;
@@ -303,7 +336,7 @@ static int release_all(int pid, int fd)
log_debug("%d release all = %d", pid, rv);
- save_rv(rv, 0);
+ save_rv(pid, rv, 0);
return rv;
}
@@ -456,12 +489,25 @@ void get_options(int argc, char *argv[])
break;
case 's':
ls_count = atoi(optionarg);
+ if (ls_count > MAX_LS_COUNT) {
+ log_error("max ls_count %d", MAX_LS_COUNT);
+ exit(-1);
+ }
break;
case 'r':
res_count = atoi(optionarg);
+ if (res_count > MAX_RES_COUNT) {
+ log_error("max res_count %d", MAX_RES_COUNT);
+ exit(-1);
+ }
break;
case 'p':
pid_count = atoi(optionarg);
+ if (pid_count > MAX_PID_COUNT) {
+ log_error("max pid_count %d", MAX_PID_COUNT);
+ exit(-1);
+ }
+ break;
default:
log_error("unknown option: %c", optchar);
exit(EXIT_FAILURE);
@@ -473,7 +519,7 @@ void get_options(int argc, char *argv[])
int do_rand(int argc, char *argv[])
{
- int children[pid_count];
+ int children[MAX_PID_COUNT];
int run_count = 0;
int i, rv, pid, status;
@@ -488,9 +534,16 @@ int do_rand(int argc, char *argv[])
if (rv < 0)
return rv;
+ printf("forking %d pids...\n", pid_count);
+
for (i = 0; i < pid_count; i++) {
pid = fork();
+ if (pid < 0) {
+ log_error("fork %d failed %d run_count %d", i, errno, run_count);
+ break;
+ }
+
if (!pid) {
do_rand_child();
exit(-1);
@@ -500,6 +553,8 @@ int do_rand(int argc, char *argv[])
run_count++;
}
+ printf("children running\n");
+
while (run_count) {
pid = wait(&status);
if (pid > 0)