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@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@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);
sanlock-devel@lists.fedorahosted.org