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>
44 #include <afs/afsutil.h>
45 #include <afs/com_err.h>
47 extern struct hostent *hostutil_GetHostByName();
50 PrintCacheConfig(struct rx_connection *aconn)
53 afs_uint32 srv_ver, conflen;
56 c.cacheConfig_len = 0;
57 c.cacheConfig_val = NULL;
58 code = RXAFSCB_GetCacheConfig(aconn, 1, &srv_ver, &conflen, &c);
60 printf("cmdebug: error checking cache config: %s\n",
61 afs_error_message(code));
65 if (srv_ver == AFS_CLIENT_RETRIEVAL_FIRST_EDITION) {
66 struct cm_initparams_v1 *c1;
68 if (c.cacheConfig_len != sizeof(*c1) / sizeof(afs_uint32)) {
69 printf("cmdebug: configuration data size mismatch (%d != %d)\n",
70 c.cacheConfig_len, sizeof(*c1) / sizeof(afs_uint32));
74 c1 = (struct cm_initparams_v1 *)c.cacheConfig_val;
75 printf("Chunk files: %d\n", c1->nChunkFiles);
76 printf("Stat caches: %d\n", c1->nStatCaches);
77 printf("Data caches: %d\n", c1->nDataCaches);
78 printf("Volume caches: %d\n", c1->nVolumeCaches);
79 printf("Chunk size: %d", c1->otherChunkSize);
80 if (c1->firstChunkSize != c1->otherChunkSize)
81 printf(" (first: %d)", c1->firstChunkSize);
83 printf("Cache size: %d kB\n", c1->cacheSize);
84 printf("Set time: %s\n", c1->setTime ? "yes" : "no");
85 printf("Cache type: %s\n", c1->memCache ? "memory" : "disk");
87 printf("cmdebug: unsupported server version %d\n", srv_ver);
91 #ifndef CAPABILITY_BITS
92 #define CAPABILITY_ERRORTRANS (1<<0)
93 #define CAPABILITY_BITS 1
97 PrintInterfaces(struct rx_connection *aconn)
100 struct interfaceAddr addr;
108 caps.Capabilities_val = NULL;
109 caps.Capabilities_len = 0;
111 code = RXAFSCB_TellMeAboutYourself(aconn, &addr, &caps);
112 if (code == RXGEN_OPCODE)
113 code = RXAFSCB_WhoAreYou(aconn, &addr);
115 printf("cmdebug: error checking interfaces: %s\n",
116 afs_error_message(code));
121 UuidToString((UUID *)&addr.uuid, &p);
122 printf("UUID: %s\n",p);
125 afsUUID_to_string(&addr.uuid, uuidstr, sizeof(uuidstr));
126 printf("UUID: %s\n",uuidstr);
129 printf("Host interfaces:\n");
130 for (i = 0; i < addr.numberOfInterfaces; i++) {
131 printf("%s", afs_inet_ntoa(htonl(addr.addr_in[i])));
132 if (addr.subnetmask[i])
133 printf(", netmask %s", afs_inet_ntoa(htonl(addr.subnetmask[i])));
135 printf(", MTU %d", addr.mtu[i]);
139 if (caps.Capabilities_val) {
140 printf("Capabilities:\n");
141 if (caps.Capabilities_val[0] & CAPABILITY_ERRORTRANS) {
142 printf("Error Translation\n");
147 if (caps.Capabilities_val)
148 free(caps.Capabilities_val);
149 caps.Capabilities_val = NULL;
150 caps.Capabilities_len = 0;
156 IsLocked(register struct AFSDBLockDesc *alock)
158 if (alock->waitStates || alock->exclLocked || alock->numWaiting
159 || alock->readersReading)
165 PrintLock(register struct AFSDBLockDesc *alock)
168 if (alock->waitStates) {
169 if (alock->waitStates & READ_LOCK)
170 printf("reader_waiting");
171 if (alock->waitStates & WRITE_LOCK)
172 printf("writer_waiting");
173 if (alock->waitStates & SHARED_LOCK)
174 printf("upgrade_waiting");
176 printf("none_waiting");
177 if (alock->exclLocked) {
178 if (alock->exclLocked & WRITE_LOCK)
179 printf(", write_locked");
180 if (alock->exclLocked & SHARED_LOCK)
181 printf(", upgrade_locked");
182 printf("(pid:%d at:%d)", alock->pid_writer, alock->src_indicator);
184 if (alock->readersReading)
185 printf(", %d read_locks(pid:%d)", alock->readersReading,
186 alock->pid_last_reader);
187 if (alock->numWaiting)
188 printf(", %d waiters", alock->numWaiting);
194 PrintLocks(register struct rx_connection *aconn, int aint32)
197 struct AFSDBLock lock;
200 for (i = 0; i < 1000; i++) {
201 code = RXAFSCB_GetLock(aconn, i, &lock);
205 /* otherwise we have an unrecognized error */
206 printf("cmdebug: error checking locks: %s\n",
207 afs_error_message(code));
210 /* here we have the lock information, so display it, perhaps */
211 if (aint32 || IsLocked(&lock.lock)) {
212 printf("Lock %s status: ", lock.name);
213 PrintLock(&lock.lock);
223 struct cell_cache *next;
227 GetCellName(struct rx_connection *aconn, afs_int32 cellnum)
229 static int no_getcellbynum;
230 static struct cell_cache *cache;
231 struct cell_cache *tcp;
239 for (tcp = cache; tcp; tcp = tcp->next)
240 if (tcp->cellnum == cellnum)
241 return tcp->cellname;
244 sl.serverList_len = 0;
245 sl.serverList_val = NULL;
246 code = RXAFSCB_GetCellByNum(aconn, cellnum, &cellname, &sl);
248 if (code == RXGEN_OPCODE)
253 if (sl.serverList_val)
254 free(sl.serverList_val);
255 tcp = malloc(sizeof(struct cell_cache));
257 tcp->cellnum = cellnum;
258 tcp->cellname = cellname;
265 PrintCacheEntries32(struct rx_connection *aconn, int aint32)
268 register afs_int32 code;
269 struct AFSDBCacheEntry centry;
272 for (i = 0; i < 10000; i++) {
273 code = RXAFSCB_GetCE(aconn, i, ¢ry);
277 printf("cmdebug: failed to get cache entry %d (%s)\n", i,
278 afs_error_message(code));
282 if (centry.addr == 0) {
284 printf("Proc %4d sleeping at %08x, pri %3d\n",
285 centry.netFid.Vnode, centry.netFid.Volume,
286 centry.netFid.Unique - 25);
290 if (aint32 == 0 && !IsLocked(¢ry.lock) ||
291 aint32 == 2 && centry.refCount == 0 ||
292 aint32 == 4 && centry.callback == 0)
295 /* otherwise print this entry */
296 printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr,
297 centry.cell, centry.netFid.Volume, centry.netFid.Vnode,
298 centry.netFid.Unique);
300 cellname = GetCellName(aconn, centry.cell);
302 printf(" [%s]\n", cellname);
306 if (IsLocked(¢ry.lock)) {
308 PrintLock(¢ry.lock);
311 printf(" %12d bytes DV %12d refcnt %5d\n", centry.Length,
312 centry.DataVersion, centry.refCount);
313 printf(" callback %08x\texpires %u\n", centry.callback,
315 printf(" %d opens\t%d writers\n", centry.opens, centry.writers);
317 /* now display states */
319 if (centry.mvstat == 0)
320 printf("normal file");
321 else if (centry.mvstat == 1)
322 printf("mount point");
323 else if (centry.mvstat == 2)
324 printf("volume root");
325 else if (centry.mvstat == 3) /* windows */
327 else if (centry.mvstat == 4) /* windows */
329 else if (centry.mvstat == 5) /* windows */
330 printf("microsoft dfs link");
331 else if (centry.mvstat == 6) /* windows */
332 printf("invalid link");
334 printf("bogus mvstat %d", centry.mvstat);
335 printf("\n states (0x%x)", centry.states);
336 if (centry.states & 1)
338 if (centry.states & 2)
340 if (centry.states & 4)
341 printf(", read-only");
342 if (centry.states & 8)
343 printf(", mt pt valid");
344 if (centry.states & 0x10)
345 printf(", pending core");
346 if (centry.states & 0x40)
347 printf(", wait-for-store");
348 if (centry.states & 0x80)
356 PrintCacheEntries64(struct rx_connection *aconn, int aint32)
359 register afs_int32 code;
360 struct AFSDBCacheEntry64 centry;
364 for (i = 0; i < 10000; i++) {
365 code = RXAFSCB_GetCE64(aconn, i, ¢ry);
369 printf("cmdebug: failed to get cache entry %d (%s)\n", i,
370 afs_error_message(code));
374 if (centry.addr == 0) {
376 printf("Proc %4d sleeping at %08x, pri %3d\n",
377 centry.netFid.Vnode, centry.netFid.Volume,
378 centry.netFid.Unique - 25);
382 if (aint32 == 0 && !IsLocked(¢ry.lock) ||
383 aint32 == 2 && centry.refCount == 0 ||
384 aint32 == 4 && centry.callback == 0)
387 /* otherwise print this entry */
388 printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr,
389 centry.cell, centry.netFid.Volume, centry.netFid.Vnode,
390 centry.netFid.Unique);
392 cellname = GetCellName(aconn, centry.cell);
394 printf(" [%s]\n", cellname);
398 if (IsLocked(¢ry.lock)) {
400 PrintLock(¢ry.lock);
405 printf(" %12I64d bytes DV %12d refcnt %5d\n", centry.Length,
406 centry.DataVersion, centry.refCount);
408 printf(" %12llu bytes DV %12d refcnt %5d\n", centry.Length,
409 centry.DataVersion, centry.refCount);
412 printf(" %12d bytes DV %12d refcnt %5d\n", centry.Length,
413 centry.DataVersion, centry.refCount);
415 printf(" callback %08x\texpires %u\n", centry.callback,
417 printf(" %d opens\t%d writers\n", centry.opens, centry.writers);
419 /* now display states */
421 if (centry.mvstat == 0)
422 printf("normal file");
423 else if (centry.mvstat == 1)
424 printf("mount point");
425 else if (centry.mvstat == 2)
426 printf("volume root");
427 else if (centry.mvstat == 3)
429 else if (centry.mvstat == 4)
431 else if (centry.mvstat == 5)
432 printf("microsoft dfs link");
433 else if (centry.mvstat == 6)
434 printf("invalid link");
436 printf("bogus mvstat %d", centry.mvstat);
437 printf("\n states (0x%x)", centry.states);
438 if (centry.states & 1)
440 if (centry.states & 2)
442 if (centry.states & 4)
443 printf(", read-only");
444 if (centry.states & 8)
445 printf(", mt pt valid");
446 if (centry.states & 0x10)
447 printf(", pending core");
448 if (centry.states & 0x40)
449 printf(", wait-for-store");
450 if (centry.states & 0x80)
458 PrintCacheEntries(struct rx_connection *aconn, int aint32)
460 register afs_int32 code;
461 struct AFSDBCacheEntry64 centry64;
463 code = RXAFSCB_GetCE64(aconn, 0, ¢ry64);
464 if (code != RXGEN_OPCODE)
465 return PrintCacheEntries64(aconn, aint32);
467 return PrintCacheEntries32(aconn, aint32);
471 CommandProc(struct cmd_syndesc *as, char *arock)
473 struct rx_connection *conn;
474 register char *hostName;
475 register struct hostent *thp;
477 struct rx_securityClass *secobj;
481 hostName = as->parms[0].items->data;
482 if (as->parms[1].items)
483 port = atoi(as->parms[1].items->data);
486 thp = hostutil_GetHostByName(hostName);
488 printf("cmdebug: can't resolve address for host %s.\n", hostName);
491 memcpy(&addr, thp->h_addr, sizeof(afs_int32));
492 secobj = rxnull_NewServerSecurityObject();
493 conn = rx_NewConnection(addr, htons(port), 1, secobj, 0);
495 printf("cmdebug: failed to create connection for host %s\n",
499 if (as->parms[5].items) {
501 PrintInterfaces(conn);
504 if (as->parms[6].items) {
506 PrintCacheConfig(conn);
509 if (as->parms[2].items)
512 else if (as->parms[3].items)
515 else if (as->parms[4].items)
521 if (int32p == 0 || int32p == 1)
522 PrintLocks(conn, int32p);
523 if (int32p >= 0 || int32p <= 4)
524 PrintCacheEntries(conn, int32p);
529 #include "AFS_component_version_number.c"
533 main(int argc, char **argv)
535 register struct cmd_syndesc *ts;
539 * The following signal action for AIX is necessary so that in case of a
540 * crash (i.e. core is generated) we can include the user's data section
541 * in the core dump. Unfortunately, by default, only a partial core is
542 * generated which, in many cases, isn't too useful.
544 struct sigaction nsa;
546 sigemptyset(&nsa.sa_mask);
547 nsa.sa_handler = SIG_DFL;
548 nsa.sa_flags = SA_FULLDUMP;
549 sigaction(SIGSEGV, &nsa, NULL);
553 if (afs_winsockInit() < 0) {
554 printf("%s: Couldn't initialize winsock. Exiting...\n", argv[0]);
561 ts = cmd_CreateSyntax(NULL, CommandProc, 0, "probe unik server");
562 cmd_AddParm(ts, "-servers", CMD_SINGLE, CMD_REQUIRED, "server machine");
563 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
564 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
565 cmd_AddParm(ts, "-refcounts", CMD_FLAG, CMD_OPTIONAL,
566 "print only cache entries with positive reference counts");
567 cmd_AddParm(ts, "-callbacks", CMD_FLAG, CMD_OPTIONAL,
568 "print only cache entries with callbacks");
569 cmd_AddParm(ts, "-addrs", CMD_FLAG, CMD_OPTIONAL,
570 "print only host interfaces");
571 cmd_AddParm(ts, "-cache", CMD_FLAG, CMD_OPTIONAL,
572 "print only cache configuration");
574 cmd_Dispatch(argc, argv);