Commit | Line | Data |
---|---|---|
805e021f CE |
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 <afsconfig.h> | |
28 | #include <afs/param.h> | |
29 | ||
30 | #include <roken.h> | |
31 | ||
32 | #ifdef AFS_NT40_ENV | |
33 | #include <windows.h> | |
34 | #include <rpc.h> | |
35 | #include <afs/cm_server.h> | |
36 | #include <WINNT/syscfg.h> | |
37 | #endif | |
38 | ||
39 | #include <afs/afsutil.h> | |
40 | #include "afscp.h" | |
41 | #include "afscp_internal.h" | |
42 | ||
43 | int afs_cb_inited = 0; | |
44 | struct interfaceAddr afs_cb_interface; | |
45 | static int afscp_maxcallbacks = 0, afscp_cballoced = 0; | |
46 | struct afscp_callback *allcallbacks = NULL; | |
47 | ||
48 | /*! | |
49 | * Initialize the callback interface structure | |
50 | */ | |
51 | static int | |
52 | init_afs_cb(void) | |
53 | { | |
54 | int cm_noIPAddr; /* number of client network interfaces */ | |
55 | int i; | |
56 | #ifdef AFS_NT40_ENV | |
57 | /* | |
58 | * This Windows section was pulled in from changes to src/venus/afsio.c but is | |
59 | * untested here and may be unnecessary if rx_getAllAddr() can be used on that | |
60 | * platform. However, there was already an ifdef here surrounding UuidCreate(). | |
61 | */ | |
62 | long rx_mtu = -1; | |
63 | int code; | |
64 | int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */ | |
65 | int cm_SubnetMask[CM_MAXINTERFACE_ADDR]; /* client's subnet mask in host order */ | |
66 | int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */ | |
67 | int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */ | |
68 | ||
69 | UuidCreate((UUID *) & afs_cb_interface.uuid); | |
70 | cm_noIPAddr = CM_MAXINTERFACE_ADDR; | |
71 | code = syscfg_GetIFInfo(&cm_noIPAddr, | |
72 | cm_IPAddr, cm_SubnetMask, cm_NetMtu, cm_NetFlags); | |
73 | if (code > 0) { | |
74 | /* return all network interface addresses */ | |
75 | afs_cb_interface.numberOfInterfaces = cm_noIPAddr; | |
76 | for (i = 0; i < cm_noIPAddr; i++) { | |
77 | afs_cb_interface.addr_in[i] = cm_IPAddr[i]; | |
78 | afs_cb_interface.subnetmask[i] = cm_SubnetMask[i]; | |
79 | afs_cb_interface.mtu[i] = (rx_mtu == -1 | |
80 | || (rx_mtu != -1 | |
81 | && cm_NetMtu[i] < | |
82 | rx_mtu)) ? cm_NetMtu[i] : rx_mtu; | |
83 | } | |
84 | } else { | |
85 | afs_cb_interface.numberOfInterfaces = 0; | |
86 | } | |
87 | #else | |
88 | afs_uuid_create(&afs_cb_interface.uuid); | |
89 | cm_noIPAddr = | |
90 | rx_getAllAddr((afs_uint32 *) afs_cb_interface.addr_in, | |
91 | AFS_MAX_INTERFACE_ADDR); | |
92 | if (cm_noIPAddr < 0) | |
93 | afs_cb_interface.numberOfInterfaces = 0; | |
94 | else { | |
95 | afs_cb_interface.numberOfInterfaces = cm_noIPAddr; | |
96 | /* we expect these in host byte order */ | |
97 | for (i = 0; i < cm_noIPAddr; i++) | |
98 | afs_cb_interface.addr_in[i] = ntohl(afs_cb_interface.addr_in[i]); | |
99 | } | |
100 | #endif | |
101 | afs_cb_inited = 1; | |
102 | return 0; | |
103 | } /* init_afs_cb */ | |
104 | ||
105 | int | |
106 | afscp_FindCallBack(const struct afscp_venusfid *f, | |
107 | const struct afscp_server *server, | |
108 | struct afscp_callback **ret) | |
109 | { | |
110 | int i; | |
111 | struct afscp_callback *use = NULL, *cb; | |
112 | time_t now; | |
113 | struct afscp_venusfid fid; | |
114 | ||
115 | *ret = NULL; | |
116 | ||
117 | time(&now); | |
118 | for (i = 0; i < afscp_maxcallbacks; i++) { | |
119 | cb = &allcallbacks[i]; | |
120 | if ((f->fid.Volume == cb->fid.Volume) && | |
121 | (f->fid.Vnode == cb->fid.Vnode) && | |
122 | (f->fid.Unique == cb->fid.Unique)) { | |
123 | if (server && (cb->server != server)) | |
124 | continue; | |
125 | use = cb; | |
126 | break; | |
127 | } | |
128 | } | |
129 | if (!use) | |
130 | return -1; | |
131 | ||
132 | if (use->cb.ExpirationTime + use->as_of < now) { | |
133 | if (use->valid) { | |
134 | fid.cell = afscp_CellById(use->server->cell); | |
135 | memcpy(&fid.fid, &use->fid, sizeof(struct AFSFid)); | |
136 | _StatInvalidate(&fid); | |
137 | } | |
138 | use->valid = 0; | |
139 | } | |
140 | ||
141 | if (use->valid) | |
142 | *ret = use; | |
143 | else | |
144 | return -1; | |
145 | ||
146 | return 0; | |
147 | } | |
148 | ||
149 | int | |
150 | afscp_AddCallBack(const struct afscp_server *server, | |
151 | const struct AFSFid *fid, | |
152 | const struct AFSFetchStatus *fst, | |
153 | const struct AFSCallBack *cb, const time_t as_of) | |
154 | { | |
155 | int i; | |
156 | struct afscp_callback *use = NULL, *newlist; | |
157 | struct afscp_venusfid f; | |
158 | time_t now; | |
159 | ||
160 | time(&now); | |
161 | ||
162 | for (i = 0; i < afscp_maxcallbacks; i++) { | |
163 | if (allcallbacks[i].cb.ExpirationTime + allcallbacks[i].as_of < now) { | |
164 | if (allcallbacks[i].valid) { | |
165 | f.cell = afscp_CellById(allcallbacks[i].server->cell); | |
166 | memcpy(&f.fid, &allcallbacks[i].fid, sizeof(struct AFSFid)); | |
167 | _StatInvalidate(&f); | |
168 | } | |
169 | allcallbacks[i].valid = 0; | |
170 | } | |
171 | ||
172 | if (allcallbacks[i].valid == 0) | |
173 | use = &allcallbacks[i]; | |
174 | if ((allcallbacks[i].server == server) && | |
175 | (fid->Volume == allcallbacks[i].fid.Volume) && | |
176 | (fid->Vnode == allcallbacks[i].fid.Vnode) && | |
177 | (fid->Unique == allcallbacks[i].fid.Unique)) { | |
178 | use = &allcallbacks[i]; | |
179 | break; | |
180 | } | |
181 | } | |
182 | if (use == NULL) { | |
183 | if (afscp_maxcallbacks >= afscp_cballoced) { | |
184 | if (afscp_cballoced != 0) | |
185 | afscp_cballoced = afscp_cballoced * 2; | |
186 | else | |
187 | afscp_cballoced = 4; | |
188 | newlist = realloc(allcallbacks, afscp_cballoced * | |
189 | sizeof(struct afscp_callback)); | |
190 | if (newlist == NULL) { | |
191 | return -1; | |
192 | } | |
193 | allcallbacks = newlist; | |
194 | } | |
195 | use = &allcallbacks[afscp_maxcallbacks++]; | |
196 | } | |
197 | use->valid = 1; | |
198 | use->server = server; | |
199 | memmove(&use->fid, fid, sizeof(struct AFSFid)); | |
200 | memmove(&use->cb, cb, sizeof(struct AFSCallBack)); | |
201 | use->as_of = as_of; | |
202 | f.cell = afscp_CellById(server->cell); | |
203 | memcpy(&f.fid, fid, sizeof(struct AFSFid)); | |
204 | _StatStuff(&f, fst); | |
205 | return 0; | |
206 | } /* afscp_AddCallBack */ | |
207 | ||
208 | int | |
209 | afscp_RemoveCallBack(const struct afscp_server *server, | |
210 | const struct afscp_venusfid *f) | |
211 | { | |
212 | struct afscp_callback *cb; | |
213 | int i; | |
214 | ||
215 | _StatInvalidate(f); | |
216 | if (server == NULL) { | |
217 | return 0; | |
218 | } | |
219 | for (i = 0; i < afscp_maxcallbacks; i++) { | |
220 | cb = &allcallbacks[i]; | |
221 | if ((cb->server == server) && | |
222 | (f->fid.Volume == cb->fid.Volume) && | |
223 | (f->fid.Vnode == cb->fid.Vnode) && | |
224 | (f->fid.Unique == cb->fid.Unique)) { | |
225 | cb->valid = 0; | |
226 | break; | |
227 | } | |
228 | } | |
229 | return 0; | |
230 | } /* afscp_ReturnCallBacks */ | |
231 | ||
232 | int | |
233 | afscp_ReturnCallBacks(const struct afscp_server *server) | |
234 | { | |
235 | struct AFSCBFids theFids; | |
236 | struct AFSCBs theCBs; | |
237 | struct afscp_callback *cb; | |
238 | struct afscp_venusfid f; | |
239 | struct rx_connection *c; | |
240 | int inited = 0; | |
241 | int ncallbacks = 0; | |
242 | int i, j, code; | |
243 | time_t now; | |
244 | ||
245 | time(&now); | |
246 | ||
247 | for (i = 0; i < afscp_maxcallbacks; i++) { | |
248 | cb = &allcallbacks[i]; | |
249 | if (cb->server != server) { | |
250 | continue; | |
251 | } | |
252 | if (cb->cb.ExpirationTime + cb->as_of < now) { | |
253 | if (cb->valid) { | |
254 | f.cell = afscp_CellById(cb->server->cell); | |
255 | memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid)); | |
256 | _StatInvalidate(&f); | |
257 | } | |
258 | cb->valid = 0; | |
259 | continue; | |
260 | } | |
261 | if (!inited) { | |
262 | theFids.AFSCBFids_val = calloc(AFSCBMAX, sizeof(struct AFSFid)); | |
263 | if (!theFids.AFSCBFids_val) { | |
264 | return -1; | |
265 | } | |
266 | theCBs.AFSCBs_val = calloc(AFSCBMAX, sizeof(struct AFSCallBack)); | |
267 | if (!theCBs.AFSCBs_val) { | |
268 | free(theFids.AFSCBFids_val); | |
269 | return -1; | |
270 | } | |
271 | inited = 1; | |
272 | } | |
273 | ||
274 | if (ncallbacks == AFSCBMAX) { | |
275 | theFids.AFSCBFids_len = ncallbacks; | |
276 | theCBs.AFSCBs_len = ncallbacks; | |
277 | for (j = 0; j < server->naddrs; j++) { | |
278 | c = afscp_ServerConnection(server, j); | |
279 | if (c == NULL) | |
280 | break; | |
281 | code = RXAFS_GiveUpCallBacks(c, &theFids, &theCBs); | |
282 | if (code == 0) | |
283 | break; | |
284 | } | |
285 | ncallbacks = 0; | |
286 | } | |
287 | memmove(&theFids.AFSCBFids_val[ncallbacks], &cb->fid, | |
288 | sizeof(struct AFSFid)); | |
289 | memmove(&theCBs.AFSCBs_val[ncallbacks], &cb->cb, | |
290 | sizeof(struct AFSCallBack)); | |
291 | ||
292 | theCBs.AFSCBs_val[ncallbacks].CallBackType = CB_DROPPED; | |
293 | ncallbacks++; | |
294 | if (cb->valid) { | |
295 | f.cell = afscp_CellById(cb->server->cell); | |
296 | memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid)); | |
297 | _StatInvalidate(&f); | |
298 | } | |
299 | ||
300 | cb->valid = 0; | |
301 | } | |
302 | if (ncallbacks > 0) { | |
303 | theFids.AFSCBFids_len = ncallbacks; | |
304 | theCBs.AFSCBs_len = ncallbacks; | |
305 | for (j = 0; j < server->naddrs; j++) { | |
306 | c = afscp_ServerConnection(server, j); | |
307 | if (c == NULL) | |
308 | break; | |
309 | code = RXAFS_GiveUpCallBacks(c, &theFids, &theCBs); | |
310 | if (code == 0) | |
311 | break; | |
312 | } | |
313 | free(theFids.AFSCBFids_val); | |
314 | free(theCBs.AFSCBs_val); | |
315 | } | |
316 | return 0; | |
317 | } /* afscp_ReturnCallBacks */ | |
318 | ||
319 | int | |
320 | afscp_ReturnAllCallBacks(void) | |
321 | { | |
322 | struct afscp_server *s; | |
323 | int i; | |
324 | ||
325 | if (allcallbacks == NULL) | |
326 | return 0; | |
327 | for (i = 0; (s = afscp_ServerByIndex(i)); i++) { | |
328 | afscp_ReturnCallBacks(s); | |
329 | } | |
330 | free(allcallbacks); | |
331 | allcallbacks = NULL; | |
332 | afscp_maxcallbacks = 0; | |
333 | afscp_cballoced = 0; | |
334 | return 0; | |
335 | } /* afscp_ReturnAllCallBacks */ | |
336 | ||
337 | /*! | |
338 | * Handle a set of callbacks from the File Server. | |
339 | * | |
340 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
341 | * \param[in] Fids_Array Ptr to the set of Fids. | |
342 | * \param[in] CallBacks_Array Ptr to the set of callbacks. | |
343 | * | |
344 | * \post Returns RXGEN_SUCCESS on success, Error value otherwise. | |
345 | * | |
346 | */ | |
347 | afs_int32 | |
348 | SRXAFSCB_CallBack(struct rx_call * rxcall, AFSCBFids * Fids_Array, | |
349 | AFSCBs * CallBack_Array) | |
350 | { | |
351 | struct rx_connection *rxconn = rx_ConnectionOf(rxcall); | |
352 | struct rx_peer *rxpeer = rx_PeerOf(rxconn); | |
353 | struct afscp_server *server = afscp_AnyServerByAddr(rx_HostOf(rxpeer)); | |
354 | struct afscp_callback *cb; | |
355 | struct afscp_venusfid f; | |
356 | struct AFSFid *fid; | |
357 | int i; | |
358 | unsigned int j; | |
359 | ||
360 | if (server == NULL) { | |
361 | return 0; | |
362 | } | |
363 | for (i = 0; i < afscp_maxcallbacks; i++) { | |
364 | cb = &allcallbacks[i]; | |
365 | if (cb->server != server) | |
366 | continue; | |
367 | for (j = 0; j < Fids_Array->AFSCBFids_len; j++) { | |
368 | fid = &Fids_Array->AFSCBFids_val[j]; | |
369 | if ((fid->Volume == cb->fid.Volume) && | |
370 | (fid->Vnode == cb->fid.Vnode) && | |
371 | (fid->Unique == cb->fid.Unique)) | |
372 | cb->valid = 0; | |
373 | f.cell = afscp_CellById(cb->server->cell); | |
374 | memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid)); | |
375 | _StatInvalidate(&f); | |
376 | } | |
377 | } | |
378 | ||
379 | return RXGEN_SUCCESS; | |
380 | } /*SRXAFSCB_CallBack */ | |
381 | ||
382 | /*! | |
383 | * Initialize callback state on this ``Cache Manager''. | |
384 | * | |
385 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
386 | * | |
387 | * \post Returns RXGEN_SUCCESS on success, Error value otherwise. | |
388 | * | |
389 | * \note This will definitely be called by the File Server (exactly once), | |
390 | * since it will think we are another new ``Cache Manager''. | |
391 | */ | |
392 | afs_int32 | |
393 | SRXAFSCB_InitCallBackState(struct rx_call * rxcall) | |
394 | { | |
395 | struct rx_connection *rxconn = rx_ConnectionOf(rxcall); | |
396 | struct rx_peer *rxpeer = rx_PeerOf(rxconn); | |
397 | struct afscp_server *server = afscp_AnyServerByAddr(rx_HostOf(rxpeer)); | |
398 | struct afscp_callback *cb; | |
399 | struct afscp_venusfid f; | |
400 | int i; | |
401 | ||
402 | if (server == NULL) { | |
403 | return 0; | |
404 | } | |
405 | for (i = 0; i < afscp_maxcallbacks; i++) { | |
406 | cb = &allcallbacks[i]; | |
407 | if (cb->server != server) | |
408 | continue; | |
409 | if (cb->valid) { | |
410 | f.cell = afscp_CellById(cb->server->cell); | |
411 | memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid)); | |
412 | _StatInvalidate(&f); | |
413 | } | |
414 | cb->valid = 0; | |
415 | } | |
416 | return RXGEN_SUCCESS; | |
417 | } /* SRXAFSCB_InitCallBackState */ | |
418 | ||
419 | /*! | |
420 | * Respond to a probe from the File Server. | |
421 | * | |
422 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
423 | * | |
424 | * \post Returns RXGEN_SUCCESS (always) | |
425 | * | |
426 | * \note If a File Server doesn't hear from you every so often, it will | |
427 | * send you a probe to make sure you're there, just like any other | |
428 | * ``Cache Manager'' it's keeping track of. | |
429 | * | |
430 | */ | |
431 | afs_int32 | |
432 | SRXAFSCB_Probe(struct rx_call * rxcall) | |
433 | { | |
434 | return RXGEN_SUCCESS; | |
435 | } /* SRXAFSCB_Probe */ | |
436 | ||
437 | /*! | |
438 | * Respond minimally to a request for returning the contents of | |
439 | * a cache lock, since someone out there thinks you're a Cache | |
440 | * Manager. | |
441 | * | |
442 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
443 | * \param[in] index | |
444 | * \param[out] lock | |
445 | * | |
446 | * \post Returns RXGEN_SUCCESS (always) | |
447 | * | |
448 | */ | |
449 | afs_int32 | |
450 | SRXAFSCB_GetLock(struct rx_call * rxcall, afs_int32 index, AFSDBLock * lock) | |
451 | { | |
452 | return RXGEN_SUCCESS; | |
453 | ||
454 | } /*SRXAFSCB_GetLock */ | |
455 | ||
456 | /*! | |
457 | * Respond minimally to a request for returning the contents of | |
458 | * a cache entry, since someone out there thinks you're a Cache | |
459 | * Manager. | |
460 | * | |
461 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
462 | * \param[in] index | |
463 | * \param[out] ce Ptr to cache entry | |
464 | * | |
465 | * \post Returns RXGEN_SUCCESS (always) | |
466 | * | |
467 | */ | |
468 | afs_int32 | |
469 | SRXAFSCB_GetCE(struct rx_call * rxcall, afs_int32 index, AFSDBCacheEntry * ce) | |
470 | { | |
471 | return RXGEN_SUCCESS; | |
472 | } /* SRXAFSCB_GetCE */ | |
473 | ||
474 | /*! | |
475 | * Respond minimally to a request for returning the contents of | |
476 | * a cache entry, since someone out there thinks you're a Cache | |
477 | * Manager. (64-bit version, though same as SRXAFSCB_GetCE()) | |
478 | * | |
479 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
480 | * \param[in] index | |
481 | * \param[out] ce Ptr to cache entry | |
482 | * | |
483 | * \post Returns RXGEN_SUCCESS (always) | |
484 | * | |
485 | */ | |
486 | afs_int32 | |
487 | SRXAFSCB_GetCE64(struct rx_call * rxcall, afs_int32 index, | |
488 | AFSDBCacheEntry64 * ce) | |
489 | { | |
490 | return RXGEN_SUCCESS; | |
491 | } /*SRXAFSCB_GetCE */ | |
492 | ||
493 | /*! | |
494 | * Respond minimally to a request for fetching the version of | |
495 | * extended Cache Manager statistics offered, since someone out | |
496 | * there thinks you're a Cache Manager. | |
497 | * | |
498 | * \param[in] rxcall Ptr to the associated Rx call structure | |
499 | * \param[out] versionNumberP | |
500 | * | |
501 | * \post Returns RXGEN_SUCCESS (always) | |
502 | * | |
503 | */ | |
504 | afs_int32 | |
505 | SRXAFSCB_XStatsVersion(struct rx_call * rxcall, afs_int32 * versionNumberP) | |
506 | { | |
507 | return RXGEN_SUCCESS; | |
508 | } /*SRXAFSCB_XStatsVersion */ | |
509 | ||
510 | /*! | |
511 | * Respond minimally to a request for returning extended | |
512 | * statistics for a Cache Manager, since someone out there thinks | |
513 | * you're a Cache Manager. | |
514 | * | |
515 | * \param[in] z_call Ptr to the associated Rx call structure | |
516 | * \param[in] clientVersionNumber | |
517 | * \param[in] collectionNumber | |
518 | * \param[out] srvVersionNumberP | |
519 | * \param[out] timeP | |
520 | * \param[out] dataP | |
521 | * | |
522 | * \post Returns RXGEN_SUCCESS (always) | |
523 | * | |
524 | */ | |
525 | afs_int32 | |
526 | SRXAFSCB_GetXStats(struct rx_call * z_call, afs_int32 clientVersionNumber, | |
527 | afs_int32 collectionNumber, afs_int32 * srvVersionNumberP, | |
528 | afs_int32 * timeP, AFSCB_CollData * dataP) | |
529 | { | |
530 | return RXGEN_SUCCESS; | |
531 | } /*SRXAFSCB_GetXStats */ | |
532 | ||
533 | /*! | |
534 | * This routine was used in the AFS 3.5 beta release, but not anymore. | |
535 | * It has since been replaced by SRXAFSCB_InitCallBackState3. | |
536 | * | |
537 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
538 | * \param[out] addr Ptr to return the list of interfaces for this client | |
539 | * | |
540 | * \post Returns RXGEN_SUCCESS (always) | |
541 | * | |
542 | */ | |
543 | afs_int32 | |
544 | SRXAFSCB_InitCallBackState2(struct rx_call * rxcall, | |
545 | struct interfaceAddr * addr) | |
546 | { | |
547 | return RXGEN_OPCODE; | |
548 | } /* SRXAFSCB_InitCallBackState2 */ | |
549 | ||
550 | /*! | |
551 | * | |
552 | * \param rxcall Ptr to the associated Rx call structure. | |
553 | * | |
554 | * \post Returns RXGEN_SUCCESS (always) | |
555 | * | |
556 | */ | |
557 | afs_int32 | |
558 | SRXAFSCB_TellMeAboutYourself(struct rx_call * a_call, | |
559 | struct interfaceAddr * addr, | |
560 | Capabilities * capabilities) | |
561 | { | |
562 | if (a_call && addr) { | |
563 | if (!afs_cb_inited) | |
564 | init_afs_cb(); | |
565 | *addr = afs_cb_interface; | |
566 | } | |
567 | if (capabilities != NULL) { | |
568 | afs_uint32 *dataBuffP; | |
569 | afs_int32 dataBytes; | |
570 | ||
571 | dataBytes = 1 * sizeof(afs_uint32); | |
572 | dataBuffP = (afs_uint32 *) xdr_alloc(dataBytes); | |
573 | dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS; | |
574 | capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32); | |
575 | capabilities->Capabilities_val = dataBuffP; | |
576 | } | |
577 | return RXGEN_SUCCESS; | |
578 | } /* SRXAFSCB_TellMeAboutYourself */ | |
579 | ||
580 | /*! | |
581 | * Routine called by the server-side callback RPC interface to | |
582 | * obtain a unique identifier for the client. The server uses | |
583 | * this identifier to figure out whether or not two RX connections | |
584 | * are from the same client, and to find out which addresses go | |
585 | * with which clients. | |
586 | * | |
587 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
588 | * \param[out] addr Ptr to return the list of interfaces for this client | |
589 | * | |
590 | * \post Returns output of TellMeAboutYourself (which | |
591 | * should be RXGEN_SUCCESS). | |
592 | * | |
593 | */ | |
594 | afs_int32 | |
595 | SRXAFSCB_WhoAreYou(struct rx_call * rxcall, struct interfaceAddr * addr) | |
596 | { | |
597 | return SRXAFSCB_TellMeAboutYourself(rxcall, addr, NULL); | |
598 | } /* SRXAFSCB_WhoAreYou */ | |
599 | ||
600 | /*! | |
601 | * Routine called by the server-side callback RPC interface to | |
602 | * implement clearing all callbacks from this host. | |
603 | * | |
604 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
605 | * \param[in] serverUuid Ptr to UUID | |
606 | * | |
607 | * \post Returns RXGEN_SUCCESS (always) | |
608 | * | |
609 | */ | |
610 | afs_int32 | |
611 | SRXAFSCB_InitCallBackState3(struct rx_call * rxcall, afsUUID * serverUuid) | |
612 | { | |
613 | struct rx_connection *rxconn = rx_ConnectionOf(rxcall); | |
614 | struct rx_peer *rxpeer = rx_PeerOf(rxconn); | |
615 | struct afscp_server *server = afscp_AnyServerByAddr(rx_HostOf(rxpeer)); | |
616 | struct afscp_callback *cb; | |
617 | struct afscp_venusfid f; | |
618 | int i; | |
619 | ||
620 | if (server == NULL) { | |
621 | return 0; | |
622 | } | |
623 | for (i = 0; i < afscp_maxcallbacks; i++) { | |
624 | cb = &allcallbacks[i]; | |
625 | if (cb->server != server) | |
626 | continue; | |
627 | if (cb->valid) { | |
628 | f.cell = afscp_CellById(cb->server->cell); | |
629 | memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid)); | |
630 | _StatInvalidate(&f); | |
631 | } | |
632 | cb->valid = 0; | |
633 | } | |
634 | return RXGEN_SUCCESS; | |
635 | } /* SRXAFSCB_InitCallBackState3 */ | |
636 | ||
637 | /*! | |
638 | * Routine called by the server-side callback RPC interface to | |
639 | * implement ``probing'' the Cache Manager, just making sure it's | |
640 | * still there is still the same client it used to be. | |
641 | * | |
642 | * \param rxcall Ptr to the associated Rx call structure. | |
643 | * \param clientUuid Ptr to UUID that must match the client's UUID | |
644 | * | |
645 | * \post Returns RXGEN_SUCCESS (always) | |
646 | * | |
647 | */ | |
648 | afs_int32 | |
649 | SRXAFSCB_ProbeUuid(struct rx_call * rxcall, afsUUID * clientUuid) | |
650 | { | |
651 | int code = 0; | |
652 | if (!afs_cb_inited) | |
653 | init_afs_cb(); | |
654 | if (!afs_uuid_equal(clientUuid, &afs_cb_interface.uuid)) | |
655 | code = 1; /* failure */ | |
656 | return code; | |
657 | } /* SRXAFSCB_ProbeUuid */ | |
658 | ||
659 | /*! | |
660 | * Routine to list server preferences used by this client. | |
661 | * | |
662 | * \param[in] a_call Ptr to Rx call on which this request came in. | |
663 | * \param[in] a_index Input server index | |
664 | * \param[out] a_srvr_addr Output server address (0xffffffff on last server) | |
665 | * \param[out] a_srvr_rank Output server rank | |
666 | * | |
667 | * \post Returns RXGEN_SUCCESS (always) | |
668 | * | |
669 | */ | |
670 | afs_int32 | |
671 | SRXAFSCB_GetServerPrefs(struct rx_call * a_call, afs_int32 a_index, | |
672 | afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank) | |
673 | { | |
674 | *a_srvr_addr = 0xffffffff; | |
675 | *a_srvr_rank = 0xffffffff; | |
676 | return RXGEN_SUCCESS; | |
677 | } /* SRXAFSCB_GetServerPrefs */ | |
678 | ||
679 | /*! | |
680 | * Routine to list cells configured for this client | |
681 | * | |
682 | * \param[in] a_call Ptr to Rx call on which this request came in. | |
683 | * \param[in] a_index Input cell index | |
684 | * \param[out] a_name Output cell name ("" on last cell) | |
685 | * \param[out] a_hosts Output cell database servers | |
686 | * | |
687 | * \post Returns RXGEN_OPCODE (always) | |
688 | * | |
689 | */ | |
690 | afs_int32 | |
691 | SRXAFSCB_GetCellServDB(struct rx_call * a_call, afs_int32 a_index, | |
692 | char **a_name, afs_int32 * a_hosts) | |
693 | { | |
694 | return RXGEN_OPCODE; | |
695 | } /* SRXAFSCB_GetCellServDB */ | |
696 | ||
697 | /*! | |
698 | * Routine to return name of client's local cell | |
699 | * | |
700 | * \param[in] a_call Ptr to Rx call on which this request came in. | |
701 | * \param[out] a_name Output cell name | |
702 | * | |
703 | * \post Returns RXGEN_SUCCESS (always) | |
704 | * | |
705 | */ | |
706 | int | |
707 | SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name) | |
708 | { | |
709 | return RXGEN_OPCODE; | |
710 | } /* SRXAFSCB_GetLocalCell */ | |
711 | ||
712 | /*! | |
713 | * Routine to return parameters used to initialize client cache. | |
714 | * Client may request any format version. Server may not return | |
715 | * format version greater than version requested by client. | |
716 | * | |
717 | * \param[in] a_call Ptr to Rx call on which this request came in. | |
718 | * \param[in] callerVersion Data format version desired by the client. | |
719 | * \param[out] serverVersion Data format version of output data. | |
720 | * \param[out] configCount Number bytes allocated for output data. | |
721 | * \param[out] config Client cache configuration. | |
722 | * | |
723 | * \post Returns RXGEN_SUCCESS (always) | |
724 | * | |
725 | */ | |
726 | int | |
727 | SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion, | |
728 | afs_uint32 * serverVersion, afs_uint32 * configCount, | |
729 | cacheConfig * config) | |
730 | { | |
731 | return RXGEN_OPCODE; | |
732 | } /* SRXAFSCB_GetCacheConfig */ | |
733 | ||
734 | /*! | |
735 | ||
736 | * | |
737 | * \param[in] rxcall Ptr to the associated Rx call structure. | |
738 | * | |
739 | * \post Returns RXGEN_OPCODE (always) | |
740 | * | |
741 | */ | |
742 | int | |
743 | SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_index, | |
744 | char **a_name, afs_int32 * a_hosts) | |
745 | { | |
746 | return RXGEN_OPCODE; | |
747 | } /* SRXAFSCB_GetCellByNum */ |