2 * Copyright 2000, International Business Machines Corporation and others.
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
12 * Exported routines (and their private support) to implement
13 * the callback RPC interface.
16 #include <afsconfig.h>
17 #include "../afs/param.h"
21 #include "../afs/sysincludes.h" /*Standard vendor system headers*/
22 #include "../afs/afsincludes.h" /*AFS-based standard headers*/
23 #include "../afs/afs_stats.h" /*Cache Manager stats*/
24 #include "../afs/afs_args.h"
26 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
27 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs*/
28 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files*/
29 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
30 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted*/
31 afs_int32 afs_evenZaps = 0; /*File cache entries deleted*/
32 afs_int32 afs_connectBacks = 0;
35 * Some debugging aids.
37 static struct ltable {
41 {"afs_xvcache", (char *)&afs_xvcache},
42 {"afs_xdcache", (char *)&afs_xdcache},
43 {"afs_xserver", (char *)&afs_xserver},
44 {"afs_xvcb", (char *)&afs_xvcb},
45 {"afs_xbrs", (char *)&afs_xbrs},
46 {"afs_xcell", (char *)&afs_xcell},
47 {"afs_xconn", (char *)&afs_xconn},
48 {"afs_xuser", (char *)&afs_xuser},
49 {"afs_xvolume", (char *)&afs_xvolume},
50 {"puttofile", (char *)&afs_puttofileLock},
51 {"afs_ftf", (char *)&afs_ftf},
52 {"afs_xcbhash", (char *)&afs_xcbhash},
53 {"afs_xaxs", (char *)&afs_xaxs},
54 {"afs_xinterface", (char *)&afs_xinterface}
56 unsigned long lastCallBack_vnode;
57 unsigned int lastCallBack_dv;
58 osi_timeval_t lastCallBack_time;
60 /* these are for storing alternate interface addresses */
61 struct interfaceAddr afs_cb_interface;
63 /*------------------------------------------------------------------------
64 * EXPORTED SRXAFSCB_GetCE
67 * Routine called by the server-side callback RPC interface to
68 * implement pulling out the contents of the i'th cache entry.
71 * a_call : Ptr to Rx call on which this request came in.
72 * a_index : Index of desired cache entry.
73 * a_result : Ptr to a buffer for the given cache entry.
76 * 0 if everything went fine,
77 * 1 if we were given a bad index.
80 * Nothing interesting.
84 *------------------------------------------------------------------------*/
86 int SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index, struct AFSDBCacheEntry *a_result)
89 register int i; /*Loop variable*/
90 register struct vcache *tvc; /*Ptr to current cache entry*/
91 int code; /*Return code*/
96 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
98 AFS_STATCNT(SRXAFSCB_GetCE);
99 for (i = 0; i < VCSIZE; i++) {
100 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
104 } /*Zip through current hash chain*/
105 } /*Zip through hash chains*/
115 * Copy out the located entry.
117 a_result->addr = afs_data_pointer_to_int32(tvc);
118 a_result->cell = tvc->fid.Cell;
119 a_result->netFid.Volume = tvc->fid.Fid.Volume;
120 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
121 a_result->netFid.Unique = tvc->fid.Fid.Unique;
122 a_result->lock.waitStates = tvc->lock.wait_states;
123 a_result->lock.exclLocked = tvc->lock.excl_locked;
124 a_result->lock.readersReading = tvc->lock.readers_reading;
125 a_result->lock.numWaiting = tvc->lock.num_waiting;
126 #if defined(INSTRUMENT_LOCKS)
127 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
128 a_result->lock.pid_writer = tvc->lock.pid_writer;
129 a_result->lock.src_indicator = tvc->lock.src_indicator;
131 /* On osf20 , the vcache does not maintain these three fields */
132 a_result->lock.pid_last_reader = 0;
133 a_result->lock.pid_writer = 0;
134 a_result->lock.src_indicator = 0;
135 #endif /* AFS_OSF20_ENV */
136 #ifdef AFS_64BIT_CLIENT
137 a_result->Length = (afs_int32) tvc->m.Length & 0xffffffff;
138 #else /* AFS_64BIT_CLIENT */
139 a_result->Length = tvc->m.Length;
140 #endif /* AFS_64BIT_CLIENT */
141 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
142 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
143 a_result->cbExpires = tvc->cbExpires;
144 a_result->refCount = VREFCOUNT(tvc);
145 a_result->opens = tvc->opens;
146 a_result->writers = tvc->execsOrWriters;
147 a_result->mvstat = tvc->mvstat;
148 a_result->states = tvc->states;
152 * Return our results.
163 int SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index, struct AFSDBCacheEntry64 *a_result)
165 register int i; /*Loop variable*/
166 register struct vcache *tvc; /*Ptr to current cache entry*/
167 int code; /*Return code*/
172 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
174 AFS_STATCNT(SRXAFSCB_GetCE64);
175 for (i = 0; i < VCSIZE; i++) {
176 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
180 } /*Zip through current hash chain*/
181 } /*Zip through hash chains*/
191 * Copy out the located entry.
193 a_result->addr = afs_data_pointer_to_int32(tvc);
194 a_result->cell = tvc->fid.Cell;
195 a_result->netFid.Volume = tvc->fid.Fid.Volume;
196 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
197 a_result->netFid.Unique = tvc->fid.Fid.Unique;
198 a_result->lock.waitStates = tvc->lock.wait_states;
199 a_result->lock.exclLocked = tvc->lock.excl_locked;
200 a_result->lock.readersReading = tvc->lock.readers_reading;
201 a_result->lock.numWaiting = tvc->lock.num_waiting;
202 #if defined(INSTRUMENT_LOCKS)
203 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
204 a_result->lock.pid_writer = tvc->lock.pid_writer;
205 a_result->lock.src_indicator = tvc->lock.src_indicator;
207 /* On osf20 , the vcache does not maintain these three fields */
208 a_result->lock.pid_last_reader = 0;
209 a_result->lock.pid_writer = 0;
210 a_result->lock.src_indicator = 0;
211 #endif /* AFS_OSF20_ENV */
213 a_result->Length = tvc->m.Length;
214 #else /* AFS_64BIT_ENV */
215 #ifdef AFS_64BIT_CLIENT
216 a_result->Length = tvc->m.Length;
217 #else /* AFS_64BIT_CLIENT */
218 a_result->Length.high = 0;
219 a_result->Length.low = tvc->m.Length;
220 #endif /* AFS_64BIT_CLIENT */
221 #endif /* AFS_64BIT_ENV */
222 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
223 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
224 a_result->cbExpires = tvc->cbExpires;
225 a_result->refCount = VREFCOUNT(tvc);
226 a_result->opens = tvc->opens;
227 a_result->writers = tvc->execsOrWriters;
228 a_result->mvstat = tvc->mvstat;
229 a_result->states = tvc->states;
233 * Return our results.
242 } /*SRXAFSCB_GetCE64*/
245 /*------------------------------------------------------------------------
246 * EXPORTED SRXAFSCB_GetLock
249 * Routine called by the server-side callback RPC interface to
250 * implement pulling out the contents of a lock in the lock
254 * a_call : Ptr to Rx call on which this request came in.
255 * a_index : Index of desired lock.
256 * a_result : Ptr to a buffer for the given lock.
259 * 0 if everything went fine,
260 * 1 if we were given a bad index.
263 * Nothing interesting.
267 *------------------------------------------------------------------------*/
269 int SRXAFSCB_GetLock (struct rx_call *a_call, afs_int32 a_index, struct AFSDBLock *a_result)
271 struct ltable *tl; /*Ptr to lock table entry*/
272 int nentries; /*Num entries in table*/
273 int code; /*Return code*/
278 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
280 AFS_STATCNT(SRXAFSCB_GetLock);
281 nentries = sizeof(ltable)/sizeof(struct ltable);
282 if (a_index < 0 || a_index >= nentries) {
290 * Found it - copy out its contents.
292 tl = <able[a_index];
293 strcpy(a_result->name, tl->name);
294 a_result->lock.waitStates = ((struct afs_lock *)(tl->addr))->wait_states;
295 a_result->lock.exclLocked = ((struct afs_lock *)(tl->addr))->excl_locked;
296 a_result->lock.readersReading = ((struct afs_lock *)(tl->addr))->readers_reading;
297 a_result->lock.numWaiting = ((struct afs_lock *)(tl->addr))->num_waiting;
298 #ifdef INSTRUMENT_LOCKS
299 a_result->lock.pid_last_reader = ((struct afs_lock *)(tl->addr))->pid_last_reader;
300 a_result->lock.pid_writer = ((struct afs_lock *)(tl->addr))->pid_writer;
301 a_result->lock.src_indicator = ((struct afs_lock *)(tl->addr))->src_indicator;
303 a_result->lock.pid_last_reader = 0;
304 a_result->lock.pid_writer = 0;
305 a_result->lock.src_indicator = 0;
316 } /*SRXAFSCB_GetLock*/
319 /*------------------------------------------------------------------------
320 * static ClearCallBack
323 * Clear out callback information for the specified file, or
324 * even a whole volume. Used to worry about callback was from
325 * within the particular cell or not. Now we don't bother with
326 * that anymore; it's not worth the time.
329 * a_conn : Ptr to Rx connection involved.
330 * a_fid : Ptr to AFS fid being cleared.
336 * Nothing interesting.
341 Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
343 *------------------------------------------------------------------------*/
345 static int ClearCallBack(register struct rx_connection *a_conn, register struct AFSFid *a_fid)
347 register struct vcache *tvc;
349 struct VenusFid localFid;
352 AFS_STATCNT(ClearCallBack);
357 * XXXX Don't hold any server locks here because of callback protocol XXX
360 localFid.Fid.Volume = a_fid->Volume;
361 localFid.Fid.Vnode = a_fid->Vnode;
362 localFid.Fid.Unique = a_fid->Unique;
365 * Volume ID of zero means don't do anything.
367 if (a_fid->Volume != 0) {
368 if (a_fid->Vnode == 0) {
370 * Clear callback for the whole volume. Zip through the
371 * hash chain, nullifying entries whose volume ID matches.
373 for (i = 0; i < VCSIZE; i++)
374 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
375 if (tvc->fid.Fid.Volume == a_fid->Volume) {
376 tvc->callback = NULL;
377 tvc->quick.stamp = 0;
379 localFid.Cell = tvc->fid.Cell;
380 tvc->h1.dchint = NULL; /* invalidate hints */
381 ObtainWriteLock(&afs_xcbhash, 449);
382 afs_DequeueCallback(tvc);
383 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
385 if (tvc->fid.Fid.Vnode & 1)
389 ReleaseWriteLock(&afs_xcbhash);
390 if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
391 osi_dnlc_purgedp(tvc);
392 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
393 ICL_TYPE_POINTER, tvc,
394 ICL_TYPE_INT32, tvc->states,
395 ICL_TYPE_INT32, a_fid->Volume);
396 } else if ((tvc->states & CMValid) && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
397 tvc->states &= ~CMValid;
399 localFid.Cell = tvc->mvid->Cell;
404 * XXXX Don't hold any locks here XXXX
406 tv = afs_FindVolume(&localFid, 0);
408 afs_ResetVolumeInfo(tv);
409 afs_PutVolume(tv, 0);
410 /* invalidate mtpoint? */
412 } /*Clear callbacks for whole volume*/
415 * Clear callbacks just for the one file.
418 if (a_fid->Vnode & 1)
419 afs_oddCBs++; /*Could do this on volume basis, too*/
421 afs_evenCBs++; /*A particular fid was specified*/
422 i = VCHash(&localFid);
423 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
424 if (tvc->fid.Fid.Vnode == a_fid->Vnode
425 && tvc->fid.Fid.Volume == a_fid->Volume
426 && tvc->fid.Fid.Unique == a_fid->Unique ) {
427 tvc->callback = NULL;
428 tvc->quick.stamp = 0;
429 tvc->h1.dchint = NULL; /* invalidate hints */
430 ObtainWriteLock(&afs_xcbhash, 450);
431 afs_DequeueCallback(tvc);
432 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
433 ReleaseWriteLock(&afs_xcbhash);
434 if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
435 osi_dnlc_purgedp(tvc);
436 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
437 ICL_TYPE_POINTER, tvc,
438 ICL_TYPE_INT32, tvc->states, ICL_TYPE_LONG, 0);
440 lastCallBack_vnode = afid->Vnode;
441 lastCallBack_dv = tvc->mstat.DataVersion.low;
442 osi_GetuTime(&lastCallBack_time);
445 } /*Walk through hash table*/
446 } /*Clear callbacks for one file*/
447 } /*Fid has non-zero volume ID*/
450 * Always return a predictable value.
457 /*------------------------------------------------------------------------
458 * EXPORTED SRXAFSCB_CallBack
461 * Routine called by the server-side callback RPC interface to
462 * implement passing in callback information.
466 * a_call : Ptr to Rx call on which this request came in.
467 * a_fids : Ptr to array of fids involved.
468 * a_callbacks : Ptr to matching callback info for the fids.
474 * Nothing interesting.
478 *------------------------------------------------------------------------*/
480 int SRXAFSCB_CallBack(struct rx_call *a_call, register struct AFSCBFids *a_fids, struct AFSCBs *a_callbacks)
482 register int i; /*Loop variable*/
483 struct AFSFid *tfid; /*Ptr to current fid*/
484 register struct rx_connection *tconn; /*Call's connection*/
490 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
492 AFS_STATCNT(SRXAFSCB_CallBack);
493 if (!(tconn = rx_ConnectionOf(a_call))) return(0);
494 tfid = (struct AFSFid *) a_fids->AFSCBFids_val;
497 * For now, we ignore callbacks, since the File Server only *breaks*
498 * callbacks at present.
500 for (i = 0; i < a_fids->AFSCBFids_len; i++)
501 ClearCallBack(tconn, &tfid[i]);
509 } /*SRXAFSCB_CallBack*/
512 /*------------------------------------------------------------------------
513 * EXPORTED SRXAFSCB_Probe
516 * Routine called by the server-side callback RPC interface to
517 * implement ``probing'' the Cache Manager, just making sure it's
521 * a_call : Ptr to Rx call on which this request came in.
527 * Nothing interesting.
531 *------------------------------------------------------------------------*/
533 int SRXAFSCB_Probe(struct rx_call *a_call)
539 AFS_STATCNT(SRXAFSCB_Probe);
541 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
551 /*------------------------------------------------------------------------
552 * EXPORTED SRXAFSCB_InitCallBackState
555 * Routine called by the server-side callback RPC interface to
556 * implement clearing all callbacks from this host.
559 * a_call : Ptr to Rx call on which this request came in.
565 * Nothing interesting.
569 *------------------------------------------------------------------------*/
571 int SRXAFSCB_InitCallBackState(struct rx_call *a_call)
574 register struct vcache *tvc;
575 register struct rx_connection *tconn;
576 register struct rx_peer *peer;
583 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
584 AFS_STATCNT(SRXAFSCB_InitCallBackState);
587 * Find the address of the host making this call
589 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
592 afs_oddCBs++; /*Including any missed via create race*/
593 afs_evenCBs++; /*Including any missed via create race*/
595 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *)0, 0);
597 for (i = 0; i < VCSIZE; i++)
598 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
599 if (tvc->callback == ts) {
600 ObtainWriteLock(&afs_xcbhash, 451);
601 afs_DequeueCallback(tvc);
602 tvc->callback = NULL;
603 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
604 ReleaseWriteLock(&afs_xcbhash);
611 /* find any volumes residing on this server and flush their state */
613 register struct volume *tv;
616 for (i=0;i<NVOLS;i++)
617 for (tv = afs_volumes[i]; tv; tv=tv->next) {
618 for (j=0; j<MAXHOSTS; j++)
619 if (tv->serverHost[j] == ts)
620 afs_ResetVolumeInfo(tv);
623 osi_dnlc_purge(); /* may be a little bit extreme */
632 } /*SRXAFSCB_InitCallBackState*/
635 /*------------------------------------------------------------------------
636 * EXPORTED SRXAFSCB_XStatsVersion
639 * Routine called by the server-side callback RPC interface to
640 * implement pulling out the xstat version number for the Cache
644 * a_versionP : Ptr to the version number variable to set.
650 * Nothing interesting.
654 *------------------------------------------------------------------------*/
656 int SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 *a_versionP)
663 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
665 *a_versionP = AFSCB_XSTAT_VERSION;
672 } /*SRXAFSCB_XStatsVersion*/
675 /*------------------------------------------------------------------------
676 * EXPORTED SRXAFSCB_GetXStats
679 * Routine called by the server-side callback RPC interface to
680 * implement getting the given data collection from the extended
681 * Cache Manager statistics.
684 * a_call : Ptr to Rx call on which this request came in.
685 * a_clientVersionNum : Client version number.
686 * a_opCode : Desired operation.
687 * a_serverVersionNumP : Ptr to version number to set.
688 * a_timeP : Ptr to time value (seconds) to set.
689 * a_dataArray : Ptr to variable array structure to return
696 * Nothing interesting.
700 *------------------------------------------------------------------------*/
702 int SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
703 afs_int32 a_collectionNumber, afs_int32 *a_srvVersionNumP,
704 afs_int32 *a_timeP, AFSCB_CollData *a_dataP)
706 register int code; /*Return value*/
707 afs_int32 *dataBuffP; /*Ptr to data to be returned*/
708 afs_int32 dataBytes; /*Bytes in data buffer*/
713 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
716 * Record the time of day and the server version number.
718 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
719 *a_timeP = osi_Time();
722 * Stuff the appropriate data in there (assume victory)
728 * We're not keeping stats, so just return successfully with
731 a_dataP->AFSCB_CollData_len = 0;
732 a_dataP->AFSCB_CollData_val = NULL;
734 switch(a_collectionNumber) {
735 case AFSCB_XSTATSCOLL_CALL_INFO:
737 * Pass back all the call-count-related data.
739 * >>> We are forced to allocate a separate area in which to
740 * >>> put this stuff in by the RPC stub generator, since it
741 * >>> will be freed at the tail end of the server stub code.
743 dataBytes = sizeof(struct afs_CMStats);
744 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
745 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
746 a_dataP->AFSCB_CollData_len = dataBytes>>2;
747 a_dataP->AFSCB_CollData_val = dataBuffP;
750 case AFSCB_XSTATSCOLL_PERF_INFO:
752 * Update and then pass back all the performance-related data.
753 * Note: the only performance fields that need to be computed
754 * at this time are the number of accesses for this collection
755 * and the current server record info.
757 * >>> We are forced to allocate a separate area in which to
758 * >>> put this stuff in by the RPC stub generator, since it
759 * >>> will be freed at the tail end of the server stub code.
761 afs_stats_cmperf.numPerfCalls++;
763 dataBytes = sizeof(afs_stats_cmperf);
764 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
765 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
766 a_dataP->AFSCB_CollData_len = dataBytes>>2;
767 a_dataP->AFSCB_CollData_val = dataBuffP;
770 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
772 * Pass back the full range of performance and statistical
773 * data available. We have to bring the normal performance
774 * data collection up to date, then copy that data into
775 * the full collection.
777 * >>> We are forced to allocate a separate area in which to
778 * >>> put this stuff in by the RPC stub generator, since it
779 * >>> will be freed at the tail end of the server stub code.
781 afs_stats_cmperf.numPerfCalls++;
783 memcpy((char *)(&(afs_stats_cmfullperf.perf)), (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
784 afs_stats_cmfullperf.numFullPerfCalls++;
786 dataBytes = sizeof(afs_stats_cmfullperf);
787 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
788 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
789 a_dataP->AFSCB_CollData_len = dataBytes>>2;
790 a_dataP->AFSCB_CollData_val = dataBuffP;
795 * Illegal collection number.
797 a_dataP->AFSCB_CollData_len = 0;
798 a_dataP->AFSCB_CollData_val = NULL;
800 } /*Switch on collection number*/
801 #endif /* AFS_NOSTATS */
809 } /*SRXAFSCB_GetXStats*/
812 /*------------------------------------------------------------------------
813 * EXPORTED afs_RXCallBackServer
816 * Body of the thread supporting callback services.
825 * Nothing interesting.
829 *------------------------------------------------------------------------*/
831 int afs_RXCallBackServer(void)
833 AFS_STATCNT(afs_RXCallBackServer);
838 afs_osi_Sleep(&afs_server);
842 * Donate this process to Rx.
847 } /*afs_RXCallBackServer*/
850 /*------------------------------------------------------------------------
851 * EXPORTED shutdown_CB
854 * Zero out important Cache Manager data structures.
863 * Nothing interesting.
867 *------------------------------------------------------------------------*/
869 int shutdown_CB(void)
871 AFS_STATCNT(shutdown_CB);
873 if (afs_cold_shutdown) {
874 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps = afs_evenZaps =
875 afs_connectBacks = 0;
882 /*------------------------------------------------------------------------
883 * EXPORTED SRXAFSCB_InitCallBackState2
886 * This routine was used in the AFS 3.5 beta release, but not anymore.
887 * It has since been replaced by SRXAFSCB_InitCallBackState3.
890 * a_call : Ptr to Rx call on which this request came in.
893 * RXGEN_OPCODE (always).
896 * Nothing interesting.
900 *------------------------------------------------------------------------*/
902 int SRXAFSCB_InitCallBackState2(struct rx_call *a_call, struct interfaceAddr *addr)
907 /*------------------------------------------------------------------------
908 * EXPORTED SRXAFSCB_WhoAreYou
911 * Routine called by the server-side callback RPC interface to
912 * obtain a unique identifier for the client. The server uses
913 * this identifier to figure out whether or not two RX connections
914 * are from the same client, and to find out which addresses go
915 * with which clients.
918 * a_call : Ptr to Rx call on which this request came in.
919 * addr: Ptr to return the list of interfaces for this client.
925 * Nothing interesting.
929 *------------------------------------------------------------------------*/
931 int SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
939 AFS_STATCNT(SRXAFSCB_WhoAreYou);
941 ObtainReadLock(&afs_xinterface);
943 /* return all network interface addresses */
944 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
945 addr->uuid = afs_cb_interface.uuid;
946 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
947 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
948 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
949 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
952 ReleaseReadLock(&afs_xinterface);
960 /*------------------------------------------------------------------------
961 * EXPORTED SRXAFSCB_InitCallBackState3
964 * Routine called by the server-side callback RPC interface to
965 * implement clearing all callbacks from this host.
968 * a_call : Ptr to Rx call on which this request came in.
974 * Nothing interesting.
978 *------------------------------------------------------------------------*/
980 int SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID *a_uuid)
985 * TBD: Lookup the server by the UUID instead of its IP address.
987 code = SRXAFSCB_InitCallBackState(a_call);
993 /*------------------------------------------------------------------------
994 * EXPORTED SRXAFSCB_ProbeUuid
997 * Routine called by the server-side callback RPC interface to
998 * implement ``probing'' the Cache Manager, just making sure it's
999 * still there is still the same client it used to be.
1002 * a_call : Ptr to Rx call on which this request came in.
1003 * a_uuid : Ptr to UUID that must match the client's UUID.
1006 * 0 if a_uuid matches the UUID for this client
1007 * Non-zero otherwize
1010 * Nothing interesting.
1014 *------------------------------------------------------------------------*/
1016 int SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID *a_uuid)
1022 AFS_STATCNT(SRXAFSCB_Probe);
1024 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1025 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1026 code = 1; /* failure */
1035 /*------------------------------------------------------------------------
1036 * EXPORTED SRXAFSCB_GetServerPrefs
1039 * Routine to list server preferences used by this client.
1042 * a_call : Ptr to Rx call on which this request came in.
1043 * a_index : Input server index
1044 * a_srvr_addr : Output server address in host byte order
1045 * (0xffffffff on last server)
1046 * a_srvr_rank : Output server rank
1052 * Nothing interesting.
1056 *------------------------------------------------------------------------*/
1058 int SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1059 afs_int32 *a_srvr_addr, afs_int32 *a_srvr_rank)
1065 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1067 ObtainReadLock(&afs_xserver);
1069 /* Search the hash table for the server with this index */
1070 *a_srvr_addr = 0xffffffff;
1071 *a_srvr_rank = 0xffffffff;
1072 for (i=0, j=0; j < NSERVERS && i <= a_index; j++) {
1073 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1075 *a_srvr_addr = ntohl(sa->sa_ip);
1076 *a_srvr_rank = sa->sa_iprank;
1081 ReleaseReadLock(&afs_xserver);
1089 /*------------------------------------------------------------------------
1090 * EXPORTED SRXAFSCB_GetCellServDB
1093 * Routine to list cells configured for this client
1096 * a_call : Ptr to Rx call on which this request came in.
1097 * a_index : Input cell index
1098 * a_name : Output cell name ("" on last cell)
1099 * a_hosts : Output cell database servers in host byte order.
1105 * Nothing interesting.
1109 *------------------------------------------------------------------------*/
1111 int SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1112 char **a_name, serverList *a_hosts)
1116 char *t_name, *p_name = NULL;
1119 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1121 tcell = afs_GetCellByIndex(a_index, READ_LOCK, 0);
1125 a_hosts->serverList_val = 0;
1126 a_hosts->serverList_len = 0;
1128 p_name = tcell->cellName;
1129 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++)
1132 a_hosts->serverList_val = (afs_int32 *)afs_osi_Alloc(j*sizeof(afs_int32));
1133 a_hosts->serverList_len = j;
1134 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++)
1135 a_hosts->serverList_val[j] = ntohl(tcell->cellHosts[j]->addr->sa_ip);
1136 afs_PutCell(tcell, READ_LOCK);
1139 t_name = (char *)afs_osi_Alloc(i+1);
1140 if (t_name == NULL) {
1141 afs_osi_Free(a_hosts->serverList_val, (j*sizeof(afs_int32)));
1148 memcpy(t_name, p_name, i);
1157 /*------------------------------------------------------------------------
1158 * EXPORTED SRXAFSCB_GetLocalCell
1161 * Routine to return name of client's local cell
1164 * a_call : Ptr to Rx call on which this request came in.
1165 * a_name : Output cell name
1171 * Nothing interesting.
1175 *------------------------------------------------------------------------*/
1177 int SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1181 struct afs_q *cq, *tq;
1182 char *t_name, *p_name = NULL;
1185 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1187 /* Search the list for the primary cell. Cell number 1 is only
1188 * the primary cell is when no other cell is explicitly marked as
1189 * the primary cell. */
1190 ObtainReadLock(&afs_xcell);
1192 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
1195 if (tcell->states & CPrimary) {
1196 p_name = tcell->cellName;
1199 if (tcell->cell == 1) {
1200 p_name = tcell->cellName;
1205 plen = strlen(p_name);
1208 t_name = (char *)afs_osi_Alloc(plen+1);
1209 if (t_name == NULL) {
1210 ReleaseReadLock(&afs_xcell);
1215 t_name[plen] = '\0';
1217 memcpy(t_name, p_name, plen);
1219 ReleaseReadLock(&afs_xcell);
1229 * afs_MarshallCacheConfig - marshall client cache configuration
1233 * IN callerVersion - the rpc stat version of the caller.
1235 * IN config - client cache configuration.
1237 * OUT ptr - buffer where configuration is marshalled.
1243 static void afs_MarshallCacheConfig(afs_uint32 callerVersion,
1244 cm_initparams_v1 *config, afs_uint32 *ptr)
1246 AFS_STATCNT(afs_MarshallCacheConfig);
1248 * We currently only support version 1.
1250 *(ptr++) = config->nChunkFiles;
1251 *(ptr++) = config->nStatCaches;
1252 *(ptr++) = config->nDataCaches;
1253 *(ptr++) = config->nVolumeCaches;
1254 *(ptr++) = config->firstChunkSize;
1255 *(ptr++) = config->otherChunkSize;
1256 *(ptr++) = config->cacheSize;
1257 *(ptr++) = config->setTime;
1258 *(ptr++) = config->memCache;
1262 /*------------------------------------------------------------------------
1263 * EXPORTED SRXAFSCB_GetCacheConfig
1266 * Routine to return parameters used to initialize client cache.
1267 * Client may request any format version. Server may not return
1268 * format version greater than version requested by client.
1271 * a_call: Ptr to Rx call on which this request came in.
1272 * callerVersion: Data format version desired by the client.
1273 * serverVersion: Data format version of output data.
1274 * configCount: Number bytes allocated for output data.
1275 * config: Client cache configuration.
1281 * Nothing interesting.
1285 *------------------------------------------------------------------------*/
1287 int SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1288 afs_uint32 *serverVersion, afs_uint32 *configCount, cacheConfig *config)
1290 afs_uint32 *t_config;
1292 cm_initparams_v1 cm_config;
1295 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1298 * Currently only support version 1
1300 allocsize = sizeof(cm_initparams_v1);
1301 t_config = (afs_uint32 *)afs_osi_Alloc(allocsize);
1302 if (t_config == NULL) {
1307 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1308 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1309 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1310 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1311 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1312 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1313 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1314 cm_config.setTime = cm_initParams.cmi_setTime;
1315 cm_config.memCache = cm_initParams.cmi_memCache;
1317 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1319 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1320 *configCount = allocsize;
1321 config->cacheConfig_val = t_config;
1322 config->cacheConfig_len = allocsize/sizeof(afs_uint32);
1329 /*------------------------------------------------------------------------
1330 * EXPORTED SRXAFSCB_FetchData
1333 * Routine to do third party move from a remioserver to the original
1334 * issuer of an ArchiveData request. Presently supported only by the
1335 * "fs" command, not by the AFS client.
1338 * rxcall: Ptr to Rx call on which this request came in.
1339 * Fid: pointer to AFSFid structure.
1340 * Fd: File descriptor inside fs command.
1341 * Position: Offset in the file.
1342 * Length: Data length to transfer.
1343 * TotalLength: Pointer to total file length field
1349 * Nothing interesting.
1352 *------------------------------------------------------------------------*/
1353 int SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1354 afs_int64 Position, afs_int64 Length, afs_int64 *TotalLength)
1359 /*------------------------------------------------------------------------
1360 * EXPORTED SRXAFSCB_StoreData
1363 * Routine to do third party move from a remioserver to the original
1364 * issuer of a RetrieveData request. Presently supported only by the
1365 * "fs" command, not by the AFS client.
1368 * rxcall: Ptr to Rx call on which this request came in.
1369 * Fid: pointer to AFSFid structure.
1370 * Fd: File descriptor inside fs command.
1371 * Position: Offset in the file.
1372 * Length: Data length to transfer.
1373 * TotalLength: Pointer to total file length field
1379 * Nothing interesting.
1383 *------------------------------------------------------------------------*/
1384 int SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1385 afs_int64 Position, afs_int64 Length, afs_int64 *TotalLength)