From 22df476ef97fbbc1d9efc00c43cc837f535ea7f2 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 20 Jan 2012 16:18:34 -0600 Subject: dlm_master: new test Signed-off-by: David Teigland --- dlm/dlm_master.c | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 dlm/dlm_master.c diff --git a/dlm/dlm_master.c b/dlm/dlm_master.c new file mode 100644 index 0000000..de4c801 --- /dev/null +++ b/dlm/dlm_master.c @@ -0,0 +1,353 @@ +/* + * Copyright 2012 David Teigland + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License V2 + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libdlm.h" + +#define MAX_NODES 16 + +static uint32_t lkids[MAX_NODES]; +static int nodes[MAX_NODES]; +static int nodes_count; +static int our_nodeid; + +static dlm_lshandle_t *dh; +static int openclose = 0; +static int quiet = 0; +static int verbose = 0; +static int sleep_sec = 1; + +#define log_debug(fmt, args...) \ +do { \ + if (!quiet) \ + printf(fmt "\n", ##args); \ +} while (0) + +#define log_error(fmt, args...) \ +do { \ + printf("ERROR " fmt "\n", ##args); \ + exit(-1); \ +} while (0) + +static int rand_int(int a, int b) +{ + return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0)); +} + +static const char *mode_str(int mode) +{ + switch (mode) { + case -1: + return "IV"; + case LKM_NLMODE: + return "NL"; + case LKM_CRMODE: + return "CR"; + case LKM_CWMODE: + return "CW"; + case LKM_PRMODE: + return "PR"; + case LKM_PWMODE: + return "PW"; + case LKM_EXMODE: + return "EX"; + } + return "??"; +} + +static void do_master(void) +{ + struct dlm_lksb lksb; + char name[DLM_RESNAME_MAXLEN]; + int rv; + + snprintf(name, sizeof(name), "nodeid%d", our_nodeid); + + memset(&lksb, 0, sizeof(lksb)); + + rv = dlm_ls_lock_wait(dh, LKM_CRMODE, &lksb, 0, + name, strlen(name), + 0, NULL, NULL, NULL); + + if (rv < 0) { + printf("lock_wait error %d\n", rv); + return; + } + + printf("master \"%s\" 0x%08x %s\n", name, lksb.sb_lkid, + mode_str(LKM_CRMODE)); +} + +static void ping_masters(int acquire_mode, int convert_mode) +{ + struct dlm_lksb lksb; + char name[DLM_RESNAME_MAXLEN]; + int rv, i; + + for (i = 0; i < nodes_count; i++) { + if (nodes[i] == our_nodeid) + continue; + + snprintf(name, sizeof(name), "nodeid%d", nodes[i]); + + memset(&lksb, 0, sizeof(lksb)); + + if (acquire_mode > -1) { + rv = dlm_ls_lock_wait(dh, acquire_mode, &lksb, 0, + name, strlen(name), + 0, NULL, NULL, NULL); + if (rv < 0) { + printf("lock_wait error %d\n", rv); + return; + } + + lkids[i] = lksb.sb_lkid; + + printf("remote \"%s\" 0x%08x %s\n", name, lksb.sb_lkid, + mode_str(acquire_mode)); + continue; + } + + if (convert_mode > -1) { + lksb.sb_lkid = lkids[i]; + + printf("ping \"%s\" 0x%08x %s", name, lksb.sb_lkid, + mode_str(convert_mode)); + fflush(stdout); + + rv = dlm_ls_lock_wait(dh, convert_mode, &lksb, + LKF_CONVERT, + name, strlen(name), + 0, NULL, NULL, NULL); + if (rv < 0) + printf(" error %d\n", rv); + else + printf(" .\n"); + continue; + } + } +} + +static int setup_nodes(void) +{ + char path[PATH_MAX]; + DIR *d; + struct dirent *de; + char local[8]; + int i, fd, rv, nodeid; + + memset(path, 0, PATH_MAX); + snprintf(path, PATH_MAX, "/sys/kernel/config/dlm/cluster/comms"); + + d = opendir(path); + if (!d) { + log_debug("%s: opendir failed: %d", path, errno); + return -1; + } + + while ((de = readdir(d))) { + if (de->d_name[0] == '.') + continue; + + nodeid = atoi(de->d_name); + + nodes[nodes_count++] = nodeid; + + memset(path, 0, PATH_MAX); + snprintf(path, PATH_MAX, "/sys/kernel/config/dlm/cluster/comms/%s/local", de->d_name); + + fd = open(path, O_RDONLY); + if (fd < 0) { + perror("open"); + return -1; + } + + rv = read(fd, local, sizeof(local)); + if (rv < 0) { + perror("read local"); + return -1; + } + + close(fd); + + if (atoi(local)) + our_nodeid = nodeid; + } + closedir(d); + + for (i = 0; i < nodes_count; i++) + printf("nodeid %d\n", nodes[i]); + printf("our_nodeid %d\n", our_nodeid); + + return 0; + +} + +static void print_usage(void) +{ + printf("dlm_master [ping]\n"); + printf("Options:\n"); + printf("\n"); + printf(" -o Open/close existing lockspace\n"); + printf(" -v Verbose output\n"); + printf(" -q Quiet output\n"); +} + +static void decode_arguments(int argc, char **argv) +{ + int cont = 1; + int optchar; + + while (cont) { + optchar = getopt(argc, argv, "vqohs:"); + + switch (optchar) { + + case 's': + sleep_sec = atoi(optarg); + break; + + case 'o': + openclose = 1; + break; + + case 'v': + verbose = 1; + break; + + case 'q': + quiet = 1; + break; + + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + break; + + case 'V': + printf("%s (built %s %s)\n", argv[0], __DATE__, __TIME__); + exit(EXIT_SUCCESS); + break; + + case ':': + case '?': + fprintf(stderr, "Please use '-h' for usage.\n"); + exit(EXIT_FAILURE); + break; + + case EOF: + cont = 0; + break; + + default: + fprintf(stderr, "unknown option: %c\n", optchar); + exit(EXIT_FAILURE); + break; + }; + } +} + +int main(int argc, char *argv[]) +{ + int rv, quit = 0; + int do_ping = 0; + + if (argc > 1 && !strcmp(argv[1], "ping")) { + do_ping = 1; + argc--; + argv++; + } + + decode_arguments(argc, argv); + + if (openclose) { + log_debug("dlm_open_lockspace..."); + + dh = dlm_open_lockspace("dlm_master"); + if (!dh) { + log_error("dlm_open_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } else { + log_debug("dlm_new_lockspace..."); + + dh = dlm_new_lockspace("dlm_master", 0600, 0); + if (!dh) { + log_error("dlm_new_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } + + rv = dlm_ls_pthread_init(dh); + if (rv < 0) { + log_error("dlm_ls_pthread_init error %d %d", rv, errno); + goto done; + } + + setup_nodes(); + + if (do_ping) { + ping_masters(LKM_NLMODE, -1); + + while (1) { + sleep(sleep_sec); + ping_masters(-1, LKM_PRMODE); + sleep(sleep_sec); + ping_masters(-1, LKM_NLMODE); + } + } else { + do_master(); + + while (1) { + sleep(10); + } + } + + done: + if (openclose) { + log_debug("dlm_close_lockspace"); + + rv = dlm_close_lockspace(dh); + if (rv < 0) + log_error("dlm_close_lockspace error %d %d", + rv, errno); + } else { + log_debug("dlm_release_lockspace"); + + rv = dlm_release_lockspace("dlm_master", dh, 1); + if (rv < 0) + log_error("dlm_release_lockspace error %d %d", + rv, errno); + } + + return 0; +} + -- cgit