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>
16 #include <sys/types.h>
17 #include <netinet/in.h>
18 #include <sys/socket.h>
31 #include <afs/afscbint.h>
35 #include <afs/afs_args.h>
37 extern struct hostent *hostutil_GetHostByName();
39 static PrintCacheConfig(aconn)
40 struct rx_connection *aconn;
43 afs_uint32 srv_ver, conflen;
46 c.cacheConfig_len = 0;
47 c.cacheConfig_val = NULL;
48 code = RXAFSCB_GetCacheConfig(aconn, 1, &srv_ver, &conflen, &c);
50 printf("cmdebug: error checking cache config: %s\n",
55 if (srv_ver == AFS_CLIENT_RETRIEVAL_FIRST_EDITION) {
56 struct cm_initparams_v1 *c1;
58 if (c.cacheConfig_len != sizeof(*c1) / sizeof(afs_uint32)) {
59 printf("cmdebug: configuration data size mismatch (%d != %d)\n",
60 c.cacheConfig_len, sizeof(*c1) / sizeof(afs_uint32));
64 c1 = (struct cm_initparams_v1 *) c.cacheConfig_val;
65 printf("Chunk files: %d\n", c1->nChunkFiles);
66 printf("Stat caches: %d\n", c1->nStatCaches);
67 printf("Data caches: %d\n", c1->nDataCaches);
68 printf("Volume caches: %d\n", c1->nVolumeCaches);
69 printf("Chunk size: %d", c1->otherChunkSize);
70 if (c1->firstChunkSize != c1->otherChunkSize)
71 printf(" (first: %d)", c1->firstChunkSize);
73 printf("Cache size: %d kB\n", c1->cacheSize);
74 printf("Set time: %s\n", c1->setTime ? "yes" : "no");
75 printf("Cache type: %s\n", c1->memCache ? "memory" : "disk");
77 printf("cmdebug: unsupported server version %d\n", srv_ver);
81 static PrintInterfaces(aconn)
82 struct rx_connection *aconn;
84 struct interfaceAddr addr;
87 code = RXAFSCB_WhoAreYou(aconn, &addr);
89 printf("cmdebug: error checking interfaces: %s\n", error_message(code));
93 printf("Host interfaces:\n");
94 for (i=0; i<addr.numberOfInterfaces; i++) {
95 printf("%s", inet_ntoa(&addr.addr_in[i]));
96 if (addr.subnetmask[i])
97 printf(", netmask %s", inet_ntoa(&addr.subnetmask[i]));
99 printf(", MTU %d", addr.mtu[i]);
106 static IsLocked(alock)
107 register struct AFSDBLockDesc *alock; {
108 if (alock->waitStates || alock->exclLocked
109 || alock->numWaiting || alock->readersReading)
114 static PrintLock(alock)
115 register struct AFSDBLockDesc *alock; {
117 if (alock->waitStates) {
118 if (alock->waitStates & READ_LOCK)
119 printf("reader_waiting");
120 if (alock->waitStates & WRITE_LOCK)
121 printf("writer_waiting");
122 if (alock->waitStates & SHARED_LOCK)
123 printf("upgrade_waiting");
126 printf("none_waiting");
127 if (alock->exclLocked) {
128 if (alock->exclLocked & WRITE_LOCK)
129 printf(", write_locked");
130 if (alock->exclLocked & SHARED_LOCK)
131 printf(", upgrade_locked");
132 printf("(pid:%d at:%d)", alock->pid_writer, alock->src_indicator);
134 if (alock->readersReading)
135 printf(", %d read_locks(pid:%d)", alock->readersReading,alock->pid_last_reader);
136 if (alock->numWaiting) printf(", %d waiters", alock->numWaiting);
141 static PrintLocks(aconn, aint32)
143 register struct rx_connection *aconn; {
145 struct AFSDBLock lock;
148 for(i=0;i<1000;i++) {
149 code = RXAFSCB_GetLock(aconn, i, &lock);
151 if (code == 1) break;
152 /* otherwise we have an unrecognized error */
153 printf("cmdebug: error checking locks: %s\n", error_message(code));
156 /* here we have the lock information, so display it, perhaps */
157 if (aint32 || IsLocked(&lock.lock)) {
158 printf("Lock %s status: ", lock.name);
159 PrintLock(&lock.lock);
169 struct cell_cache *next;
172 static char *GetCellName(struct rx_connection *aconn, afs_int32 cellnum)
174 static int no_getcellbynum;
175 static struct cell_cache *cache;
176 struct cell_cache *tcp;
184 for (tcp = cache; tcp; tcp = tcp->next)
185 if (tcp->cellnum == cellnum)
186 return tcp->cellname;
189 sl.serverList_len = 0;
190 sl.serverList_val = NULL;
191 code = RXAFSCB_GetCellByNum(aconn, cellnum, &cellname, &sl);
193 if (code == RXGEN_OPCODE)
198 if (sl.serverList_val)
199 free (sl.serverList_val);
200 tcp = malloc(sizeof(struct cell_cache));
202 tcp->cellnum = cellnum;
203 tcp->cellname = cellname;
209 static PrintCacheEntries(struct rx_connection *aconn, int aint32)
212 register afs_int32 code;
213 struct AFSDBCacheEntry centry;
216 for(i=0;i<10000;i++) {
217 code = RXAFSCB_GetCE(aconn, i, ¢ry);
219 if (code == 1) break;
220 printf("cmdebug: failed to get cache entry %d (%s)\n", i,
221 error_message(code));
225 if (centry.addr == 0) {
227 printf("Proc %4d sleeping at %08x, pri %3d\n",
228 centry.netFid.Vnode, centry.netFid.Volume, centry.netFid.Unique-25);
232 if (!aint32 && !IsLocked(¢ry.lock)) continue;
234 /* otherwise print this entry */
235 printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr,
236 centry.cell, centry.netFid.Volume, centry.netFid.Vnode,
237 centry.netFid.Unique);
239 cellname = GetCellName(aconn, centry.cell);
241 printf(" [%s]\n", cellname);
245 if (IsLocked(¢ry.lock)) {
247 PrintLock(¢ry.lock);
250 printf(" %d bytes\tDV %d refcnt %d\n", centry.Length, centry.DataVersion, centry.refCount);
251 printf(" callback %08x\texpires %u\n", centry.callback, centry.cbExpires);
252 printf(" %d opens\t%d writers\n", centry.opens, centry.writers);
254 /* now display states */
256 if (centry.mvstat == 0) printf("normal file");
257 else if (centry.mvstat == 1) printf("mount point");
258 else if (centry.mvstat == 2) printf("volume root");
259 else printf("bogus mvstat %d", centry.mvstat);
260 printf("\n states (0x%x)", centry.states);
261 if (centry.states & 1) printf(", stat'd");
262 if (centry.states & 2) printf(", backup");
263 if (centry.states & 4) printf(", read-only");
264 if (centry.states & 8) printf(", mt pt valid");
265 if (centry.states & 0x10) printf(", pending core");
266 if (centry.states & 0x40) printf(", wait-for-store");
267 if (centry.states & 0x80) printf(", mapped");
273 static CommandProc(as)
274 struct cmd_syndesc *as; {
275 struct rx_connection *conn;
276 register char *hostName;
277 register struct hostent *thp;
279 struct rx_securityClass *secobj;
283 hostName = as->parms[0].items->data;
284 if (as->parms[1].items)
285 port = atoi(as->parms[1].items->data);
288 thp = hostutil_GetHostByName(hostName);
290 printf("cmdebug: can't resolve address for host %s.\n", hostName);
293 memcpy(&addr, thp->h_addr, sizeof(afs_int32));
294 secobj = rxnull_NewServerSecurityObject();
295 conn = rx_NewConnection(addr, htons(port), 1, secobj, 0);
297 printf("cmdebug: failed to create connection for host %s\n", hostName);
300 if (as->parms[3].items) {
302 PrintInterfaces(conn);
305 if (as->parms[4].items) {
307 PrintCacheConfig(conn);
310 if (as->parms[2].items) int32p = 1;
312 PrintLocks(conn, int32p);
313 PrintCacheEntries(conn, int32p);
317 #include "AFS_component_version_number.c"
322 register struct cmd_syndesc *ts;
326 * The following signal action for AIX is necessary so that in case of a
327 * crash (i.e. core is generated) we can include the user's data section
328 * in the core dump. Unfortunately, by default, only a partial core is
329 * generated which, in many cases, isn't too useful.
331 struct sigaction nsa;
333 sigemptyset(&nsa.sa_mask);
334 nsa.sa_handler = SIG_DFL;
335 nsa.sa_flags = SA_FULLDUMP;
336 sigaction(SIGSEGV, &nsa, NULL);
340 ts = cmd_CreateSyntax(NULL, CommandProc, 0, "probe unik server");
341 cmd_AddParm(ts, "-servers", CMD_SINGLE, CMD_REQUIRED, "server machine");
342 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
343 cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
344 cmd_AddParm(ts, "-addrs", CMD_FLAG, CMD_OPTIONAL, "print only host interfaces");
345 cmd_AddParm(ts, "-cache", CMD_FLAG, CMD_OPTIONAL, "print only cache configuration");
347 cmd_Dispatch(argc, argv);