added a ctdb_get_config call
[samba.git] / ctdb / tools / ctdb_control.c
1 /* 
2    ctdb control tool
3
4    Copyright (C) Andrew Tridgell  2007
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2 of the License, or (at your option) any later version.
10
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "includes.h"
22 #include "lib/events/events.h"
23 #include "system/filesys.h"
24 #include "popt.h"
25 #include "cmdline.h"
26 #include "../include/ctdb_private.h"
27
28
29 /*
30   show usage message
31  */
32 static void usage(void)
33 {
34         printf("Usage: ctdb_control [options] <control>\n");
35         printf("\nControls:\n");
36         printf("  ping\n");
37         printf("  process-exists <vnn:pid>\n");
38         printf("  status <vnn>\n");
39         exit(1);
40 }
41
42 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
43 {
44         uint32_t vnn, pid;
45         int ret;
46         if (argc < 1) {
47                 usage();
48         }
49
50         if (sscanf(argv[0], "%u:%u", &vnn, &pid) != 2) {
51                 printf("Badly formed vnn:pid\n");
52                 return -1;
53         }
54
55         ret = ctdb_process_exists(ctdb, vnn, pid);
56         if (ret == 0) {
57                 printf("%u:%u exists\n", vnn, pid);
58         } else {
59                 printf("%u:%u does not exist\n", vnn, pid);
60         }
61         return ret;
62 }
63
64 /*
65   display status structure
66  */
67 static void show_status(struct ctdb_status *s)
68 {
69         printf("CTDB version %u\n", CTDB_VERSION);
70         printf(" client_packets_sent     %u\n", s->client_packets_sent);
71         printf(" client_packets_recv     %u\n", s->client_packets_recv);
72         printf("   req_call              %u\n", s->client.req_call);
73         printf("   req_message           %u\n", s->client.req_message);
74         printf("   req_finished          %u\n", s->client.req_finished);
75         printf("   req_register          %u\n", s->client.req_register);
76         printf("   req_connect_wait      %u\n", s->client.req_connect_wait);
77         printf("   req_shutdown          %u\n", s->client.req_shutdown);
78         printf("   req_control           %u\n", s->client.req_control);
79         printf(" node_packets_sent       %u\n", s->node_packets_sent);
80         printf(" node_packets_recv       %u\n", s->node_packets_recv);
81         printf("   req_call              %u\n", s->count.req_call);
82         printf("   reply_call            %u\n", s->count.reply_call);
83         printf("   reply_redirect        %u\n", s->count.reply_redirect);
84         printf("   req_dmaster           %u\n", s->count.req_dmaster);
85         printf("   reply_dmaster         %u\n", s->count.reply_dmaster);
86         printf("   reply_error           %u\n", s->count.reply_error);
87         printf("   reply_redirect        %u\n", s->count.reply_redirect);
88         printf("   req_message           %u\n", s->count.req_message);
89         printf("   req_finished          %u\n", s->count.req_finished);
90         printf(" total_calls             %u\n", s->total_calls);
91         printf(" pending_calls           %u\n", s->pending_calls);
92         printf(" lockwait_calls          %u\n", s->lockwait_calls);
93         printf(" pending_lockwait_calls  %u\n", s->pending_lockwait_calls);
94         printf(" max_redirect_count      %u\n", s->max_redirect_count);
95         printf(" max_call_latency        %.6f sec\n", s->max_call_latency);
96         printf(" max_lockwait_latency    %.6f sec\n", s->max_lockwait_latency);
97 }
98
99 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
100 {
101         uint32_t vnn;
102         int ret;
103         struct ctdb_status status;
104         if (argc < 1) {
105                 usage();
106         }
107
108         vnn = strtoul(argv[0], NULL, 0);
109
110         ret = ctdb_status(ctdb, vnn, &status);
111         if (ret != 0) {
112                 printf("Unable to get status from node %u\n", vnn);
113                 return ret;
114         }
115         show_status(&status);
116         return 0;
117 }
118
119
120 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
121 {
122         int ret, i;
123
124         for (i=0;i<ctdb->num_nodes;i++) {
125                 struct timeval tv = timeval_current();
126                 ret = ctdb_ping(ctdb, i);
127                 if (ret != 0) {
128                         printf("Unable to get ping response from node %u\n", i);
129                 } else {
130                         printf("response from %u time=%.6f sec\n", 
131                                i, timeval_elapsed(&tv));
132                 }
133         }
134         return 0;
135 }
136
137 /*
138   main program
139 */
140 int main(int argc, const char *argv[])
141 {
142         struct ctdb_context *ctdb;
143         struct poptOption popt_options[] = {
144                 POPT_AUTOHELP
145                 POPT_CTDB_CMDLINE
146                 POPT_TABLEEND
147         };
148         int opt;
149         const char **extra_argv;
150         int extra_argc = 0;
151         int ret;
152         poptContext pc;
153         struct event_context *ev;
154         const char *control;
155
156         pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
157
158         while ((opt = poptGetNextOpt(pc)) != -1) {
159                 switch (opt) {
160                 default:
161                         fprintf(stderr, "Invalid option %s: %s\n", 
162                                 poptBadOption(pc, 0), poptStrerror(opt));
163                         exit(1);
164                 }
165         }
166
167         /* setup the remaining options for the main program to use */
168         extra_argv = poptGetArgs(pc);
169         if (extra_argv) {
170                 extra_argv++;
171                 while (extra_argv[extra_argc]) extra_argc++;
172         }
173
174         if (extra_argc < 1) {
175                 usage();
176         }
177
178         control = extra_argv[0];
179
180         ev = event_context_init(NULL);
181
182         /* initialise ctdb */
183         ctdb = ctdb_cmdline_client(ev);
184         if (ctdb == NULL) {
185                 printf("Failed to init ctdb\n");
186                 exit(1);
187         }
188
189         if (strcmp(control, "process-exists") == 0) {
190                 ret = control_process_exists(ctdb, extra_argc-1, extra_argv+1);
191         } else if (strcmp(control, "status") == 0) {
192                 ret = control_status(ctdb, extra_argc-1, extra_argv+1);
193         } else if (strcmp(control, "ping") == 0) {
194                 ret = control_ping(ctdb, extra_argc-1, extra_argv+1);
195         } else {
196                 printf("Unknown control '%s'\n", control);
197                 exit(1);
198         }
199
200         return ret;
201 }