src/client_cmd.c | 336 +++++++++++++++++++++++++++++++++++++++++--------
src/client_cmd.h | 2
src/main.c | 32 +++-
src/sanlock.8 | 1
src/sanlock_internal.h | 1
5 files changed, 311 insertions(+), 61 deletions(-)
New commits:
commit 758e7c83b6bdd3e8a8203de6b541c38385ad9196
Author: David Teigland <teigland(a)redhat.com>
Date: Tue Sep 13 11:39:23 2011 -0500
sanlock: status output sorting
-o p|s to sort resources by pid/lockspace.
Also fix host_status bug when -s not found.
diff --git a/src/client_cmd.c b/src/client_cmd.c
index 73404bf..119149f 100644
--- a/src/client_cmd.c
+++ b/src/client_cmd.c
@@ -56,16 +56,15 @@ static void print_debug(char *str, int len)
printf(" %s\n", p);
}
-static void status_daemon(int fd GNUC_UNUSED, struct sanlk_state *st, char *str, int
debug)
+static void status_daemon(struct sanlk_state *st, char *str, int debug)
{
printf("daemon %.48s\n", st->name);
- if (st->str_len && debug) {
+ if (st->str_len && debug)
print_debug(str, st->str_len);
- }
}
-static void status_client(int fd GNUC_UNUSED, struct sanlk_state *st, char *str, int
debug)
+static void status_client(struct sanlk_state *st, char *str, int debug)
{
printf("p %d ", st->data32);
printf("%.48s\n", st->name);
@@ -74,38 +73,33 @@ static void status_client(int fd GNUC_UNUSED, struct sanlk_state *st,
char *str,
print_debug(str, st->str_len);
}
-static void status_lockspace(int fd, struct sanlk_state *st, char *str, int debug)
+static void status_lockspace(struct sanlk_state *st, char *str, char *bin, int debug)
{
- struct sanlk_lockspace lockspace;
- int rv;
-
- rv = recv(fd, &lockspace, sizeof(lockspace), MSG_WAITALL);
+ struct sanlk_lockspace *ls = (struct sanlk_lockspace *)bin;
printf("s %.48s:%llu:%s:%llu\n",
- lockspace.name,
- (unsigned long long)lockspace.host_id,
- lockspace.host_id_disk.path,
- (unsigned long long)lockspace.host_id_disk.offset);
+ ls->name,
+ (unsigned long long)ls->host_id,
+ ls->host_id_disk.path,
+ (unsigned long long)ls->host_id_disk.offset);
if (st->str_len && debug)
print_debug(str, st->str_len);
}
-static void status_resource(int fd, struct sanlk_state *st, char *str, int debug)
+static void status_resource(struct sanlk_state *st, char *str, char *bin, int debug)
{
- struct sanlk_resource resource;
- struct sanlk_disk disk;
- int i, rv;
-
- rv = recv(fd, &resource, sizeof(resource), MSG_WAITALL);
+ struct sanlk_resource *res = (struct sanlk_resource *)bin;
+ struct sanlk_disk *disk;
+ int i;
- printf("r %.48s:%.48s", resource.lockspace_name, resource.name);
+ printf("r %.48s:%.48s", res->lockspace_name, res->name);
- for (i = 0; i < resource.num_disks; i++) {
- rv = recv(fd, &disk, sizeof(disk), MSG_WAITALL);
+ for (i = 0; i < res->num_disks; i++) {
+ disk = (struct sanlk_disk *)(bin + sizeof(struct sanlk_resource) + i * sizeof(struct
sanlk_disk));
printf(":%s:%llu",
- disk.path, (unsigned long long)disk.offset);
+ disk->path, (unsigned long long)disk->offset);
}
printf(":%llu p %u\n", (unsigned long long)st->data64, st->data32);
@@ -113,7 +107,7 @@ static void status_resource(int fd, struct sanlk_state *st, char *str,
int debug
print_debug(str, st->str_len);
}
-static void status_host(int fd GNUC_UNUSED, struct sanlk_state *st, char *str, int
debug)
+static void status_host(struct sanlk_state *st, char *str, int debug)
{
printf("%u timestamp %llu\n", st->data32,
(unsigned long long)st->data64);
@@ -122,12 +116,213 @@ static void status_host(int fd GNUC_UNUSED, struct sanlk_state *st,
char *str, i
print_debug(str, st->str_len);
}
-int sanlock_status(int debug)
+static void print_st(struct sanlk_state *st, char *str, char *bin, int debug)
+{
+ switch (st->type) {
+ case SANLK_STATE_DAEMON:
+ status_daemon(st, str, debug);
+ break;
+ case SANLK_STATE_CLIENT:
+ status_client(st, str, debug);
+ break;
+ case SANLK_STATE_LOCKSPACE:
+ status_lockspace(st, str, bin, debug);
+ break;
+ case SANLK_STATE_RESOURCE:
+ status_resource(st, str, bin, debug);
+ break;
+ }
+}
+
+#define MAX_SORT_ENTRIES 1024
+static char *sort_bufs[MAX_SORT_ENTRIES];
+static int sort_count;
+static int sort_done;
+
+static void print_type(int type, int debug)
+{
+ struct sanlk_state *st;
+ char *buf, *str, *bin;
+ int i;
+
+ for (i = 0; i < sort_count; i++) {
+ buf = sort_bufs[i];
+ if (!buf)
+ continue;
+ st = (struct sanlk_state *)buf;
+ str = buf + sizeof(struct sanlk_state);
+ bin = buf + sizeof(struct sanlk_state) + SANLK_STATE_MAXSTR;
+
+ if (!type || st->type == type) {
+ print_st(st, str, bin, debug);
+ free(buf);
+ sort_bufs[i] = NULL;
+ sort_done++;
+ }
+ }
+}
+
+static void print_p(int p, int debug)
+{
+ struct sanlk_state *st;
+ char *buf, *str, *bin;
+ int i;
+
+ for (i = 0; i < sort_count; i++) {
+ buf = sort_bufs[i];
+ if (!buf)
+ continue;
+ st = (struct sanlk_state *)buf;
+ str = buf + sizeof(struct sanlk_state);
+ bin = buf + sizeof(struct sanlk_state) + SANLK_STATE_MAXSTR;
+
+ if (st->type != SANLK_STATE_CLIENT)
+ continue;
+
+ if (st->data32 == p) {
+ print_st(st, str, bin, debug);
+ free(buf);
+ sort_bufs[i] = NULL;
+ sort_done++;
+ }
+ }
+}
+
+static int find_type(int type, int *sort_index)
+{
+ struct sanlk_state *st;
+ char *buf;
+ int i;
+
+ for (i = 0; i < sort_count; i++) {
+ buf = sort_bufs[i];
+ if (!buf)
+ continue;
+ st = (struct sanlk_state *)buf;
+
+ if (st->type == type) {
+ *sort_index = i;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static void print_r(int p, char *s, int debug)
+{
+ struct sanlk_resource *res;
+ struct sanlk_state *st;
+ char *buf, *str, *bin;
+ int i;
+
+ for (i = 0; i < sort_count; i++) {
+ buf = sort_bufs[i];
+ if (!buf)
+ continue;
+ st = (struct sanlk_state *)buf;
+ str = buf + sizeof(struct sanlk_state);
+ bin = buf + sizeof(struct sanlk_state) + SANLK_STATE_MAXSTR;
+
+ if (st->type != SANLK_STATE_RESOURCE)
+ continue;
+
+ res = (struct sanlk_resource *)bin;
+
+ if ((p && st->data32 == p) ||
+ (s && !strncmp(s, res->lockspace_name, SANLK_NAME_LEN))) {
+ print_st(st, str, bin, debug);
+ free(buf);
+ sort_bufs[i] = NULL;
+ sort_done++;
+ }
+ }
+}
+
+static void print_r_by_p(int debug)
+{
+ struct sanlk_state *st;
+ char *buf, *str, *bin;
+ int rv, i;
+
+ while (1) {
+ rv = find_type(SANLK_STATE_CLIENT, &i);
+ if (rv < 0)
+ return;
+
+ buf = sort_bufs[i];
+ st = (struct sanlk_state *)buf;
+ str = buf + sizeof(struct sanlk_state);
+ bin = buf + sizeof(struct sanlk_state) + SANLK_STATE_MAXSTR;
+
+ print_st(st, str, bin, debug);
+
+ print_r(st->data32, NULL, debug);
+
+ free(buf);
+ sort_bufs[i] = NULL;
+ sort_done++;
+ }
+}
+
+static void print_r_by_s(int debug)
+{
+ struct sanlk_state *st;
+ char *buf, *str, *bin;
+ int rv, i;
+
+ while (1) {
+ rv = find_type(SANLK_STATE_LOCKSPACE, &i);
+ if (rv < 0)
+ return;
+
+ buf = sort_bufs[i];
+ st = (struct sanlk_state *)buf;
+ str = buf + sizeof(struct sanlk_state);
+ bin = buf + sizeof(struct sanlk_state) + SANLK_STATE_MAXSTR;
+
+ print_st(st, str, bin, debug);
+
+ print_r(0, st->name, debug);
+
+ free(buf);
+ sort_bufs[i] = NULL;
+ sort_done++;
+ }
+}
+
+static void recv_bin(int fd, struct sanlk_state *st, char *bin)
+{
+ struct sanlk_resource *res;
+
+ if (st->type == SANLK_STATE_LOCKSPACE) {
+ recv(fd, bin, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+
+ } else if (st->type == SANLK_STATE_RESOURCE) {
+ recv(fd, bin, sizeof(struct sanlk_resource), MSG_WAITALL);
+
+ res = (struct sanlk_resource *)bin;
+
+ recv(fd, bin+sizeof(struct sanlk_resource),
+ res->num_disks * sizeof(struct sanlk_disk),
+ MSG_WAITALL);
+ }
+}
+
+int sanlock_status(int debug, char sort_arg)
{
struct sm_header h;
- struct sanlk_state st;
- char str[SANLK_STATE_MAXSTR];
- int fd, rv;
+ struct sanlk_state state;
+ char maxstr[SANLK_STATE_MAXSTR];
+ char maxbin[SANLK_STATE_MAXSTR];
+ struct sanlk_state *st;
+ char *buf, *str, *bin;
+ int fd, rv, len;
+ int sort_p = 0, sort_s = 0;
+
+ if (sort_arg == 'p')
+ sort_p = 1;
+ else if (sort_arg == 's')
+ sort_s = 1;
fd = send_command(SM_CMD_STATUS, 0);
if (fd < 0)
@@ -143,34 +338,74 @@ int sanlock_status(int debug)
goto out;
}
+ st = &state;
+ str = maxstr;
+ bin = maxbin;
+
while (1) {
- rv = recv(fd, &st, sizeof(st), MSG_WAITALL);
+ if (sort_p || sort_s) {
+ len = sizeof(struct sanlk_state) + SANLK_STATE_MAXSTR*4;
+ buf = malloc(len);
+ if (!buf)
+ return -ENOMEM;
+ memset(buf, 0, len);
+ st = (struct sanlk_state *)buf;
+ str = buf + sizeof(struct sanlk_state);
+ bin = buf + sizeof(struct sanlk_state) + SANLK_STATE_MAXSTR;
+ } else {
+ memset(&state, 0, sizeof(state));
+ memset(maxstr, 0, sizeof(maxstr));
+ memset(maxbin, 0, sizeof(maxbin));
+ }
+
+ rv = recv(fd, st, sizeof(struct sanlk_state), MSG_WAITALL);
if (!rv)
break;
- if (rv != sizeof(st))
+ if (rv != sizeof(struct sanlk_state))
break;
- if (st.str_len) {
- rv = recv(fd, str, st.str_len, MSG_WAITALL);
- if (rv != st.str_len)
+ if (st->str_len) {
+ rv = recv(fd, str, st->str_len, MSG_WAITALL);
+ if (rv != st->str_len)
break;
}
- switch (st.type) {
- case SANLK_STATE_DAEMON:
- status_daemon(fd, &st, str, debug);
- break;
- case SANLK_STATE_CLIENT:
- status_client(fd, &st, str, debug);
- break;
- case SANLK_STATE_LOCKSPACE:
- status_lockspace(fd, &st, str, debug);
- break;
- case SANLK_STATE_RESOURCE:
- status_resource(fd, &st, str, debug);
- break;
+ recv_bin(fd, st, bin);
+
+ if (sort_p || sort_s) {
+ if (sort_count == MAX_SORT_ENTRIES) {
+ printf("cannot sort over %d\n", MAX_SORT_ENTRIES);
+ goto out;
+ }
+ sort_bufs[sort_count++] = buf;
+ continue;
}
+
+ /* no sorting, print as received */
+
+ print_st(st, str, bin, debug);
}
+
+ if (sort_p) {
+ print_type(SANLK_STATE_DAEMON, debug);
+ print_p(-1, debug);
+ print_type(SANLK_STATE_LOCKSPACE, debug);
+ print_r_by_p(debug);
+ if (sort_done < sort_count) {
+ printf("-\n");
+ print_type(0, debug);
+ }
+ } else if (sort_s) {
+ print_type(SANLK_STATE_DAEMON, debug);
+ print_p(-1, debug);
+ print_type(SANLK_STATE_CLIENT, debug);
+ print_r_by_s(debug);
+ if (sort_done < sort_count) {
+ printf("-\n");
+ print_type(0, debug);
+ }
+ }
+
rv = 0;
out:
close(fd);
@@ -224,12 +459,12 @@ int sanlock_host_status(int debug, char *lockspace_name)
switch (st.type) {
case SANLK_STATE_HOST:
- status_host(fd, &st, str, debug);
+ status_host(&st, str, debug);
break;
}
}
- rv = 0;
+ rv = h.data;
out:
close(fd);
return rv;
diff --git a/src/client_cmd.h b/src/client_cmd.h
index 3599659..dceb7ca 100644
--- a/src/client_cmd.h
+++ b/src/client_cmd.h
@@ -9,7 +9,7 @@
#ifndef __CLIENT_CMD_H__
#define __CLIENT_CMD_H__
-int sanlock_status(int debug);
+int sanlock_status(int debug, char sort_arg);
int sanlock_host_status(int debug, char *lockspace_name);
int sanlock_log_dump(void);
int sanlock_shutdown(void);
diff --git a/src/main.c b/src/main.c
index 5b7477d..d3d0c4f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2027,7 +2027,7 @@ static int print_state_resource(struct resource *r, char *str, const
char *list_
"list=%s "
"flags=%x "
"lver=%llu "
- "token_id=%u ",
+ "token_id=%u",
list_name,
r->flags,
(unsigned long long)r->lver,
@@ -2046,7 +2046,7 @@ static int print_state_host(struct host_status *hs, char *str)
"last_req=%llu "
"owner_id=%llu "
"owner_generation=%llu "
- "timestamp=%llu ",
+ "timestamp=%llu",
(unsigned long long)hs->last_check,
(unsigned long long)hs->last_live,
(unsigned long long)hs->last_req,
@@ -2255,13 +2255,19 @@ static void cmd_host_status(int fd, struct sm_header *h_recv)
goto fail;
}
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
-
pthread_mutex_lock(&spaces_mutex);
sp = find_lockspace(lockspace.name);
- memcpy(status, &sp->host_status, status_len);
+ if (sp)
+ memcpy(status, &sp->host_status, status_len);
pthread_mutex_unlock(&spaces_mutex);
+ if (!sp) {
+ h.data = -ENOSPC;
+ goto fail;
+ }
+
+ send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+
for (i = 0; i < DEFAULT_MAX_HOSTS; i++) {
hs = &status[i];
if (!hs->last_live && !hs->owner_id)
@@ -3007,7 +3013,7 @@ static void print_usage(void)
printf(" -o 0|1 io timeout in seconds (%d)\n", DEFAULT_IO_TIMEOUT);
printf("\n");
printf("sanlock client <action> [options]\n");
- printf("sanlock client status [-D]\n");
+ printf("sanlock client status [-D] [-o p|s]\n");
printf("sanlock client host_status -s LOCKSPACE [-D]\n");
printf("sanlock client log_dump\n");
printf("sanlock client shutdown\n");
@@ -3231,9 +3237,13 @@ static int read_command_line(int argc, char *argv[])
com.high_priority = atoi(optionarg);
break;
case 'o':
- com.io_timeout_arg = atoi(optionarg);
- if (!com.io_timeout_arg)
- com.io_timeout_arg = DEFAULT_IO_TIMEOUT;
+ if (com.action == ACT_STATUS) {
+ com.sort_arg = *optionarg;
+ } else {
+ com.io_timeout_arg = atoi(optionarg);
+ if (!com.io_timeout_arg)
+ com.io_timeout_arg = DEFAULT_IO_TIMEOUT;
+ }
break;
case 'n':
com.num_hosts = atoi(optionarg);
@@ -3344,7 +3354,7 @@ static int do_client(void)
switch (com.action) {
case ACT_STATUS:
- rv = sanlock_status(com.debug);
+ rv = sanlock_status(com.debug, com.sort_arg);
break;
case ACT_HOST_STATUS:
diff --git a/src/sanlock.8 b/src/sanlock.8
index 4462280..891ab86 100644
--- a/src/sanlock.8
+++ b/src/sanlock.8
@@ -247,6 +247,7 @@ io timeout in seconds
Print processes, lockspaces, and resources being manged 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.
.BR "sanlock client host_status -s" " LOCKSPACE"
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h
index 2621317..0b39934 100644
--- a/src/sanlock_internal.h
+++ b/src/sanlock_internal.h
@@ -492,6 +492,7 @@ struct command_line {
int uid; /* -U */
int gid; /* -G */
int pid; /* -p */
+ char sort_arg;
uint64_t local_host_id; /* -i */
uint64_t local_host_generation; /* -g */
int num_hosts; /* -n */
commit ad80edea0471fc32221da1d2610d3197f9e31275
Author: David Teigland <teigland(a)redhat.com>
Date: Mon Sep 12 14:26:58 2011 -0500
sanlock: improve status output
diff --git a/src/client_cmd.c b/src/client_cmd.c
index a3949d1..73404bf 100644
--- a/src/client_cmd.c
+++ b/src/client_cmd.c
@@ -58,15 +58,16 @@ static void print_debug(char *str, int len)
static void status_daemon(int fd GNUC_UNUSED, struct sanlk_state *st, char *str, int
debug)
{
- printf("daemon\n");
+ printf("daemon %.48s\n", st->name);
- if (st->str_len && debug)
+ if (st->str_len && debug) {
print_debug(str, st->str_len);
+ }
}
static void status_client(int fd GNUC_UNUSED, struct sanlk_state *st, char *str, int
debug)
{
- printf("pid %d ", st->data32);
+ printf("p %d ", st->data32);
printf("%.48s\n", st->name);
if (st->str_len && debug)
@@ -80,7 +81,7 @@ static void status_lockspace(int fd, struct sanlk_state *st, char *str,
int debu
rv = recv(fd, &lockspace, sizeof(lockspace), MSG_WAITALL);
- printf("lockspace %.48s:%llu:%s:%llu\n",
+ printf("s %.48s:%llu:%s:%llu\n",
lockspace.name,
(unsigned long long)lockspace.host_id,
lockspace.host_id_disk.path,
@@ -98,7 +99,7 @@ static void status_resource(int fd, struct sanlk_state *st, char *str,
int debug
rv = recv(fd, &resource, sizeof(resource), MSG_WAITALL);
- printf("pid %d resource %.48s:%.48s", st->data32, resource.lockspace_name,
resource.name);
+ printf("r %.48s:%.48s", resource.lockspace_name, resource.name);
for (i = 0; i < resource.num_disks; i++) {
rv = recv(fd, &disk, sizeof(disk), MSG_WAITALL);
@@ -106,7 +107,7 @@ static void status_resource(int fd, struct sanlk_state *st, char *str,
int debug
printf(":%s:%llu",
disk.path, (unsigned long long)disk.offset);
}
- printf("\n");
+ printf(":%llu p %u\n", (unsigned long long)st->data64, st->data32);
if (st->str_len && debug)
print_debug(str, st->str_len);
diff --git a/src/main.c b/src/main.c
index b7cfe91..5b7477d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2064,6 +2064,7 @@ static void send_state_daemon(int fd)
int str_len;
memset(&st, 0, sizeof(st));
+ strncpy(st.name, our_host_name_global, NAME_ID_SIZE);
st.type = SANLK_STATE_DAEMON;
@@ -2137,6 +2138,7 @@ static void send_state_resource(int fd, struct resource *r, const
char *list_nam
st.type = SANLK_STATE_RESOURCE;
st.data32 = r->pid;
+ st.data64 = r->lver;
strncpy(st.name, r->r.name, NAME_ID_SIZE);
str_len = print_state_resource(r, str, list_name);