cacheout-some-fixing-20030304
[openafs.git] / src / venus / cacheout.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/vldbint.h>
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15 RCSID("$Header$");
16
17 #include <stdio.h>
18 #include <string.h>
19
20 #ifdef  AFS_AIX32_ENV
21 #include <signal.h>
22 #endif
23
24 #include <ctype.h>
25 #include <sys/types.h>
26 #include <afs/cmd.h>
27 #include <afs/cellconfig.h>
28 #include <rx/rx.h>
29 #include <rx/xdr.h>
30
31 #include <ubik.h>
32 #include <afs/kauth.h>
33 #include <afs/afsutil.h>
34
35 /*
36 File servers in NW byte order.
37 */
38
39 int server_count=0;
40 afs_int32 server_id[256];
41
42 struct ubik_client *client;
43
44 struct ViceIds
45 {
46         int ViceIds_len;
47         afs_int32 *ViceIds_val;
48 }
49 ;
50
51 struct IPAddrs
52 {
53         int IPAddrs_len;
54         afs_int32 *IPAddrs_val;
55 }
56 ;
57
58 struct ubik_dbase *VL_dbase;
59 struct afsconf_dir *vldb_confdir;
60 struct kadstats dynamic_statistics;
61 struct rx_securityClass *junk;
62
63 #include <sys/socket.h>
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
66
67 extern int VL_GetAddrs();
68
69 afs_int32 InvalidateCache(as)
70 struct cmd_syndesc *as;
71 {
72         afs_int32 code=0;
73         struct cmd_item *u;
74         struct rx_connection *conn;
75         int i;
76         afs_int32 port=7000;
77
78         afs_int32 spare1=0;
79         afs_int32 spare2,spare3;
80
81         afs_int32 id[256];
82         afs_int32 ip[256];
83
84         struct ViceIds vid;
85         struct IPAddrs ipa;
86
87         code=ListServers();
88         if(code)
89                 return code;
90
91
92         /* make sure something there */
93
94         if( !as->parms[0].items && !as->parms[1].items)
95         {
96                 printf("Use -help flag for list of optional argmuments\n");
97                 return 1;
98         }
99
100         /* get user ids */
101
102         for(i=0,u=as->parms[0].items;i<255 && u;++i,u=u->next)
103         {
104                 code=util_GetInt32(u->data,&id[i]);
105                 if(code)
106                 {
107                         printf("Fatal error: bad conversion to long for %s\n",u->data);
108                         return code;
109                 }
110         }
111
112         id[i]=0;
113         vid.ViceIds_len=i;
114         vid.ViceIds_val=id;
115
116         /* get IP addresses, convert to NW byte order */
117
118         for(i=0,u=as->parms[1].items;i<255 && u;++i,u=u->next)
119                 ip[i]=inet_addr(u->data);
120
121         ip[i]=0;
122         ipa.IPAddrs_len=i;
123         ipa.IPAddrs_val=ip;
124
125         for(i=0;i<server_count;++i)
126         {
127                 conn=rx_NewConnection(server_id[i],htonl(port),1,
128                         junk,0);
129                 if(!conn)
130                 {
131                         printf("Informational: could not connect to \
132 file server %lx\n",server_id[i]);
133                         continue;
134                 }
135
136                 /* invalidate the cache */
137
138                 code=RXAFS_FlushCPS(conn,&vid,&ipa,spare1,&spare2,&spare3);
139
140                 /*
141                 May get spurious error codes in case server is
142                 down or is reported by VLDB as a file server
143                 even though it is not configured as such in the
144                 cell.
145                 */
146
147                 if(code)
148                         printf("Informational: failed to invalidate \
149 file server %lx cache code = %ld\n",server_id[i],code);
150
151                 rx_DestroyConnection(conn);
152         }
153         return 0;
154 }
155
156 /*
157 Obtain list of file servers as known to VLDB. These may
158 not actually be configured as file servers in the cell.
159 */
160
161 afs_int32 ListServers()
162 {
163     afs_int32 code;
164     struct rx_connection *conn;
165     struct rx_call *call;
166     int i;
167     int byte_count;
168     int nentries;
169     afs_int32 base, index;
170
171     afs_int32 Handle=0;
172     afs_int32 spare2=0;
173     struct VLCallBack spare3;
174
175     bulkaddrs addrs, m_addrs;
176     ListAddrByAttributes m_attrs;
177     afs_int32 m_unique, m_nentries;
178     afs_uint32 *p;
179
180     /* get list of file servers in NW byte order */
181     memset(&addrs, 0, sizeof(addrs));
182     memset(&spare3, 0, sizeof(spare3));
183     code=ubik_Call(VL_GetAddrs,client,0,Handle,spare2,&spare3,
184                    &server_count,&addrs);
185     if(code)
186     {
187         printf("Fatal error: could not get list of file servers\n");
188         return 1;
189     }
190
191     for(i=0,p=addrs.bulkaddrs_val;i<server_count;++i,++p) {
192         if ( ((*p & 0xff000000) == 0xff000000) && ((*p)&0xffff) ) {
193             if ( (base  >= 0) && (base  <= VL_MAX_ADDREXTBLKS) &&
194                  (index >= 1) && (index <= VL_MHSRV_PERBLK)    ) {
195                 m_attrs.Mask  = VLADDR_INDEX;
196                 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
197                 m_nentries            = 0;
198                 m_addrs.bulkaddrs_val = 0;
199                 m_addrs.bulkaddrs_len = 0;
200                 code = ubik_Call(VL_GetAddrsU, client, 0,
201                                  &m_attrs, &m_uuid, &m_unique, &m_nentries, &m_addrs);
202                 if (vcode) 
203                     return code;
204
205                 m_addrp = (afs_int32 *)m_addrs.bulkaddrs_val;
206                 for (j=0; j<m_nentries; j++, m_addrp++) {
207                     server_id[i] = *m_addrp;
208                     *m_addrp = htonl(*m_addrp);       
209                     printf("host %s\n", hostutil_GetNameByINet(*p));
210                 }
211             }
212         } else {
213             server_id[i] = *p;
214             *p = htonl(*p);
215             printf("host %s\n", hostutil_GetNameByINet(*p));
216         }
217     }
218     return code;
219 }
220
221 afs_int32 GetServerList()
222 {
223         afs_int32 code;
224         int i;
225
226         code=ListServers();
227         if(code)
228                 return(code);
229
230         printf("There are %d file servers in the cell\n\n",server_count);
231         fflush(stdout);
232         for(i=0;i<server_count;++i)
233                 printf("%s\n",
234                         hostutil_GetNameByINet(server_id[i]));
235         fflush(stdout);
236
237         return code;
238 }
239
240 /*
241 User enters lists of:
242
243         1. AFS user ids - say from "pts exam username".
244         2. IP addresses - say from /etc/hosts (no wildcards).
245
246 Command is executed in user's cell.
247 */
248
249 static MyBeforeProc(as, arock)
250 struct cmd_syndesc *as;
251 char *arock; {
252     register char *tcell = NULL;
253     char confdir[200];
254     struct afsconf_dir *tdir;
255     struct afsconf_cell info;
256     struct rx_connection *serverconns[MAXSERVERS];
257     register afs_int32 code, i;
258     register afs_int32 sauth;
259
260     sprintf(confdir,"%s",AFSDIR_CLIENT_ETC_DIRPATH);
261     /* setup to talk to servers */
262     code=rx_Init(0);
263     if (code)
264         printf("Warning: could not initialize network communication.\n");
265
266     junk=rxnull_NewClientSecurityObject();
267     tdir=afsconf_Open(confdir);
268     if(!tdir)
269         printf("Warning: could not get cell configuration.\n");
270
271     if (as->parms[2].items) /* if -cell specified */
272         tcell = as->parms[2].items->data;
273     code = afsconf_GetCellInfo(tdir, tcell, AFSCONF_VLDBSERVICE,&info);
274     if (info.numServers > MAXSERVERS)
275         printf("Warning: could not init cell info.\n");
276
277     for(i=0;i<info.numServers;++i)
278         serverconns[i]=rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
279                                         info.hostAddr[i].sin_port,
280                                         USER_SERVICE_ID, junk, 0);
281     for (;i < MAXSERVERS; ++i) {
282         serverconns[i] = (struct rx_connection *)0;
283     }
284     code=ubik_ClientInit(serverconns,&client);
285     if(code)
286         printf("Warning: could not initialize RPC interface.\n");
287 }
288
289
290 int main (argc, argv)
291 int argc;
292 char **argv;
293 {
294         afs_int32 code=0;
295         struct cmd_syndesc *ts;
296         int i;
297
298 #ifdef  AFS_AIX32_ENV
299         struct sigaction nsa;
300         
301         sigemptyset(&nsa.sa_mask);
302         nsa.sa_handler = SIG_DFL;
303         nsa.sa_flags = SA_FULLDUMP;
304         sigaction(SIGSEGV, &nsa, NULL);
305 #endif
306
307         /*
308         Look in /usr/vice/etc (client side database).
309         */
310         cmd_SetBeforeProc(MyBeforeProc,  NULL);
311
312         ts = cmd_CreateSyntax("initcmd"/*"invalidatecache"*/,InvalidateCache,0,
313                 "invalidate server ACL cache");
314         cmd_AddParm(ts,"-id",CMD_LIST,CMD_OPTIONAL,"user identifier");
315         cmd_AddParm(ts,"-ip",CMD_LIST,CMD_OPTIONAL,"IP address");
316         cmd_CreateAlias(ts,"ic");
317         cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
318
319         ts = cmd_CreateSyntax("listservers",GetServerList,0,
320                 "list servers in the cell");
321         cmd_CreateAlias(ts,"ls");
322
323         code = cmd_Dispatch(argc,argv);
324         
325         rx_Finalize();
326
327         exit(code);
328 }
329