src/client.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
src/cmd.c | 24 +++++++++++++++---
src/lockspace.c | 47 +++++++++++++++++++++++++++++++++++
src/lockspace.h | 1
src/main.c | 56 +++++++++++++++++++++++++++++++++++++++++-
src/sanlock.8 | 8 +++++-
src/sanlock_admin.h | 18 +++++++++++++
src/sanlock_internal.h | 1
src/sanlock_sock.h | 1
9 files changed, 216 insertions(+), 5 deletions(-)
New commits:
commit 5ea36dff88fa2eddb66c81985f0ab3cc34c74b1a
Author: David Teigland <teigland(a)redhat.com>
Date: Wed Nov 28 14:46:00 2012 -0600
sanlock: new get_lockspaces api
returns a copy of all lockspaces from the daemon
in an array of sanlk_lockspace structs.
example and test by new command,
sanlock gets
s lockspace1:1:/dev/vg/leases1:0
s lockspace0:1:/dev/vg/leases0:0 ADD
Signed-off-by: David Teigland <teigland(a)redhat.com>
diff --git a/src/client.c b/src/client.c
index ae73226..5b4d81b 100644
--- a/src/client.c
+++ b/src/client.c
@@ -163,6 +163,71 @@ int sanlock_rem_lockspace(struct sanlk_lockspace *ls, uint32_t
flags)
return cmd_lockspace(SM_CMD_REM_LOCKSPACE, ls, flags, 0);
}
+int sanlock_get_lockspaces(struct sanlk_lockspace *lss, int lss_size,
+ int *lss_count, uint32_t flags)
+{
+ struct sanlk_lockspace *ls;
+ struct sm_header h;
+ int rv, fd, i, ret, recv_count;
+
+ rv = connect_socket(&fd);
+ if (rv < 0)
+ return rv;
+
+ rv = send_header(fd, SM_CMD_GET_LOCKSPACES, flags, 0, 0, 0);
+ if (rv < 0)
+ goto out;
+
+ /* receive result and ls structs */
+
+ memset(&h, 0, sizeof(struct sm_header));
+
+ rv = recv(fd, &h, sizeof(h), MSG_WAITALL);
+ if (rv < 0) {
+ rv = -errno;
+ goto out;
+ }
+
+ if (rv != sizeof(h)) {
+ rv = -1;
+ goto out;
+ }
+
+ /* -ENOSPC means that the daemon's send buffer ran out of space */
+
+ rv = (int)h.data;
+ if (rv < 0 && rv != -ENOSPC)
+ goto out;
+
+ *lss_count = h.data2;
+ recv_count = h.data2;
+
+ if (recv_count * sizeof(struct sanlk_lockspace) > lss_size) {
+ recv_count = lss_size / sizeof(struct sanlk_lockspace);
+ rv = -ENOBUFS;
+ }
+
+ ls = lss;
+
+ for (i = 0; i < recv_count; i++) {
+ ret = recv(fd, ls, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ if (ret < 0) {
+ rv = -errno;
+ goto out;
+ }
+
+ if (ret != sizeof(struct sanlk_lockspace)) {
+ rv = -1;
+ goto out;
+ }
+
+ ls++;
+ }
+ out:
+ close(fd);
+ return rv;
+}
+
int sanlock_align(struct sanlk_disk *disk)
{
int rv, fd;
diff --git a/src/cmd.c b/src/cmd.c
index 18b9db0..6f9310f 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1896,18 +1896,32 @@ static void cmd_host_status(int fd, struct sm_header *h_recv)
free(status);
}
-static char send_log_dump[LOG_DUMP_SIZE];
+static char send_data_buf[LOG_DUMP_SIZE];
static void cmd_log_dump(int fd, struct sm_header *h_recv)
{
int len;
- copy_log_dump(send_log_dump, &len);
+ copy_log_dump(send_data_buf, &len);
h_recv->data = len;
send(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
- send(fd, send_log_dump, len, MSG_NOSIGNAL);
+ send(fd, send_data_buf, len, MSG_NOSIGNAL);
+}
+
+static void cmd_get_lockspaces(int fd, struct sm_header *h_recv)
+{
+ int count, len, rv;
+
+ rv = get_lockspaces(send_data_buf, &len, &count, LOG_DUMP_SIZE);
+
+ h_recv->length = sizeof(struct sm_header) + len;
+ h_recv->data = rv;
+ h_recv->data2 = count;
+
+ send(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send(fd, send_data_buf, len, MSG_NOSIGNAL);
}
static void cmd_restrict(int ci, int fd, struct sm_header *h_recv)
@@ -1982,6 +1996,10 @@ void call_cmd_daemon(int ci, struct sm_header *h_recv, int
client_maxi)
strcpy(client[ci].owner_name, "log_dump");
cmd_log_dump(fd, h_recv);
break;
+ case SM_CMD_GET_LOCKSPACES:
+ strcpy(client[ci].owner_name, "get_lockspaces");
+ cmd_get_lockspaces(fd, h_recv);
+ break;
};
if (auto_close)
diff --git a/src/lockspace.c b/src/lockspace.c
index 8e05fa5..2940549 100644
--- a/src/lockspace.c
+++ b/src/lockspace.c
@@ -24,6 +24,7 @@
#include <sys/un.h>
#include "sanlock_internal.h"
+#include "sanlock_admin.h"
#include "sanlock_sock.h"
#include "diskio.h"
#include "log.h"
@@ -859,6 +860,52 @@ int rem_lockspace_wait(struct sanlk_lockspace *ls, unsigned int
space_id)
return 0;
}
+int get_lockspaces(char *buf, int *len, int *count, int maxlen)
+{
+ struct sanlk_lockspace *ls;
+ struct space *sp;
+ struct list_head *heads[] = {&spaces, &spaces_rem, &spaces_add};
+ int i, rv, sp_count = 0;
+
+ rv = 0;
+ *len = 0;
+ *count = 0;
+ ls = (struct sanlk_lockspace *)buf;
+
+ pthread_mutex_lock(&spaces_mutex);
+ for (i = 0; i < 3; i++) {
+ list_for_each_entry(sp, heads[i], list) {
+ sp_count++;
+
+ if (*len + sizeof(struct sanlk_lockspace) > maxlen) {
+ rv = -ENOSPC;
+ continue;
+ }
+
+ memcpy(ls->name, sp->space_name, NAME_ID_SIZE);
+ memcpy(&ls->host_id_disk, &sp->host_id_disk, sizeof(struct sync_disk));
+ ls->host_id_disk.pad1 = 0;
+ ls->host_id_disk.pad2 = 0;
+ ls->host_id = sp->host_id;
+ ls->flags = 0;
+
+ if (i == 1)
+ ls->flags |= SANLK_LSF_REM;
+ else if (i == 2)
+ ls->flags |= SANLK_LSF_ADD;
+
+ *len += sizeof(struct sanlk_lockspace);
+
+ ls++;
+ }
+ }
+ pthread_mutex_unlock(&spaces_mutex);
+
+ *count = sp_count;
+
+ return rv;
+}
+
/*
* we call stop_host_id() when all pids are gone and we're in a safe state, so
* it's safe to unlink the watchdog right away here. We want to sp the unlink
diff --git a/src/lockspace.h b/src/lockspace.h
index dc1099d..47ce5ba 100644
--- a/src/lockspace.h
+++ b/src/lockspace.h
@@ -25,5 +25,6 @@ int inq_lockspace(struct sanlk_lockspace *ls);
int rem_lockspace_start(struct sanlk_lockspace *ls, unsigned int *space_id);
int rem_lockspace_wait(struct sanlk_lockspace *ls, unsigned int space_id);
void free_lockspaces(int wait);
+int get_lockspaces(char *buf, int *len, int *count, int maxlen);
#endif
diff --git a/src/main.c b/src/main.c
index 37b20db..0291e22 100644
--- a/src/main.c
+++ b/src/main.c
@@ -54,6 +54,8 @@
#include "helper.h"
#include "timeouts.h"
+#define ONEMB 1048576
+
#define SIGRUNPATH 100 /* anything that's not SIGTERM/SIGKILL */
struct thread_pool {
@@ -1148,6 +1150,7 @@ static void process_connection(int ci)
case SM_CMD_STATUS:
case SM_CMD_HOST_STATUS:
case SM_CMD_LOG_DUMP:
+ case SM_CMD_GET_LOCKSPACES:
call_cmd_daemon(ci, &h, client_maxi);
break;
case SM_CMD_ADD_LOCKSPACE:
@@ -1777,6 +1780,7 @@ static void print_usage(void)
printf("\n");
printf("sanlock client <action> [options]\n");
printf("sanlock client status [-D] [-o p|s]\n");
+ printf("sanlock client gets\n");
printf("sanlock client host_status -s LOCKSPACE [-D]\n");
printf("sanlock client log_dump\n");
printf("sanlock client shutdown [-f 0|1]\n");
@@ -1879,6 +1883,8 @@ static int read_command_line(int argc, char *argv[])
com.action = ACT_STATUS;
else if (!strcmp(act, "host_status"))
com.action = ACT_HOST_STATUS;
+ else if (!strcmp(act, "gets"))
+ com.action = ACT_GETS;
else if (!strcmp(act, "log_dump"))
com.action = ACT_LOG_DUMP;
else if (!strcmp(act, "shutdown"))
@@ -2119,14 +2125,33 @@ static int read_command_line(int argc, char *argv[])
return 0;
}
+/* only used by do_client */
+static char *lsf_to_str(uint32_t flags)
+{
+ static char lsf_str[16];
+
+ memset(lsf_str, 0, 16);
+
+ if (flags & SANLK_LSF_ADD)
+ strcat(lsf_str, "ADD ");
+
+ if (flags & SANLK_LSF_REM)
+ strcat(lsf_str, "REM ");
+
+ return lsf_str;
+}
+
static int do_client(void)
{
struct sanlk_resource **res_args = NULL;
struct sanlk_resource *res;
+ struct sanlk_lockspace *ls;
char *res_state = NULL;
char *res_str = NULL;
+ char *buf;
uint32_t io_timeout = 0;
- int i, fd, rv = 0;
+ int i, fd, count;
+ int rv = 0;
if (com.action == ACT_COMMAND || com.action == ACT_ACQUIRE) {
if (com.num_hosts) {
@@ -2147,6 +2172,35 @@ static int do_client(void)
rv = sanlock_host_status(com.debug, com.lockspace.name);
break;
+ case ACT_GETS:
+ buf = malloc(ONEMB);
+ if (!buf)
+ break;
+ memset(buf, 0, ONEMB);
+ ls = (struct sanlk_lockspace *)buf;
+
+ rv = sanlock_get_lockspaces(ls, ONEMB, &count, 0);
+ if (rv < 0)
+ log_tool("gets error %d", rv);
+
+ if (rv < 0 && rv != -ENOBUFS && rv != -ENOSPC) {
+ free(buf);
+ break;
+ }
+
+ for (i = 0; i < count; i++) {
+ log_tool("s %.48s:%llu:%s:%llu %s",
+ ls->name,
+ (unsigned long long)ls->host_id,
+ ls->host_id_disk.path,
+ (unsigned long long)ls->host_id_disk.offset,
+ !ls->flags ? "" : lsf_to_str(ls->flags));
+ ls++;
+ }
+
+ free(buf);
+ break;
+
case ACT_LOG_DUMP:
rv = sanlock_log_dump(LOG_DUMP_SIZE);
break;
diff --git a/src/sanlock.8 b/src/sanlock.8
index 59ef392..dca5db8 100644
--- a/src/sanlock.8
+++ b/src/sanlock.8
@@ -248,7 +248,7 @@ use async i/o
.B sanlock client status
-Print processes, lockspaces, and resources being manged by the sanlock
+Print processes, lockspaces, and resources being managed by the sanlock
daemon. Add -D to show extra internal daemon status for debugging.
Add -o p to show resources by pid, or -o s to show resources by lockspace.
@@ -258,6 +258,12 @@ Print state of host_id delta leases read during the last renewal.
State of all lockspaces is shown (use -s to select one).
Add -D to show extra internal daemon status for debugging.
+.B sanlock client gets
+
+Print lockspaces being managed by the sanlock daemon. The LOCKSPACE
+string will be followed by ADD or REM if the lockspace is currently being
+added or removed.
+
.B sanlock client log_dump
Print the sanlock daemon internal debug log.
diff --git a/src/sanlock_admin.h b/src/sanlock_admin.h
index 14b1e7a..dadd034 100644
--- a/src/sanlock_admin.h
+++ b/src/sanlock_admin.h
@@ -20,6 +20,10 @@
/* inq flags */
#define SANLK_INQ_WAIT 0x00000001
+/* sanlk_lockspace.flags returned by get */
+#define SANLK_LSF_ADD 0x00000001
+#define SANLK_LSF_REM 0x00000002
+
/*
* add_lockspace returns:
* 0: the lockspace has been added successfully
@@ -59,6 +63,20 @@ int sanlock_inq_lockspace(struct sanlk_lockspace *ls, uint32_t flags);
int sanlock_rem_lockspace(struct sanlk_lockspace *ls, uint32_t flags);
/*
+ * get_lockspace returns:
+ * 0: all lockspaces copied out, lss_count set to number
+ * -ENOSPC: sanlock internal buffer ran out of space
+ * (lss_count set to number that would have been copied)
+ * -ENOBUFS: lss_size too small
+ * (lss_count set to number that would have been copied)
+ *
+ * sanlk_lockspace.flags set to SANLK_LSF_
+ */
+
+int sanlock_get_lockspaces(struct sanlk_lockspace *lss, int lss_size,
+ int *lss_count, uint32_t flags);
+
+/*
* Returns the alignment in bytes required by sanlock_init()
* (1MB for disks with 512 sectors, 8MB for disks with 4096 sectors)
*/
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h
index 414ceb8..6deef0e 100644
--- a/src/sanlock_internal.h
+++ b/src/sanlock_internal.h
@@ -312,6 +312,7 @@ enum {
ACT_CLIENT_READ,
ACT_CLIENT_ALIGN,
ACT_EXAMINE,
+ ACT_GETS,
};
EXTERN int external_shutdown;
diff --git a/src/sanlock_sock.h b/src/sanlock_sock.h
index fbabbb2..bbffa7d 100644
--- a/src/sanlock_sock.h
+++ b/src/sanlock_sock.h
@@ -39,6 +39,7 @@ enum {
SM_CMD_WRITE_RESOURCE = 19,
SM_CMD_READ_LOCKSPACE = 20,
SM_CMD_READ_RESOURCE = 21,
+ SM_CMD_GET_LOCKSPACES = 22,
};
struct sm_header {