465d3b9b1c455099ef6b73bc53ba95c16e1e5e0e
[openafs.git] / src / venus / cmdebug.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID("$Header$");
14
15
16 #include <sys/types.h>
17 #include <netinet/in.h>
18 #include <sys/socket.h>
19 #include <netdb.h>
20 #include <stdio.h>
21 #ifdef  AFS_AIX32_ENV
22 #include <signal.h>
23 #endif
24 #include <afs/afscbint.h>
25 #include <afs/cmd.h>
26 #include <rx/rx.h>
27 #include <lock.h>
28
29 extern struct rx_securityClass *rxnull_NewServerSecurityObject();
30 extern struct hostent *hostutil_GetHostByName();
31
32 static PrintInterfaces(aconn)
33     struct rx_connection *aconn;
34 {
35     struct interfaceAddr addr;
36     int i, code;
37
38     code = RXAFSCB_WhoAreYou(aconn, &addr);
39     if (code) {
40         printf("cmdebug: error checking locks: %s\n", error_message(code));
41         return 0;
42     }
43
44     printf("Host interfaces:\n");
45     for (i=0; i<addr.numberOfInterfaces; i++) {
46         printf("%s", inet_ntoa(&addr.addr_in[i]));
47         if (addr.subnetmask[i])
48             printf(", netmask %s", inet_ntoa(&addr.subnetmask[i]));
49         if (addr.mtu[i])
50             printf(", MTU %d", addr.mtu[i]);
51         printf("\n");
52     }
53
54     return 0;
55 }
56
57 static IsLocked(alock)
58 register struct AFSDBLockDesc *alock; {
59     if (alock->waitStates || alock->exclLocked
60         || alock->numWaiting || alock->readersReading)
61         return 1;
62     return 0;
63 }
64
65 static PrintLock(alock)
66 register struct AFSDBLockDesc *alock; {
67     printf("(");
68     if (alock->waitStates) {
69         if (alock->waitStates & READ_LOCK)
70             printf("reader_waiting");
71         if (alock->waitStates & WRITE_LOCK)
72             printf("writer_waiting");
73         if (alock->waitStates & SHARED_LOCK)
74             printf("upgrade_waiting");
75     }
76     else
77         printf("none_waiting");
78     if (alock->exclLocked) {
79         if (alock->exclLocked & WRITE_LOCK)
80             printf(", write_locked");
81         if (alock->exclLocked & SHARED_LOCK)
82             printf(", upgrade_locked");
83         printf("(pid:%d at:%d)", alock->pid_writer, alock->src_indicator);
84     }
85     if (alock->readersReading)
86         printf(", %d read_locks(pid:%d)", alock->readersReading,alock->pid_last_reader);
87     if (alock->numWaiting) printf(", %d waiters", alock->numWaiting);
88     printf(")");
89     return 0;
90 }
91
92 static PrintLocks(aconn, aint32)
93 int aint32;
94 register struct rx_connection *aconn; {
95     register int i;
96     struct AFSDBLock lock;
97     afs_int32 code;
98
99     for(i=0;i<1000;i++) {
100         code = RXAFSCB_GetLock(aconn, i, &lock);
101         if (code) {
102             if (code == 1) break;
103             /* otherwise we have an unrecognized error */
104             printf("cmdebug: error checking locks: %s\n", error_message(code));
105             return code;
106         }
107         /* here we have the lock information, so display it, perhaps */
108         if (aint32 || IsLocked(&lock.lock)) {
109             printf("Lock %s status: ", lock.name);
110             PrintLock(&lock.lock);
111             printf("\n");
112         }
113     }
114     return 0;
115 }
116
117 static PrintCacheEntries(aconn, aint32)
118 int aint32;
119 register struct rx_connection *aconn; {
120     register int i;
121     register afs_int32 code;
122     struct AFSDBCacheEntry centry;
123
124     for(i=0;i<10000;i++) {
125         code = RXAFSCB_GetCE(aconn, i, &centry);
126         if (code) {
127             if (code == 1) break;
128             printf("cmdebug: failed to get cache entry %d (%s)\n", i,
129                    error_message(code));
130             return code;
131         }
132
133         if (centry.addr == 0) {
134             /* PS output */
135             printf("Proc %4d sleeping at %08x, pri %3d\n",
136                    centry.netFid.Vnode, centry.netFid.Volume, centry.netFid.Unique-25);
137             continue;
138         }
139
140         if (!aint32 && !IsLocked(&centry.lock)) continue;
141
142         /* otherwise print this entry */
143         printf("** Cache entry @ 0x%08x for %d.%d.%d.%d\n", centry.addr, centry.cell,
144                centry.netFid.Volume, centry.netFid.Vnode, centry.netFid.Unique);
145         if (IsLocked(&centry.lock)) {
146             printf("    locks: ");
147             PrintLock(&centry.lock);
148             printf("\n");
149         }
150         printf("    %d bytes\tDV %d refcnt %d\n", centry.Length, centry.DataVersion, centry.refCount);
151         printf("    callback %08x\texpires %u\n", centry.callback, centry.cbExpires);
152         printf("    %d opens\t%d writers\n", centry.opens, centry.writers);
153
154         /* now display states */
155         printf("    ");
156         if (centry.mvstat == 0) printf("normal file");
157         else if (centry.mvstat == 1) printf("mount point");
158         else if (centry.mvstat == 2) printf("volume root");
159         else printf("bogus mvstat %d", centry.mvstat);
160         printf("\n    states (0x%x)", centry.states);
161         if (centry.states & 1) printf(", stat'd");
162         if (centry.states & 2) printf(", backup");
163         if (centry.states & 4) printf(", read-only");
164         if (centry.states & 8) printf(", mt pt valid");
165         if (centry.states & 0x10) printf(", pending core");
166         if (centry.states & 0x40) printf(", wait-for-store");
167         if (centry.states & 0x80) printf(", mapped");
168         printf("\n");
169     }
170     return 0;
171 }
172
173 static CommandProc(as)
174 struct cmd_syndesc *as; {
175     struct rx_connection *conn;
176     register char *hostName;
177     register struct hostent *thp;
178     afs_int32 port;
179     struct rx_securityClass *secobj;
180     int int32p;
181     afs_int32 addr;
182
183     hostName = as->parms[0].items->data;
184     if (as->parms[1].items)
185         port = atoi(as->parms[1].items->data);
186     else
187         port = 7001;
188     thp = hostutil_GetHostByName(hostName);
189     if (!thp) {
190         printf("cmdebug: can't resolve address for host %s.\n", hostName);
191         exit(1);
192     }
193     memcpy(&addr, thp->h_addr, sizeof(afs_int32));
194     secobj = rxnull_NewServerSecurityObject();
195     conn = rx_NewConnection(addr, htons(port), 1, secobj, 0);
196     if (!conn) {
197         printf("cmdebug: failed to create connection for host %s\n", hostName);
198         exit(1);
199     }
200     if (as->parms[3].items) {
201         /* -addrs */
202         PrintInterfaces(conn);
203         return 0;
204     }
205     if (as->parms[2].items) int32p = 1;
206     else int32p = 0;
207     PrintLocks(conn, int32p);
208     PrintCacheEntries(conn, int32p);
209     return 0;
210 }
211
212 #include "AFS_component_version_number.c"
213
214 main(argc, argv)
215 int argc;
216 char **argv; {
217     register struct cmd_syndesc *ts;
218
219 #ifdef  AFS_AIX32_ENV
220     /*
221      * The following signal action for AIX is necessary so that in case of a 
222      * crash (i.e. core is generated) we can include the user's data section 
223      * in the core dump. Unfortunately, by default, only a partial core is
224      * generated which, in many cases, isn't too useful.
225      */
226     struct sigaction nsa;
227     
228     sigemptyset(&nsa.sa_mask);
229     nsa.sa_handler = SIG_DFL;
230     nsa.sa_flags = SA_FULLDUMP;
231     sigaction(SIGSEGV, &nsa, NULL);
232 #endif
233     rx_Init(0);
234
235     ts = cmd_CreateSyntax((char *) 0, CommandProc, 0, "probe unik server");
236     cmd_AddParm(ts, "-servers", CMD_SINGLE, CMD_REQUIRED, "server machine");
237     cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
238     cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
239     cmd_AddParm(ts, "-addrs", CMD_FLAG, CMD_OPTIONAL, "print only host interfaces");
240
241     cmd_Dispatch(argc, argv);
242     exit(0);
243 }