2
* Copyright 2004-2012 Red Hat, Inc.
4
* This copyrighted material is made available to anyone wishing to use,
5
* modify, copy, or redistribute it subject to the terms and conditions
6
* of the GNU General Public License v2 or (at your option) any later version.
15
#include <sys/types.h>
16
#include <sys/socket.h>
19
#include <linux/dlmconstants.h>
20
#include "dlm_controld.h"
21
#include "libdlmcontrol.h"
23
static int do_read(int fd, void *buf, size_t count)
28
rv = read(fd, (char *)buf + off, count - off);
31
if (rv == -1 && errno == EINTR)
40
static int do_write(int fd, void *buf, size_t count)
45
rv = write(fd, (char *)buf + off, count);
46
if (rv == -1 && errno == EINTR)
60
static int do_connect(const char *sock_path)
62
struct sockaddr_un sun;
66
fd = socket(PF_UNIX, SOCK_STREAM, 0);
70
memset(&sun, 0, sizeof(sun));
71
sun.sun_family = AF_UNIX;
72
strcpy(&sun.sun_path[1], sock_path);
73
addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
75
rv = connect(fd, (struct sockaddr *) &sun, addrlen);
84
static void init_header(struct dlmc_header *h, int cmd, char *name,
87
memset(h, 0, sizeof(struct dlmc_header));
89
h->magic = DLMC_MAGIC;
90
h->version = DLMC_VERSION;
91
h->len = sizeof(struct dlmc_header) + extra_len;
95
strncpy(h->name, name, DLM_LOCKSPACE_LEN);
98
static char copy_buf[DLMC_DUMP_SIZE];
100
static int do_dump(int cmd, char *name, char *buf)
102
struct dlmc_header h;
105
memset(copy_buf, 0, DLMC_DUMP_SIZE);
107
init_header(&h, cmd, name, 0);
109
fd = do_connect(DLMC_QUERY_SOCK_PATH);
115
rv = do_write(fd, &h, sizeof(h));
119
memset(&h, 0, sizeof(h));
121
rv = do_read(fd, &h, sizeof(h));
125
len = h.len - sizeof(h);
127
if (len <= 0 || len > DLMC_DUMP_SIZE)
130
rv = do_read(fd, copy_buf, len);
134
memcpy(buf, copy_buf, len);
141
int dlmc_dump_debug(char *buf)
143
return do_dump(DLMC_CMD_DUMP_DEBUG, NULL, buf);
146
int dlmc_dump_config(char *buf)
148
return do_dump(DLMC_CMD_DUMP_CONFIG, NULL, buf);
151
int dlmc_dump_log_plock(char *buf)
153
return do_dump(DLMC_CMD_DUMP_LOG_PLOCK, NULL, buf);
156
int dlmc_dump_plocks(char *name, char *buf)
158
return do_dump(DLMC_CMD_DUMP_PLOCKS, name, buf);
161
static int nodeid_compare(const void *va, const void *vb)
169
static void print_str(char *str, int len)
175
for (i = 0; i < len-1; i++) {
187
static unsigned int kv(char *str, const char *k)
197
p = strstr(p, "=") + 1;
201
memset(valstr, 0, 64);
203
for (i = 0; i < 64; i++) {
214
return (unsigned int)strtoul(valstr, NULL, 0);
217
static char *ks(char *str, const char *k)
219
static char valstr[64];
227
p = strstr(p, "=") + 1;
231
memset(valstr, 0, 64);
233
for (i = 0; i < 64; i++) {
247
static void print_daemon(struct dlmc_state *st, char *str, char *bin, uint32_t flags)
249
unsigned int cluster_ringid, daemon_ringid;
252
if (flags & DLMC_STATUS_VERBOSE) {
253
printf("our_nodeid %d\n", st->nodeid);
254
print_str(str, st->str_len);
258
cluster_ringid = kv(str, "cluster_ringid");
259
daemon_ringid = kv(str, "daemon_ringid");
261
printf("cluster nodeid %d quorate %u ring seq %u %u\n",
264
cluster_ringid, daemon_ringid);
266
fipu = kv(str, "fence_in_progress_unknown");
268
printf("daemon now %u fence_pid %u %s\n",
270
kv(str, "fence_pid"),
271
fipu ? "fence_init" : "");
274
static void format_daemon_node(struct dlmc_state *st, char *str, char *bin, uint32_t flags,
275
char *node_line, char *fence_line)
277
unsigned int delay_fencing, result_wait, killed;
280
if (st->type == DLMC_STATE_STARTUP_NODE)
282
else if (kv(str, "member"))
288
snprintf(node_line, DLMC_STATE_MAXSTR - 1,
289
"node %d %c add %u rem %u fail %u fence %u at %u %u\n",
294
kv(str, "fail_monotime"),
295
kv(str, "fence_monotime"),
296
kv(str, "actor_done"),
297
kv(str, "fence_walltime"));
299
if (!kv(str, "need_fencing"))
302
delay_fencing = kv(str, "delay_fencing");
303
result_wait = kv(str, "fence_result_wait");
304
killed = kv(str, "killed");
307
snprintf(fence_line, DLMC_STATE_MAXSTR - 1,
308
"fence %d %s delay actor %u fail %u fence %u now %u%s%s\n",
310
ks(str, "left_reason"),
311
kv(str, "actor_last"),
312
kv(str, "fail_walltime"),
313
kv(str, "fence_walltime"),
314
(unsigned int)time(NULL),
315
result_wait ? " result_wait" : "",
316
killed ? " killed" : "");
318
snprintf(fence_line, DLMC_STATE_MAXSTR - 1,
319
"fence %d %s pid %d actor %u fail %u fence %u now %u%s%s\n",
321
ks(str, "left_reason"),
322
kv(str, "fence_pid"),
323
kv(str, "actor_last"),
324
kv(str, "fail_walltime"),
325
kv(str, "fence_walltime"),
326
(unsigned int)time(NULL),
327
result_wait ? " result_wait" : "",
328
killed ? " killed" : "");
333
int dlmc_print_status(uint32_t flags)
335
struct dlmc_header h;
336
struct dlmc_state state;
337
struct dlmc_state *st;
338
char maxstr[DLMC_STATE_MAXSTR];
339
char maxbin[DLMC_STATE_MAXBIN];
341
int all_count, node_count, fence_count;
342
int all_ids[MAX_SORT], node_ids[MAX_SORT], fence_ids[MAX_SORT];
343
char *node_lines[MAX_SORT], *fence_lines[MAX_SORT];
344
char *node_line, *fence_line;
348
init_header(&h, DLMC_CMD_DUMP_STATUS, NULL, 0);
350
fd = do_connect(DLMC_QUERY_SOCK_PATH);
352
printf("cannot connect to dlm_controld\n");
357
rv = do_write(fd, &h, sizeof(h));
359
printf("cannot send to dlm_controld\n");
371
memset(&all_ids, 0, sizeof(all_ids));
372
memset(&node_ids, 0, sizeof(node_ids));
373
memset(&fence_ids, 0, sizeof(fence_ids));
374
memset(node_lines, 0, sizeof(node_lines));
375
memset(fence_lines, 0, sizeof(fence_lines));
378
memset(&state, 0, sizeof(state));
379
memset(maxstr, 0, sizeof(maxstr));
380
memset(maxbin, 0, sizeof(maxbin));
382
rv = recv(fd, st, sizeof(struct dlmc_state), MSG_WAITALL);
385
if (rv != sizeof(struct dlmc_state))
389
rv = recv(fd, str, st->str_len, MSG_WAITALL);
390
if (rv != st->str_len)
395
rv = recv(fd, bin, st->bin_len, MSG_WAITALL);
396
if (rv != st->bin_len)
401
case DLMC_STATE_DAEMON:
402
print_daemon(st, str, bin, flags);
405
case DLMC_STATE_DAEMON_NODE:
406
case DLMC_STATE_STARTUP_NODE:
408
if (flags & DLMC_STATUS_VERBOSE) {
409
printf("nodeid %d\n", st->nodeid);
410
print_str(str, st->str_len);
412
node_line = malloc(DLMC_STATE_MAXSTR);
415
fence_line = malloc(DLMC_STATE_MAXSTR);
420
memset(node_line, 0, DLMC_STATE_MAXSTR);
421
memset(fence_line, 0, DLMC_STATE_MAXSTR);
423
format_daemon_node(st, str, bin, flags,
424
node_line, fence_line);
426
all_ids[all_count++] = st->nodeid;
428
node_ids[node_count] = st->nodeid;
429
node_lines[node_count++] = node_line;
432
if (!fence_line[0]) {
435
fence_ids[fence_count] = st->nodeid;
436
fence_lines[fence_count] = fence_line;
451
qsort(all_ids, all_count, sizeof(int), nodeid_compare);
453
if (all_count && fence_count) {
454
for (i = 0; i < all_count; i++) {
455
for (j = 0; j < fence_count; j++) {
456
if (all_ids[i] != fence_ids[j])
458
printf("%s", fence_lines[j]);
459
free(fence_lines[j]);
465
if (all_count && node_count) {
466
for (i = 0; i < all_count; i++) {
467
for (j = 0; j < node_count; j++) {
468
if (all_ids[i] != node_ids[j])
470
printf("%s", node_lines[j]);
483
int dlmc_node_info(char *name, int nodeid, struct dlmc_node *node)
485
struct dlmc_header h, *rh;
486
char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_node)];
489
init_header(&h, DLMC_CMD_NODE_INFO, name, 0);
492
memset(reply, 0, sizeof(reply));
494
fd = do_connect(DLMC_QUERY_SOCK_PATH);
500
rv = do_write(fd, &h, sizeof(h));
504
rv = do_read(fd, reply, sizeof(reply));
508
rh = (struct dlmc_header *)reply;
513
memcpy(node, (char *)reply + sizeof(struct dlmc_header),
514
sizeof(struct dlmc_node));
521
int dlmc_lockspace_info(char *name, struct dlmc_lockspace *lockspace)
523
struct dlmc_header h, *rh;
524
char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_lockspace)];
527
init_header(&h, DLMC_CMD_LOCKSPACE_INFO, name, 0);
529
memset(reply, 0, sizeof(reply));
531
fd = do_connect(DLMC_QUERY_SOCK_PATH);
537
rv = do_write(fd, &h, sizeof(h));
541
rv = do_read(fd, reply, sizeof(reply));
545
rh = (struct dlmc_header *)reply;
550
memcpy(lockspace, (char *)reply + sizeof(struct dlmc_header),
551
sizeof(struct dlmc_lockspace));
558
int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss)
560
struct dlmc_header h, *rh;
563
int fd, rv, result, ls_count;
565
init_header(&h, DLMC_CMD_LOCKSPACES, NULL, 0);
568
reply_len = sizeof(struct dlmc_header) +
569
(max * sizeof(struct dlmc_lockspace));
570
reply = malloc(reply_len);
575
memset(reply, 0, reply_len);
577
fd = do_connect(DLMC_QUERY_SOCK_PATH);
583
rv = do_write(fd, &h, sizeof(h));
587
/* won't usually get back the full reply_len */
588
do_read(fd, reply, reply_len);
590
rh = (struct dlmc_header *)reply;
592
if (result < 0 && result != -E2BIG) {
597
if (result == -E2BIG) {
606
memcpy(lss, (char *)reply + sizeof(struct dlmc_header),
607
ls_count * sizeof(struct dlmc_lockspace));
614
int dlmc_lockspace_nodes(char *name, int type, int max, int *count,
615
struct dlmc_node *nodes)
617
struct dlmc_header h, *rh;
620
int fd, rv, result, node_count;
622
init_header(&h, DLMC_CMD_LOCKSPACE_NODES, name, 0);
626
reply_len = sizeof(struct dlmc_header) +
627
(max * sizeof(struct dlmc_node));
628
reply = malloc(reply_len);
633
memset(reply, 0, reply_len);
635
fd = do_connect(DLMC_QUERY_SOCK_PATH);
641
rv = do_write(fd, &h, sizeof(h));
645
/* won't usually get back the full reply_len */
646
do_read(fd, reply, reply_len);
648
rh = (struct dlmc_header *)reply;
650
if (result < 0 && result != -E2BIG) {
655
if (result == -E2BIG) {
664
memcpy(nodes, (char *)reply + sizeof(struct dlmc_header),
665
node_count * sizeof(struct dlmc_node));
672
int dlmc_fs_connect(void)
674
return do_connect(DLMC_SOCK_PATH);
677
void dlmc_fs_disconnect(int fd)
682
int dlmc_fs_register(int fd, char *name)
684
struct dlmc_header h;
686
init_header(&h, DLMC_CMD_FS_REGISTER, name, 0);
688
return do_write(fd, &h, sizeof(h));
691
int dlmc_fs_unregister(int fd, char *name)
693
struct dlmc_header h;
695
init_header(&h, DLMC_CMD_FS_UNREGISTER, name, 0);
697
return do_write(fd, &h, sizeof(h));
700
int dlmc_fs_notified(int fd, char *name, int nodeid)
702
struct dlmc_header h;
704
init_header(&h, DLMC_CMD_FS_NOTIFIED, name, 0);
707
return do_write(fd, &h, sizeof(h));
710
int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result)
712
struct dlmc_header h;
715
rv = do_read(fd, &h, sizeof(h));
719
strncpy(name, h.name, DLM_LOCKSPACE_LEN);
724
case DLMC_CMD_FS_REGISTER:
725
*type = DLMC_RESULT_REGISTER;
727
case DLMC_CMD_FS_NOTIFIED:
728
*type = DLMC_RESULT_NOTIFIED;
737
int dlmc_deadlock_check(char *name)
739
struct dlmc_header h;
742
init_header(&h, DLMC_CMD_DEADLOCK_CHECK, name, 0);
744
fd = do_connect(DLMC_SOCK_PATH);
750
rv = do_write(fd, &h, sizeof(h));
756
int dlmc_fence_ack(char *name)
758
struct dlmc_header h;
761
init_header(&h, DLMC_CMD_FENCE_ACK, name, 0);
763
fd = do_connect(DLMC_SOCK_PATH);
769
rv = do_write(fd, &h, sizeof(h));