Gitweb:
http://git.fedorahosted.org/git/dlm.git?p=dlm.git;a=commitdiff;h=2a1ff7ea...
Commit: 2a1ff7ea5b9c86e3e6ade2ea8da1bd22e2b61749
Parent: 7c18aed3909b817e0f18840dc4ea8737a4f11ac6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Sep 30 14:15:57 2011 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Sep 30 14:15:57 2011 -0500
dlm_controld: build libdlmcontrol
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
dlm/libdlmcontrol/libdlmcontrol.h | 90 --------
dlm/libdlmcontrol/main.c | 421 -------------------------------------
dlm_controld/Makefile | 30 +++-
dlm_controld/lib.c | 419 ++++++++++++++++++++++++++++++++++++
dlm_controld/libdlmcontrol.h | 90 ++++++++
5 files changed, 537 insertions(+), 513 deletions(-)
diff --git a/dlm/libdlmcontrol/libdlmcontrol.h b/dlm/libdlmcontrol/libdlmcontrol.h
deleted file mode 100644
index 64a3814..0000000
--- a/dlm/libdlmcontrol/libdlmcontrol.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _LIBDLMCONTROL_H_
-#define _LIBDLMCONTROL_H_
-
-#define DLMC_DUMP_SIZE (1024 * 1024)
-
-#define DLMC_NF_MEMBER 0x00000001 /* node is member in cg */
-#define DLMC_NF_START 0x00000002 /* start message recvd for cg */
-#define DLMC_NF_DISALLOWED 0x00000004 /* node disallowed in cg */
-#define DLMC_NF_CHECK_FENCING 0x00000008
-#define DLMC_NF_CHECK_QUORUM 0x00000010
-#define DLMC_NF_CHECK_FS 0x00000020
-
-struct dlmc_node {
- int nodeid;
- uint32_t flags;
- uint32_t added_seq;
- uint32_t removed_seq;
- int failed_reason;
-};
-
-struct dlmc_change {
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
- int wait_condition; /* 0 no, 1 fencing, 2 quorum, 3 fs */
- int wait_messages; /* 0 no, 1 yes */
- uint32_t seq;
- uint32_t combined_seq;
-};
-
-#define DLMC_LF_JOINING 0x00000001
-#define DLMC_LF_LEAVING 0x00000002
-#define DLMC_LF_KERNEL_STOPPED 0x00000004
-#define DLMC_LF_FS_REGISTERED 0x00000008
-#define DLMC_LF_NEED_PLOCKS 0x00000010
-#define DLMC_LF_SAVE_PLOCKS 0x00000020
-
-struct dlmc_lockspace {
- int group_mode;
- struct dlmc_change cg_prev; /* completed change (started_change) */
- struct dlmc_change cg_next; /* in-progress change (changes list) */
- uint32_t flags;
- uint32_t global_id;
- char name[DLM_LOCKSPACE_LEN+1];
-};
-
-/* dlmc_lockspace_nodes() types
-
- MEMBERS: members in completed (prev) change,
- zero if there's no completed (prev) change
- NEXT: members in in-progress (next) change,
- zero if there's no in-progress (next) change
- ALL: NEXT + nonmembers if there's an in-progress (next) change,
- MEMBERS + nonmembers if there's no in-progress (next) change, but
- there is a completed (prev) change
- nonmembers if there's no in-progress (next) or completed (prev)
- change (possible?)
-
- dlmc_node_info() returns info for in-progress (next) change, if one exists,
- otherwise it returns info for completed (prev) change.
-*/
-
-#define DLMC_NODES_ALL 1
-#define DLMC_NODES_MEMBERS 2
-#define DLMC_NODES_NEXT 3
-
-int dlmc_dump_debug(char *buf);
-int dlmc_dump_log_plock(char *buf);
-int dlmc_dump_plocks(char *name, char *buf);
-int dlmc_lockspace_info(char *lsname, struct dlmc_lockspace *ls);
-int dlmc_node_info(char *lsname, int nodeid, struct dlmc_node *node);
-int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss);
-int dlmc_lockspace_nodes(char *lsname, int type, int max, int *count,
- struct dlmc_node *nodes);
-
-#define DLMC_RESULT_REGISTER 1
-#define DLMC_RESULT_NOTIFIED 2
-
-int dlmc_fs_connect(void);
-void dlmc_fs_disconnect(int fd);
-int dlmc_fs_register(int fd, char *name);
-int dlmc_fs_unregister(int fd, char *name);
-int dlmc_fs_notified(int fd, char *name, int nodeid);
-int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result);
-
-int dlmc_deadlock_check(char *name);
-
-#endif
-
diff --git a/dlm/libdlmcontrol/main.c b/dlm/libdlmcontrol/main.c
deleted file mode 100644
index a4cf500..0000000
--- a/dlm/libdlmcontrol/main.c
+++ /dev/null
@@ -1,421 +0,0 @@
-#include "clusterautoconfig.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <linux/dlmconstants.h>
-#include "dlm_controld.h"
-#include "libdlmcontrol.h"
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_connect(const char *sock_path)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-static void init_header(struct dlmc_header *h, int cmd, char *name,
- int extra_len)
-{
- memset(h, 0, sizeof(struct dlmc_header));
-
- h->magic = DLMC_MAGIC;
- h->version = DLMC_VERSION;
- h->len = sizeof(struct dlmc_header) + extra_len;
- h->command = cmd;
-
- if (name)
- strncpy(h->name, name, DLM_LOCKSPACE_LEN);
-}
-
-static char copy_buf[DLMC_DUMP_SIZE];
-
-static int do_dump(int cmd, char *name, char *buf)
-{
- struct dlmc_header h;
- int fd, rv, len;
-
- memset(copy_buf, 0, DLMC_DUMP_SIZE);
-
- init_header(&h, cmd, name, 0);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- memset(&h, 0, sizeof(h));
-
- rv = do_read(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- len = h.len - sizeof(h);
-
- if (len <= 0 || len > DLMC_DUMP_SIZE)
- goto out_close;
-
- rv = do_read(fd, copy_buf, len);
- if (rv < 0)
- goto out_close;
-
- memcpy(buf, copy_buf, len);
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_dump_debug(char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_DEBUG, NULL, buf);
-}
-
-int dlmc_dump_log_plock(char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_LOG_PLOCK, NULL, buf);
-}
-
-int dlmc_dump_plocks(char *name, char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_PLOCKS, name, buf);
-}
-
-int dlmc_node_info(char *name, int nodeid, struct dlmc_node *node)
-{
- struct dlmc_header h, *rh;
- char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_node)];
- int fd, rv;
-
- init_header(&h, DLMC_CMD_NODE_INFO, name, 0);
- h.data = nodeid;
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(node, (char *)reply + sizeof(struct dlmc_header),
- sizeof(struct dlmc_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspace_info(char *name, struct dlmc_lockspace *lockspace)
-{
- struct dlmc_header h, *rh;
- char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_lockspace)];
- int fd, rv;
-
- init_header(&h, DLMC_CMD_LOCKSPACE_INFO, name, 0);
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(lockspace, (char *)reply + sizeof(struct dlmc_header),
- sizeof(struct dlmc_lockspace));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv, result, ls_count;
-
- init_header(&h, DLMC_CMD_LOCKSPACES, NULL, 0);
- h.data = max;
-
- reply_len = sizeof(struct dlmc_header) +
- (max * sizeof(struct dlmc_lockspace));
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't usually get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- result = rh->data;
- if (result < 0 && result != -E2BIG) {
- rv = result;
- goto out_close;
- }
-
- if (result == -E2BIG) {
- *count = -E2BIG;
- ls_count = max;
- } else {
- *count = result;
- ls_count = result;
- }
- rv = 0;
-
- memcpy(lss, (char *)reply + sizeof(struct dlmc_header),
- ls_count * sizeof(struct dlmc_lockspace));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspace_nodes(char *name, int type, int max, int *count,
- struct dlmc_node *nodes)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv, result, node_count;
-
- init_header(&h, DLMC_CMD_LOCKSPACE_NODES, name, 0);
- h.option = type;
- h.data = max;
-
- reply_len = sizeof(struct dlmc_header) +
- (max * sizeof(struct dlmc_node));
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't usually get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- result = rh->data;
- if (result < 0 && result != -E2BIG) {
- rv = result;
- goto out_close;
- }
-
- if (result == -E2BIG) {
- *count = -E2BIG;
- node_count = max;
- } else {
- *count = result;
- node_count = result;
- }
- rv = 0;
-
- memcpy(nodes, (char *)reply + sizeof(struct dlmc_header),
- node_count * sizeof(struct dlmc_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_fs_connect(void)
-{
- return do_connect(DLMC_SOCK_PATH);
-}
-
-void dlmc_fs_disconnect(int fd)
-{
- close(fd);
-}
-
-int dlmc_fs_register(int fd, char *name)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_REGISTER, name, 0);
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_unregister(int fd, char *name)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_UNREGISTER, name, 0);
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_notified(int fd, char *name, int nodeid)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_NOTIFIED, name, 0);
- h.data = nodeid;
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result)
-{
- struct dlmc_header h;
- int rv;
-
- rv = do_read(fd, &h, sizeof(h));
- if (rv < 0)
- goto out;
-
- strncpy(name, h.name, DLM_LOCKSPACE_LEN);
- *nodeid = h.option;
- *result = h.data;
-
- switch (h.command) {
- case DLMC_CMD_FS_REGISTER:
- *type = DLMC_RESULT_REGISTER;
- break;
- case DLMC_CMD_FS_NOTIFIED:
- *type = DLMC_RESULT_NOTIFIED;
- break;
- default:
- *type = 0;
- }
- out:
- return rv;
-}
-
-int dlmc_deadlock_check(char *name)
-{
- struct dlmc_header h;
- int fd, rv;
-
- init_header(&h, DLMC_CMD_DEADLOCK_CHECK, name, 0);
-
- fd = do_connect(DLMC_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- close(fd);
- out:
- return rv;
-}
-
diff --git a/dlm_controld/Makefile b/dlm_controld/Makefile
index d47f71b..f643ec3 100644
--- a/dlm_controld/Makefile
+++ b/dlm_controld/Makefile
@@ -1,6 +1,16 @@
BIN_TARGET = dlm_controld
+
MAN_TARGET = dlm_controld.8
+HDR_TARGET = libdlmcontrol.h
+
+LIB_NAME = libdlmcontrol
+LIB_MAJOR = 3
+LIB_MINOR = 1
+LIB_SO = $(LIB_NAME).so
+LIB_SMAJOR = $(LIB_SO).$(LIB_MAJOR)
+LIB_TARGET = $(LIB_SO).$(LIB_MAJOR).$(LIB_MINOR)
+
BIN_SOURCE = \
action.c \
cpg.c \
@@ -35,17 +45,26 @@ BIN_CFLAGS += -D_GNU_SOURCE -g \
BIN_CFLAGS += -fPIE -DPIE
BIN_CFLAGS += `xml2-config --cflags`
-BIN_CFLAGS += -I../dlm/libdlm -I../dlm/libdlmcontrol
+BIN_CFLAGS += -I../dlm/libdlm
BIN_LDFLAGS += -Wl,-z,now -Wl,-z,relro -pie
BIN_LDFLAGS += `xml2-config --libs`
BIN_LDFLAGS += -lpthread -llogthread -lcpg -lconfdb -lcfg -lquorum -lfenced
-all: $(BIN_TARGET)
+LIB_SOURCE = lib.c
+LIB_CFLAGS += $(BIN_CFLAGS)
+LIB_LDFLAGS += -Wl,-z,relro -pie
+
+all: $(LIB_TARGET) $(BIN_TARGET)
$(BIN_TARGET): $(BIN_SOURCE)
$(CC) $(BIN_CFLAGS) $(BIN_LDFLAGS) $(BIN_SOURCE) -o $@ -L.
+$(LIB_TARGET): $(LIB_SOURCE)
+ $(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -fPIC -o $@ -Wl,-soname=$(LIB_SMAJOR) $^
+ ln -sf $(LIB_TARGET) $(LIB_SO)
+ ln -sf $(LIB_TARGET) $(LIB_SMAJOR)
+
clean:
rm -f *.o *.so *.so.* $(BIN_TARGET)
@@ -54,12 +73,19 @@ INSTALL=$(shell which install)
DESTDIR=
BINDIR=/usr/sbin
+LIBDIR=/usr/lib64
+HDRDIR=/usr/include
MANDIR=/usr/share/man
.PHONY: install
install: all
$(INSTALL) -d $(DESTDIR)/$(BINDIR)
+ $(INSTALL) -d $(DESTDIR)/$(LIBDIR)
+ $(INSTALL) -d $(DESTDIR)/$(HDRDIR)
$(INSTALL) -d $(DESTDIR)/$(MANDIR)/man8
$(INSTALL) -c -m 755 $(BIN_TARGET) $(DESTDIR)/$(BINDIR)
+ $(INSTALL) -c -m 755 $(LIB_TARGET) $(DESTDIR)/$(LIBDIR)
+ cp -a $(LIB_SO) $(DESTDIR)/$(LIBDIR)
+ $(INSTALL) -c -m 644 $(HDR_TARGET) $(DESTDIR)/$(HDRDIR)
$(INSTALL) -m 644 $(MAN_TARGET) $(DESTDIR)/$(MANDIR)/man8/
diff --git a/dlm_controld/lib.c b/dlm_controld/lib.c
new file mode 100644
index 0000000..e714ff9
--- /dev/null
+++ b/dlm_controld/lib.c
@@ -0,0 +1,419 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <linux/dlmconstants.h>
+#include "dlm_controld.h"
+#include "libdlmcontrol.h"
+
+static int do_read(int fd, void *buf, size_t count)
+{
+ int rv, off = 0;
+
+ while (off < count) {
+ rv = read(fd, (char *)buf + off, count - off);
+ if (rv == 0)
+ return -1;
+ if (rv == -1 && errno == EINTR)
+ continue;
+ if (rv == -1)
+ return -1;
+ off += rv;
+ }
+ return 0;
+}
+
+static int do_write(int fd, void *buf, size_t count)
+{
+ int rv, off = 0;
+
+ retry:
+ rv = write(fd, (char *)buf + off, count);
+ if (rv == -1 && errno == EINTR)
+ goto retry;
+ if (rv < 0) {
+ return rv;
+ }
+
+ if (rv != count) {
+ count -= rv;
+ off += rv;
+ goto retry;
+ }
+ return 0;
+}
+
+static int do_connect(const char *sock_path)
+{
+ struct sockaddr_un sun;
+ socklen_t addrlen;
+ int rv, fd;
+
+ fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ goto out;
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ strcpy(&sun.sun_path[1], sock_path);
+ addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
+
+ rv = connect(fd, (struct sockaddr *) &sun, addrlen);
+ if (rv < 0) {
+ close(fd);
+ fd = rv;
+ }
+ out:
+ return fd;
+}
+
+static void init_header(struct dlmc_header *h, int cmd, char *name,
+ int extra_len)
+{
+ memset(h, 0, sizeof(struct dlmc_header));
+
+ h->magic = DLMC_MAGIC;
+ h->version = DLMC_VERSION;
+ h->len = sizeof(struct dlmc_header) + extra_len;
+ h->command = cmd;
+
+ if (name)
+ strncpy(h->name, name, DLM_LOCKSPACE_LEN);
+}
+
+static char copy_buf[DLMC_DUMP_SIZE];
+
+static int do_dump(int cmd, char *name, char *buf)
+{
+ struct dlmc_header h;
+ int fd, rv, len;
+
+ memset(copy_buf, 0, DLMC_DUMP_SIZE);
+
+ init_header(&h, cmd, name, 0);
+
+ fd = do_connect(DLMC_QUERY_SOCK_PATH);
+ if (fd < 0) {
+ rv = fd;
+ goto out;
+ }
+
+ rv = do_write(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out_close;
+
+ memset(&h, 0, sizeof(h));
+
+ rv = do_read(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out_close;
+
+ len = h.len - sizeof(h);
+
+ if (len <= 0 || len > DLMC_DUMP_SIZE)
+ goto out_close;
+
+ rv = do_read(fd, copy_buf, len);
+ if (rv < 0)
+ goto out_close;
+
+ memcpy(buf, copy_buf, len);
+ out_close:
+ close(fd);
+ out:
+ return rv;
+}
+
+int dlmc_dump_debug(char *buf)
+{
+ return do_dump(DLMC_CMD_DUMP_DEBUG, NULL, buf);
+}
+
+int dlmc_dump_log_plock(char *buf)
+{
+ return do_dump(DLMC_CMD_DUMP_LOG_PLOCK, NULL, buf);
+}
+
+int dlmc_dump_plocks(char *name, char *buf)
+{
+ return do_dump(DLMC_CMD_DUMP_PLOCKS, name, buf);
+}
+
+int dlmc_node_info(char *name, int nodeid, struct dlmc_node *node)
+{
+ struct dlmc_header h, *rh;
+ char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_node)];
+ int fd, rv;
+
+ init_header(&h, DLMC_CMD_NODE_INFO, name, 0);
+ h.data = nodeid;
+
+ memset(reply, 0, sizeof(reply));
+
+ fd = do_connect(DLMC_QUERY_SOCK_PATH);
+ if (fd < 0) {
+ rv = fd;
+ goto out;
+ }
+
+ rv = do_write(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out_close;
+
+ rv = do_read(fd, reply, sizeof(reply));
+ if (rv < 0)
+ goto out_close;
+
+ rh = (struct dlmc_header *)reply;
+ rv = rh->data;
+ if (rv < 0)
+ goto out_close;
+
+ memcpy(node, (char *)reply + sizeof(struct dlmc_header),
+ sizeof(struct dlmc_node));
+ out_close:
+ close(fd);
+ out:
+ return rv;
+}
+
+int dlmc_lockspace_info(char *name, struct dlmc_lockspace *lockspace)
+{
+ struct dlmc_header h, *rh;
+ char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_lockspace)];
+ int fd, rv;
+
+ init_header(&h, DLMC_CMD_LOCKSPACE_INFO, name, 0);
+
+ memset(reply, 0, sizeof(reply));
+
+ fd = do_connect(DLMC_QUERY_SOCK_PATH);
+ if (fd < 0) {
+ rv = fd;
+ goto out;
+ }
+
+ rv = do_write(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out_close;
+
+ rv = do_read(fd, reply, sizeof(reply));
+ if (rv < 0)
+ goto out_close;
+
+ rh = (struct dlmc_header *)reply;
+ rv = rh->data;
+ if (rv < 0)
+ goto out_close;
+
+ memcpy(lockspace, (char *)reply + sizeof(struct dlmc_header),
+ sizeof(struct dlmc_lockspace));
+ out_close:
+ close(fd);
+ out:
+ return rv;
+}
+
+int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss)
+{
+ struct dlmc_header h, *rh;
+ char *reply;
+ int reply_len;
+ int fd, rv, result, ls_count;
+
+ init_header(&h, DLMC_CMD_LOCKSPACES, NULL, 0);
+ h.data = max;
+
+ reply_len = sizeof(struct dlmc_header) +
+ (max * sizeof(struct dlmc_lockspace));
+ reply = malloc(reply_len);
+ if (!reply) {
+ rv = -1;
+ goto out;
+ }
+ memset(reply, 0, reply_len);
+
+ fd = do_connect(DLMC_QUERY_SOCK_PATH);
+ if (fd < 0) {
+ rv = fd;
+ goto out;
+ }
+
+ rv = do_write(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out_close;
+
+ /* won't usually get back the full reply_len */
+ do_read(fd, reply, reply_len);
+
+ rh = (struct dlmc_header *)reply;
+ result = rh->data;
+ if (result < 0 && result != -E2BIG) {
+ rv = result;
+ goto out_close;
+ }
+
+ if (result == -E2BIG) {
+ *count = -E2BIG;
+ ls_count = max;
+ } else {
+ *count = result;
+ ls_count = result;
+ }
+ rv = 0;
+
+ memcpy(lss, (char *)reply + sizeof(struct dlmc_header),
+ ls_count * sizeof(struct dlmc_lockspace));
+ out_close:
+ close(fd);
+ out:
+ return rv;
+}
+
+int dlmc_lockspace_nodes(char *name, int type, int max, int *count,
+ struct dlmc_node *nodes)
+{
+ struct dlmc_header h, *rh;
+ char *reply;
+ int reply_len;
+ int fd, rv, result, node_count;
+
+ init_header(&h, DLMC_CMD_LOCKSPACE_NODES, name, 0);
+ h.option = type;
+ h.data = max;
+
+ reply_len = sizeof(struct dlmc_header) +
+ (max * sizeof(struct dlmc_node));
+ reply = malloc(reply_len);
+ if (!reply) {
+ rv = -1;
+ goto out;
+ }
+ memset(reply, 0, reply_len);
+
+ fd = do_connect(DLMC_QUERY_SOCK_PATH);
+ if (fd < 0) {
+ rv = fd;
+ goto out;
+ }
+
+ rv = do_write(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out_close;
+
+ /* won't usually get back the full reply_len */
+ do_read(fd, reply, reply_len);
+
+ rh = (struct dlmc_header *)reply;
+ result = rh->data;
+ if (result < 0 && result != -E2BIG) {
+ rv = result;
+ goto out_close;
+ }
+
+ if (result == -E2BIG) {
+ *count = -E2BIG;
+ node_count = max;
+ } else {
+ *count = result;
+ node_count = result;
+ }
+ rv = 0;
+
+ memcpy(nodes, (char *)reply + sizeof(struct dlmc_header),
+ node_count * sizeof(struct dlmc_node));
+ out_close:
+ close(fd);
+ out:
+ return rv;
+}
+
+int dlmc_fs_connect(void)
+{
+ return do_connect(DLMC_SOCK_PATH);
+}
+
+void dlmc_fs_disconnect(int fd)
+{
+ close(fd);
+}
+
+int dlmc_fs_register(int fd, char *name)
+{
+ struct dlmc_header h;
+
+ init_header(&h, DLMC_CMD_FS_REGISTER, name, 0);
+
+ return do_write(fd, &h, sizeof(h));
+}
+
+int dlmc_fs_unregister(int fd, char *name)
+{
+ struct dlmc_header h;
+
+ init_header(&h, DLMC_CMD_FS_UNREGISTER, name, 0);
+
+ return do_write(fd, &h, sizeof(h));
+}
+
+int dlmc_fs_notified(int fd, char *name, int nodeid)
+{
+ struct dlmc_header h;
+
+ init_header(&h, DLMC_CMD_FS_NOTIFIED, name, 0);
+ h.data = nodeid;
+
+ return do_write(fd, &h, sizeof(h));
+}
+
+int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result)
+{
+ struct dlmc_header h;
+ int rv;
+
+ rv = do_read(fd, &h, sizeof(h));
+ if (rv < 0)
+ goto out;
+
+ strncpy(name, h.name, DLM_LOCKSPACE_LEN);
+ *nodeid = h.option;
+ *result = h.data;
+
+ switch (h.command) {
+ case DLMC_CMD_FS_REGISTER:
+ *type = DLMC_RESULT_REGISTER;
+ break;
+ case DLMC_CMD_FS_NOTIFIED:
+ *type = DLMC_RESULT_NOTIFIED;
+ break;
+ default:
+ *type = 0;
+ }
+ out:
+ return rv;
+}
+
+int dlmc_deadlock_check(char *name)
+{
+ struct dlmc_header h;
+ int fd, rv;
+
+ init_header(&h, DLMC_CMD_DEADLOCK_CHECK, name, 0);
+
+ fd = do_connect(DLMC_SOCK_PATH);
+ if (fd < 0) {
+ rv = fd;
+ goto out;
+ }
+
+ rv = do_write(fd, &h, sizeof(h));
+ close(fd);
+ out:
+ return rv;
+}
+
diff --git a/dlm_controld/libdlmcontrol.h b/dlm_controld/libdlmcontrol.h
new file mode 100644
index 0000000..64a3814
--- /dev/null
+++ b/dlm_controld/libdlmcontrol.h
@@ -0,0 +1,90 @@
+#ifndef _LIBDLMCONTROL_H_
+#define _LIBDLMCONTROL_H_
+
+#define DLMC_DUMP_SIZE (1024 * 1024)
+
+#define DLMC_NF_MEMBER 0x00000001 /* node is member in cg */
+#define DLMC_NF_START 0x00000002 /* start message recvd for cg */
+#define DLMC_NF_DISALLOWED 0x00000004 /* node disallowed in cg */
+#define DLMC_NF_CHECK_FENCING 0x00000008
+#define DLMC_NF_CHECK_QUORUM 0x00000010
+#define DLMC_NF_CHECK_FS 0x00000020
+
+struct dlmc_node {
+ int nodeid;
+ uint32_t flags;
+ uint32_t added_seq;
+ uint32_t removed_seq;
+ int failed_reason;
+};
+
+struct dlmc_change {
+ int member_count;
+ int joined_count;
+ int remove_count;
+ int failed_count;
+ int wait_condition; /* 0 no, 1 fencing, 2 quorum, 3 fs */
+ int wait_messages; /* 0 no, 1 yes */
+ uint32_t seq;
+ uint32_t combined_seq;
+};
+
+#define DLMC_LF_JOINING 0x00000001
+#define DLMC_LF_LEAVING 0x00000002
+#define DLMC_LF_KERNEL_STOPPED 0x00000004
+#define DLMC_LF_FS_REGISTERED 0x00000008
+#define DLMC_LF_NEED_PLOCKS 0x00000010
+#define DLMC_LF_SAVE_PLOCKS 0x00000020
+
+struct dlmc_lockspace {
+ int group_mode;
+ struct dlmc_change cg_prev; /* completed change (started_change) */
+ struct dlmc_change cg_next; /* in-progress change (changes list) */
+ uint32_t flags;
+ uint32_t global_id;
+ char name[DLM_LOCKSPACE_LEN+1];
+};
+
+/* dlmc_lockspace_nodes() types
+
+ MEMBERS: members in completed (prev) change,
+ zero if there's no completed (prev) change
+ NEXT: members in in-progress (next) change,
+ zero if there's no in-progress (next) change
+ ALL: NEXT + nonmembers if there's an in-progress (next) change,
+ MEMBERS + nonmembers if there's no in-progress (next) change, but
+ there is a completed (prev) change
+ nonmembers if there's no in-progress (next) or completed (prev)
+ change (possible?)
+
+ dlmc_node_info() returns info for in-progress (next) change, if one exists,
+ otherwise it returns info for completed (prev) change.
+*/
+
+#define DLMC_NODES_ALL 1
+#define DLMC_NODES_MEMBERS 2
+#define DLMC_NODES_NEXT 3
+
+int dlmc_dump_debug(char *buf);
+int dlmc_dump_log_plock(char *buf);
+int dlmc_dump_plocks(char *name, char *buf);
+int dlmc_lockspace_info(char *lsname, struct dlmc_lockspace *ls);
+int dlmc_node_info(char *lsname, int nodeid, struct dlmc_node *node);
+int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss);
+int dlmc_lockspace_nodes(char *lsname, int type, int max, int *count,
+ struct dlmc_node *nodes);
+
+#define DLMC_RESULT_REGISTER 1
+#define DLMC_RESULT_NOTIFIED 2
+
+int dlmc_fs_connect(void);
+void dlmc_fs_disconnect(int fd);
+int dlmc_fs_register(int fd, char *name);
+int dlmc_fs_unregister(int fd, char *name);
+int dlmc_fs_notified(int fd, char *name, int nodeid);
+int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result);
+
+int dlmc_deadlock_check(char *name);
+
+#endif
+