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)
938 AFS_STATCNT(SRXAFSCB_WhoAreYou);
940 ObtainReadLock(&afs_xinterface);
942 /* return all network interface addresses */
943 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
944 addr->uuid = afs_cb_interface.uuid;
945 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
946 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
947 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
948 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
951 ReleaseReadLock(&afs_xinterface);
959 /*------------------------------------------------------------------------
960 * EXPORTED SRXAFSCB_InitCallBackState3
963 * Routine called by the server-side callback RPC interface to
964 * implement clearing all callbacks from this host.
967 * a_call : Ptr to Rx call on which this request came in.
973 * Nothing interesting.
977 *------------------------------------------------------------------------*/
979 int SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID *a_uuid)
984 * TBD: Lookup the server by the UUID instead of its IP address.
986 code = SRXAFSCB_InitCallBackState(a_call);
992 /*------------------------------------------------------------------------
993 * EXPORTED SRXAFSCB_ProbeUuid
996 * Routine called by the server-side callback RPC interface to
997 * implement ``probing'' the Cache Manager, just making sure it's
998 * still there is still the same client it used to be.
1001 * a_call : Ptr to Rx call on which this request came in.
1002 * a_uuid : Ptr to UUID that must match the client's UUID.
1005 * 0 if a_uuid matches the UUID for this client
1006 * Non-zero otherwize
1009 * Nothing interesting.
1013 *------------------------------------------------------------------------*/
1015 int SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID *a_uuid)
1021 AFS_STATCNT(SRXAFSCB_Probe);
1023 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1024 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1025 code = 1; /* failure */
1034 /*------------------------------------------------------------------------
1035 * EXPORTED SRXAFSCB_GetServerPrefs
1038 * Routine to list server preferences used by this client.
1041 * a_call : Ptr to Rx call on which this request came in.
1042 * a_index : Input server index
1043 * a_srvr_addr : Output server address in host byte order
1044 * (0xffffffff on last server)
1045 * a_srvr_rank : Output server rank
1051 * Nothing interesting.
1055 *------------------------------------------------------------------------*/
1057 int SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1058 afs_int32 *a_srvr_addr, afs_int32 *a_srvr_rank)
1064 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1066 ObtainReadLock(&afs_xserver);
1068 /* Search the hash table for the server with this index */
1069 *a_srvr_addr = 0xffffffff;
1070 *a_srvr_rank = 0xffffffff;
1071 for (i=0, j=0; j < NSERVERS && i <= a_index; j++) {
1072 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1074 *a_srvr_addr = ntohl(sa->sa_ip);
1075 *a_srvr_rank = sa->sa_iprank;
1080 ReleaseReadLock(&afs_xserver);
1088 /*------------------------------------------------------------------------
1089 * EXPORTED SRXAFSCB_GetCellServDB
1092 * Routine to list cells configured for this client
1095 * a_call : Ptr to Rx call on which this request came in.
1096 * a_index : Input cell index
1097 * a_name : Output cell name ("" on last cell)
1098 * a_hosts : Output cell database servers in host byte order.
1104 * Nothing interesting.
1108 *------------------------------------------------------------------------*/
1110 int SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1111 char **a_name, serverList *a_hosts)
1115 char *t_name, *p_name = NULL;
1118 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1120 tcell = afs_GetCellByIndex(a_index, READ_LOCK);
1124 a_hosts->serverList_val = 0;
1125 a_hosts->serverList_len = 0;
1127 p_name = tcell->cellName;
1128 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++)
1131 a_hosts->serverList_val = (afs_int32 *)afs_osi_Alloc(j*sizeof(afs_int32));
1132 a_hosts->serverList_len = j;
1133 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++)
1134 a_hosts->serverList_val[j] = ntohl(tcell->cellHosts[j]->addr->sa_ip);
1135 afs_PutCell(tcell, READ_LOCK);
1138 t_name = (char *)afs_osi_Alloc(i+1);
1139 if (t_name == NULL) {
1140 afs_osi_Free(a_hosts->serverList_val, (j*sizeof(afs_int32)));
1147 memcpy(t_name, p_name, i);
1156 /*------------------------------------------------------------------------
1157 * EXPORTED SRXAFSCB_GetLocalCell
1160 * Routine to return name of client's local cell
1163 * a_call : Ptr to Rx call on which this request came in.
1164 * a_name : Output cell name
1170 * Nothing interesting.
1174 *------------------------------------------------------------------------*/
1176 int SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1180 char *t_name, *p_name = NULL;
1183 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1185 /* Search the list for the primary cell. Cell number 1 is only
1186 * the primary cell is when no other cell is explicitly marked as
1187 * the primary cell. */
1188 tcell = afs_GetPrimaryCell(READ_LOCK);
1190 p_name = tcell->cellName;
1192 plen = strlen(p_name);
1195 t_name = (char *)afs_osi_Alloc(plen+1);
1196 if (t_name == NULL) {
1197 if (tcell) afs_PutCell(tcell, READ_LOCK);
1202 t_name[plen] = '\0';
1204 memcpy(t_name, p_name, plen);
1209 if (tcell) afs_PutCell(tcell, READ_LOCK);
1215 * afs_MarshallCacheConfig - marshall client cache configuration
1219 * IN callerVersion - the rpc stat version of the caller.
1221 * IN config - client cache configuration.
1223 * OUT ptr - buffer where configuration is marshalled.
1229 static void afs_MarshallCacheConfig(afs_uint32 callerVersion,
1230 cm_initparams_v1 *config, afs_uint32 *ptr)
1232 AFS_STATCNT(afs_MarshallCacheConfig);
1234 * We currently only support version 1.
1236 *(ptr++) = config->nChunkFiles;
1237 *(ptr++) = config->nStatCaches;
1238 *(ptr++) = config->nDataCaches;
1239 *(ptr++) = config->nVolumeCaches;
1240 *(ptr++) = config->firstChunkSize;
1241 *(ptr++) = config->otherChunkSize;
1242 *(ptr++) = config->cacheSize;
1243 *(ptr++) = config->setTime;
1244 *(ptr++) = config->memCache;
1248 /*------------------------------------------------------------------------
1249 * EXPORTED SRXAFSCB_GetCacheConfig
1252 * Routine to return parameters used to initialize client cache.
1253 * Client may request any format version. Server may not return
1254 * format version greater than version requested by client.
1257 * a_call: Ptr to Rx call on which this request came in.
1258 * callerVersion: Data format version desired by the client.
1259 * serverVersion: Data format version of output data.
1260 * configCount: Number bytes allocated for output data.
1261 * config: Client cache configuration.
1267 * Nothing interesting.
1271 *------------------------------------------------------------------------*/
1273 int SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1274 afs_uint32 *serverVersion, afs_uint32 *configCount, cacheConfig *config)
1276 afs_uint32 *t_config;
1278 cm_initparams_v1 cm_config;
1281 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1284 * Currently only support version 1
1286 allocsize = sizeof(cm_initparams_v1);
1287 t_config = (afs_uint32 *)afs_osi_Alloc(allocsize);
1288 if (t_config == NULL) {
1293 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1294 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1295 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1296 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1297 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1298 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1299 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1300 cm_config.setTime = cm_initParams.cmi_setTime;
1301 cm_config.memCache = cm_initParams.cmi_memCache;
1303 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1305 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1306 *configCount = allocsize;
1307 config->cacheConfig_val = t_config;
1308 config->cacheConfig_len = allocsize/sizeof(afs_uint32);
1315 /*------------------------------------------------------------------------
1316 * EXPORTED SRXAFSCB_FetchData
1319 * Routine to do third party move from a remioserver to the original
1320 * issuer of an ArchiveData request. Presently supported only by the
1321 * "fs" command, not by the AFS client.
1324 * rxcall: Ptr to Rx call on which this request came in.
1325 * Fid: pointer to AFSFid structure.
1326 * Fd: File descriptor inside fs command.
1327 * Position: Offset in the file.
1328 * Length: Data length to transfer.
1329 * TotalLength: Pointer to total file length field
1335 * Nothing interesting.
1338 *------------------------------------------------------------------------*/
1339 int SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1340 afs_int64 Position, afs_int64 Length, afs_int64 *TotalLength)
1345 /*------------------------------------------------------------------------
1346 * EXPORTED SRXAFSCB_StoreData
1349 * Routine to do third party move from a remioserver to the original
1350 * issuer of a RetrieveData request. Presently supported only by the
1351 * "fs" command, not by the AFS client.
1354 * rxcall: Ptr to Rx call on which this request came in.
1355 * Fid: pointer to AFSFid structure.
1356 * Fd: File descriptor inside fs command.
1357 * Position: Offset in the file.
1358 * Length: Data length to transfer.
1359 * TotalLength: Pointer to total file length field
1365 * Nothing interesting.
1369 *------------------------------------------------------------------------*/
1370 int SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1371 afs_int64 Position, afs_int64 Length, afs_int64 *TotalLength)
1376 /*------------------------------------------------------------------------
1377 * EXPORTED SRXAFSCB_GetCellByNum
1380 * Routine to get information about a cell specified by its
1381 * cell number (returned by GetCE/GetCE64).
1384 * a_call : Ptr to Rx call on which this request came in.
1385 * a_cellnum : Input cell number
1386 * a_name : Output cell name (one zero byte when no such cell).
1387 * a_hosts : Output cell database servers in host byte order.
1393 * Nothing interesting.
1397 *------------------------------------------------------------------------*/
1399 int SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
1400 char **a_name, serverList *a_hosts)
1406 AFS_STATCNT(SRXAFSCB_GetCellByNum);
1408 a_hosts->serverList_val = 0;
1409 a_hosts->serverList_len = 0;
1411 tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
1413 *a_name = afs_strdup("");
1418 ObtainReadLock(&tcell->lock);
1419 *a_name = afs_strdup(tcell->cellName);
1421 for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++)
1423 a_hosts->serverList_len = sn;
1424 a_hosts->serverList_val = (afs_int32 *) afs_osi_Alloc(sn*sizeof(afs_int32));
1426 for (i = 0; i < sn; i++)
1427 a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
1428 ReleaseReadLock(&tcell->lock);
1429 afs_PutCell(tcell, READ_LOCK);