From mboxrd@z Thu Jan 1 00:00:00 1970 From: teigland@sourceware.org Date: 2 Jul 2007 15:08:47 -0000 Subject: [Cluster-devel] cluster/dlm/tool Makefile main.c Message-ID: <20070702150847.15839.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL4 Changes by: teigland at sourceware.org 2007-07-02 15:08:47 Added files: dlm/tool : Makefile main.c Log message: Add dlm_tool to RHEL4 branch to join/leave lockspaces and dump lock listing. Not entirely certain what we'll do with yet, if anything. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tool/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.2.4.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tool/main.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.3.2.1 /cvs/cluster/cluster/dlm/tool/Makefile,v --> standard output revision 1.2.4.1 --- cluster/dlm/tool/Makefile +++ - 2007-07-02 15:08:47.585279000 +0000 @@ -0,0 +1,35 @@ +############################################################################### +############################################################################### +## +## Copyright (C) 2004 Red Hat, Inc. All rights reserved. +## +## This copyrighted material is made available to anyone wishing to use, +## modify, copy, or redistribute it subject to the terms and conditions +## of the GNU General Public License v.2. +## +############################################################################### +############################################################################### +top_srcdir = ../.. +UNINSTALL=${top_srcdir}/scripts/uninstall.pl + +BINARIES=dlm_tool + +all: $(BINARIES) + +CFLAGS+=-I${top_srcdir}/dlm/lib -L${top_srcdir}/dlm/lib -g + +ifneq (${KERNEL_SRC}, ) +CFLAGS += -I${KERNEL_SRC}/include/cluster +else +CFLAGS += -I/usr/include/linux/cluster +endif + + +dlm_tool: main.c + $(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread + +clean: + rm -f *.o $(BINARIES) *~ core + +copytobin: + /cvs/cluster/cluster/dlm/tool/main.c,v --> standard output revision 1.3.2.1 --- cluster/dlm/tool/main.c +++ - 2007-07-02 15:08:47.680016000 +0000 @@ -0,0 +1,420 @@ +/****************************************************************************** +******************************************************************************* +** +** Copyright (C) 2007 Red Hat, Inc. All rights reserved. +** +** This copyrighted material is made available to anyone wishing to use, +** modify, copy, or redistribute it subject to the terms and conditions +** of the GNU General Public License v.2. +** +******************************************************************************* +******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libdlm.h" + +#define OPTION_STRING "MhVvd:m:" + +#define OP_JOIN 1 +#define OP_LEAVE 2 +#define OP_SPACES 3 +#define OP_LOCKDUMP 4 + +static char *prog_name; +static char *lsname; +static int operation; +static int opt_ind; +static int verbose; +static int dump_mstcpy = 0; +static mode_t create_mode = 0600; + +static void print_usage(void) +{ + printf("Usage:\n"); + printf("\n"); + printf("%s [options] [join|leave|spaces|lockdump]\n", prog_name); + printf("\n"); + printf("Options:\n"); + printf(" -v Verbose output, extra event information\n"); + printf(" -m Permission mode for lockspace device (octal)\n"); + printf(" -M Print MSTCPY locks in lockdump (remote locks, locally mastered)\n"); + printf(" -h Print this help, then exit\n"); + printf(" -V Print program version information, then exit\n"); + printf("\n"); +} + +static void decode_arguments(int argc, char **argv) +{ + int cont = 1; + int optchar; + int need_lsname = 1; + char modebuf[8]; + + while (cont) { + optchar = getopt(argc, argv, OPTION_STRING); + + switch (optchar) { + case 'm': + memset(modebuf, 0, sizeof(modebuf)); + snprintf(modebuf, 8, optarg); + sscanf(modebuf, "%o", &create_mode); + break; + + case 'M': + dump_mstcpy = 1; + break; + + case 'v': + verbose = 1; + break; + + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + break; + + case 'V': + printf("%s (built %s %s)\n", + prog_name, __DATE__, __TIME__); + /* printf("%s\n", REDHAT_COPYRIGHT); */ + 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; + }; + } + + while (optind < argc) { + if (!strncmp(argv[optind], "join", 4) && + (strlen(argv[optind]) == 4)) { + operation = OP_JOIN; + opt_ind = optind + 1; + break; + } else if (!strncmp(argv[optind], "leave", 5) && + (strlen(argv[optind]) == 5)) { + operation = OP_LEAVE; + opt_ind = optind + 1; + break; + } else if (!strncmp(argv[optind], "spaces", 6) && + (strlen(argv[optind]) == 6)) { + operation = OP_SPACES; + opt_ind = optind + 1; + need_lsname = 0; + break; + } else if (!strncmp(argv[optind], "lockdump", 8) && + (strlen(argv[optind]) == 8)) { + operation = OP_LOCKDUMP; + opt_ind = optind + 1; + break; + } + optind++; + } + + if (!operation || !opt_ind) { + print_usage(); + exit(EXIT_FAILURE); + } + + if (optind < argc - 1) + lsname = argv[opt_ind]; + else if (need_lsname) { + fprintf(stderr, "lockspace name required\n"); + exit(EXIT_FAILURE); + } +} + +void do_join(char *name) +{ + dlm_lshandle_t *dh; + + printf("Joining lockspace \"%s\", permission %o\n", name, create_mode); + fflush(stdout); + + dh = dlm_create_lockspace(name, create_mode); + if (!dh) { + fprintf(stderr, "dlm_create_lockspace %s error %p %d\n", + name, dh, errno); + exit(-1); + } + + printf("done\n"); +} + +void do_leave(char *name) +{ + dlm_lshandle_t *dh; + + printf("Leaving lockspace \"%s\"\n", name); + fflush(stdout); + + dh = dlm_open_lockspace(name); + if (!dh) { + fprintf(stderr, "dlm_open_lockspace %s error %p %d\n", + name, dh, errno); + exit(-1); + } + + dlm_release_lockspace(name, dh, 1); + printf("done\n"); +} + +#define PROC_LINE_MAX 256 + +void do_spaces(void) +{ + FILE *file; + char path[PATH_MAX]; + char line[PROC_LINE_MAX]; + int fd; + int error; + + snprintf(path, PATH_MAX, "/proc/cluster/services"); + + file = fopen(path, "r"); + + while (fgets(line, PROC_LINE_MAX, file)) { + if (strstr(line, "DLM")) + printf("%s", line); + } + + fclose(file); +} + +char *parse_resource(char *line) +{ + static char name[65]; + char *p; + int i = 0; + int begin = 0; + + memset(name, 0, sizeof(name)); + + for (p = line; ; p++) { + if (*p == '"') { + if (begin) { + name[i++] = *p; + break; + } + begin = 1; + } + if (begin) + name[i++] = *p; + } + + return name; +} + +void print_granted(char *line, char *name, int master) +{ + char lkid[16]; + char grmode[8]; + char remote_lkid[16]; + int remote_nodeid; + unsigned int pid; + + if (strstr(line, "Remote:")) { + if (!dump_mstcpy) + return; + + sscanf(line, "%s %s %u Remote: %d %s\n", &lkid, &grmode, + &pid, &remote_nodeid, remote_lkid); + + printf("id %s gr %s rq %s pid %u MSTCPY %d %s\n", lkid, grmode, "IV", + pid, remote_nodeid, name); + + return; + } + + sscanf(line, "%s %s %u\n", &lkid, &grmode, &pid); + + printf("id %s gr %s rq %s pid %u master %d %s\n", lkid, grmode, "IV", + pid, master, name); +} + +void print_convert(char *line, char *name, int master) +{ + char lkid[16]; + char grmode[8]; + char rqmode[8]; + char remote_lkid[16]; + int remote_nodeid; + unsigned int pid; + + if (strstr(line, "Remote:")) { + if (!dump_mstcpy) + return; + + sscanf(line, "%s %s (%s) %u Remote: %d %s\n", &lkid, &grmode, + &rqmode, &pid, &remote_nodeid, remote_lkid); + + printf("id %s gr %s rq %s pid %u MSTCPY %d %s\n", lkid, grmode, + rqmode, pid, remote_nodeid, name); + + return; + } + + sscanf(line, "%s %s (%s) %u\n", &lkid, &grmode, &rqmode, &pid); + + printf("id %s gr %s rq %s pid %u master %d %s\n", lkid, grmode, rqmode, + pid, master, name); +} + +void print_waiting(char *line, char *name, int master) +{ + char lkid[16]; + char grmode[8]; + char rqmode[8]; + char remote_lkid[16]; + int remote_nodeid; + unsigned int pid; + + if (strstr(line, "Remote:")) { + if (!dump_mstcpy) + return; + + sscanf(line, "%s %s (%s) %u Remote: %d %s\n", &lkid, &grmode, + &rqmode, &pid, &remote_nodeid, remote_lkid); + + printf("id %s gr %s rq %s pid %u MSTCPY %d %s\n", lkid, "IV", + rqmode, pid, remote_nodeid, name); + + return; + } + + sscanf(line, "%s %s (%s) %u\n", &lkid, &grmode, &rqmode, &pid); + + printf("id %s gr %s rq %s pid %u master %d %s\n", lkid, "IV", rqmode, + pid, master, name); +} + +int parse_master_nodeid(char *line) +{ + int nodeid; + + sscanf(line, "Local Copy, Master is node %d", &nodeid); + + return nodeid; +} + +void do_lockdump(char *name) +{ + FILE *file; + char path[PATH_MAX]; + char line[PROC_LINE_MAX]; + char *rname; + int fd; + int error; + int master; + int next_is_granted, next_is_convert, next_is_waiting; + + snprintf(path, PATH_MAX, "/proc/cluster/dlm_locks"); + + fd = open(path, O_WRONLY); + + error = write(fd, name, strlen(name)); + + close(fd); + + file = fopen(path, "r"); + + while (fgets(line, PROC_LINE_MAX, file)) { + if (verbose) { + printf("%s", line); + continue; + } + + if (strlen(line) < 4) { + continue; + } else if (!strncmp(line, "LVB: ", 5)) { + continue; + } else if (!strncmp(line, " ", 5)) { + continue; + } else if (!strncmp(line, "Resource", 8)) { + rname = parse_resource(line); + continue; + } else if (strstr(line, "Master Copy")) { + master = 0; + continue; + } else if (strstr(line, "Local Copy")) { + master = parse_master_nodeid(line); + continue; + } else if (strstr(line, "Granted Queue")) { + next_is_granted = 1; + next_is_convert = 0; + next_is_waiting = 0; + continue; + } else if (strstr(line, "Conversion Queue")) { + next_is_granted = 0; + next_is_convert = 1; + next_is_waiting = 0; + continue; + } else if (strstr(line, "Waiting Queue")) { + next_is_granted = 0; + next_is_convert = 0; + next_is_waiting = 1; + continue; + } else { + if (next_is_granted) + print_granted(line, rname, master); + else if (next_is_convert) + print_convert(line, rname, master); + else if (next_is_waiting) + print_waiting(line, rname, master); + } + } + + fclose(file); +} + +int main(int argc, char **argv) +{ + prog_name = argv[0]; + decode_arguments(argc, argv); + /* check_name(lsname); */ + + switch (operation) { + case OP_JOIN: + do_join(lsname); + break; + + case OP_LEAVE: + do_leave(lsname); + break; + + case OP_SPACES: + do_spaces(); + break; + + case OP_LOCKDUMP: + do_lockdump(lsname); + break; + } + + return 0; +} +