2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
29 #include <sys/param.h>
30 #include <netinet/in.h>
44 #define UBIK_INTERNALS
48 /* needed by Irix. Include a header to get it, or leave it alone. */
49 extern struct hostent *hostutil_GetHostByName();
52 PortNumber(register char *aport)
55 register afs_int32 total;
58 while ((tc = *aport++)) {
59 if (tc < '0' || tc > '9')
60 return -1; /* bad port number */
62 total += tc - (int)'0';
73 ts = getservbyname(aname, NULL);
76 return ntohs(ts->s_port); /* returns it in host byte order */
79 if (strncmp(aname, "vlserver", len) == 0) {
81 } else if (strncmp(aname, "ptserver", len) == 0) {
83 } else if (strncmp(aname, "kaserver", len) == 0) {
85 } else if (strncmp(aname, "buserver", len) == 0) {
92 CommandProc(struct cmd_syndesc *as, char *arock)
94 char *hostName, *portName, *times;
96 struct in_addr inhostAddr;
97 register afs_int32 i, j, code;
100 afs_int32 now, diff, newtime;
102 struct rx_connection *tconn;
103 struct rx_securityClass *sc;
104 struct ubik_debug udebug;
105 struct ubik_sdebug usdebug;
106 int oldServer = 0; /* are we talking to a pre 3.5 server? */
107 afs_int32 isClone = 0;
109 int32p = (as->parms[2].items ? 1 : 0);
111 if (as->parms[0].items)
112 hostName = as->parms[0].items->data;
116 if (as->parms[1].items)
117 portName = as->parms[1].items->data;
123 th = hostutil_GetHostByName(hostName);
125 printf("udebug: host %s not found in host table\n", hostName);
128 memcpy(&hostAddr, th->h_addr, sizeof(afs_int32));
130 hostAddr = htonl(0x7f000001); /* IP localhost */
133 port = htons(3000); /* default */
135 port = PortNumber(portName);
137 port = PortName(portName);
139 printf("udebug: can't resolve port name %s\n", portName);
146 sc = rxnull_NewClientSecurityObject();
147 tconn = rx_NewConnection(hostAddr, port, VOTE_SERVICE_ID, sc, 0);
149 /* now do the main call */
150 code = VOTE_XDebug(tconn, &udebug, &isClone);
152 code = VOTE_Debug(tconn, &udebug);
153 if (code == RXGEN_OPCODE) {
154 oldServer = 1; /* talking to a pre 3.5 server */
155 memset(&udebug, 0, sizeof(udebug));
156 code = VOTE_DebugOld(tconn, &udebug);
160 printf("return code %d from VOTE_Debug\n", code);
165 /* now print the main info */
166 times = ctime((time_t *) & udebug.now);
168 inhostAddr.s_addr = hostAddr;
170 printf("Host's addresses are: ");
171 for (j = 0; udebug.interfaceAddr[j] && (j < UBIK_MAX_INTERFACE_ADDR);
173 printf("%s ", afs_inet_ntoa(htonl(udebug.interfaceAddr[j])));
176 printf("Host's %s time is %s\n", inet_ntoa(inhostAddr), times);
180 diff = now - udebug.now;
181 printf("Local time is %s (time differential %d secs)\n", times, diff);
182 if (abs(diff) >= MAXSKEW)
183 printf("****clock may be bad\n");
185 /* UBIK skips the voting if 1 server - so we fudge it here */
186 if (udebug.amSyncSite && (udebug.nServers == 1)) {
187 udebug.lastYesHost = hostAddr;
188 udebug.lastYesTime = udebug.now;
189 udebug.lastYesState = 1;
190 udebug.lastYesClaim = udebug.now;
191 udebug.syncVersion.epoch = udebug.localVersion.epoch;
192 udebug.syncVersion.counter = udebug.localVersion.counter;
195 /* sockaddr is always in net-order */
196 if (udebug.lastYesHost == 0xffffffff) {
197 printf("Last yes vote not cast yet \n");
199 inhostAddr.s_addr = htonl(udebug.lastYesHost);
200 diff = udebug.now - udebug.lastYesTime;
201 printf("Last yes vote for %s was %d secs ago (%ssync site); \n",
202 inet_ntoa(inhostAddr), diff,
203 ((udebug.lastYesState) ? "" : "not "));
205 diff = udebug.now - udebug.lastYesClaim;
206 newtime = now - diff;
207 times = ctime(&newtime);
209 printf("Last vote started %d secs ago (at %s)\n", diff, times);
212 printf("Local db version is %d.%d\n", udebug.localVersion.epoch,
213 udebug.localVersion.counter);
215 if (udebug.amSyncSite) {
216 if (udebug.syncSiteUntil == 0x7fffffff) {
217 printf("I am sync site forever (%d server%s)\n", udebug.nServers,
218 ((udebug.nServers > 1) ? "s" : ""));
220 diff = udebug.syncSiteUntil - udebug.now;
221 newtime = now + diff;
222 times = ctime(&newtime);
225 ("I am sync site until %d secs from now (at %s) (%d server%s)\n",
226 diff, times, udebug.nServers,
227 ((udebug.nServers > 1) ? "s" : ""));
229 printf("Recovery state %x\n", udebug.recoveryState);
230 if (udebug.activeWrite) {
231 printf("I am currently managing write trans %d.%d\n",
232 udebug.epochTime, udebug.tidCounter);
236 printf("I am a clone and never can become sync site\n");
238 printf("I am not sync site\n");
239 inhostAddr.s_addr = htonl(udebug.lowestHost);
240 diff = udebug.now - udebug.lowestTime;
241 printf("Lowest host %s was set %d secs ago\n", inet_ntoa(inhostAddr),
244 inhostAddr.s_addr = htonl(udebug.syncHost);
245 diff = udebug.now - udebug.syncTime;
246 printf("Sync host %s was set %d secs ago\n", inet_ntoa(inhostAddr),
250 printf("Sync site's db version is %d.%d\n", udebug.syncVersion.epoch,
251 udebug.syncVersion.counter);
252 printf("%d locked pages, %d of them for write\n", udebug.lockedPages,
253 udebug.writeLockedPages);
255 if (udebug.anyReadLocks)
256 printf("There are read locks held\n");
257 if (udebug.anyWriteLocks)
258 printf("There are write locks held\n");
260 if (udebug.currentTrans) {
261 if (udebug.writeTrans)
262 printf("There is an active write transaction\n");
264 printf("There is at least one active read transaction\n");
265 printf("Transaction tid is %d.%d\n", udebug.syncTid.epoch,
266 udebug.syncTid.counter);
268 if (udebug.epochTime) {
269 diff = udebug.now - udebug.epochTime;
270 newtime = now - diff;
271 times = ctime(&newtime);
274 ("Last time a new db version was labelled was:\n\t %d secs ago (at %s)\n",
278 if (int32p || udebug.amSyncSite) {
279 /* now do the subcalls */
282 code = VOTE_XSDebug(tconn, i, &usdebug, &isClone);
284 if (oldServer) { /* pre 3.5 server */
285 memset(&usdebug, 0, sizeof(usdebug));
286 code = VOTE_SDebugOld(tconn, i, &usdebug);
288 code = VOTE_SDebug(tconn, i, &usdebug);
293 printf("error code %d from VOTE_SDebug\n", code);
296 inhostAddr.s_addr = htonl(usdebug.addr);
297 /* otherwise print the structure */
298 printf("\nServer (%s", afs_inet_ntoa(htonl(usdebug.addr)));
300 ((usdebug.altAddr[j]) && (j < UBIK_MAX_INTERFACE_ADDR - 1));
302 printf(" %s", afs_inet_ntoa(htonl(usdebug.altAddr[j])));
303 printf("): (db %d.%d)", usdebug.remoteVersion.epoch,
304 usdebug.remoteVersion.counter);
306 printf(" is only a clone!");
309 if (usdebug.lastVoteTime == 0) {
310 printf(" last vote never rcvd \n");
312 diff = udebug.now - usdebug.lastVoteTime;
313 newtime = now - diff;
314 times = ctime(&newtime);
316 printf(" last vote rcvd %d secs ago (at %s),\n", diff,
320 if (usdebug.lastBeaconSent == 0) {
321 printf(" last beacon never sent \n");
323 diff = udebug.now - usdebug.lastBeaconSent;
324 newtime = now - diff;
325 times = ctime(&newtime);
328 (" last beacon sent %d secs ago (at %s), last vote was %s\n",
329 diff, times, ((usdebug.lastVote) ? "yes" : "no"));
332 printf(" dbcurrent=%d, up=%d beaconSince=%d\n",
333 usdebug.currentDB, usdebug.up, usdebug.beaconSinceDown);
339 #include "AFS_component_version_number.c"
342 main(int argc, char **argv)
344 struct cmd_syndesc *ts;
348 * The following signal action for AIX is necessary so that in case of a
349 * crash (i.e. core is generated) we can include the user's data section
350 * in the core dump. Unfortunately, by default, only a partial core is
351 * generated which, in many cases, isn't too useful.
353 struct sigaction nsa;
355 sigemptyset(&nsa.sa_mask);
356 nsa.sa_handler = SIG_DFL;
357 nsa.sa_flags = SA_FULLDUMP;
358 sigaction(SIGSEGV, &nsa, NULL);
360 ts = cmd_CreateSyntax(NULL, CommandProc, 0, "probe ubik server");
361 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server machine");
362 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
363 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
365 cmd_Dispatch(argc, argv);