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>
15 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <netinet/in.h>
43 #define UBIK_INTERNALS
47 extern struct hostent *hostutil_GetHostByName();
49 static short PortNumber(aport)
50 register char *aport; {
52 register afs_int32 total;
55 while ((tc = *aport++)) {
56 if (tc < '0' || tc > '9') return -1; /* bad port number */
58 total += tc - (int) '0';
63 static short PortName(aname)
69 ts = getservbyname(aname, (char *) 0);
72 return ntohs(ts->s_port); /* returns it in host byte order */
75 if (strncmp(aname,"vlserver",len) == 0) {
77 } else if (strncmp(aname,"ptserver",len) == 0) {
79 } else if (strncmp(aname,"kaserver",len) == 0) {
81 } else if (strncmp(aname,"buserver",len) == 0) {
87 static CommandProc(as, arock)
89 struct cmd_syndesc *as; {
90 char *hostName, *portName, *times;
92 struct in_addr inhostAddr;
93 register afs_int32 i, j, code;
96 afs_int32 now, diff, newtime;
98 struct rx_connection *tconn;
99 struct rx_securityClass *sc;
100 struct ubik_debug udebug;
101 struct ubik_sdebug usdebug;
102 int oldServer =0; /* are we talking to a pre 3.5 server? */
103 afs_int32 isClone = 0;
105 int32p = (as->parms[2].items ? 1 : 0);
107 if (as->parms[0].items)
108 hostName = as->parms[0].items->data;
110 hostName = (char *) 0;
112 if (as->parms[1].items)
113 portName = as->parms[1].items->data;
115 portName = (char *) 0;
119 th = hostutil_GetHostByName(hostName);
121 printf("udebug: host %s not found in host table\n", hostName);
124 bcopy(th->h_addr, &hostAddr, sizeof(afs_int32));
126 else hostAddr = htonl(0x7f000001); /* IP localhost */
129 port = htons(3000); /* default */
131 port = PortNumber(portName);
133 port = PortName(portName);
135 printf("udebug: can't resolve port name %s\n", portName);
142 sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
143 tconn = rx_NewConnection(hostAddr, port, VOTE_SERVICE_ID, sc, 0);
145 /* now do the main call */
146 code = VOTE_XDebug(tconn, &udebug, &isClone);
147 if (code) code = VOTE_Debug(tconn, &udebug);
148 if ( code == RXGEN_OPCODE )
150 oldServer = 1; /* talking to a pre 3.5 server */
151 memset(&udebug, 0, sizeof(udebug));
152 code = VOTE_DebugOld(tconn, &udebug);
156 printf("return code %d from VOTE_Debug\n", code);
161 /* now print the main info */
162 times = ctime((time_t *)&udebug.now); times[24] = 0;
163 inhostAddr.s_addr = hostAddr;
166 printf("Host's addresses are: ");
167 for ( j=0; udebug.interfaceAddr[j] && ( j<UBIK_MAX_INTERFACE_ADDR );j++)
168 printf("%s ", afs_inet_ntoa(htonl(udebug.interfaceAddr[j])));
171 printf("Host's %s time is %s\n", inet_ntoa(inhostAddr), times);
173 times = ctime(&now); times[24] = 0;
174 diff = now - udebug.now;
175 printf("Local time is %s (time differential %d secs)\n", times, diff);
176 if (abs(diff) >= MAXSKEW)
177 printf("****clock may be bad\n");
179 /* UBIK skips the voting if 1 server - so we fudge it here */
180 if (udebug.amSyncSite && (udebug.nServers == 1)) {
181 udebug.lastYesHost = hostAddr;
182 udebug.lastYesTime = udebug.now;
183 udebug.lastYesState = 1;
184 udebug.lastYesClaim = udebug.now;
185 udebug.syncVersion.epoch = udebug.localVersion.epoch;
186 udebug.syncVersion.counter = udebug.localVersion.counter;
189 /* sockaddr is always in net-order */
190 if (udebug.lastYesHost == 0xffffffff) {
191 printf("Last yes vote not cast yet \n");
193 inhostAddr.s_addr = htonl(udebug.lastYesHost);
194 diff = udebug.now - udebug.lastYesTime;
195 printf("Last yes vote for %s was %d secs ago (%ssync site); \n",
196 inet_ntoa(inhostAddr), diff, ((udebug.lastYesState)?"":"not "));
198 diff = udebug.now - udebug.lastYesClaim;
199 newtime = now - diff;
200 times = ctime(&newtime); times[24] = 0;
201 printf("Last vote started %d secs ago (at %s)\n", diff, times);
204 printf("Local db version is %d.%d\n", udebug.localVersion.epoch, udebug.localVersion.counter);
206 if (udebug.amSyncSite) {
207 if (udebug.syncSiteUntil == 0x7fffffff) {
208 printf("I am sync site forever (%d server%s)\n",
209 udebug.nServers, ((udebug.nServers>1)?"s":""));
211 diff = udebug.syncSiteUntil - udebug.now;
212 newtime = now + diff;
213 times = ctime(&newtime); times[24] = 0;
214 printf("I am sync site until %d secs from now (at %s) (%d server%s)\n",
215 diff, times, udebug.nServers,
216 ((udebug.nServers>1)?"s":""));
218 printf("Recovery state %x\n", udebug.recoveryState);
219 if (udebug.activeWrite) {
220 printf("I am currently managing write trans %d.%d\n",
221 udebug.epochTime, udebug.tidCounter);
225 printf("I am a clone and never can become sync site\n");
227 printf("I am not sync site\n");
228 inhostAddr.s_addr = htonl(udebug.lowestHost);
229 diff = udebug.now - udebug.lowestTime;
230 printf("Lowest host %s was set %d secs ago\n", inet_ntoa(inhostAddr), diff);
232 inhostAddr.s_addr = htonl(udebug.syncHost);
233 diff = udebug.now - udebug.syncTime;
234 printf("Sync host %s was set %d secs ago\n", inet_ntoa(inhostAddr), diff);
237 printf("Sync site's db version is %d.%d\n",
238 udebug.syncVersion.epoch, udebug.syncVersion.counter);
239 printf("%d locked pages, %d of them for write\n",
240 udebug.lockedPages, udebug.writeLockedPages);
242 if (udebug.anyReadLocks) printf("There are read locks held\n");
243 if (udebug.anyWriteLocks) printf("There are write locks held\n");
245 if (udebug.currentTrans) {
246 if (udebug.writeTrans) printf("There is an active write transaction\n");
247 else printf("There is at least one active read transaction\n");
248 printf("Transaction tid is %d.%d\n", udebug.syncTid.epoch, udebug.syncTid.counter);
250 if (udebug.epochTime) {
251 diff = udebug.now - udebug.epochTime;
252 newtime = now - diff;
253 times = ctime(&newtime); times[24] = 0;
254 printf("Last time a new db version was labelled was:\n\t %d secs ago (at %s)\n",
258 if (int32p || udebug.amSyncSite) {
259 /* now do the subcalls */
262 code = VOTE_XSDebug(tconn, i, &usdebug, &isClone);
264 if ( oldServer ) { /* pre 3.5 server */
265 memset(&usdebug, 0, sizeof(usdebug));
266 code = VOTE_SDebugOld(tconn, i, &usdebug);
269 code = VOTE_SDebug(tconn, i, &usdebug);
271 if (code > 0) break; /* done */
273 printf("error code %d from VOTE_SDebug\n", code);
276 inhostAddr.s_addr = htonl(usdebug.addr);
277 /* otherwise print the structure */
278 printf("\nServer (%s", afs_inet_ntoa(htonl(usdebug.addr)));
279 for ( j=0;((usdebug.altAddr[j]) &&
280 (j<UBIK_MAX_INTERFACE_ADDR-1)); j++)
281 printf(" %s", afs_inet_ntoa(htonl(usdebug.altAddr[j])));
282 printf("): (db %d.%d)",
283 usdebug.remoteVersion.epoch, usdebug.remoteVersion.counter);
285 printf(" is only a clone!");
288 if (usdebug.lastVoteTime == 0) {
289 printf(" last vote never rcvd \n");
291 diff = udebug.now - usdebug.lastVoteTime;
292 newtime = now - diff;
293 times = ctime(&newtime); times[24] = 0;
294 printf(" last vote rcvd %d secs ago (at %s),\n", diff, times);
297 if (usdebug.lastBeaconSent == 0) {
298 printf(" last beacon never sent \n");
300 diff = udebug.now - usdebug.lastBeaconSent;
301 newtime = now - diff;
302 times = ctime(&newtime); times[24] = 0;
303 printf(" last beacon sent %d secs ago (at %s), last vote was %s\n",
304 diff, times, ((usdebug.lastVote)?"yes":"no"));
307 printf(" dbcurrent=%d, up=%d beaconSince=%d\n",
308 usdebug.currentDB, usdebug.up, usdebug.beaconSinceDown);
314 #include "AFS_component_version_number.c"
320 struct cmd_syndesc *ts;
324 * The following signal action for AIX is necessary so that in case of a
325 * crash (i.e. core is generated) we can include the user's data section
326 * in the core dump. Unfortunately, by default, only a partial core is
327 * generated which, in many cases, isn't too useful.
329 struct sigaction nsa;
331 sigemptyset(&nsa.sa_mask);
332 nsa.sa_handler = SIG_DFL;
333 nsa.sa_flags = SA_FULLDUMP;
334 sigaction(SIGSEGV, &nsa, NULL);
336 ts = cmd_CreateSyntax((char *) 0, CommandProc, 0, "probe ubik server");
337 cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server machine");
338 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
339 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
341 cmd_Dispatch(argc, argv);