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>
17 #include <sys/types.h>
22 #ifdef HAVE_NETINET_IN_H
23 #include <netinet/in.h>
25 #include <sys/socket.h>
39 #include <afs/afscbint.h>
43 #include <afs/afs_args.h>
45 extern struct hostent *hostutil_GetHostByName();
48 PrintCacheConfig(struct rx_connection *aconn)
51 afs_uint32 srv_ver, conflen;
54 c.cacheConfig_len = 0;
55 c.cacheConfig_val = NULL;
56 code = RXAFSCB_GetCacheConfig(aconn, 1, &srv_ver, &conflen, &c);
58 printf("cmdebug: error checking cache config: %s\n",
63 if (srv_ver == AFS_CLIENT_RETRIEVAL_FIRST_EDITION) {
64 struct cm_initparams_v1 *c1;
66 if (c.cacheConfig_len != sizeof(*c1) / sizeof(afs_uint32)) {
67 printf("cmdebug: configuration data size mismatch (%d != %d)\n",
68 c.cacheConfig_len, sizeof(*c1) / sizeof(afs_uint32));
72 c1 = (struct cm_initparams_v1 *)c.cacheConfig_val;
73 printf("Chunk files: %d\n", c1->nChunkFiles);
74 printf("Stat caches: %d\n", c1->nStatCaches);
75 printf("Data caches: %d\n", c1->nDataCaches);
76 printf("Volume caches: %d\n", c1->nVolumeCaches);
77 printf("Chunk size: %d", c1->otherChunkSize);
78 if (c1->firstChunkSize != c1->otherChunkSize)
79 printf(" (first: %d)", c1->firstChunkSize);
81 printf("Cache size: %d kB\n", c1->cacheSize);
82 printf("Set time: %s\n", c1->setTime ? "yes" : "no");
83 printf("Cache type: %s\n", c1->memCache ? "memory" : "disk");
85 printf("cmdebug: unsupported server version %d\n", srv_ver);
89 #ifndef CAPABILITY_BITS
90 #define CAPABILITY_ERRORTRANS (1<<0)
91 #define CAPABILITY_BITS 1
95 PrintInterfaces(struct rx_connection *aconn)
98 struct interfaceAddr addr;
102 caps.Capabilities_val = NULL;
103 caps.Capabilities_len = 0;
105 code = RXAFSCB_TellMeAboutYourself(aconn, &addr, &caps);
106 if (code == RXGEN_OPCODE)
107 code = RXAFSCB_WhoAreYou(aconn, &addr);
109 printf("cmdebug: error checking interfaces: %s\n",
110 error_message(code));
114 UuidToString((UUID *)&addr.uuid, &p);
115 printf("UUID: %s\n",p);
118 printf("Host interfaces:\n");
119 for (i = 0; i < addr.numberOfInterfaces; i++) {
120 printf("%s", afs_inet_ntoa(htonl(addr.addr_in[i])));
121 if (addr.subnetmask[i])
122 printf(", netmask %s", afs_inet_ntoa(htonl(addr.subnetmask[i])));
124 printf(", MTU %d", addr.mtu[i]);
128 if (caps.Capabilities_val) {
129 printf("Capabilities:\n");
130 if (caps.Capabilities_val[0] & CAPABILITY_ERRORTRANS) {
131 printf("Error Translation\n");
136 if (caps.Capabilities_val)
137 free(caps.Capabilities_val);
138 caps.Capabilities_val = NULL;
139 caps.Capabilities_len = 0;
145 IsLocked(register struct AFSDBLockDesc *alock)
147 if (alock->waitStates || alock->exclLocked || alock->numWaiting
148 || alock->readersReading)
154 PrintLock(register struct AFSDBLockDesc *alock)
157 if (alock->waitStates) {
158 if (alock->waitStates & READ_LOCK)
159 printf("reader_waiting");
160 if (alock->waitStates & WRITE_LOCK)
161 printf("writer_waiting");
162 if (alock->waitStates & SHARED_LOCK)
163 printf("upgrade_waiting");
165 printf("none_waiting");
166 if (alock->exclLocked) {
167 if (alock->exclLocked & WRITE_LOCK)
168 printf(", write_locked");
169 if (alock->exclLocked & SHARED_LOCK)
170 printf(", upgrade_locked");
171 printf("(pid:%d at:%d)", alock->pid_writer, alock->src_indicator);
173 if (alock->readersReading)
174 printf(", %d read_locks(pid:%d)", alock->readersReading,
175 alock->pid_last_reader);
176 if (alock->numWaiting)
177 printf(", %d waiters", alock->numWaiting);
183 PrintLocks(register struct rx_connection *aconn, int aint32)
186 struct AFSDBLock lock;
189 for (i = 0; i < 1000; i++) {
190 code = RXAFSCB_GetLock(aconn, i, &lock);
194 /* otherwise we have an unrecognized error */
195 printf("cmdebug: error checking locks: %s\n",
196 error_message(code));
199 /* here we have the lock information, so display it, perhaps */
200 if (aint32 || IsLocked(&lock.lock)) {
201 printf("Lock %s status: ", lock.name);
202 PrintLock(&lock.lock);
212 struct cell_cache *next;
216 GetCellName(struct rx_connection *aconn, afs_int32 cellnum)
218 static int no_getcellbynum;
219 static struct cell_cache *cache;
220 struct cell_cache *tcp;
228 for (tcp = cache; tcp; tcp = tcp->next)
229 if (tcp->cellnum == cellnum)
230 return tcp->cellname;
233 sl.serverList_len = 0;
234 sl.serverList_val = NULL;
235 code = RXAFSCB_GetCellByNum(aconn, cellnum, &cellname, &sl);
237 if (code == RXGEN_OPCODE)
242 if (sl.serverList_val)
243 free(sl.serverList_val);
244 tcp = malloc(sizeof(struct cell_cache));
246 tcp->cellnum = cellnum;
247 tcp->cellname = cellname;
254 PrintCacheEntries32(struct rx_connection *aconn, int aint32)
257 register afs_int32 code;
258 struct AFSDBCacheEntry centry;
261 for (i = 0; i < 10000; i++) {
262 code = RXAFSCB_GetCE(aconn, i, ¢ry);
266 printf("cmdebug: failed to get cache entry %d (%s)\n", i,
267 error_message(code));
271 if (centry.addr == 0) {
273 printf("Proc %4d sleeping at %08x, pri %3d\n",
274 centry.netFid.Vnode, centry.netFid.Volume,
275 centry.netFid.Unique - 25);
279 if (aint32 == 0 && !IsLocked(¢ry.lock) ||
280 aint32 == 2 && centry.refCount == 0 ||
281 aint32 == 4 && centry.callback == 0)
284 /* otherwise print this entry */
285 printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr,
286 centry.cell, centry.netFid.Volume, centry.netFid.Vnode,
287 centry.netFid.Unique);
289 cellname = GetCellName(aconn, centry.cell);
291 printf(" [%s]\n", cellname);
295 if (IsLocked(¢ry.lock)) {
297 PrintLock(¢ry.lock);
300 printf(" %012d bytes DV %012d refcnt %05d\n", centry.Length,
301 centry.DataVersion, centry.refCount);
302 printf(" callback %08x\texpires %u\n", centry.callback,
304 printf(" %d opens\t%d writers\n", centry.opens, centry.writers);
306 /* now display states */
308 if (centry.mvstat == 0)
309 printf("normal file");
310 else if (centry.mvstat == 1)
311 printf("mount point");
312 else if (centry.mvstat == 2)
313 printf("volume root");
314 else if (centry.mvstat == 3)
316 else if (centry.mvstat == 4)
318 else if (centry.mvstat == 5)
319 printf("microsoft dfs link");
320 else if (centry.mvstat == 6)
321 printf("invalid link");
323 printf("bogus mvstat %d", centry.mvstat);
324 printf("\n states (0x%x)", centry.states);
325 if (centry.states & 1)
327 if (centry.states & 2)
329 if (centry.states & 4)
330 printf(", read-only");
331 if (centry.states & 8)
332 printf(", mt pt valid");
333 if (centry.states & 0x10)
334 printf(", pending core");
335 if (centry.states & 0x40)
336 printf(", wait-for-store");
337 if (centry.states & 0x80)
345 PrintCacheEntries64(struct rx_connection *aconn, int aint32)
348 register afs_int32 code;
349 struct AFSDBCacheEntry64 centry;
353 for (i = 0; i < 10000; i++) {
354 code = RXAFSCB_GetCE64(aconn, i, ¢ry);
358 printf("cmdebug: failed to get cache entry %d (%s)\n", i,
359 error_message(code));
363 if (centry.addr == 0) {
365 printf("Proc %4d sleeping at %08x, pri %3d\n",
366 centry.netFid.Vnode, centry.netFid.Volume,
367 centry.netFid.Unique - 25);
371 if (aint32 == 0 && !IsLocked(¢ry.lock) ||
372 aint32 == 2 && centry.refCount == 0 ||
373 aint32 == 4 && centry.callback == 0)
376 /* otherwise print this entry */
377 printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr,
378 centry.cell, centry.netFid.Volume, centry.netFid.Vnode,
379 centry.netFid.Unique);
381 cellname = GetCellName(aconn, centry.cell);
383 printf(" [%s]\n", cellname);
387 if (IsLocked(¢ry.lock)) {
389 PrintLock(¢ry.lock);
393 printf(" %012I64d bytes DV %012d refcnt %05d\n", centry.Length,
394 centry.DataVersion, centry.refCount);
396 printf(" %012d bytes DV %012d refcnt %05d\n", centry.Length,
397 centry.DataVersion, centry.refCount);
399 printf(" callback %08x\texpires %u\n", centry.callback,
401 printf(" %d opens\t%d writers\n", centry.opens, centry.writers);
403 /* now display states */
405 if (centry.mvstat == 0)
406 printf("normal file");
407 else if (centry.mvstat == 1)
408 printf("mount point");
409 else if (centry.mvstat == 2)
410 printf("volume root");
411 else if (centry.mvstat == 3)
413 else if (centry.mvstat == 4)
415 else if (centry.mvstat == 5)
416 printf("microsoft dfs link");
417 else if (centry.mvstat == 6)
418 printf("invalid link");
420 printf("bogus mvstat %d", centry.mvstat);
421 printf("\n states (0x%x)", centry.states);
422 if (centry.states & 1)
424 if (centry.states & 2)
426 if (centry.states & 4)
427 printf(", read-only");
428 if (centry.states & 8)
429 printf(", mt pt valid");
430 if (centry.states & 0x10)
431 printf(", pending core");
432 if (centry.states & 0x40)
433 printf(", wait-for-store");
434 if (centry.states & 0x80)
442 PrintCacheEntries(struct rx_connection *aconn, int aint32)
444 register afs_int32 code;
445 struct AFSDBCacheEntry64 centry64;
447 code = RXAFSCB_GetCE64(aconn, 0, ¢ry64);
448 if (code != RXGEN_OPCODE)
449 return PrintCacheEntries64(aconn, aint32);
451 return PrintCacheEntries32(aconn, aint32);
455 CommandProc(struct cmd_syndesc *as)
457 struct rx_connection *conn;
458 register char *hostName;
459 register struct hostent *thp;
461 struct rx_securityClass *secobj;
465 hostName = as->parms[0].items->data;
466 if (as->parms[1].items)
467 port = atoi(as->parms[1].items->data);
470 thp = hostutil_GetHostByName(hostName);
472 printf("cmdebug: can't resolve address for host %s.\n", hostName);
475 memcpy(&addr, thp->h_addr, sizeof(afs_int32));
476 secobj = rxnull_NewServerSecurityObject();
477 conn = rx_NewConnection(addr, htons(port), 1, secobj, 0);
479 printf("cmdebug: failed to create connection for host %s\n",
483 if (as->parms[5].items) {
485 PrintInterfaces(conn);
488 if (as->parms[6].items) {
490 PrintCacheConfig(conn);
493 if (as->parms[2].items)
496 else if (as->parms[3].items)
499 else if (as->parms[4].items)
505 if (int32p == 0 || int32p == 1)
506 PrintLocks(conn, int32p);
507 if (int32p >= 0 || int32p <= 4)
508 PrintCacheEntries(conn, int32p);
513 #include "AFS_component_version_number.c"
517 main(int argc, char **argv)
519 register struct cmd_syndesc *ts;
523 * The following signal action for AIX is necessary so that in case of a
524 * crash (i.e. core is generated) we can include the user's data section
525 * in the core dump. Unfortunately, by default, only a partial core is
526 * generated which, in many cases, isn't too useful.
528 struct sigaction nsa;
530 sigemptyset(&nsa.sa_mask);
531 nsa.sa_handler = SIG_DFL;
532 nsa.sa_flags = SA_FULLDUMP;
533 sigaction(SIGSEGV, &nsa, NULL);
537 if (afs_winsockInit() < 0) {
538 printf("%s: Couldn't initialize winsock. Exiting...\n", argv[0]);
545 ts = cmd_CreateSyntax(NULL, CommandProc, 0, "probe unik server");
546 cmd_AddParm(ts, "-servers", CMD_SINGLE, CMD_REQUIRED, "server machine");
547 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
548 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
549 cmd_AddParm(ts, "-refcounts", CMD_FLAG, CMD_OPTIONAL,
550 "print only cache entries with positive reference counts");
551 cmd_AddParm(ts, "-callbacks", CMD_FLAG, CMD_OPTIONAL,
552 "print only cache entries with callbacks");
553 cmd_AddParm(ts, "-addrs", CMD_FLAG, CMD_OPTIONAL,
554 "print only host interfaces");
555 cmd_AddParm(ts, "-cache", CMD_FLAG, CMD_OPTIONAL,
556 "print only cache configuration");
558 cmd_Dispatch(argc, argv);