ubik-warnings-cleanup-20010605
[openafs.git] / src / ubik / udebug.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afs/param.h>
11 #include <afsconfig.h>
12 #include <sys/types.h>
13 #include <stdlib.h>
14 #ifdef HAVE_STRING_H
15 #include <string.h>
16 #endif
17 #ifdef HAVE_STRINGS_H
18 #include <strings.h>
19 #endif
20 #ifdef AFS_NT40_ENV
21 #include <winsock2.h>
22 #else
23 #include <sys/file.h>
24 #include <sys/param.h>
25 #include <netinet/in.h>
26 #include <netdb.h>
27 #endif
28 #ifdev HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #include <signal.h>
32 #include <time.h>
33
34 #include <lock.h>
35 #include <rx/xdr.h>
36 #include <rx/rx.h>
37 #include <afs/cmd.h>
38
39 #define UBIK_INTERNALS
40 #include "ubik.h"
41 #include "ubik_int.h"
42
43 extern struct hostent *hostutil_GetHostByName();
44
45 static short PortNumber(aport)
46 register char *aport; {
47     register int tc;
48     register afs_int32 total;
49
50     total = 0;
51     while ((tc = *aport++)) {
52         if (tc < '0' || tc > '9') return -1;    /* bad port number */
53         total *= 10;
54         total += tc - (int) '0';
55     }
56     return(total);
57 }
58
59 static short PortName(aname)
60     char *aname;
61 {
62     struct servent *ts;
63     int len;
64
65     ts = getservbyname(aname, (char *) 0);
66
67     if (ts)
68        return ntohs(ts->s_port);  /* returns it in host byte order */
69
70     len = strlen(aname);
71     if        (strncmp(aname,"vlserver",len) == 0) {
72        return 7003;
73     } else if (strncmp(aname,"ptserver",len) == 0) {
74        return 7002;
75     } else if (strncmp(aname,"kaserver",len) == 0) {
76        return 7004;
77     } else if (strncmp(aname,"buserver",len) == 0) {
78        return 7021;
79     }
80     return(-1);
81 }
82
83 static CommandProc(as, arock)
84 char *arock;
85 struct cmd_syndesc *as; {
86     char *hostName, *portName, *times;
87     afs_int32 hostAddr;
88     struct in_addr inhostAddr;
89     register afs_int32 i, j, code;
90     short port;
91     int int32p;
92     afs_int32 now, diff, newtime;
93     struct hostent *th;
94     struct rx_connection *tconn;
95     struct rx_securityClass *sc;
96     struct ubik_debug udebug;
97     struct ubik_sdebug usdebug;
98     int         oldServer =0;   /* are we talking to a pre 3.5 server? */
99     afs_int32 isClone = 0;
100
101     int32p = (as->parms[2].items ? 1 : 0);
102
103     if (as->parms[0].items)
104         hostName = as->parms[0].items->data;
105     else
106         hostName = (char *) 0;
107
108     if (as->parms[1].items)
109         portName = as->parms[1].items->data;
110     else
111         portName = (char *) 0;
112
113     /* lookup host */
114     if (hostName) {
115         th = hostutil_GetHostByName(hostName);
116         if (!th) {
117             printf("udebug: host %s not found in host table\n", hostName);
118             exit(1);
119         }
120         bcopy(th->h_addr, &hostAddr, sizeof(afs_int32));
121     }
122     else hostAddr = htonl(0x7f000001);  /* IP localhost */
123
124     if (!portName)
125         port = htons(3000);             /* default */
126     else {
127       port = PortNumber(portName);
128       if (port < 0)
129         port = PortName(portName);
130       if (port < 0) {
131         printf("udebug: can't resolve port name %s\n", portName);
132         exit(1);
133       }
134       port = htons(port);
135     }
136
137     rx_Init(0);
138     sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
139     tconn = rx_NewConnection(hostAddr, port, VOTE_SERVICE_ID, sc, 0);
140     
141     /* now do the main call */
142     code = VOTE_XDebug(tconn, &udebug, &isClone);
143     if (code) code = VOTE_Debug(tconn, &udebug);
144     if ( code == RXGEN_OPCODE ) 
145     {
146         oldServer = 1;                  /* talking to a pre 3.5 server */
147         memset(&udebug, 0, sizeof(udebug)); 
148         code = VOTE_DebugOld(tconn, &udebug);
149     }
150
151     if (code) {
152         printf("return code %d from VOTE_Debug\n", code);
153         exit(0);
154     }
155     now = time(0);
156
157     /* now print the main info */
158     times = ctime((time_t *)&udebug.now); times[24] = 0;
159     inhostAddr.s_addr = hostAddr;
160     if ( !oldServer )
161     {
162         printf("Host's addresses are: ");
163         for ( j=0; udebug.interfaceAddr[j] && ( j<UBIK_MAX_INTERFACE_ADDR );j++)
164             printf("%s ", afs_inet_ntoa(htonl(udebug.interfaceAddr[j])));
165         printf("\n");
166     }
167     printf("Host's %s time is %s\n",  inet_ntoa(inhostAddr), times);
168
169     times = ctime(&now); times[24] = 0;
170     diff = now - udebug.now;
171     printf("Local time is %s (time differential %d secs)\n", times, diff);
172     if (abs(diff) >= MAXSKEW)
173         printf("****clock may be bad\n");
174
175     /* UBIK skips the voting if 1 server - so we fudge it here */
176     if (udebug.amSyncSite && (udebug.nServers == 1)) {
177        udebug.lastYesHost  = hostAddr;
178        udebug.lastYesTime  = udebug.now;
179        udebug.lastYesState = 1;
180        udebug.lastYesClaim = udebug.now;
181        udebug.syncVersion.epoch   = udebug.localVersion.epoch;
182        udebug.syncVersion.counter = udebug.localVersion.counter;
183     }
184
185     /* sockaddr is always in net-order */
186     if (udebug.lastYesHost == 0xffffffff) {
187        printf("Last yes vote not cast yet \n");
188     } else {
189        inhostAddr.s_addr = htonl(udebug.lastYesHost);
190        diff = udebug.now - udebug.lastYesTime;
191        printf("Last yes vote for %s was %d secs ago (%ssync site); \n",
192               inet_ntoa(inhostAddr), diff, ((udebug.lastYesState)?"":"not "));
193
194        diff = udebug.now - udebug.lastYesClaim;
195        newtime = now - diff;
196        times = ctime(&newtime); times[24] = 0;
197        printf("Last vote started %d secs ago (at %s)\n", diff, times);
198     }
199
200     printf("Local db version is %d.%d\n", udebug.localVersion.epoch, udebug.localVersion.counter);
201
202     if (udebug.amSyncSite) {
203         if (udebug.syncSiteUntil == 0x7fffffff) {
204            printf("I am sync site forever (%d server%s)\n",
205                   udebug.nServers, ((udebug.nServers>1)?"s":""));
206         } else {
207            diff = udebug.syncSiteUntil - udebug.now;
208            newtime = now + diff;
209            times = ctime(&newtime); times[24] = 0;
210            printf("I am sync site until %d secs from now (at %s) (%d server%s)\n",
211                   diff, times, udebug.nServers,
212                   ((udebug.nServers>1)?"s":""));
213         }
214         printf("Recovery state %x\n", udebug.recoveryState);
215         if (udebug.activeWrite) {
216             printf("I am currently managing write trans %d.%d\n",
217                    udebug.epochTime, udebug.tidCounter);
218         }
219     } else {
220         if (isClone) 
221             printf("I am a clone and never can become sync site\n");
222         else
223             printf("I am not sync site\n");
224         inhostAddr.s_addr = htonl(udebug.lowestHost);
225         diff = udebug.now - udebug.lowestTime;
226         printf("Lowest host %s was set %d secs ago\n", inet_ntoa(inhostAddr), diff);
227
228         inhostAddr.s_addr = htonl(udebug.syncHost);
229         diff = udebug.now - udebug.syncTime;
230         printf("Sync host %s was set %d secs ago\n", inet_ntoa(inhostAddr), diff);
231     }
232
233     printf("Sync site's db version is %d.%d\n",
234            udebug.syncVersion.epoch, udebug.syncVersion.counter);
235     printf("%d locked pages, %d of them for write\n",
236            udebug.lockedPages, udebug.writeLockedPages);
237     
238     if (udebug.anyReadLocks)  printf("There are read locks held\n");
239     if (udebug.anyWriteLocks) printf("There are write locks held\n");
240     
241     if (udebug.currentTrans) {
242         if (udebug.writeTrans) printf("There is an active write transaction\n");
243         else printf("There is at least one active read transaction\n");
244         printf("Transaction tid is %d.%d\n", udebug.syncTid.epoch, udebug.syncTid.counter);
245     }
246     if (udebug.epochTime) {
247         diff = udebug.now - udebug.epochTime;
248         newtime = now - diff;
249         times = ctime(&newtime); times[24] = 0;
250         printf("Last time a new db version was labelled was:\n\t %d secs ago (at %s)\n",
251                diff, times);
252     }
253
254     if (int32p || udebug.amSyncSite) {
255         /* now do the subcalls */
256         for(i=0;;i++) {
257             isClone = 0;
258             code = VOTE_XSDebug(tconn, i, &usdebug, &isClone);
259             if (code < 0) {
260                 if ( oldServer ) {                      /* pre 3.5 server */
261                     memset(&usdebug, 0, sizeof(usdebug)); 
262                     code = VOTE_SDebugOld(tconn, i, &usdebug);
263                 }
264                 else
265                     code = VOTE_SDebug(tconn, i, &usdebug);
266             }
267             if (code > 0) break;        /* done */
268             if (code < 0) {
269                 printf("error code %d from VOTE_SDebug\n", code);
270                 break;
271             }
272             inhostAddr.s_addr = htonl(usdebug.addr);
273             /* otherwise print the structure */
274             printf("\nServer (%s", afs_inet_ntoa(htonl(usdebug.addr))); 
275             for ( j=0;((usdebug.altAddr[j]) && 
276                                 (j<UBIK_MAX_INTERFACE_ADDR-1)); j++)
277                 printf(" %s", afs_inet_ntoa(htonl(usdebug.altAddr[j])));
278             printf("): (db %d.%d)",
279                    usdebug.remoteVersion.epoch, usdebug.remoteVersion.counter);
280             if (isClone)
281                 printf("    is only a clone!");
282             printf("\n");
283
284             if (usdebug.lastVoteTime == 0) {
285                printf("    last vote never rcvd \n");
286             } else {
287                diff = udebug.now - usdebug.lastVoteTime;
288                newtime = now - diff;
289                times = ctime(&newtime); times[24] = 0;
290                printf("    last vote rcvd %d secs ago (at %s),\n", diff, times);
291             }
292
293             if (usdebug.lastBeaconSent == 0) {
294                printf("    last beacon never sent \n");
295             } else {
296                diff = udebug.now - usdebug.lastBeaconSent;
297                newtime = now - diff;
298                times = ctime(&newtime); times[24] = 0;
299                printf("    last beacon sent %d secs ago (at %s), last vote was %s\n",
300                       diff, times, ((usdebug.lastVote)?"yes":"no"));
301             }
302
303             printf("    dbcurrent=%d, up=%d beaconSince=%d\n",
304                    usdebug.currentDB, usdebug.up, usdebug.beaconSinceDown);
305         }
306     }
307     return (0);
308 }
309
310 #include "AFS_component_version_number.c"
311
312 int
313 main(argc, argv)
314     int argc;
315     char **argv; {
316     struct cmd_syndesc *ts;
317
318 #ifdef  AFS_AIX32_ENV
319     /*
320      * The following signal action for AIX is necessary so that in case of a 
321      * crash (i.e. core is generated) we can include the user's data section 
322      * in the core dump. Unfortunately, by default, only a partial core is
323      * generated which, in many cases, isn't too useful.
324      */
325     struct sigaction nsa;
326     
327     sigemptyset(&nsa.sa_mask);
328     nsa.sa_handler = SIG_DFL;
329     nsa.sa_flags = SA_FULLDUMP;
330     sigaction(SIGSEGV, &nsa, NULL);
331 #endif
332     ts = cmd_CreateSyntax((char *) 0, CommandProc, 0, "probe ubik server");
333     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server machine");
334     cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
335     cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
336
337     cmd_Dispatch(argc, argv);
338     exit(0);
339 }