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