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*/
112 #ifdef RX_ENABLE_LOCKS
114 #endif /* RX_ENABLE_LOCKS */
116 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
118 AFS_STATCNT(SRXAFSCB_GetCE);
119 for (i = 0; i < VCSIZE; i++) {
120 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
124 } /*Zip through current hash chain*/
125 } /*Zip through hash chains*/
128 if (tvc == (struct vcache *) 0) {
135 * Copy out the located entry.
137 a_result->addr = afs_data_pointer_to_int32(tvc);
138 a_result->cell = tvc->fid.Cell;
139 a_result->netFid.Volume = tvc->fid.Fid.Volume;
140 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
141 a_result->netFid.Unique = tvc->fid.Fid.Unique;
142 a_result->lock.waitStates = tvc->lock.wait_states;
143 a_result->lock.exclLocked = tvc->lock.excl_locked;
144 a_result->lock.readersReading = tvc->lock.readers_reading;
145 a_result->lock.numWaiting = tvc->lock.num_waiting;
146 #if defined(INSTRUMENT_LOCKS)
147 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
148 a_result->lock.pid_writer = tvc->lock.pid_writer;
149 a_result->lock.src_indicator = tvc->lock.src_indicator;
151 /* On osf20 , the vcache does not maintain these three fields */
152 a_result->lock.pid_last_reader = 0;
153 a_result->lock.pid_writer = 0;
154 a_result->lock.src_indicator = 0;
155 #endif /* AFS_OSF20_ENV */
156 a_result->Length = tvc->m.Length;
157 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
158 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
159 a_result->cbExpires = tvc->cbExpires;
160 a_result->refCount = tvc->vrefCount;
161 a_result->opens = tvc->opens;
162 a_result->writers = tvc->execsOrWriters;
163 a_result->mvstat = tvc->mvstat;
164 a_result->states = tvc->states;
168 * Return our results.
173 #ifdef RX_ENABLE_LOCKS
175 #endif /* RX_ENABLE_LOCKS */
182 /*------------------------------------------------------------------------
183 * EXPORTED SRXAFSCB_GetLock
186 * Routine called by the server-side callback RPC interface to
187 * implement pulling out the contents of a lock in the lock
191 * a_call : Ptr to Rx call on which this request came in.
192 * a_index : Index of desired lock.
193 * a_result : Ptr to a buffer for the given lock.
196 * 0 if everything went fine,
197 * 1 if we were given a bad index.
200 * Nothing interesting.
204 *------------------------------------------------------------------------*/
206 int SRXAFSCB_GetLock (a_call, a_index, a_result)
207 struct rx_call *a_call;
209 struct AFSDBLock *a_result;
211 { /*SRXAFSCB_GetLock*/
213 struct ltable *tl; /*Ptr to lock table entry*/
214 int nentries; /*Num entries in table*/
215 int code; /*Return code*/
218 #ifdef RX_ENABLE_LOCKS
220 #endif /* RX_ENABLE_LOCKS */
222 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
224 AFS_STATCNT(SRXAFSCB_GetLock);
225 nentries = sizeof(ltable)/sizeof(struct ltable);
226 if (a_index < 0 || a_index >= nentries) {
234 * Found it - copy out its contents.
236 tl = <able[a_index];
237 strcpy(a_result->name, tl->name);
238 a_result->lock.waitStates = ((struct afs_lock *)(tl->addr))->wait_states;
239 a_result->lock.exclLocked = ((struct afs_lock *)(tl->addr))->excl_locked;
240 a_result->lock.readersReading = ((struct afs_lock *)(tl->addr))->readers_reading;
241 a_result->lock.numWaiting = ((struct afs_lock *)(tl->addr))->num_waiting;
242 a_result->lock.pid_last_reader = ((struct afs_lock *)(tl->addr))->pid_last_reader;
243 a_result->lock.pid_writer = ((struct afs_lock *)(tl->addr))->pid_writer;
244 a_result->lock.src_indicator = ((struct afs_lock *)(tl->addr))->src_indicator;
250 #ifdef RX_ENABLE_LOCKS
252 #endif /* RX_ENABLE_LOCKS */
256 } /*SRXAFSCB_GetLock*/
259 /*------------------------------------------------------------------------
260 * static ClearCallBack
263 * Clear out callback information for the specified file, or
264 * even a whole volume. Used to worry about callback was from
265 * within the particular cell or not. Now we don't bother with
266 * that anymore; it's not worth the time.
269 * a_conn : Ptr to Rx connection involved.
270 * a_fid : Ptr to AFS fid being cleared.
276 * Nothing interesting.
280 *------------------------------------------------------------------------*/
282 static ClearCallBack(a_conn, a_fid)
283 register struct rx_connection *a_conn;
284 register struct AFSFid *a_fid;
288 register struct vcache *tvc;
290 struct VenusFid localFid;
293 AFS_STATCNT(ClearCallBack);
296 * XXXX Don't hold any server locks here because of callback protocol XXX
299 localFid.Fid.Volume = a_fid->Volume;
300 localFid.Fid.Vnode = a_fid->Vnode;
301 localFid.Fid.Unique = a_fid->Unique;
304 * Volume ID of zero means don't do anything.
306 if (a_fid->Volume != 0) {
307 if (a_fid->Vnode == 0) {
309 * Clear callback for the whole volume. Zip through the
310 * hash chain, nullifying entries whose volume ID matches.
312 for (i = 0; i < VCSIZE; i++)
313 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
314 if (tvc->fid.Fid.Volume == a_fid->Volume) {
315 tvc->callback = (struct server *)0;
316 tvc->quick.stamp = 0;
318 localFid.Cell = tvc->fid.Cell;
319 tvc->h1.dchint = NULL; /* invalidate hints */
320 ObtainWriteLock(&afs_xcbhash, 449);
321 afs_DequeueCallback(tvc);
322 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
324 if (tvc->fid.Fid.Vnode & 1)
328 ReleaseWriteLock(&afs_xcbhash);
329 if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
330 osi_dnlc_purgedp(tvc);
331 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
332 ICL_TYPE_POINTER, tvc,
333 ICL_TYPE_INT32, tvc->states,
334 ICL_TYPE_INT32, a_fid->Volume);
335 } else if ((tvc->states & CMValid) && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
336 tvc->states &= ~CMValid;
338 localFid.Cell = tvc->mvid->Cell;
343 * XXXX Don't hold any locks here XXXX
345 tv = afs_FindVolume(&localFid, 0);
347 afs_ResetVolumeInfo(tv);
348 afs_PutVolume(tv, 0);
349 /* invalidate mtpoint? */
351 } /*Clear callbacks for whole volume*/
354 * Clear callbacks just for the one file.
357 if (a_fid->Vnode & 1)
358 afs_oddCBs++; /*Could do this on volume basis, too*/
360 afs_evenCBs++; /*A particular fid was specified*/
361 i = VCHash(&localFid);
362 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
363 if (tvc->fid.Fid.Vnode == a_fid->Vnode
364 && tvc->fid.Fid.Volume == a_fid->Volume
365 && tvc->fid.Fid.Unique == a_fid->Unique ) {
366 tvc->callback = (struct server *)0;
367 tvc->quick.stamp = 0;
368 tvc->h1.dchint = NULL; /* invalidate hints */
369 ObtainWriteLock(&afs_xcbhash, 450);
370 afs_DequeueCallback(tvc);
371 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
372 ReleaseWriteLock(&afs_xcbhash);
373 if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
374 osi_dnlc_purgedp(tvc);
375 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
376 ICL_TYPE_POINTER, tvc,
377 ICL_TYPE_INT32, tvc->states, ICL_TYPE_LONG, 0);
379 lastCallBack_vnode = afid->Vnode;
380 lastCallBack_dv = tvc->mstat.DataVersion.low;
381 osi_GetuTime(&lastCallBack_time);
384 } /*Walk through hash table*/
385 } /*Clear callbacks for one file*/
386 } /*Fid has non-zero volume ID*/
389 * Always return a predictable value.
396 /*------------------------------------------------------------------------
397 * EXPORTED SRXAFSCB_CallBack
400 * Routine called by the server-side callback RPC interface to
401 * implement passing in callback information.
405 * a_call : Ptr to Rx call on which this request came in.
406 * a_fids : Ptr to array of fids involved.
407 * a_callbacks : Ptr to matching callback info for the fids.
413 * Nothing interesting.
417 *------------------------------------------------------------------------*/
419 int SRXAFSCB_CallBack(a_call, a_fids, a_callbacks)
420 struct rx_call *a_call;
421 register struct AFSCBFids *a_fids;
422 struct AFSCBs *a_callbacks;
424 { /*SRXAFSCB_CallBack*/
426 register int i; /*Loop variable*/
427 struct AFSFid *tfid; /*Ptr to current fid*/
428 register struct rx_connection *tconn; /*Call's connection*/
432 #ifdef RX_ENABLE_LOCKS
434 #endif /* RX_ENABLE_LOCKS */
436 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
438 AFS_STATCNT(SRXAFSCB_CallBack);
439 if (!(tconn = rx_ConnectionOf(a_call))) return;
440 tfid = (struct AFSFid *) a_fids->AFSCBFids_val;
443 * For now, we ignore callbacks, since the File Server only *breaks*
444 * callbacks at present.
446 for (i = 0; i < a_fids->AFSCBFids_len; i++)
447 ClearCallBack(tconn, &tfid[i]);
451 #ifdef RX_ENABLE_LOCKS
453 #endif /* RX_ENABLE_LOCKS */
457 } /*SRXAFSCB_CallBack*/
460 /*------------------------------------------------------------------------
461 * EXPORTED SRXAFSCB_Probe
464 * Routine called by the server-side callback RPC interface to
465 * implement ``probing'' the Cache Manager, just making sure it's
469 * a_call : Ptr to Rx call on which this request came in.
475 * Nothing interesting.
479 *------------------------------------------------------------------------*/
481 int SRXAFSCB_Probe(a_call)
482 struct rx_call *a_call;
488 #ifdef RX_ENABLE_LOCKS
490 #endif /* RX_ENABLE_LOCKS */
491 AFS_STATCNT(SRXAFSCB_Probe);
493 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
496 #ifdef RX_ENABLE_LOCKS
498 #endif /* RX_ENABLE_LOCKS */
505 /*------------------------------------------------------------------------
506 * EXPORTED SRXAFSCB_InitCallBackState
509 * Routine called by the server-side callback RPC interface to
510 * implement clearing all callbacks from this host.
513 * a_call : Ptr to Rx call on which this request came in.
519 * Nothing interesting.
523 *------------------------------------------------------------------------*/
525 int SRXAFSCB_InitCallBackState(a_call)
526 struct rx_call *a_call;
528 { /*SRXAFSCB_InitCallBackState*/
531 register struct vcache *tvc;
532 register struct rx_connection *tconn;
533 register struct rx_peer *peer;
536 extern int osi_dnlc_purge();
539 #ifdef RX_ENABLE_LOCKS
541 #endif /* RX_ENABLE_LOCKS */
543 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
544 AFS_STATCNT(SRXAFSCB_InitCallBackState);
547 * Find the address of the host making this call
549 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
552 afs_oddCBs++; /*Including any missed via create race*/
553 afs_evenCBs++; /*Including any missed via create race*/
555 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *)0, 0);
557 for (i = 0; i < VCSIZE; i++)
558 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
559 if (tvc->callback == ts) {
560 ObtainWriteLock(&afs_xcbhash, 451);
561 afs_DequeueCallback(tvc);
562 tvc->callback = (struct server *)0;
563 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
564 ReleaseWriteLock(&afs_xcbhash);
571 /* find any volumes residing on this server and flush their state */
573 register struct volume *tv;
576 for (i=0;i<NVOLS;i++)
577 for (tv = afs_volumes[i]; tv; tv=tv->next) {
578 for (j=0; j<MAXHOSTS; j++)
579 if (tv->serverHost[j] == ts)
580 afs_ResetVolumeInfo(tv);
583 osi_dnlc_purge(); /* may be a little bit extreme */
588 #ifdef RX_ENABLE_LOCKS
590 #endif /* RX_ENABLE_LOCKS */
594 } /*SRXAFSCB_InitCallBackState*/
597 /*------------------------------------------------------------------------
598 * EXPORTED SRXAFSCB_XStatsVersion
601 * Routine called by the server-side callback RPC interface to
602 * implement pulling out the xstat version number for the Cache
606 * a_versionP : Ptr to the version number variable to set.
612 * Nothing interesting.
616 *------------------------------------------------------------------------*/
618 int SRXAFSCB_XStatsVersion(a_call, a_versionP)
619 struct rx_call *a_call;
620 afs_int32 *a_versionP;
622 { /*SRXAFSCB_XStatsVersion*/
627 #ifdef RX_ENABLE_LOCKS
629 #endif /* RX_ENABLE_LOCKS */
630 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
632 *a_versionP = AFSCB_XSTAT_VERSION;
636 #ifdef RX_ENABLE_LOCKS
638 #endif /* RX_ENABLE_LOCKS */
641 } /*SRXAFSCB_XStatsVersion*/
644 /*------------------------------------------------------------------------
645 * EXPORTED SRXAFSCB_GetXStats
648 * Routine called by the server-side callback RPC interface to
649 * implement getting the given data collection from the extended
650 * Cache Manager statistics.
653 * a_call : Ptr to Rx call on which this request came in.
654 * a_clientVersionNum : Client version number.
655 * a_opCode : Desired operation.
656 * a_serverVersionNumP : Ptr to version number to set.
657 * a_timeP : Ptr to time value (seconds) to set.
658 * a_dataArray : Ptr to variable array structure to return
665 * Nothing interesting.
669 *------------------------------------------------------------------------*/
671 int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVersionNumP, a_timeP, a_dataP)
672 struct rx_call *a_call;
673 afs_int32 a_clientVersionNum;
674 afs_int32 a_collectionNumber;
675 afs_int32 *a_srvVersionNumP;
677 AFSCB_CollData *a_dataP;
679 { /*SRXAFSCB_GetXStats*/
681 register int code; /*Return value*/
682 afs_int32 *dataBuffP; /*Ptr to data to be returned*/
683 afs_int32 dataBytes; /*Bytes in data buffer*/
686 #ifdef RX_ENABLE_LOCKS
688 #endif /* RX_ENABLE_LOCKS */
690 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
693 * Record the time of day and the server version number.
695 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
696 *a_timeP = osi_Time();
699 * Stuff the appropriate data in there (assume victory)
705 * We're not keeping stats, so just return successfully with
708 a_dataP->AFSCB_CollData_len = 0;
709 a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
711 switch(a_collectionNumber) {
712 case AFSCB_XSTATSCOLL_CALL_INFO:
714 * Pass back all the call-count-related data.
716 * >>> We are forced to allocate a separate area in which to
717 * >>> put this stuff in by the RPC stub generator, since it
718 * >>> will be freed at the tail end of the server stub code.
720 dataBytes = sizeof(struct afs_CMStats);
721 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
722 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
723 a_dataP->AFSCB_CollData_len = dataBytes>>2;
724 a_dataP->AFSCB_CollData_val = dataBuffP;
727 case AFSCB_XSTATSCOLL_PERF_INFO:
729 * Update and then pass back all the performance-related data.
730 * Note: the only performance fields that need to be computed
731 * at this time are the number of accesses for this collection
732 * and the current server record info.
734 * >>> We are forced to allocate a separate area in which to
735 * >>> put this stuff in by the RPC stub generator, since it
736 * >>> will be freed at the tail end of the server stub code.
738 afs_stats_cmperf.numPerfCalls++;
740 dataBytes = sizeof(afs_stats_cmperf);
741 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
742 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
743 a_dataP->AFSCB_CollData_len = dataBytes>>2;
744 a_dataP->AFSCB_CollData_val = dataBuffP;
747 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
749 * Pass back the full range of performance and statistical
750 * data available. We have to bring the normal performance
751 * data collection up to date, then copy that data into
752 * the full collection.
754 * >>> We are forced to allocate a separate area in which to
755 * >>> put this stuff in by the RPC stub generator, since it
756 * >>> will be freed at the tail end of the server stub code.
758 afs_stats_cmperf.numPerfCalls++;
760 memcpy((char *)(&(afs_stats_cmfullperf.perf)), (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
761 afs_stats_cmfullperf.numFullPerfCalls++;
763 dataBytes = sizeof(afs_stats_cmfullperf);
764 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
765 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
766 a_dataP->AFSCB_CollData_len = dataBytes>>2;
767 a_dataP->AFSCB_CollData_val = dataBuffP;
772 * Illegal collection number.
774 a_dataP->AFSCB_CollData_len = 0;
775 a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
777 } /*Switch on collection number*/
778 #endif /* AFS_NOSTATS */
782 #ifdef RX_ENABLE_LOCKS
784 #endif /* RX_ENABLE_LOCKS */
788 } /*SRXAFSCB_GetXStats*/
791 /*------------------------------------------------------------------------
792 * EXPORTED afs_RXCallBackServer
795 * Body of the thread supporting callback services.
804 * Nothing interesting.
808 *------------------------------------------------------------------------*/
810 int afs_RXCallBackServer()
812 { /*afs_RXCallBackServer*/
813 AFS_STATCNT(afs_RXCallBackServer);
818 afs_osi_Sleep(&afs_server);
822 * Donate this process to Rx.
827 } /*afs_RXCallBackServer*/
830 /*------------------------------------------------------------------------
831 * EXPORTED shutdown_CB
834 * Zero out important Cache Manager data structures.
843 * Nothing interesting.
847 *------------------------------------------------------------------------*/
853 extern int afs_cold_shutdown;
855 AFS_STATCNT(shutdown_CB);
857 if (afs_cold_shutdown) {
858 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps = afs_evenZaps =
859 afs_connectBacks = 0;
866 /*------------------------------------------------------------------------
867 * EXPORTED SRXAFSCB_InitCallBackState2
870 * This routine was used in the AFS 3.5 beta release, but not anymore.
871 * It has since been replaced by SRXAFSCB_InitCallBackState3.
874 * a_call : Ptr to Rx call on which this request came in.
877 * RXGEN_OPCODE (always).
880 * Nothing interesting.
884 *------------------------------------------------------------------------*/
886 int SRXAFSCB_InitCallBackState2(a_call, addr)
887 struct rx_call *a_call;
888 struct interfaceAddr * addr;
893 /*------------------------------------------------------------------------
894 * EXPORTED SRXAFSCB_WhoAreYou
897 * Routine called by the server-side callback RPC interface to
898 * obtain a unique identifier for the client. The server uses
899 * this identifier to figure out whether or not two RX connections
900 * are from the same client, and to find out which addresses go
901 * with which clients.
904 * a_call : Ptr to Rx call on which this request came in.
905 * addr: Ptr to return the list of interfaces for this client.
911 * Nothing interesting.
915 *------------------------------------------------------------------------*/
917 int SRXAFSCB_WhoAreYou(a_call, addr)
918 struct rx_call *a_call;
919 struct interfaceAddr *addr;
925 #ifdef RX_ENABLE_LOCKS
927 #endif /* RX_ENABLE_LOCKS */
929 AFS_STATCNT(SRXAFSCB_WhoAreYou);
931 ObtainReadLock(&afs_xinterface);
933 /* return all network interface addresses */
934 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
935 addr->uuid = afs_cb_interface.uuid;
936 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
937 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
938 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
939 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
942 ReleaseReadLock(&afs_xinterface);
944 #ifdef RX_ENABLE_LOCKS
946 #endif /* RX_ENABLE_LOCKS */
952 /*------------------------------------------------------------------------
953 * EXPORTED SRXAFSCB_InitCallBackState3
956 * Routine called by the server-side callback RPC interface to
957 * implement clearing all callbacks from this host.
960 * a_call : Ptr to Rx call on which this request came in.
966 * Nothing interesting.
970 *------------------------------------------------------------------------*/
972 int SRXAFSCB_InitCallBackState3(a_call, a_uuid)
973 struct rx_call *a_call;
979 * TBD: Lookup the server by the UUID instead of its IP address.
981 code = SRXAFSCB_InitCallBackState(a_call);
987 /*------------------------------------------------------------------------
988 * EXPORTED SRXAFSCB_ProbeUuid
991 * Routine called by the server-side callback RPC interface to
992 * implement ``probing'' the Cache Manager, just making sure it's
993 * still there is still the same client it used to be.
996 * a_call : Ptr to Rx call on which this request came in.
997 * a_uuid : Ptr to UUID that must match the client's UUID.
1000 * 0 if a_uuid matches the UUID for this client
1001 * Non-zero otherwize
1004 * Nothing interesting.
1008 *------------------------------------------------------------------------*/
1010 int SRXAFSCB_ProbeUuid(a_call, a_uuid)
1011 struct rx_call *a_call;
1017 #ifdef RX_ENABLE_LOCKS
1019 #endif /* RX_ENABLE_LOCKS */
1020 AFS_STATCNT(SRXAFSCB_Probe);
1022 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1023 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1024 code = 1; /* failure */
1027 #ifdef RX_ENABLE_LOCKS
1029 #endif /* RX_ENABLE_LOCKS */
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(
1059 struct rx_call *a_call,
1061 afs_int32 *a_srvr_addr,
1062 afs_int32 *a_srvr_rank)
1067 #ifdef RX_ENABLE_LOCKS
1069 #endif /* RX_ENABLE_LOCKS */
1070 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1072 ObtainReadLock(&afs_xserver);
1074 /* Search the hash table for the server with this index */
1075 *a_srvr_addr = 0xffffffff;
1076 *a_srvr_rank = 0xffffffff;
1077 for (i=0, j=0; j < NSERVERS && i <= a_index; j++) {
1078 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1080 *a_srvr_addr = ntohl(sa->sa_ip);
1081 *a_srvr_rank = sa->sa_iprank;
1086 ReleaseReadLock(&afs_xserver);
1088 #ifdef RX_ENABLE_LOCKS
1090 #endif /* RX_ENABLE_LOCKS */
1096 /*------------------------------------------------------------------------
1097 * EXPORTED SRXAFSCB_GetCellServDB
1100 * Routine to list cells configured for this client
1103 * a_call : Ptr to Rx call on which this request came in.
1104 * a_index : Input cell index
1105 * a_name : Output cell name ("" on last cell)
1106 * a_hosts : Output cell database servers in host byte order.
1112 * Nothing interesting.
1116 *------------------------------------------------------------------------*/
1118 int SRXAFSCB_GetCellServDB(
1119 struct rx_call *a_call,
1126 struct afs_q *cq, *tq;
1127 char *t_name, *p_name = NULL;
1129 #ifdef RX_ENABLE_LOCKS
1131 #endif /* RX_ENABLE_LOCKS */
1132 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1134 memset(a_hosts, 0, AFSMAXCELLHOSTS * sizeof(afs_int32));
1136 /* search the list for the cell with this index */
1137 ObtainReadLock(&afs_xcell);
1138 for (i=0, cq = CellLRU.next; cq != &CellLRU && i<= a_index; cq = tq, i++) {
1142 p_name = tcell->cellName;
1143 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++) {
1144 a_hosts[j] = ntohl(tcell->cellHosts[j]->addr->sa_ip);
1153 t_name = (char *)rxi_Alloc(i+1);
1154 if (t_name == NULL) {
1155 #ifdef RX_ENABLE_LOCKS
1157 #endif /* RX_ENABLE_LOCKS */
1163 memcpy(t_name, p_name, i);
1165 ReleaseReadLock(&afs_xcell);
1167 #ifdef RX_ENABLE_LOCKS
1169 #endif /* RX_ENABLE_LOCKS */
1176 /*------------------------------------------------------------------------
1177 * EXPORTED SRXAFSCB_GetLocalCell
1180 * Routine to return name of client's local cell
1183 * a_call : Ptr to Rx call on which this request came in.
1184 * a_name : Output cell name
1190 * Nothing interesting.
1194 *------------------------------------------------------------------------*/
1196 int SRXAFSCB_GetLocalCell(
1197 struct rx_call *a_call,
1202 struct afs_q *cq, *tq;
1203 char *t_name, *p_name = NULL;
1205 #ifdef RX_ENABLE_LOCKS
1207 #endif /* RX_ENABLE_LOCKS */
1208 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1210 /* Search the list for the primary cell. Cell number 1 is only
1211 * the primary cell is when no other cell is explicitly marked as
1212 * the primary cell. */
1213 ObtainReadLock(&afs_xcell);
1214 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
1217 if (tcell->states & CPrimary) {
1218 p_name = tcell->cellName;
1221 if (tcell->cell == 1) {
1222 p_name = tcell->cellName;
1227 plen = strlen(p_name);
1230 t_name = (char *)rxi_Alloc(plen+1);
1231 if (t_name == NULL) {
1232 #ifdef RX_ENABLE_LOCKS
1234 #endif /* RX_ENABLE_LOCKS */
1238 t_name[plen] = '\0';
1240 memcpy(t_name, p_name, plen);
1242 ReleaseReadLock(&afs_xcell);
1244 #ifdef RX_ENABLE_LOCKS
1246 #endif /* RX_ENABLE_LOCKS */
1254 * afs_MarshallCacheConfig - marshall client cache configuration
1258 * IN callerVersion - the rpc stat version of the caller.
1260 * IN config - client cache configuration.
1262 * OUT ptr - buffer where configuration is marshalled.
1268 static void afs_MarshallCacheConfig(
1269 afs_uint32 callerVersion,
1270 cm_initparams_v1 *config,
1273 AFS_STATCNT(afs_MarshallCacheConfig);
1275 * We currently only support version 1.
1277 *(ptr++) = config->nChunkFiles;
1278 *(ptr++) = config->nStatCaches;
1279 *(ptr++) = config->nDataCaches;
1280 *(ptr++) = config->nVolumeCaches;
1281 *(ptr++) = config->firstChunkSize;
1282 *(ptr++) = config->otherChunkSize;
1283 *(ptr++) = config->cacheSize;
1284 *(ptr++) = config->setTime;
1285 *(ptr++) = config->memCache;
1290 /*------------------------------------------------------------------------
1291 * EXPORTED SRXAFSCB_GetCacheConfig
1294 * Routine to return parameters used to initialize client cache.
1295 * Client may request any format version. Server may not return
1296 * format version greater than version requested by client.
1299 * a_call: Ptr to Rx call on which this request came in.
1300 * callerVersion: Data format version desired by the client.
1301 * serverVersion: Data format version of output data.
1302 * configCount: Number bytes allocated for output data.
1303 * config: Client cache configuration.
1309 * Nothing interesting.
1313 *------------------------------------------------------------------------*/
1315 int SRXAFSCB_GetCacheConfig(
1316 struct rx_call *a_call,
1317 afs_uint32 callerVersion,
1318 afs_uint32 *serverVersion,
1319 afs_uint32 *configCount,
1320 cacheConfig *config)
1322 afs_uint32 *t_config;
1324 cm_initparams_v1 cm_config;
1326 #ifdef RX_ENABLE_LOCKS
1328 #endif /* RX_ENABLE_LOCKS */
1329 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1332 * Currently only support version 1
1334 allocsize = sizeof(cm_initparams_v1);
1335 t_config = (afs_uint32 *)rxi_Alloc(allocsize);
1336 if (t_config == NULL) {
1337 #ifdef RX_ENABLE_LOCKS
1339 #endif /* RX_ENABLE_LOCKS */
1343 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1344 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1345 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1346 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1347 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1348 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1349 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1350 cm_config.setTime = cm_initParams.cmi_setTime;
1351 cm_config.memCache = cm_initParams.cmi_memCache;
1353 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1355 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1356 *configCount = allocsize;
1357 config->cacheConfig_val = t_config;
1358 config->cacheConfig_len = allocsize/sizeof(afs_uint32);
1360 #ifdef RX_ENABLE_LOCKS
1362 #endif /* RX_ENABLE_LOCKS */