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