src/Makefile tests/devcount.c
by David Teigland
src/Makefile | 4
tests/devcount.c | 363 +++++++++++++++++++++++++++++++++++++------------------
2 files changed, 250 insertions(+), 117 deletions(-)
New commits:
commit 36a731ab8e2b9adc197e0679ca629f7792bf624e
Author: David Teigland <teigland(a)redhat.com>
Date: Tue Mar 1 15:05:38 2011 -0600
libsanlock: include admin functions
and install sanlock_admin.h
diff --git a/src/Makefile b/src/Makefile
index 2aa188e..31df6d2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -8,7 +8,7 @@ CMD_TARGET = sanlock
LIB_TARGET = libsanlock
-HEADER_TARGET = sanlock.h sanlock_resource.h
+HEADER_TARGET = sanlock.h sanlock_resource.h sanlock_admin.h
SOMAJOR=1
SOMINOR=0
@@ -16,7 +16,6 @@ SOMINOR=0
SHLIB_TARGET = $(LIB_TARGET).so.$(SOMAJOR).$(SOMINOR)
CMD_SOURCE = \
- client_admin.c \
crc32c.c \
delta_lease.c \
direct.c \
@@ -32,6 +31,7 @@ CMD_SOURCE = \
LIB_SOURCE = \
client_msg.c \
client_resource.c \
+ client_admin.c
CFLAGS += -D_GNU_SOURCE -g \
-Wall \
diff --git a/tests/devcount.c b/tests/devcount.c
index fdaa3de..c29be3f 100644
--- a/tests/devcount.c
+++ b/tests/devcount.c
@@ -14,9 +14,19 @@
#include <limits.h>
#include <time.h>
+#include "sanlock.h"
+#include "sanlock_admin.h"
+#include "sanlock_resource.h"
+
FILE *turn_file;
-char path[PATH_MAX];
+
+char count_path[PATH_MAX];
+char lock_path[PATH_MAX];
+int count_offset;
+int lock_offset;
+
int our_hostid;
+
int seconds;
int verify;
int quiet;
@@ -35,6 +45,11 @@ struct entry {
uint64_t last_count;
};
+static int rand_int(int a, int b)
+{
+ return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0));
+}
+
/* 64 byte entry: can fit up to 8 nodes in a 512 byte block */
void print_entries(char *buf)
@@ -77,88 +92,35 @@ void print_our_we(struct entry *our_we)
(unsigned long long)our_we->last_count);
}
-int verify_vbuf(char *rbuf, char *wbuf, char *vbuf)
-{
- struct entry *re, *we, *ve;
- int i;
+#define COUNT_ARGS 6
+#define LOCK_ARGS 8
- re = (struct entry *)rbuf;
- we = (struct entry *)wbuf;
- ve = (struct entry *)vbuf;
+/*
+ * devcount count <count_disk> <rsec> <wsec> <hostid>
+ */
- for (i = 0; i < (512 / sizeof(struct entry)); i++) {
- if (i == (our_hostid - 1)) {
- if (memcmp(we, ve, sizeof(struct entry)))
- return -1;
- } else {
- if (memcmp(re, ve, sizeof(struct entry)))
- return -1;
- }
-
- re++;
- we++;
- ve++;
- }
-
- return 0;
-}
-
-void set_args(int argc, char *argv[])
-{
- int cont = 1;
- int optchar;
-
- if (argc == 1) {
- printf("devcount -d /path/to/disk -i our_hostid\n");
- exit(1);
- }
-
- while (cont) {
- optchar = getopt(argc, argv, "d:i:s:v:qf:");
-
- switch (optchar) {
- case 'd':
- strncpy(path, optarg, PATH_MAX);
- break;
- case 'i':
- our_hostid = atoi(optarg);
- break;
- case 's':
- seconds = atoi(optarg);
- break;
- case 'v':
- verify = atoi(optarg);
- break;
- case 'q':
- quiet = 1;
- break;
- case 'f':
- turn_file = fopen(optarg, "a");
- break;
- case EOF:
- cont = 0;
- break;
- }
- }
-
- if (!our_hostid || our_hostid > 512 / sizeof(struct entry)) {
- printf("valid host_id 1 - %d\n", 512 / sizeof(struct entry));
- exit(1);
- }
-}
-
-int main(int argc, char *argv[])
+static int do_count(int argc, char *argv[])
{
char *rbuf, **p_rbuf, *wbuf, **p_wbuf, *vbuf, **p_vbuf;
struct entry *re, *max_re, *our_we;
int i, fd, rv, max_i;
- time_t start, now;
+ time_t start;
uint32_t our_pid = getpid();
uint32_t max_turn;
+ int read_seconds, write_seconds;
+
+ if (argc < COUNT_ARGS)
+ return -1;
+
+ strcpy(count_path, argv[2]);
+ read_seconds = atoi(argv[3]);
+ write_seconds = atoi(argv[4]);
+ our_hostid = atoi(argv[5]);
- set_args(argc, argv);
+ printf("%d count count_disk %s rsec %d wsec %d our_hostid %d\n",
+ our_pid, count_path, read_seconds, write_seconds, our_hostid);
- fd = open(path, O_RDWR | O_DIRECT | O_SYNC, 0);
+ fd = open(count_path, O_RDWR | O_DIRECT | O_SYNC, 0);
if (fd < 0) {
perror("open failed");
goto fail;
@@ -192,7 +154,12 @@ int main(int argc, char *argv[])
goto fail;
}
- lseek(fd, 0, SEEK_SET);
+ /*
+ * Quickly read, then reread for a few seconds to see if
+ * the previous writer does another write.
+ */
+
+ lseek(fd, count_offset, SEEK_SET);
rv = read(fd, rbuf, 512);
if (rv != 512) {
@@ -200,7 +167,31 @@ int main(int argc, char *argv[])
goto fail;
}
- print_entries(rbuf);
+ /* print_entries(rbuf); */
+
+ for (i = 0; i < read_seconds; i++) {
+ sleep(1);
+
+ lseek(fd, count_offset, SEEK_SET);
+
+ rv = read(fd, vbuf, 512);
+ if (rv != 512) {
+ perror("read failed");
+ goto fail;
+ }
+
+ if (memcmp(rbuf, vbuf, 512)) {
+ printf("rbuf:\n");
+ print_entries(rbuf);
+ printf("vbuf:\n");
+ print_entries(vbuf);
+ goto fail;
+ }
+ }
+
+ /*
+ * Now start writing
+ */
re = (struct entry *)rbuf;
max_re = NULL;
@@ -223,8 +214,10 @@ int main(int argc, char *argv[])
goto fail;
}
+ /*
printf("max index %d turn %d count %llu\n", max_i, max_turn,
(unsigned long long)max_re->count);
+ */
memcpy(wbuf, rbuf, 512);
@@ -243,7 +236,7 @@ int main(int argc, char *argv[])
our_we->time = time(NULL);
our_we->count = max_re->count + 1;
- lseek(fd, 0, SEEK_SET);
+ lseek(fd, count_offset, SEEK_SET);
rv = write(fd, wbuf, 512);
if (rv != 512) {
@@ -251,48 +244,16 @@ int main(int argc, char *argv[])
goto fail;
}
+ printf("%d first write\n", our_pid);
print_our_we(our_we);
start = time(NULL);
while (1) {
- now = time(NULL);
-
- if (verify && (now - start < verify)) {
- /* If one node starts before the other stops, the
- starting node will notice the writes from the
- stopping node. */
-
- lseek(fd, 0, SEEK_SET);
-
- rv = read(fd, vbuf, 512);
- if (rv != 512) {
- perror("read failed");
- goto fail;
- }
-
- /*
- if (!quiet)
- printf("read\n");
- */
-
- rv = verify_vbuf(rbuf, wbuf, vbuf);
-
- if (rv < 0) {
- printf("rbuf:\n");
- print_entries(rbuf);
- printf("wbuf:\n");
- print_entries(wbuf);
- printf("vbuf:\n");
- print_entries(vbuf);
- goto fail;
- }
- }
-
our_we->count++;
- our_we->time = now;
+ our_we->time = time(NULL);
- lseek(fd, 0, SEEK_SET);
+ lseek(fd, count_offset, SEEK_SET);
rv = write(fd, wbuf, 512);
if (rv != 512) {
@@ -300,13 +261,11 @@ int main(int argc, char *argv[])
goto fail;
}
- if (!quiet)
- print_our_we(our_we);
-
- if (seconds && (now - start >= seconds))
+ if (write_seconds && (our_we->time - start >= write_seconds))
break;
}
+ printf("%d last write\n", our_pid);
print_our_we(our_we);
if (turn_file) {
@@ -326,3 +285,177 @@ int main(int argc, char *argv[])
return -1;
}
+/*
+ * devcount lock <lock_disk> count <count_disk> <rsec> <wsec> <hostid>
+ * sanlock add_lockspace -s devcount:<hostid>:<lock_disk>:0
+ * devcount count <count_disk> <rsec> <wsec> <hostid>
+ */
+
+static int do_lock(int argc, char *argv[])
+{
+ char *av[COUNT_ARGS+1];
+ struct sanlk_lockspace lockspace;
+ struct sanlk_resource *res;
+ int i, j, pid, rv, sock, len, status;
+ uint32_t our_pid = getpid();
+
+ if (argc < LOCK_ARGS)
+ return -1;
+
+ strcpy(lock_path, argv[2]);
+ strcpy(count_path, argv[4]);
+ our_hostid = atoi(argv[7]);
+
+ len = sizeof(struct sanlk_resource) + sizeof(struct sanlk_disk);
+ res = malloc(len);
+ memset(res, 0, len);
+ strcpy(res->lockspace_name, "devcount");
+ snprintf(res->name, SANLK_NAME_LEN, "resource%s", count_path);
+ res->name[SANLK_NAME_LEN-1] = '\0';
+ res->num_disks = 1;
+ strncpy(res->disks[0].path, lock_path, SANLK_PATH_LEN);
+ res->disks[0].path[SANLK_PATH_LEN-1] = '\0';
+ res->disks[0].offset = 1024000;
+
+ printf("%d lock_disk %s count_disk %s our_hostid %d\n",
+ our_pid, lock_path, count_path, our_hostid);
+
+ memset(&lockspace, 0, sizeof(lockspace));
+ strcpy(lockspace.name, "devcount");
+ strcpy(lockspace.host_id_disk.path, lock_path);
+ lockspace.host_id_disk.offset = lock_offset;
+ lockspace.host_id = our_hostid;
+
+ rv = sanlock_add_lockspace(&lockspace, 0);
+ if (rv < 0) {
+ printf("sanlock_add_lockspace error %d\n", rv);
+ exit(EXIT_FAILURE);
+ }
+ printf("sanlock_add_lockspace done\n");
+
+ /*
+ * argv[0] = devcount
+ * argv[1] = lock
+ * argv[2] = <lock_disk>
+ * argv[3] = count
+ * start copying at argv[3]
+ */
+
+ j = 0;
+ memset(av, 0, sizeof(char *) * COUNT_ARGS+1);
+
+ av[j++] = strdup(argv[0]);
+ for (i = 3; i < LOCK_ARGS; i++)
+ av[j++] = strdup(argv[i]);
+
+ while (1) {
+ pid = fork();
+ if (!pid) {
+ int our_pid = getpid();
+
+ printf("\n");
+
+ sock = sanlock_register();
+ rv = sanlock_acquire(sock, -1, 1, &res, NULL);
+ if (rv < 0) {
+ printf("%d sanlock_acquire error %d\n",
+ our_pid, rv);
+ exit(0);
+ }
+ printf("%d sanlock_acquire done\n", our_pid);
+
+ execv(av[0], av);
+ perror("execv devcount problem");
+ exit(EXIT_FAILURE);
+ }
+
+ waitpid(pid, &status, 0);
+ sleep(rand_int(0, 1));
+ }
+}
+
+/*
+ * devcount init <lock_disk> <count_disk>
+ * sanlock direct init -n 8 -s devcount:0:<lock_disk>:0
+ * sanlock direct init -n 8 -r devcount:resource<count_disk>:<lock_disk>:1024000
+ */
+
+int do_init(int argc, char *argv[])
+{
+ char command[4096];
+ char *colon;
+
+ if (argc < 4)
+ return -1;
+
+ /* initialize host_id lease area at offset 0 */
+
+ memset(command, 0, sizeof(command));
+
+ snprintf(command, sizeof(command),
+ "sanlock direct init -n 8 -s devcount:0:%s:0",
+ argv[2]);
+
+ printf("%s\n", command);
+
+ system(command);
+
+ /* initialize first resource lease area at offset 1024000 */
+
+ memset(command, 0, sizeof(command));
+
+ strcpy(count_path, argv[3]);
+
+ snprintf(command, sizeof(command),
+ "sanlock direct init -n 8 -r devcount:resource%s:%s:1024000",
+ argv[3],
+ argv[2]);
+
+ printf("%s\n", command);
+
+ system(command);
+}
+
+int main(int argc, char *argv[])
+{
+ int rv;
+
+ if (argc < 2)
+ goto out;
+
+ if (!strcmp(argv[1], "init"))
+ rv = do_init(argc, argv);
+
+ else if (!strcmp(argv[1], "count"))
+ rv = do_count(argc, argv);
+
+ else if (!strcmp(argv[1], "lock"))
+ rv = do_lock(argc, argv);
+
+ if (!rv)
+ return 0;
+
+ out:
+ /*
+ * sanlock direct init -n 8 -s devcount:0:/dev/bull/leases:0
+ * sanlock direct init -n 8 -r devcount:resource/dev/bull/count:/dev/bull/leases:1024000
+ *
+ * host_id leases exists at <lock_disk> offset 0
+ * first resource lease exists at <lock_disk> offset 1024000
+ */
+
+ printf("devcount init <lock_disk> <count_disk>\n");
+ printf(" sanlock direct init -n 8 -s devcount:0:<lock_disk>:0\n");
+ printf(" sanlock direct init -n 8 -r devcount:resource<count_disk>:<lock_disk>:1024000\n");
+ printf("\n");
+ printf("devcount lock <lock_disk> count <count_disk> <rsec> <wsec> <hostid>\n");
+ printf(" sanlock add_lockspace -s devcount:<hostid>:<lock_disk>:0\n");
+ printf(" loop around fork, sanlock_acquire, exec devcount count\n");
+ printf("\n");
+ printf("devcount count <count_disk> <rsec> <wsec> <hostid>\n");
+ printf(" read disk count for rsec seconds, looking for any writes\n");
+ printf(" write disk count for wsec seconds, (wsec 0 indefinite)\n");
+ printf("\n");
+ return -1;
+}
+
13 years, 1 month