libafscp: a library for "clientless" operations
[openafs.git] / src / libafscp / afscp_callback.c
1 /* AUTORIGHTS
2 Copyright (C) 2003 - 2010 Chaskiel Grundman
3 All rights reserved
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include <afs/param.h>
28 #include <afs/afsint.h>               /*Callback interface defs*/
29 #include <afs/afsutil.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include "afscp.h"
33 #include "afscp_internal.h"
34
35 int afs_cb_inited = 0;
36 struct interfaceAddr afs_cb_interface;
37 static int afs_maxcallbacks=0, afs_cballoced=0;
38 struct afs_callback *allcallbacks=NULL;
39
40 static int init_afs_cb() {
41     int count;
42
43     afs_uuid_create(&afs_cb_interface.uuid);
44     count = rx_getAllAddr(&afs_cb_interface.addr_in, AFS_MAX_INTERFACE_ADDR);
45     if ( count <= 0 )
46         afs_cb_interface.numberOfInterfaces = 0;
47     else
48         afs_cb_interface.numberOfInterfaces = count;
49     afs_cb_inited = 1;
50     return 0;
51 }
52
53 int AddCallBack(const struct afs_server *server, const struct AFSFid *fid,
54                 const struct AFSFetchStatus *fst, const struct AFSCallBack *cb)
55 {
56      int i;
57      struct afs_callback *use=NULL, *newlist;
58      struct afs_venusfid f;
59      time_t now;
60
61      time(&now);
62
63      for (i=0;i<afs_maxcallbacks;i++) {
64           if (allcallbacks[i].cb.ExpirationTime < now) {
65             if (allcallbacks[i].valid) {
66                  f.cell=afs_cellbyid(allcallbacks[i].server->cell);
67                  memcpy(&f.fid, &allcallbacks[i].fid, sizeof(struct afs_venusfid));
68                  _StatInvalidate(&f);
69             }
70             allcallbacks[i].valid=0;
71
72           }
73
74           if (allcallbacks[i].valid == 0)
75                use=&allcallbacks[i];
76           if (allcallbacks[i].server==server &&
77               fid->Volume == allcallbacks[i].fid.Volume &&
78               fid->Vnode == allcallbacks[i].fid.Vnode &&
79               fid->Unique == allcallbacks[i].fid.Unique) {
80             use=&allcallbacks[i];
81             break;
82           }
83      }
84      if (!use) {
85           if (afs_maxcallbacks >= afs_cballoced) {
86                if (afs_cballoced)
87                     afs_cballoced = afs_cballoced *2;
88                else
89                     afs_cballoced = 4;
90                newlist=realloc(allcallbacks, afs_cballoced *
91                                sizeof(struct afs_callback));
92                if (!newlist)
93                     return -1;
94                allcallbacks=newlist;
95           }
96           use=&allcallbacks[afs_maxcallbacks++];
97      }
98      use->valid=1;
99      use->server=server;
100      memmove(&use->fid, fid, sizeof(struct AFSFid));
101      memmove(&use->cb, cb, sizeof(struct AFSCallBack));
102      f.cell=afs_cellbyid(server->cell);
103      memcpy(&f.fid, fid, sizeof(struct AFSFid));
104      _StatStuff(&f, fst);
105      return 0;
106 }
107 int RemoveCallBack(const struct afs_server *server, const struct afs_venusfid *f)
108 {
109      struct afs_callback *cb;
110      int i;
111
112      _StatInvalidate(f);
113      if (!server)
114           return 0;
115      for (i=0;i<afs_maxcallbacks;i++) {
116           cb=&allcallbacks[i];
117           if (cb->server == server &&
118               f->fid.Volume == cb->fid.Volume &&
119               f->fid.Vnode == cb->fid.Vnode &&
120               f->fid.Unique == cb->fid.Unique) {
121                cb->valid = 0;
122                break;
123           }
124      }
125      return 0;
126 }
127
128 int ReturnCallBacks(const struct afs_server *server)
129 {
130      struct AFSCBFids theFids;
131      struct AFSCBs theCBs;
132      struct afs_callback *cb;
133      struct afs_venusfid f;
134      int inited=0;
135      int ncallbacks=0;
136      int i,j;
137      time_t now;
138
139      time(&now);
140
141      for (i=0;i<afs_maxcallbacks;i++) {
142           cb=&allcallbacks[i];
143 /*          printf("%d %x %x %ld %d", i, cb, cb->server, cb->cb.ExpirationTime,
144             cb->valid);*/
145           if (cb->server != server)
146                continue;
147           if (cb->cb.ExpirationTime < now) {
148             if (cb->valid) {
149                  f.cell=afs_cellbyid(cb->server->cell);
150                  memcpy(&f.fid, &cb->fid, sizeof(struct afs_venusfid));
151                  _StatInvalidate(&f);
152             }
153
154             cb->valid=0;
155             continue;
156           }
157           if (!inited) {
158                theFids.AFSCBFids_val=malloc(sizeof(struct AFSCallBack) * AFSCBMAX);
159                if (!theFids.AFSCBFids_val)
160                     return -1;
161                theCBs.AFSCBs_val=malloc(sizeof(struct AFSFid) * AFSCBMAX);
162                if (!theCBs.AFSCBs_val) {
163                     free(theFids.AFSCBFids_val);
164                     return -1;
165                }
166           }
167
168           if (ncallbacks == AFSCBMAX) {
169                theFids.AFSCBFids_len=ncallbacks;
170                theCBs.AFSCBs_len=ncallbacks;
171                for (j=0;j<server->naddrs;j++) {
172                  if (!RXAFS_GiveUpCallBacks(server->conns[j], &theFids,
173                                            &theCBs))
174                    break;
175                }
176                ncallbacks=0;
177           }
178           memmove(&theFids.AFSCBFids_val[ncallbacks], &cb->fid,
179                   sizeof(struct AFSFid));
180           memmove(&theCBs.AFSCBs_val[ncallbacks], &cb->cb,
181                   sizeof(struct AFSCallBack));
182
183           theCBs.AFSCBs_val[ncallbacks].CallBackType = CB_DROPPED;
184           ncallbacks++;
185           if (cb->valid) {
186                f.cell=afs_cellbyid(cb->server->cell);
187                memcpy(&f.fid, &cb->fid, sizeof(struct afs_callback));
188                _StatInvalidate(&f);
189           }
190
191           cb->valid=0;
192      }
193      if (ncallbacks) {
194        theFids.AFSCBFids_len=ncallbacks;
195        theCBs.AFSCBs_len=ncallbacks;
196        for (j=0;j<server->naddrs;j++) {
197          if (!RXAFS_GiveUpCallBacks(server->conns[j], &theFids,
198                                    &theCBs))
199            break;
200        }
201        free(theFids.AFSCBFids_val);
202        free(theCBs.AFSCBs_val);
203      }
204      return 0;
205 }
206
207 int ReturnAllCallBacks(void)
208 {
209      struct afs_server *s;
210      int i;
211
212      for (i=0;(s=afs_serverbyindex(i));i++)
213           ReturnCallBacks(s);
214      return 0;
215 }
216
217
218
219 afs_int32 SRXAFSCB_CallBack(rxcall, Fids_Array, CallBack_Array)
220     struct rx_call *rxcall;
221     AFSCBFids *Fids_Array;
222     AFSCBs *CallBack_Array;
223
224 { /*SRXAFSCB_CallBack*/
225      struct rx_connection *rxconn=rx_ConnectionOf(rxcall);
226      struct rx_peer *rxpeer=rx_PeerOf(rxconn);
227      struct afs_server *server=afs_anyserverbyaddr(rxpeer->host);
228      struct afs_callback *cb;
229      struct afs_venusfid f;
230      struct AFSFid *fid;
231      int i,j;
232
233      if (!server)
234           return 0;
235      for (i=0;i<afs_maxcallbacks;i++) {
236           cb=&allcallbacks[i];
237           if (cb->server != server)
238                continue;
239           for (j=0;j<Fids_Array->AFSCBFids_len;j++) {
240                fid=&Fids_Array->AFSCBFids_val[j];
241                if (fid->Volume == cb->fid.Volume &&
242                    fid->Vnode == cb->fid.Vnode &&
243                    fid->Unique == cb->fid.Unique)
244                     cb->valid = 0;
245                f.cell=afs_cellbyid(cb->server->cell);
246                memcpy(&f.fid, &cb->fid, sizeof(struct afs_venusfid));
247                _StatInvalidate(&f);
248           }
249      }
250
251     return(0);
252
253 } /*SRXAFSCB_CallBack*/
254
255
256 afs_int32 SRXAFSCB_InitCallBackState(rxcall)
257     struct rx_call *rxcall;
258
259 { /*SRXAFSCB_InitCallBackState*/
260      struct rx_connection *rxconn=rx_ConnectionOf(rxcall);
261      struct rx_peer *rxpeer=rx_PeerOf(rxconn);
262      struct afs_server *server=afs_anyserverbyaddr(rxpeer->host);
263      struct afs_callback *cb;
264      struct afs_venusfid f;
265      int i;
266
267      if (!server)
268           return 0;
269      for (i=0;i<afs_maxcallbacks;i++) {
270           cb=&allcallbacks[i];
271           if (cb->server != server)
272                continue;
273           if (cb->valid) {
274                f.cell=afs_cellbyid(cb->server->cell);
275                memcpy(&f.fid, &cb->fid, sizeof(struct afs_callback));
276                _StatInvalidate(&f);
277           }
278           cb->valid = 0;
279      }
280      return(0);
281
282 } /*SRXAFSCB_InitCallBackState*/
283
284 afs_int32 SRXAFSCB_Probe(rxcall)
285         struct rx_call *rxcall;
286
287 { /*SRXAFSCB_Probe*/
288     return(0);
289
290 } /*SRXAFSCB_Probe*/
291
292
293 afs_int32 SRXAFSCB_GetCE(rxcall)
294     struct rx_call *rxcall;
295
296 { /*SRXAFSCB_GetCE*/
297      return(0);
298 } /*SRXAFSCB_GetCE*/
299
300 afs_int32 SRXAFSCB_GetCE64(rxcall)
301     struct rx_call *rxcall;
302
303 { /*SRXAFSCB_GetCE*/
304      return(0);
305 } /*SRXAFSCB_GetCE*/
306
307
308 afs_int32 SRXAFSCB_GetLock(rxcall)
309     struct rx_call *rxcall;
310
311 { /*SRXAFSCB_GetLock*/
312     return(0);
313
314 } /*SRXAFSCB_GetLock*/
315 afs_int32 SRXAFSCB_XStatsVersion(rxcall)
316     struct rx_call *rxcall;
317
318 { /*SRXAFSCB_XStatsVersion*/
319     return(0);
320
321 } /*SRXAFSCB_XStatsVersion*/
322
323 afs_int32 SRXAFSCB_GetXStats(rxcall)
324     struct rx_call *rxcall;
325
326 { /*SRXAFSCB_GetXStats*/
327      return(0);
328 } /*SRXAFSCB_GetXStats*/
329
330 int SRXAFSCB_InitCallBackState2(rxcall, addr)
331 struct rx_call *rxcall;
332 struct interfaceAddr * addr;
333 {
334     return RXGEN_OPCODE;
335 }
336
337 int SRXAFSCB_WhoAreYou(rxcall, addr)
338 struct rx_call *rxcall;
339 struct interfaceAddr *addr;
340 {
341     XDR x;
342     if ( rxcall && addr )
343     {
344         if (!afs_cb_inited) init_afs_cb();
345         *addr = afs_cb_interface;
346     }
347 #ifdef STRANGEDEBUG
348     xdrrx_create(&x, rxcall, XDR_ENCODE);
349     xdr_interfaceAddr(&x, addr);
350     rx_Write(rxcall,"",0);
351     rxi_FlushWrite(rxcall);
352     rx_EndCall(rxcall, 0);
353     IOMGR_Sleep(10);
354     IOMGR_Sleep(600);
355 #endif
356     return(0);
357 }
358
359 int SRXAFSCB_InitCallBackState3(rxcall, uuidp)
360 struct rx_call *rxcall;
361 afsUUID *uuidp;
362 {
363      struct rx_connection *rxconn=rx_ConnectionOf(rxcall);
364      struct rx_peer *rxpeer=rx_PeerOf(rxconn);
365      struct afs_server *server=afs_anyserverbyaddr(rxpeer->host);
366      struct afs_callback *cb;
367      struct afs_venusfid f;
368      int i;
369
370      if (!server)
371           return 0;
372      for (i=0;i<afs_maxcallbacks;i++) {
373           cb=&allcallbacks[i];
374           if (cb->server != server)
375                continue;
376           if (cb->valid) {
377                f.cell=afs_cellbyid(cb->server->cell);
378                memcpy(&f.fid, &cb->fid, sizeof(struct afs_callback));
379                _StatInvalidate(&f);
380           }
381           cb->valid = 0;
382      }
383      return(0);
384 }
385 int SRXAFSCB_ProbeUuid(rxcall, uuidp)
386 struct rx_call *rxcall;
387 afsUUID *uuidp;
388 {
389     int code = 0;
390     if (!afs_cb_inited) init_afs_cb();
391     if (!afs_uuid_equal(uuidp, &afs_cb_interface.uuid))
392         code = 1; /* failure */
393 #ifdef STRANGEDEBUG
394     rx_EndCall(rxcall,code);
395     IOMGR_Sleep(600);
396 #endif
397     return code;
398 }
399 int SRXAFSCB_GetServerPrefs(
400     struct rx_call *a_call,
401     afs_int32 a_index,
402     afs_int32 *a_srvr_addr,
403     afs_int32 *a_srvr_rank)
404 {
405     *a_srvr_addr = 0xffffffff;
406     *a_srvr_rank = 0xffffffff;
407     return 0;
408 }
409
410 int SRXAFSCB_GetCellServDB(
411     struct rx_call *a_call,
412     afs_int32 a_index,
413     char **a_name,
414     afs_int32 *a_hosts)
415 {
416     return RXGEN_OPCODE;
417 }
418
419 int SRXAFSCB_GetLocalCell(
420     struct rx_call *a_call,
421     char **a_name)
422 {
423     return RXGEN_OPCODE;
424 }
425
426 int SRXAFSCB_GetCacheConfig(
427     struct rx_call *a_call,
428     afs_uint32 callerVersion,
429     afs_uint32 *serverVersion,
430     afs_uint32 *configCount,
431     cacheConfig *config)
432 {
433     return RXGEN_OPCODE;
434 }
435 int SRXAFSCB_GetCellByNum(
436     struct rx_call *a_call,
437     afs_int32 a_index,
438     char **a_name,
439     afs_int32 *a_hosts)
440 {
441     return RXGEN_OPCODE;
442 }
443 #ifdef AFS_64BIT_CLIENT
444 afs_int32
445 SRXAFSCB_TellMeAboutYourself(struct rx_call * rxcall,
446                              struct interfaceAddr * addr,
447                              Capabilities * capabilities)
448 {
449     if ( rxcall && addr )
450     {
451         if (!afs_cb_inited) init_afs_cb();
452         *addr = afs_cb_interface;
453     }
454     return(0);
455 }
456 #endif