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>
19 #include <afs/afscbint.h>
23 #include <afs/afs_args.h>
24 #include <afs/afsutil.h>
25 #include <afs/com_err.h>
27 static int print_ctime
= 0;
30 PrintCacheConfig(struct rx_connection
*aconn
)
33 afs_uint32 srv_ver
, conflen
;
36 c
.cacheConfig_len
= 0;
37 c
.cacheConfig_val
= NULL
;
38 code
= RXAFSCB_GetCacheConfig(aconn
, 1, &srv_ver
, &conflen
, &c
);
40 printf("cmdebug: error checking cache config: %s\n",
41 afs_error_message(code
));
45 if (srv_ver
== AFS_CLIENT_RETRIEVAL_FIRST_EDITION
) {
46 struct cm_initparams_v1
*c1
;
48 if (c
.cacheConfig_len
!= sizeof(*c1
) / sizeof(afs_uint32
)) {
49 printf("cmdebug: configuration data size mismatch (%d != %" AFS_SIZET_FMT
")\n",
50 c
.cacheConfig_len
, sizeof(*c1
) / sizeof(afs_uint32
));
54 c1
= (struct cm_initparams_v1
*)c
.cacheConfig_val
;
55 printf("Chunk files: %d\n", c1
->nChunkFiles
);
56 printf("Stat caches: %d\n", c1
->nStatCaches
);
57 printf("Data caches: %d\n", c1
->nDataCaches
);
58 printf("Volume caches: %d\n", c1
->nVolumeCaches
);
59 printf("Chunk size: %d", c1
->otherChunkSize
);
60 if (c1
->firstChunkSize
!= c1
->otherChunkSize
)
61 printf(" (first: %d)", c1
->firstChunkSize
);
63 printf("Cache size: %d kB\n", c1
->cacheSize
);
64 printf("Set time: %s\n", c1
->setTime
? "yes" : "no");
65 printf("Cache type: %s\n", c1
->memCache
? "memory" : "disk");
67 printf("cmdebug: unsupported server version %d\n", srv_ver
);
72 #ifndef CAPABILITY_BITS
73 #define CAPABILITY_ERRORTRANS (1<<0)
74 #define CAPABILITY_BITS 1
78 PrintInterfaces(struct rx_connection
*aconn
)
81 struct interfaceAddr addr
;
90 caps
.Capabilities_val
= NULL
;
91 caps
.Capabilities_len
= 0;
93 code
= RXAFSCB_TellMeAboutYourself(aconn
, &addr
, &caps
);
94 if (code
== RXGEN_OPCODE
)
95 code
= RXAFSCB_WhoAreYou(aconn
, &addr
);
97 printf("cmdebug: error checking interfaces: %s\n",
98 afs_error_message(code
));
103 UuidToString((UUID
*)&addr
.uuid
, &p
);
104 printf("UUID: %s\n",p
);
107 afsUUID_to_string(&addr
.uuid
, uuidstr
, sizeof(uuidstr
));
108 printf("UUID: %s\n",uuidstr
);
111 printf("Host interfaces:\n");
112 for (i
= 0; i
< addr
.numberOfInterfaces
; i
++) {
113 printf("%s", afs_inet_ntoa_r(htonl(addr
.addr_in
[i
]), hoststr
));
114 if (addr
.subnetmask
[i
])
115 printf(", netmask %s", afs_inet_ntoa_r(htonl(addr
.subnetmask
[i
]), hoststr
));
117 printf(", MTU %d", addr
.mtu
[i
]);
121 if (caps
.Capabilities_val
) {
122 printf("Capabilities:\n");
123 if (caps
.Capabilities_val
[0] & CAPABILITY_ERRORTRANS
) {
124 printf("Error Translation\n");
129 if (caps
.Capabilities_val
)
130 free(caps
.Capabilities_val
);
131 caps
.Capabilities_val
= NULL
;
132 caps
.Capabilities_len
= 0;
138 IsLocked(struct AFSDBLockDesc
*alock
)
140 if (alock
->waitStates
|| alock
->exclLocked
|| alock
->numWaiting
141 || alock
->readersReading
)
147 PrintLock(struct AFSDBLockDesc
*alock
)
150 if (alock
->waitStates
) {
151 if (alock
->waitStates
& READ_LOCK
)
152 printf("reader_waiting");
153 if (alock
->waitStates
& WRITE_LOCK
)
154 printf("writer_waiting");
155 if (alock
->waitStates
& SHARED_LOCK
)
156 printf("upgrade_waiting");
158 printf("none_waiting");
159 if (alock
->exclLocked
) {
160 if (alock
->exclLocked
& WRITE_LOCK
)
161 printf(", write_locked");
162 if (alock
->exclLocked
& SHARED_LOCK
)
163 printf(", upgrade_locked");
164 printf("(pid:%d at:%d)", alock
->pid_writer
, alock
->src_indicator
);
166 if (alock
->readersReading
)
167 printf(", %d read_locks(pid:%d)", alock
->readersReading
,
168 alock
->pid_last_reader
);
169 if (alock
->numWaiting
)
170 printf(", %d waiters", alock
->numWaiting
);
176 PrintLocks(struct rx_connection
*aconn
, int aint32
)
179 struct AFSDBLock lock
;
182 for (i
= 0; i
< 1000; i
++) {
183 code
= RXAFSCB_GetLock(aconn
, i
, &lock
);
187 /* otherwise we have an unrecognized error */
188 printf("cmdebug: error checking locks: %s\n",
189 afs_error_message(code
));
192 /* here we have the lock information, so display it, perhaps */
193 if (aint32
|| IsLocked(&lock
.lock
)) {
194 printf("Lock %s status: ", lock
.name
);
195 PrintLock(&lock
.lock
);
205 struct cell_cache
*next
;
209 GetCellName(struct rx_connection
*aconn
, afs_int32 cellnum
)
211 static int no_getcellbynum
;
212 static struct cell_cache
*cache
;
213 struct cell_cache
*tcp
;
221 for (tcp
= cache
; tcp
; tcp
= tcp
->next
)
222 if (tcp
->cellnum
== cellnum
)
223 return tcp
->cellname
;
226 sl
.serverList_len
= 0;
227 sl
.serverList_val
= NULL
;
228 code
= RXAFSCB_GetCellByNum(aconn
, cellnum
, &cellname
, &sl
);
230 if (code
== RXGEN_OPCODE
)
235 if (sl
.serverList_val
)
236 free(sl
.serverList_val
);
237 tcp
= malloc(sizeof(struct cell_cache
));
239 tcp
->cellnum
= cellnum
;
240 tcp
->cellname
= cellname
;
247 PrintCacheEntries32(struct rx_connection
*aconn
, int aint32
)
251 struct AFSDBCacheEntry centry
;
254 for (i
= 0; i
< 1000000; i
++) {
255 code
= RXAFSCB_GetCE(aconn
, i
, ¢ry
);
259 printf("cmdebug: failed to get cache entry %d (%s)\n", i
,
260 afs_error_message(code
));
264 if (centry
.addr
== 0) {
266 printf("Proc %4d sleeping at %08x, pri %3d\n",
267 centry
.netFid
.Vnode
, centry
.netFid
.Volume
,
268 centry
.netFid
.Unique
- 25);
272 if ((aint32
== 0 && !IsLocked(¢ry
.lock
)) ||
273 (aint32
== 2 && centry
.refCount
== 0) ||
274 (aint32
== 4 && centry
.callback
== 0))
277 /* otherwise print this entry */
278 printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry
.addr
,
279 centry
.cell
, centry
.netFid
.Volume
, centry
.netFid
.Vnode
,
280 centry
.netFid
.Unique
);
282 cellname
= GetCellName(aconn
, centry
.cell
);
284 printf(" [%s]\n", cellname
);
288 if (IsLocked(¢ry
.lock
)) {
290 PrintLock(¢ry
.lock
);
293 printf(" %12d bytes DV %12d refcnt %5d\n", centry
.Length
,
294 centry
.DataVersion
, centry
.refCount
);
296 time_t t
= centry
.cbExpires
;
297 printf(" callback %08x\texpires %s\n", centry
.callback
,
300 printf(" callback %08x\texpires %u\n", centry
.callback
,
302 printf(" %d opens\t%d writers\n", centry
.opens
, centry
.writers
);
304 /* now display states */
306 if (centry
.mvstat
== 0)
307 printf("normal file");
308 else if (centry
.mvstat
== 1)
309 printf("mount point");
310 else if (centry
.mvstat
== 2)
311 printf("volume root");
312 else if (centry
.mvstat
== 3) /* windows */
314 else if (centry
.mvstat
== 4) /* windows */
316 else if (centry
.mvstat
== 5) /* windows */
317 printf("microsoft dfs link");
318 else if (centry
.mvstat
== 6) /* windows */
319 printf("invalid link");
321 printf("bogus mvstat %d", centry
.mvstat
);
322 printf("\n states (0x%x)", centry
.states
);
323 if (centry
.states
& 1)
325 if (centry
.states
& 2)
327 if (centry
.states
& 4)
328 printf(", read-only");
329 if (centry
.states
& 8)
330 printf(", mt pt valid");
331 if (centry
.states
& 0x10)
332 printf(", pending core");
333 if (centry
.states
& 0x40)
334 printf(", wait-for-store");
335 if (centry
.states
& 0x80)
343 PrintCacheEntries64(struct rx_connection
*aconn
, int aint32
)
347 struct AFSDBCacheEntry64 centry
;
350 for (i
= 0; i
< 1000000; i
++) {
351 code
= RXAFSCB_GetCE64(aconn
, i
, ¢ry
);
355 printf("cmdebug: failed to get cache entry %d (%s)\n", i
,
356 afs_error_message(code
));
360 if (centry
.addr
== 0) {
362 printf("Proc %4d sleeping at %08x, pri %3d\n",
363 centry
.netFid
.Vnode
, centry
.netFid
.Volume
,
364 centry
.netFid
.Unique
- 25);
368 if ((aint32
== 0 && !IsLocked(¢ry
.lock
)) ||
369 (aint32
== 2 && centry
.refCount
== 0) ||
370 (aint32
== 4 && centry
.callback
== 0))
373 /* otherwise print this entry */
374 printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry
.addr
,
375 centry
.cell
, centry
.netFid
.Volume
, centry
.netFid
.Vnode
,
376 centry
.netFid
.Unique
);
378 cellname
= GetCellName(aconn
, centry
.cell
);
380 printf(" [%s]\n", cellname
);
384 if (IsLocked(¢ry
.lock
)) {
386 PrintLock(¢ry
.lock
);
390 printf(" %12I64d bytes DV %12d refcnt %5d\n", centry
.Length
,
391 centry
.DataVersion
, centry
.refCount
);
393 printf(" %12llu bytes DV %12d refcnt %5d\n", centry
.Length
,
394 centry
.DataVersion
, centry
.refCount
);
397 time_t t
= centry
.cbExpires
;
398 printf(" callback %08x\texpires %s\n", centry
.callback
,
401 printf(" callback %08x\texpires %u\n", centry
.callback
,
403 printf(" %d opens\t%d writers\n", centry
.opens
, centry
.writers
);
405 /* now display states */
407 if (centry
.mvstat
== 0)
408 printf("normal file");
409 else if (centry
.mvstat
== 1)
410 printf("mount point");
411 else if (centry
.mvstat
== 2)
412 printf("volume root");
413 else if (centry
.mvstat
== 3)
415 else if (centry
.mvstat
== 4)
417 else if (centry
.mvstat
== 5)
418 printf("microsoft dfs link");
419 else if (centry
.mvstat
== 6)
420 printf("invalid link");
422 printf("bogus mvstat %d", centry
.mvstat
);
423 printf("\n states (0x%x)", centry
.states
);
424 if (centry
.states
& 1)
426 if (centry
.states
& 2)
428 if (centry
.states
& 4)
429 printf(", read-only");
430 if (centry
.states
& 8)
431 printf(", mt pt valid");
432 if (centry
.states
& 0x10)
433 printf(", pending core");
434 if (centry
.states
& 0x40)
435 printf(", wait-for-store");
436 if (centry
.states
& 0x80)
444 PrintCacheEntries(struct rx_connection
*aconn
, int aint32
)
447 struct AFSDBCacheEntry64 centry64
;
449 code
= RXAFSCB_GetCE64(aconn
, 0, ¢ry64
);
450 if (code
!= RXGEN_OPCODE
)
451 return PrintCacheEntries64(aconn
, aint32
);
453 return PrintCacheEntries32(aconn
, aint32
);
457 PrintCellServDBEntry(struct rx_connection
*aconn
, afs_int32 cellnum
)
466 sl
.serverList_len
= 0;
467 sl
.serverList_val
= NULL
;
468 code
= RXAFSCB_GetCellServDB(aconn
, cellnum
, &cellname
, &sl
);
472 if ( !cellname
|| !cellname
[0] )
476 printf(">%-23s#%s\n", cellname
, cellname
);
478 if (sl
.serverList_val
) {
480 for ( n
=0; n
<sl
.serverList_len
; n
++) {
481 struct hostent
*host
;
482 afs_uint32 addr
= ntohl(sl
.serverList_val
[n
]);
484 host
= gethostbyaddr((const char *)&addr
, sizeof(afs_uint32
), AF_INET
);
485 printf("%-28s#%s\n", afs_inet_ntoa_r(addr
, hoststr
),
486 host
? host
->h_name
: "");
494 if (sl
.serverList_val
)
495 free(sl
.serverList_val
);
501 PrintCellServDB(struct rx_connection
*aconn
)
505 for ( index
= 0 ; PrintCellServDBEntry(aconn
, index
); index
++ );
509 CommandProc(struct cmd_syndesc
*as
, void *arock
)
511 struct rx_connection
*conn
;
515 struct rx_securityClass
*secobj
;
519 hostName
= as
->parms
[0].items
->data
;
520 if (as
->parms
[1].items
)
521 port
= atoi(as
->parms
[1].items
->data
);
524 thp
= hostutil_GetHostByName(hostName
);
526 printf("cmdebug: can't resolve address for host %s.\n", hostName
);
529 memcpy(&addr
, thp
->h_addr
, sizeof(afs_int32
));
530 secobj
= rxnull_NewServerSecurityObject();
531 conn
= rx_NewConnection(addr
, htons(port
), 1, secobj
, 0);
533 printf("cmdebug: failed to create connection for host %s\n",
538 if (as
->parms
[6].items
) {
540 PrintInterfaces(conn
);
543 if (as
->parms
[7].items
) {
545 PrintCacheConfig(conn
);
549 if (as
->parms
[8].items
) {
551 PrintCellServDB(conn
);
555 if (as
->parms
[5].items
)
558 if (as
->parms
[2].items
)
561 else if (as
->parms
[3].items
)
564 else if (as
->parms
[4].items
)
570 if (int32p
== 0 || int32p
== 1)
571 PrintLocks(conn
, int32p
);
573 PrintCacheEntries(conn
, int32p
);
578 #include "AFS_component_version_number.c"
582 main(int argc
, char **argv
)
584 struct cmd_syndesc
*ts
;
588 * The following signal action for AIX is necessary so that in case of a
589 * crash (i.e. core is generated) we can include the user's data section
590 * in the core dump. Unfortunately, by default, only a partial core is
591 * generated which, in many cases, isn't too useful.
593 struct sigaction nsa
;
595 sigemptyset(&nsa
.sa_mask
);
596 nsa
.sa_handler
= SIG_DFL
;
597 nsa
.sa_flags
= SA_FULLDUMP
;
598 sigaction(SIGSEGV
, &nsa
, NULL
);
602 if (afs_winsockInit() < 0) {
603 printf("%s: Couldn't initialize winsock. Exiting...\n", argv
[0]);
610 ts
= cmd_CreateSyntax(NULL
, CommandProc
, NULL
, 0, "query afs cache manager");
611 cmd_AddParm(ts
, "-servers", CMD_SINGLE
, CMD_REQUIRED
, "server machine");
612 cmd_AddParm(ts
, "-port", CMD_SINGLE
, CMD_OPTIONAL
, "IP port");
613 cmd_AddParm(ts
, "-long", CMD_FLAG
, CMD_OPTIONAL
, "print all info");
614 cmd_AddParm(ts
, "-refcounts", CMD_FLAG
, CMD_OPTIONAL
,
615 "print only cache entries with positive reference counts");
616 cmd_AddParm(ts
, "-callbacks", CMD_FLAG
, CMD_OPTIONAL
,
617 "print only cache entries with callbacks");
618 cmd_AddParm(ts
, "-ctime", CMD_FLAG
, CMD_OPTIONAL
,
619 "print human readable expiration time");
622 cmd_AddParm(ts
, "-addrs", CMD_FLAG
, CMD_OPTIONAL
,
623 "print only host interfaces");
624 cmd_AddParm(ts
, "-cache", CMD_FLAG
, CMD_OPTIONAL
,
625 "print only cache configuration");
626 cmd_AddParm(ts
, "-cellservdb", CMD_FLAG
, CMD_OPTIONAL
,
627 "print only cellservdb info");
629 cmd_Dispatch(argc
, argv
);