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 extern struct volume *afs_volumes[NVOLS]; /* volume hash table */
27 extern void afs_DequeueCallback();
28 extern void afs_ComputePAGStats();
29 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
30 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs*/
31 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files*/
32 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
33 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted*/
34 afs_int32 afs_evenZaps = 0; /*File cache entries deleted*/
35 afs_int32 afs_connectBacks = 0;
36 extern struct rx_service *afs_server;
38 extern afs_lock_t afs_xvcb, afs_xbrs, afs_xdcache;
39 extern afs_rwlock_t afs_xvcache, afs_xserver, afs_xcell, afs_xuser;
40 extern afs_rwlock_t afs_xvolume, afs_puttofileLock, afs_ftf, afs_xinterface;
41 extern afs_rwlock_t afs_xconn;
42 extern struct afs_lock afs_xaxs;
43 extern afs_lock_t afs_xcbhash;
44 extern struct srvAddr *afs_srvAddrs[NSERVERS];
45 extern struct afs_q CellLRU;
46 extern struct cm_initparams cm_initParams;
49 * Some debugging aids.
51 static struct ltable {
55 "afs_xvcache", (char *)&afs_xvcache,
56 "afs_xdcache", (char *)&afs_xdcache,
57 "afs_xserver", (char *)&afs_xserver,
58 "afs_xvcb", (char *)&afs_xvcb,
59 "afs_xbrs", (char *)&afs_xbrs,
60 "afs_xcell", (char *)&afs_xcell,
61 "afs_xconn", (char *)&afs_xconn,
62 "afs_xuser", (char *)&afs_xuser,
63 "afs_xvolume", (char *)&afs_xvolume,
64 "puttofile", (char *)&afs_puttofileLock,
65 "afs_ftf", (char *)&afs_ftf,
66 "afs_xcbhash", (char *)&afs_xcbhash,
67 "afs_xaxs", (char *)&afs_xaxs,
68 "afs_xinterface", (char *)&afs_xinterface,
70 unsigned long lastCallBack_vnode;
71 unsigned int lastCallBack_dv;
72 osi_timeval_t lastCallBack_time;
74 /* these are for storing alternate interface addresses */
75 struct interfaceAddr afs_cb_interface;
77 /*------------------------------------------------------------------------
78 * EXPORTED SRXAFSCB_GetCE
81 * Routine called by the server-side callback RPC interface to
82 * implement pulling out the contents of the i'th cache entry.
85 * a_call : Ptr to Rx call on which this request came in.
86 * a_index : Index of desired cache entry.
87 * a_result : Ptr to a buffer for the given cache entry.
90 * 0 if everything went fine,
91 * 1 if we were given a bad index.
94 * Nothing interesting.
98 *------------------------------------------------------------------------*/
100 int SRXAFSCB_GetCE(a_call, a_index, a_result)
101 struct rx_call *a_call;
103 struct AFSDBCacheEntry *a_result;
107 register int i; /*Loop variable*/
108 register struct vcache *tvc; /*Ptr to current cache entry*/
109 int code; /*Return code*/
114 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
116 AFS_STATCNT(SRXAFSCB_GetCE);
117 for (i = 0; i < VCSIZE; i++) {
118 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
122 } /*Zip through current hash chain*/
123 } /*Zip through hash chains*/
126 if (tvc == (struct vcache *) 0) {
133 * Copy out the located entry.
135 a_result->addr = afs_data_pointer_to_int32(tvc);
136 a_result->cell = tvc->fid.Cell;
137 a_result->netFid.Volume = tvc->fid.Fid.Volume;
138 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
139 a_result->netFid.Unique = tvc->fid.Fid.Unique;
140 a_result->lock.waitStates = tvc->lock.wait_states;
141 a_result->lock.exclLocked = tvc->lock.excl_locked;
142 a_result->lock.readersReading = tvc->lock.readers_reading;
143 a_result->lock.numWaiting = tvc->lock.num_waiting;
144 #if defined(INSTRUMENT_LOCKS)
145 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
146 a_result->lock.pid_writer = tvc->lock.pid_writer;
147 a_result->lock.src_indicator = tvc->lock.src_indicator;
149 /* On osf20 , the vcache does not maintain these three fields */
150 a_result->lock.pid_last_reader = 0;
151 a_result->lock.pid_writer = 0;
152 a_result->lock.src_indicator = 0;
153 #endif /* AFS_OSF20_ENV */
154 #ifdef AFS_64BIT_CLIENT
155 a_result->Length = (afs_int32) tvc->m.Length & 0xffffffff;
156 #else /* AFS_64BIT_CLIENT */
157 a_result->Length = tvc->m.Length;
158 #endif /* AFS_64BIT_CLIENT */
159 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
160 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
161 a_result->cbExpires = tvc->cbExpires;
162 a_result->refCount = VREFCOUNT(tvc);
163 a_result->opens = tvc->opens;
164 a_result->writers = tvc->execsOrWriters;
165 a_result->mvstat = tvc->mvstat;
166 a_result->states = tvc->states;
170 * Return our results.
181 int SRXAFSCB_GetCE64(a_call, a_index, a_result)
182 struct rx_call *a_call;
184 struct AFSDBCacheEntry64 *a_result;
186 { /*SRXAFSCB_GetCE64*/
188 register int i; /*Loop variable*/
189 register struct vcache *tvc; /*Ptr to current cache entry*/
190 int code; /*Return code*/
195 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
197 AFS_STATCNT(SRXAFSCB_GetCE64);
198 for (i = 0; i < VCSIZE; i++) {
199 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
203 } /*Zip through current hash chain*/
204 } /*Zip through hash chains*/
207 if (tvc == (struct vcache *) 0) {
214 * Copy out the located entry.
216 a_result->addr = afs_data_pointer_to_int32(tvc);
217 a_result->cell = tvc->fid.Cell;
218 a_result->netFid.Volume = tvc->fid.Fid.Volume;
219 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
220 a_result->netFid.Unique = tvc->fid.Fid.Unique;
221 a_result->lock.waitStates = tvc->lock.wait_states;
222 a_result->lock.exclLocked = tvc->lock.excl_locked;
223 a_result->lock.readersReading = tvc->lock.readers_reading;
224 a_result->lock.numWaiting = tvc->lock.num_waiting;
225 #if defined(INSTRUMENT_LOCKS)
226 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
227 a_result->lock.pid_writer = tvc->lock.pid_writer;
228 a_result->lock.src_indicator = tvc->lock.src_indicator;
230 /* On osf20 , the vcache does not maintain these three fields */
231 a_result->lock.pid_last_reader = 0;
232 a_result->lock.pid_writer = 0;
233 a_result->lock.src_indicator = 0;
234 #endif /* AFS_OSF20_ENV */
236 a_result->Length = tvc->m.Length;
237 #else /* AFS_64BIT_ENV */
238 #ifdef AFS_64BIT_CLIENT
239 a_result->Length = tvc->m.Length;
240 #else /* AFS_64BIT_CLIENT */
241 a_result->Length.high = 0;
242 a_result->Length.low = tvc->m.Length;
243 #endif /* AFS_64BIT_CLIENT */
244 #endif /* AFS_64BIT_ENV */
245 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
246 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
247 a_result->cbExpires = tvc->cbExpires;
248 a_result->refCount = VREFCOUNT(tvc);
249 a_result->opens = tvc->opens;
250 a_result->writers = tvc->execsOrWriters;
251 a_result->mvstat = tvc->mvstat;
252 a_result->states = tvc->states;
256 * Return our results.
265 } /*SRXAFSCB_GetCE64*/
268 /*------------------------------------------------------------------------
269 * EXPORTED SRXAFSCB_GetLock
272 * Routine called by the server-side callback RPC interface to
273 * implement pulling out the contents of a lock in the lock
277 * a_call : Ptr to Rx call on which this request came in.
278 * a_index : Index of desired lock.
279 * a_result : Ptr to a buffer for the given lock.
282 * 0 if everything went fine,
283 * 1 if we were given a bad index.
286 * Nothing interesting.
290 *------------------------------------------------------------------------*/
292 int SRXAFSCB_GetLock (a_call, a_index, a_result)
293 struct rx_call *a_call;
295 struct AFSDBLock *a_result;
297 { /*SRXAFSCB_GetLock*/
299 struct ltable *tl; /*Ptr to lock table entry*/
300 int nentries; /*Num entries in table*/
301 int code; /*Return code*/
306 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
308 AFS_STATCNT(SRXAFSCB_GetLock);
309 nentries = sizeof(ltable)/sizeof(struct ltable);
310 if (a_index < 0 || a_index >= nentries) {
318 * Found it - copy out its contents.
320 tl = <able[a_index];
321 strcpy(a_result->name, tl->name);
322 a_result->lock.waitStates = ((struct afs_lock *)(tl->addr))->wait_states;
323 a_result->lock.exclLocked = ((struct afs_lock *)(tl->addr))->excl_locked;
324 a_result->lock.readersReading = ((struct afs_lock *)(tl->addr))->readers_reading;
325 a_result->lock.numWaiting = ((struct afs_lock *)(tl->addr))->num_waiting;
326 #ifdef INSTRUMENT_LOCKS
327 a_result->lock.pid_last_reader = ((struct afs_lock *)(tl->addr))->pid_last_reader;
328 a_result->lock.pid_writer = ((struct afs_lock *)(tl->addr))->pid_writer;
329 a_result->lock.src_indicator = ((struct afs_lock *)(tl->addr))->src_indicator;
331 a_result->lock.pid_last_reader = 0;
332 a_result->lock.pid_writer = 0;
333 a_result->lock.src_indicator = 0;
344 } /*SRXAFSCB_GetLock*/
347 /*------------------------------------------------------------------------
348 * static ClearCallBack
351 * Clear out callback information for the specified file, or
352 * even a whole volume. Used to worry about callback was from
353 * within the particular cell or not. Now we don't bother with
354 * that anymore; it's not worth the time.
357 * a_conn : Ptr to Rx connection involved.
358 * a_fid : Ptr to AFS fid being cleared.
364 * Nothing interesting.
368 *------------------------------------------------------------------------*/
370 static ClearCallBack(a_conn, a_fid)
371 register struct rx_connection *a_conn;
372 register struct AFSFid *a_fid;
376 register struct vcache *tvc;
378 struct VenusFid localFid;
381 AFS_STATCNT(ClearCallBack);
384 * XXXX Don't hold any server locks here because of callback protocol XXX
387 localFid.Fid.Volume = a_fid->Volume;
388 localFid.Fid.Vnode = a_fid->Vnode;
389 localFid.Fid.Unique = a_fid->Unique;
392 * Volume ID of zero means don't do anything.
394 if (a_fid->Volume != 0) {
395 if (a_fid->Vnode == 0) {
397 * Clear callback for the whole volume. Zip through the
398 * hash chain, nullifying entries whose volume ID matches.
400 for (i = 0; i < VCSIZE; i++)
401 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
402 if (tvc->fid.Fid.Volume == a_fid->Volume) {
403 tvc->callback = (struct server *)0;
404 tvc->quick.stamp = 0;
406 localFid.Cell = tvc->fid.Cell;
407 tvc->h1.dchint = NULL; /* invalidate hints */
408 ObtainWriteLock(&afs_xcbhash, 449);
409 afs_DequeueCallback(tvc);
410 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
412 if (tvc->fid.Fid.Vnode & 1)
416 ReleaseWriteLock(&afs_xcbhash);
417 if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
418 osi_dnlc_purgedp(tvc);
419 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
420 ICL_TYPE_POINTER, tvc,
421 ICL_TYPE_INT32, tvc->states,
422 ICL_TYPE_INT32, a_fid->Volume);
423 } else if ((tvc->states & CMValid) && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
424 tvc->states &= ~CMValid;
426 localFid.Cell = tvc->mvid->Cell;
431 * XXXX Don't hold any locks here XXXX
433 tv = afs_FindVolume(&localFid, 0);
435 afs_ResetVolumeInfo(tv);
436 afs_PutVolume(tv, 0);
437 /* invalidate mtpoint? */
439 } /*Clear callbacks for whole volume*/
442 * Clear callbacks just for the one file.
445 if (a_fid->Vnode & 1)
446 afs_oddCBs++; /*Could do this on volume basis, too*/
448 afs_evenCBs++; /*A particular fid was specified*/
449 i = VCHash(&localFid);
450 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
451 if (tvc->fid.Fid.Vnode == a_fid->Vnode
452 && tvc->fid.Fid.Volume == a_fid->Volume
453 && tvc->fid.Fid.Unique == a_fid->Unique ) {
454 tvc->callback = (struct server *)0;
455 tvc->quick.stamp = 0;
456 tvc->h1.dchint = NULL; /* invalidate hints */
457 ObtainWriteLock(&afs_xcbhash, 450);
458 afs_DequeueCallback(tvc);
459 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
460 ReleaseWriteLock(&afs_xcbhash);
461 if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
462 osi_dnlc_purgedp(tvc);
463 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
464 ICL_TYPE_POINTER, tvc,
465 ICL_TYPE_INT32, tvc->states, ICL_TYPE_LONG, 0);
467 lastCallBack_vnode = afid->Vnode;
468 lastCallBack_dv = tvc->mstat.DataVersion.low;
469 osi_GetuTime(&lastCallBack_time);
472 } /*Walk through hash table*/
473 } /*Clear callbacks for one file*/
474 } /*Fid has non-zero volume ID*/
477 * Always return a predictable value.
484 /*------------------------------------------------------------------------
485 * EXPORTED SRXAFSCB_CallBack
488 * Routine called by the server-side callback RPC interface to
489 * implement passing in callback information.
493 * a_call : Ptr to Rx call on which this request came in.
494 * a_fids : Ptr to array of fids involved.
495 * a_callbacks : Ptr to matching callback info for the fids.
501 * Nothing interesting.
505 *------------------------------------------------------------------------*/
507 int SRXAFSCB_CallBack(a_call, a_fids, a_callbacks)
508 struct rx_call *a_call;
509 register struct AFSCBFids *a_fids;
510 struct AFSCBs *a_callbacks;
512 { /*SRXAFSCB_CallBack*/
514 register int i; /*Loop variable*/
515 struct AFSFid *tfid; /*Ptr to current fid*/
516 register struct rx_connection *tconn; /*Call's connection*/
522 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
524 AFS_STATCNT(SRXAFSCB_CallBack);
525 if (!(tconn = rx_ConnectionOf(a_call))) return;
526 tfid = (struct AFSFid *) a_fids->AFSCBFids_val;
529 * For now, we ignore callbacks, since the File Server only *breaks*
530 * callbacks at present.
532 for (i = 0; i < a_fids->AFSCBFids_len; i++)
533 ClearCallBack(tconn, &tfid[i]);
541 } /*SRXAFSCB_CallBack*/
544 /*------------------------------------------------------------------------
545 * EXPORTED SRXAFSCB_Probe
548 * Routine called by the server-side callback RPC interface to
549 * implement ``probing'' the Cache Manager, just making sure it's
553 * a_call : Ptr to Rx call on which this request came in.
559 * Nothing interesting.
563 *------------------------------------------------------------------------*/
565 int SRXAFSCB_Probe(a_call)
566 struct rx_call *a_call;
573 AFS_STATCNT(SRXAFSCB_Probe);
575 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
585 /*------------------------------------------------------------------------
586 * EXPORTED SRXAFSCB_InitCallBackState
589 * Routine called by the server-side callback RPC interface to
590 * implement clearing all callbacks from this host.
593 * a_call : Ptr to Rx call on which this request came in.
599 * Nothing interesting.
603 *------------------------------------------------------------------------*/
605 int SRXAFSCB_InitCallBackState(a_call)
606 struct rx_call *a_call;
608 { /*SRXAFSCB_InitCallBackState*/
611 register struct vcache *tvc;
612 register struct rx_connection *tconn;
613 register struct rx_peer *peer;
616 extern int osi_dnlc_purge();
621 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
622 AFS_STATCNT(SRXAFSCB_InitCallBackState);
625 * Find the address of the host making this call
627 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
630 afs_oddCBs++; /*Including any missed via create race*/
631 afs_evenCBs++; /*Including any missed via create race*/
633 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *)0, 0);
635 for (i = 0; i < VCSIZE; i++)
636 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
637 if (tvc->callback == ts) {
638 ObtainWriteLock(&afs_xcbhash, 451);
639 afs_DequeueCallback(tvc);
640 tvc->callback = (struct server *)0;
641 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
642 ReleaseWriteLock(&afs_xcbhash);
649 /* find any volumes residing on this server and flush their state */
651 register struct volume *tv;
654 for (i=0;i<NVOLS;i++)
655 for (tv = afs_volumes[i]; tv; tv=tv->next) {
656 for (j=0; j<MAXHOSTS; j++)
657 if (tv->serverHost[j] == ts)
658 afs_ResetVolumeInfo(tv);
661 osi_dnlc_purge(); /* may be a little bit extreme */
670 } /*SRXAFSCB_InitCallBackState*/
673 /*------------------------------------------------------------------------
674 * EXPORTED SRXAFSCB_XStatsVersion
677 * Routine called by the server-side callback RPC interface to
678 * implement pulling out the xstat version number for the Cache
682 * a_versionP : Ptr to the version number variable to set.
688 * Nothing interesting.
692 *------------------------------------------------------------------------*/
694 int SRXAFSCB_XStatsVersion(a_call, a_versionP)
695 struct rx_call *a_call;
696 afs_int32 *a_versionP;
698 { /*SRXAFSCB_XStatsVersion*/
704 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
706 *a_versionP = AFSCB_XSTAT_VERSION;
713 } /*SRXAFSCB_XStatsVersion*/
716 /*------------------------------------------------------------------------
717 * EXPORTED SRXAFSCB_GetXStats
720 * Routine called by the server-side callback RPC interface to
721 * implement getting the given data collection from the extended
722 * Cache Manager statistics.
725 * a_call : Ptr to Rx call on which this request came in.
726 * a_clientVersionNum : Client version number.
727 * a_opCode : Desired operation.
728 * a_serverVersionNumP : Ptr to version number to set.
729 * a_timeP : Ptr to time value (seconds) to set.
730 * a_dataArray : Ptr to variable array structure to return
737 * Nothing interesting.
741 *------------------------------------------------------------------------*/
743 int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVersionNumP, a_timeP, a_dataP)
744 struct rx_call *a_call;
745 afs_int32 a_clientVersionNum;
746 afs_int32 a_collectionNumber;
747 afs_int32 *a_srvVersionNumP;
749 AFSCB_CollData *a_dataP;
751 { /*SRXAFSCB_GetXStats*/
753 register int code; /*Return value*/
754 afs_int32 *dataBuffP; /*Ptr to data to be returned*/
755 afs_int32 dataBytes; /*Bytes in data buffer*/
760 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
763 * Record the time of day and the server version number.
765 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
766 *a_timeP = osi_Time();
769 * Stuff the appropriate data in there (assume victory)
775 * We're not keeping stats, so just return successfully with
778 a_dataP->AFSCB_CollData_len = 0;
779 a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
781 switch(a_collectionNumber) {
782 case AFSCB_XSTATSCOLL_CALL_INFO:
784 * Pass back all the call-count-related data.
786 * >>> We are forced to allocate a separate area in which to
787 * >>> put this stuff in by the RPC stub generator, since it
788 * >>> will be freed at the tail end of the server stub code.
790 dataBytes = sizeof(struct afs_CMStats);
791 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
792 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
793 a_dataP->AFSCB_CollData_len = dataBytes>>2;
794 a_dataP->AFSCB_CollData_val = dataBuffP;
797 case AFSCB_XSTATSCOLL_PERF_INFO:
799 * Update and then pass back all the performance-related data.
800 * Note: the only performance fields that need to be computed
801 * at this time are the number of accesses for this collection
802 * and the current server record info.
804 * >>> We are forced to allocate a separate area in which to
805 * >>> put this stuff in by the RPC stub generator, since it
806 * >>> will be freed at the tail end of the server stub code.
808 afs_stats_cmperf.numPerfCalls++;
810 dataBytes = sizeof(afs_stats_cmperf);
811 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
812 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
813 a_dataP->AFSCB_CollData_len = dataBytes>>2;
814 a_dataP->AFSCB_CollData_val = dataBuffP;
817 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
819 * Pass back the full range of performance and statistical
820 * data available. We have to bring the normal performance
821 * data collection up to date, then copy that data into
822 * the full collection.
824 * >>> We are forced to allocate a separate area in which to
825 * >>> put this stuff in by the RPC stub generator, since it
826 * >>> will be freed at the tail end of the server stub code.
828 afs_stats_cmperf.numPerfCalls++;
830 memcpy((char *)(&(afs_stats_cmfullperf.perf)), (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
831 afs_stats_cmfullperf.numFullPerfCalls++;
833 dataBytes = sizeof(afs_stats_cmfullperf);
834 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
835 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
836 a_dataP->AFSCB_CollData_len = dataBytes>>2;
837 a_dataP->AFSCB_CollData_val = dataBuffP;
842 * Illegal collection number.
844 a_dataP->AFSCB_CollData_len = 0;
845 a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
847 } /*Switch on collection number*/
848 #endif /* AFS_NOSTATS */
856 } /*SRXAFSCB_GetXStats*/
859 /*------------------------------------------------------------------------
860 * EXPORTED afs_RXCallBackServer
863 * Body of the thread supporting callback services.
872 * Nothing interesting.
876 *------------------------------------------------------------------------*/
878 int afs_RXCallBackServer()
880 { /*afs_RXCallBackServer*/
881 AFS_STATCNT(afs_RXCallBackServer);
886 afs_osi_Sleep(&afs_server);
890 * Donate this process to Rx.
895 } /*afs_RXCallBackServer*/
898 /*------------------------------------------------------------------------
899 * EXPORTED shutdown_CB
902 * Zero out important Cache Manager data structures.
911 * Nothing interesting.
915 *------------------------------------------------------------------------*/
921 extern int afs_cold_shutdown;
923 AFS_STATCNT(shutdown_CB);
925 if (afs_cold_shutdown) {
926 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps = afs_evenZaps =
927 afs_connectBacks = 0;
934 /*------------------------------------------------------------------------
935 * EXPORTED SRXAFSCB_InitCallBackState2
938 * This routine was used in the AFS 3.5 beta release, but not anymore.
939 * It has since been replaced by SRXAFSCB_InitCallBackState3.
942 * a_call : Ptr to Rx call on which this request came in.
945 * RXGEN_OPCODE (always).
948 * Nothing interesting.
952 *------------------------------------------------------------------------*/
954 int SRXAFSCB_InitCallBackState2(a_call, addr)
955 struct rx_call *a_call;
956 struct interfaceAddr * addr;
961 /*------------------------------------------------------------------------
962 * EXPORTED SRXAFSCB_WhoAreYou
965 * Routine called by the server-side callback RPC interface to
966 * obtain a unique identifier for the client. The server uses
967 * this identifier to figure out whether or not two RX connections
968 * are from the same client, and to find out which addresses go
969 * with which clients.
972 * a_call : Ptr to Rx call on which this request came in.
973 * addr: Ptr to return the list of interfaces for this client.
979 * Nothing interesting.
983 *------------------------------------------------------------------------*/
985 int SRXAFSCB_WhoAreYou(a_call, addr)
986 struct rx_call *a_call;
987 struct interfaceAddr *addr;
995 AFS_STATCNT(SRXAFSCB_WhoAreYou);
997 ObtainReadLock(&afs_xinterface);
999 /* return all network interface addresses */
1000 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1001 addr->uuid = afs_cb_interface.uuid;
1002 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
1003 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1004 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1005 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1008 ReleaseReadLock(&afs_xinterface);
1016 /*------------------------------------------------------------------------
1017 * EXPORTED SRXAFSCB_InitCallBackState3
1020 * Routine called by the server-side callback RPC interface to
1021 * implement clearing all callbacks from this host.
1024 * a_call : Ptr to Rx call on which this request came in.
1030 * Nothing interesting.
1034 *------------------------------------------------------------------------*/
1036 int SRXAFSCB_InitCallBackState3(a_call, a_uuid)
1037 struct rx_call *a_call;
1043 * TBD: Lookup the server by the UUID instead of its IP address.
1045 code = SRXAFSCB_InitCallBackState(a_call);
1051 /*------------------------------------------------------------------------
1052 * EXPORTED SRXAFSCB_ProbeUuid
1055 * Routine called by the server-side callback RPC interface to
1056 * implement ``probing'' the Cache Manager, just making sure it's
1057 * still there is still the same client it used to be.
1060 * a_call : Ptr to Rx call on which this request came in.
1061 * a_uuid : Ptr to UUID that must match the client's UUID.
1064 * 0 if a_uuid matches the UUID for this client
1065 * Non-zero otherwize
1068 * Nothing interesting.
1072 *------------------------------------------------------------------------*/
1074 int SRXAFSCB_ProbeUuid(a_call, a_uuid)
1075 struct rx_call *a_call;
1082 AFS_STATCNT(SRXAFSCB_Probe);
1084 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1085 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1086 code = 1; /* failure */
1095 /*------------------------------------------------------------------------
1096 * EXPORTED SRXAFSCB_GetServerPrefs
1099 * Routine to list server preferences used by this client.
1102 * a_call : Ptr to Rx call on which this request came in.
1103 * a_index : Input server index
1104 * a_srvr_addr : Output server address in host byte order
1105 * (0xffffffff on last server)
1106 * a_srvr_rank : Output server rank
1112 * Nothing interesting.
1116 *------------------------------------------------------------------------*/
1118 int SRXAFSCB_GetServerPrefs(
1119 struct rx_call *a_call,
1121 afs_int32 *a_srvr_addr,
1122 afs_int32 *a_srvr_rank)
1128 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1130 ObtainReadLock(&afs_xserver);
1132 /* Search the hash table for the server with this index */
1133 *a_srvr_addr = 0xffffffff;
1134 *a_srvr_rank = 0xffffffff;
1135 for (i=0, j=0; j < NSERVERS && i <= a_index; j++) {
1136 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1138 *a_srvr_addr = ntohl(sa->sa_ip);
1139 *a_srvr_rank = sa->sa_iprank;
1144 ReleaseReadLock(&afs_xserver);
1152 /*------------------------------------------------------------------------
1153 * EXPORTED SRXAFSCB_GetCellServDB
1156 * Routine to list cells configured for this client
1159 * a_call : Ptr to Rx call on which this request came in.
1160 * a_index : Input cell index
1161 * a_name : Output cell name ("" on last cell)
1162 * a_hosts : Output cell database servers in host byte order.
1168 * Nothing interesting.
1172 *------------------------------------------------------------------------*/
1174 int SRXAFSCB_GetCellServDB(
1175 struct rx_call *a_call,
1182 struct afs_q *cq, *tq;
1183 char *t_name, *p_name = NULL;
1186 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1188 memset(a_hosts, 0, AFSMAXCELLHOSTS * sizeof(afs_int32));
1190 /* search the list for the cell with this index */
1191 ObtainReadLock(&afs_xcell);
1193 tcell = afs_GetCellByIndex(a_index, READ_LOCK, 0);
1198 p_name = tcell->cellName;
1199 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++) {
1200 a_hosts[j] = ntohl(tcell->cellHosts[j]->addr->sa_ip);
1203 afs_PutCell(tcell, READ_LOCK);
1206 t_name = (char *)afs_osi_Alloc(i+1);
1207 if (t_name == NULL) {
1208 ReleaseReadLock(&afs_xcell);
1215 memcpy(t_name, p_name, i);
1217 ReleaseReadLock(&afs_xcell);
1226 /*------------------------------------------------------------------------
1227 * EXPORTED SRXAFSCB_GetLocalCell
1230 * Routine to return name of client's local cell
1233 * a_call : Ptr to Rx call on which this request came in.
1234 * a_name : Output cell name
1240 * Nothing interesting.
1244 *------------------------------------------------------------------------*/
1246 int SRXAFSCB_GetLocalCell(
1247 struct rx_call *a_call,
1252 struct afs_q *cq, *tq;
1253 char *t_name, *p_name = NULL;
1256 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1258 /* Search the list for the primary cell. Cell number 1 is only
1259 * the primary cell is when no other cell is explicitly marked as
1260 * the primary cell. */
1261 ObtainReadLock(&afs_xcell);
1263 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
1266 if (tcell->states & CPrimary) {
1267 p_name = tcell->cellName;
1270 if (tcell->cell == 1) {
1271 p_name = tcell->cellName;
1276 plen = strlen(p_name);
1279 t_name = (char *)afs_osi_Alloc(plen+1);
1280 if (t_name == NULL) {
1281 ReleaseReadLock(&afs_xcell);
1286 t_name[plen] = '\0';
1288 memcpy(t_name, p_name, plen);
1290 ReleaseReadLock(&afs_xcell);
1300 * afs_MarshallCacheConfig - marshall client cache configuration
1304 * IN callerVersion - the rpc stat version of the caller.
1306 * IN config - client cache configuration.
1308 * OUT ptr - buffer where configuration is marshalled.
1314 static void afs_MarshallCacheConfig(
1315 afs_uint32 callerVersion,
1316 cm_initparams_v1 *config,
1319 AFS_STATCNT(afs_MarshallCacheConfig);
1321 * We currently only support version 1.
1323 *(ptr++) = config->nChunkFiles;
1324 *(ptr++) = config->nStatCaches;
1325 *(ptr++) = config->nDataCaches;
1326 *(ptr++) = config->nVolumeCaches;
1327 *(ptr++) = config->firstChunkSize;
1328 *(ptr++) = config->otherChunkSize;
1329 *(ptr++) = config->cacheSize;
1330 *(ptr++) = config->setTime;
1331 *(ptr++) = config->memCache;
1336 /*------------------------------------------------------------------------
1337 * EXPORTED SRXAFSCB_GetCacheConfig
1340 * Routine to return parameters used to initialize client cache.
1341 * Client may request any format version. Server may not return
1342 * format version greater than version requested by client.
1345 * a_call: Ptr to Rx call on which this request came in.
1346 * callerVersion: Data format version desired by the client.
1347 * serverVersion: Data format version of output data.
1348 * configCount: Number bytes allocated for output data.
1349 * config: Client cache configuration.
1355 * Nothing interesting.
1359 *------------------------------------------------------------------------*/
1361 int SRXAFSCB_GetCacheConfig(
1362 struct rx_call *a_call,
1363 afs_uint32 callerVersion,
1364 afs_uint32 *serverVersion,
1365 afs_uint32 *configCount,
1366 cacheConfig *config)
1368 afs_uint32 *t_config;
1370 cm_initparams_v1 cm_config;
1373 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1376 * Currently only support version 1
1378 allocsize = sizeof(cm_initparams_v1);
1379 t_config = (afs_uint32 *)afs_osi_Alloc(allocsize);
1380 if (t_config == NULL) {
1385 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1386 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1387 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1388 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1389 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1390 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1391 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1392 cm_config.setTime = cm_initParams.cmi_setTime;
1393 cm_config.memCache = cm_initParams.cmi_memCache;
1395 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1397 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1398 *configCount = allocsize;
1399 config->cacheConfig_val = t_config;
1400 config->cacheConfig_len = allocsize/sizeof(afs_uint32);
1407 /*------------------------------------------------------------------------
1408 * EXPORTED SRXAFSCB_FetchData
1411 * Routine to do third party move from a remioserver to the original
1412 * issuer of an ArchiveData request. Presently supported only by the
1413 * "fs" command, not by the AFS client.
1416 * rxcall: Ptr to Rx call on which this request came in.
1417 * Fid: pointer to AFSFid structure.
1418 * Fd: File descriptor inside fs command.
1419 * Position: Offset in the file.
1420 * Length: Data length to transfer.
1421 * TotalLength: Pointer to total file length field
1427 * Nothing interesting.
1430 *------------------------------------------------------------------------*/
1431 SRXAFSCB_FetchData(rxcall, Fid, Fd, Position, Length, TotalLength)
1432 struct rx_call *rxcall;
1437 afs_int64 *TotalLength;
1442 /*------------------------------------------------------------------------
1443 * EXPORTED SRXAFSCB_StoreData
1446 * Routine to do third party move from a remioserver to the original
1447 * issuer of a RetrieveData request. Presently supported only by the
1448 * "fs" command, not by the AFS client.
1451 * rxcall: Ptr to Rx call on which this request came in.
1452 * Fid: pointer to AFSFid structure.
1453 * Fd: File descriptor inside fs command.
1454 * Position: Offset in the file.
1455 * Length: Data length to transfer.
1456 * TotalLength: Pointer to total file length field
1462 * Nothing interesting.
1466 *------------------------------------------------------------------------*/
1467 SRXAFSCB_StoreData(rxcall, Fid, Fd, Position, Length, TotalLength)
1468 struct rx_call *rxcall;
1473 afs_int64 *TotalLength;