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>
14 #include <sys/types.h>
25 #include <sys/param.h>
26 #include <netinet/in.h>
38 #include <afs/afsutil.h>
40 #define UBIK_INTERNALS
44 static_inline int afs_cast_time_t(time_t d) { return (int) d; }
47 PortNumber(char *aport)
53 while ((tc = *aport++)) {
54 if (tc < '0' || tc > '9')
55 return -1; /* bad port number */
57 total += tc - (int)'0';
68 ts = getservbyname(aname, NULL);
71 return ntohs(ts->s_port); /* returns it in host byte order */
74 if (strncmp(aname, "vlserver", len) == 0) {
76 } else if (strncmp(aname, "ptserver", len) == 0) {
78 } else if (strncmp(aname, "kaserver", len) == 0) {
80 } else if (strncmp(aname, "buserver", len) == 0) {
87 CommandProc(struct cmd_syndesc *as, void *arock)
89 char *hostName, *portName, *times;
94 time_t now, then, diff, newtime;
96 struct rx_connection *tconn;
97 struct rx_securityClass *sc;
98 struct ubik_debug udebug;
99 struct ubik_sdebug usdebug;
100 int oldServer = 0; /* are we talking to a pre 3.5 server? */
101 afs_int32 isClone = 0;
104 int32p = (as->parms[2].items ? 1 : 0);
106 if (as->parms[0].items)
107 hostName = as->parms[0].items->data;
111 if (as->parms[1].items)
112 portName = as->parms[1].items->data;
118 th = hostutil_GetHostByName(hostName);
120 printf("udebug: host %s not found in host table\n", hostName);
123 memcpy(&hostAddr, th->h_addr, sizeof(afs_int32));
125 hostAddr = htonl(0x7f000001); /* IP localhost */
128 port = htons(3000); /* default */
130 port = PortNumber(portName);
132 port = PortName(portName);
134 printf("udebug: can't resolve port name %s\n", portName);
141 sc = rxnull_NewClientSecurityObject();
142 tconn = rx_NewConnection(hostAddr, port, VOTE_SERVICE_ID, sc, 0);
144 /* now do the main call */
145 code = VOTE_XDebug(tconn, &udebug, &isClone);
147 code = VOTE_Debug(tconn, &udebug);
148 if (code == RXGEN_OPCODE) {
149 oldServer = 1; /* talking to a pre 3.5 server */
150 memset(&udebug, 0, sizeof(udebug));
151 code = VOTE_DebugOld(tconn, (ubik_debug_old *)&udebug);
155 printf("return code %d from VOTE_Debug\n", code);
161 /* now print the main info */
162 times = ctime(&then);
165 printf("Host's addresses are: ");
166 for (j = 0; udebug.interfaceAddr[j] && (j < UBIK_MAX_INTERFACE_ADDR);
168 printf("%s ", afs_inet_ntoa_r(htonl(udebug.interfaceAddr[j]), hoststr));
171 printf("Host's %s time is %s\n", afs_inet_ntoa_r(hostAddr, hoststr), times);
175 diff = now - udebug.now;
176 printf("Local time is %s (time differential %d secs)\n", times, afs_cast_time_t(diff));
177 if (abs((int)diff) >= MAXSKEW)
178 printf("****clock may be bad\n");
180 /* UBIK skips the voting if 1 server - so we fudge it here */
181 if (udebug.amSyncSite && (udebug.nServers == 1)) {
182 udebug.lastYesHost = hostAddr;
183 udebug.lastYesTime = udebug.now;
184 udebug.lastYesState = 1;
185 udebug.lastYesClaim = udebug.now;
186 udebug.syncVersion.epoch = udebug.localVersion.epoch;
187 udebug.syncVersion.counter = udebug.localVersion.counter;
190 /* XDR converts addresses for us, so all addresses are in HBO */
191 if (udebug.lastYesHost == 0xffffffff) {
192 printf("Last yes vote not cast yet \n");
194 diff = udebug.now - udebug.lastYesTime;
195 printf("Last yes vote for %s was %d secs ago (%ssync site); \n",
196 afs_inet_ntoa_r(htonl(udebug.lastYesHost), hoststr),
197 afs_cast_time_t(diff),
198 ((udebug.lastYesState) ? "" : "not "));
200 diff = udebug.now - udebug.lastYesClaim;
201 newtime = now - diff;
202 times = ctime(&newtime);
204 printf("Last vote started %d secs ago (at %s)\n",
205 afs_cast_time_t(diff), times);
208 printf("Local db version is %d.%d\n", udebug.localVersion.epoch,
209 udebug.localVersion.counter);
211 if (udebug.amSyncSite) {
212 if (udebug.syncSiteUntil == 0x7fffffff) {
213 printf("I am sync site forever (%d server%s)\n", udebug.nServers,
214 ((udebug.nServers > 1) ? "s" : ""));
216 diff = udebug.syncSiteUntil - udebug.now;
217 newtime = now + diff;
218 times = ctime(&newtime);
221 ("I am sync site until %d secs from now (at %s) (%d server%s)\n",
222 afs_cast_time_t(diff), times, udebug.nServers,
223 ((udebug.nServers > 1) ? "s" : ""));
225 printf("Recovery state %x\n", udebug.recoveryState);
226 if (udebug.activeWrite) {
227 printf("I am currently managing write trans %d.%d\n",
228 udebug.epochTime, udebug.tidCounter);
232 printf("I am a clone and never can become sync site\n");
234 printf("I am not sync site\n");
235 diff = udebug.now - udebug.lowestTime;
236 printf("Lowest host %s was set %d secs ago\n",
237 afs_inet_ntoa_r(htonl(udebug.lowestHost), hoststr),
238 afs_cast_time_t(diff));
240 diff = udebug.now - udebug.syncTime;
241 printf("Sync host %s was set %d secs ago\n",
242 afs_inet_ntoa_r(htonl(udebug.syncHost), hoststr),
243 afs_cast_time_t(diff));
246 printf("Sync site's db version is %d.%d\n", udebug.syncVersion.epoch,
247 udebug.syncVersion.counter);
248 printf("%d locked pages, %d of them for write\n", udebug.lockedPages,
249 udebug.writeLockedPages);
251 if (udebug.anyReadLocks)
252 printf("There are read locks held\n");
253 if (udebug.anyWriteLocks)
254 printf("There are write locks held\n");
256 if (udebug.currentTrans) {
257 if (udebug.writeTrans)
258 printf("There is an active write transaction\n");
260 printf("There is at least one active read transaction\n");
261 printf("Transaction tid is %d.%d\n", udebug.syncTid.epoch,
262 udebug.syncTid.counter);
264 if (udebug.epochTime) {
265 diff = udebug.now - udebug.epochTime;
266 newtime = now - diff;
267 times = ctime(&newtime);
270 ("Last time a new db version was labelled was:\n\t %d secs ago (at %s)\n",
271 afs_cast_time_t(diff), times);
274 if (int32p || udebug.amSyncSite) {
275 /* now do the subcalls */
278 code = VOTE_XSDebug(tconn, i, &usdebug, &isClone);
280 if (oldServer) { /* pre 3.5 server */
281 memset(&usdebug, 0, sizeof(usdebug));
282 code = VOTE_SDebugOld(tconn, i, (ubik_sdebug_old *)&usdebug);
284 code = VOTE_SDebug(tconn, i, &usdebug);
289 printf("error code %d from VOTE_SDebug\n", code);
292 /* otherwise print the structure */
293 printf("\nServer (%s", afs_inet_ntoa_r(htonl(usdebug.addr), hoststr));
295 ((usdebug.altAddr[j]) && (j < UBIK_MAX_INTERFACE_ADDR - 1));
297 printf(" %s", afs_inet_ntoa_r(htonl(usdebug.altAddr[j]), hoststr));
298 printf("): (db %d.%d)", usdebug.remoteVersion.epoch,
299 usdebug.remoteVersion.counter);
301 printf(" is only a clone!");
304 if (usdebug.lastVoteTime == 0) {
305 printf(" last vote never rcvd \n");
307 diff = udebug.now - usdebug.lastVoteTime;
308 newtime = now - diff;
309 times = ctime(&newtime);
311 printf(" last vote rcvd %d secs ago (at %s),\n",
312 afs_cast_time_t(diff),
316 if (usdebug.lastBeaconSent == 0) {
317 printf(" last beacon never sent \n");
319 diff = udebug.now - usdebug.lastBeaconSent;
320 newtime = now - diff;
321 times = ctime(&newtime);
324 (" last beacon sent %d secs ago (at %s), last vote was %s\n",
325 afs_cast_time_t(diff), times, ((usdebug.lastVote) ? "yes" : "no"));
328 printf(" dbcurrent=%d, up=%d beaconSince=%d\n",
329 usdebug.currentDB, usdebug.up, usdebug.beaconSinceDown);
335 #include "AFS_component_version_number.c"
338 main(int argc, char **argv)
340 struct cmd_syndesc *ts;
344 * The following signal action for AIX is necessary so that in case of a
345 * crash (i.e. core is generated) we can include the user's data section
346 * in the core dump. Unfortunately, by default, only a partial core is
347 * generated which, in many cases, isn't too useful.
349 struct sigaction nsa;
351 sigemptyset(&nsa.sa_mask);
352 nsa.sa_handler = SIG_DFL;
353 nsa.sa_flags = SA_FULLDUMP;
354 sigaction(SIGSEGV, &nsa, NULL);
356 ts = cmd_CreateSyntax(NULL, CommandProc, NULL, "probe ubik server");
357 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server machine");
358 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
359 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
361 cmd_Dispatch(argc, argv);