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 "../afs/param.h" /*Should be always first*/
17 #include "../afs/sysincludes.h" /*Standard vendor system headers*/
18 #include "../afs/afsincludes.h" /*AFS-based standard headers*/
19 #include "../afs/afs_stats.h" /*Cache Manager stats*/
20 #include "../afs/afs_args.h"
22 extern struct volume *afs_volumes[NVOLS]; /* volume hash table */
23 extern void afs_DequeueCallback();
24 extern void afs_ComputePAGStats();
25 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
26 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs*/
27 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files*/
28 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
29 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted*/
30 afs_int32 afs_evenZaps = 0; /*File cache entries deleted*/
31 afs_int32 afs_connectBacks = 0;
32 extern struct rx_service *afs_server;
34 extern afs_lock_t afs_xvcb, afs_xbrs, afs_xdcache;
35 extern afs_rwlock_t afs_xvcache, afs_xserver, afs_xcell, afs_xuser;
36 extern afs_rwlock_t afs_xvolume, afs_puttofileLock, afs_ftf, afs_xinterface;
37 extern afs_rwlock_t afs_xconn;
38 extern struct afs_lock afs_xaxs;
39 extern afs_lock_t afs_xcbhash;
40 extern struct srvAddr *afs_srvAddrs[NSERVERS];
41 extern struct afs_q CellLRU;
42 extern struct cm_initparams cm_initParams;
45 * Some debugging aids.
47 static struct ltable {
51 "afs_xvcache", (char *)&afs_xvcache,
52 "afs_xdcache", (char *)&afs_xdcache,
53 "afs_xserver", (char *)&afs_xserver,
54 "afs_xvcb", (char *)&afs_xvcb,
55 "afs_xbrs", (char *)&afs_xbrs,
56 "afs_xcell", (char *)&afs_xcell,
57 "afs_xconn", (char *)&afs_xconn,
58 "afs_xuser", (char *)&afs_xuser,
59 "afs_xvolume", (char *)&afs_xvolume,
60 "puttofile", (char *)&afs_puttofileLock,
61 "afs_ftf", (char *)&afs_ftf,
62 "afs_xcbhash", (char *)&afs_xcbhash,
63 "afs_xaxs", (char *)&afs_xaxs,
64 "afs_xinterface", (char *)&afs_xinterface,
66 unsigned long lastCallBack_vnode;
67 unsigned int lastCallBack_dv;
68 osi_timeval_t lastCallBack_time;
70 /* these are for storing alternate interface addresses */
71 struct interfaceAddr afs_cb_interface;
73 /*------------------------------------------------------------------------
74 * EXPORTED SRXAFSCB_GetCE
77 * Routine called by the server-side callback RPC interface to
78 * implement pulling out the contents of the i'th cache entry.
81 * a_call : Ptr to Rx call on which this request came in.
82 * a_index : Index of desired cache entry.
83 * a_result : Ptr to a buffer for the given cache entry.
86 * 0 if everything went fine,
87 * 1 if we were given a bad index.
90 * Nothing interesting.
94 *------------------------------------------------------------------------*/
96 int SRXAFSCB_GetCE(a_call, a_index, a_result)
97 struct rx_call *a_call;
99 struct AFSDBCacheEntry *a_result;
103 register int i; /*Loop variable*/
104 register struct vcache *tvc; /*Ptr to current cache entry*/
105 int code; /*Return code*/
108 #ifdef RX_ENABLE_LOCKS
110 #endif /* RX_ENABLE_LOCKS */
112 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
114 AFS_STATCNT(SRXAFSCB_GetCE);
115 for (i = 0; i < VCSIZE; i++) {
116 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
120 } /*Zip through current hash chain*/
121 } /*Zip through hash chains*/
124 if (tvc == (struct vcache *) 0) {
131 * Copy out the located entry.
133 a_result->addr = afs_data_pointer_to_int32(tvc);
134 a_result->cell = tvc->fid.Cell;
135 a_result->netFid.Volume = tvc->fid.Fid.Volume;
136 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
137 a_result->netFid.Unique = tvc->fid.Fid.Unique;
138 a_result->lock.waitStates = tvc->lock.wait_states;
139 a_result->lock.exclLocked = tvc->lock.excl_locked;
140 a_result->lock.readersReading = tvc->lock.readers_reading;
141 a_result->lock.numWaiting = tvc->lock.num_waiting;
142 #if defined(INSTRUMENT_LOCKS)
143 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
144 a_result->lock.pid_writer = tvc->lock.pid_writer;
145 a_result->lock.src_indicator = tvc->lock.src_indicator;
147 /* On osf20 , the vcache does not maintain these three fields */
148 a_result->lock.pid_last_reader = 0;
149 a_result->lock.pid_writer = 0;
150 a_result->lock.src_indicator = 0;
151 #endif /* AFS_OSF20_ENV */
152 a_result->Length = tvc->m.Length;
153 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
154 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
155 a_result->cbExpires = tvc->cbExpires;
156 a_result->refCount = tvc->vrefCount;
157 a_result->opens = tvc->opens;
158 a_result->writers = tvc->execsOrWriters;
159 a_result->mvstat = tvc->mvstat;
160 a_result->states = tvc->states;
164 * Return our results.
169 #ifdef RX_ENABLE_LOCKS
171 #endif /* RX_ENABLE_LOCKS */
178 /*------------------------------------------------------------------------
179 * EXPORTED SRXAFSCB_GetLock
182 * Routine called by the server-side callback RPC interface to
183 * implement pulling out the contents of a lock in the lock
187 * a_call : Ptr to Rx call on which this request came in.
188 * a_index : Index of desired lock.
189 * a_result : Ptr to a buffer for the given lock.
192 * 0 if everything went fine,
193 * 1 if we were given a bad index.
196 * Nothing interesting.
200 *------------------------------------------------------------------------*/
202 int SRXAFSCB_GetLock (a_call, a_index, a_result)
203 struct rx_call *a_call;
205 struct AFSDBLock *a_result;
207 { /*SRXAFSCB_GetLock*/
209 struct ltable *tl; /*Ptr to lock table entry*/
210 int nentries; /*Num entries in table*/
211 int code; /*Return code*/
214 #ifdef RX_ENABLE_LOCKS
216 #endif /* RX_ENABLE_LOCKS */
218 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
220 AFS_STATCNT(SRXAFSCB_GetLock);
221 nentries = sizeof(ltable)/sizeof(struct ltable);
222 if (a_index < 0 || a_index >= nentries) {
230 * Found it - copy out its contents.
232 tl = <able[a_index];
233 strcpy(a_result->name, tl->name);
234 a_result->lock.waitStates = ((struct afs_lock *)(tl->addr))->wait_states;
235 a_result->lock.exclLocked = ((struct afs_lock *)(tl->addr))->excl_locked;
236 a_result->lock.readersReading = ((struct afs_lock *)(tl->addr))->readers_reading;
237 a_result->lock.numWaiting = ((struct afs_lock *)(tl->addr))->num_waiting;
238 a_result->lock.pid_last_reader = ((struct afs_lock *)(tl->addr))->pid_last_reader;
239 a_result->lock.pid_writer = ((struct afs_lock *)(tl->addr))->pid_writer;
240 a_result->lock.src_indicator = ((struct afs_lock *)(tl->addr))->src_indicator;
246 #ifdef RX_ENABLE_LOCKS
248 #endif /* RX_ENABLE_LOCKS */
252 } /*SRXAFSCB_GetLock*/
255 /*------------------------------------------------------------------------
256 * static ClearCallBack
259 * Clear out callback information for the specified file, or
260 * even a whole volume. Used to worry about callback was from
261 * within the particular cell or not. Now we don't bother with
262 * that anymore; it's not worth the time.
265 * a_conn : Ptr to Rx connection involved.
266 * a_fid : Ptr to AFS fid being cleared.
272 * Nothing interesting.
276 *------------------------------------------------------------------------*/
278 static ClearCallBack(a_conn, a_fid)
279 register struct rx_connection *a_conn;
280 register struct AFSFid *a_fid;
284 register struct vcache *tvc;
286 struct VenusFid localFid;
289 AFS_STATCNT(ClearCallBack);
292 * XXXX Don't hold any server locks here because of callback protocol XXX
295 localFid.Fid.Volume = a_fid->Volume;
296 localFid.Fid.Vnode = a_fid->Vnode;
297 localFid.Fid.Unique = a_fid->Unique;
300 * Volume ID of zero means don't do anything.
302 if (a_fid->Volume != 0) {
303 if (a_fid->Vnode == 0) {
305 * Clear callback for the whole volume. Zip through the
306 * hash chain, nullifying entries whose volume ID matches.
308 for (i = 0; i < VCSIZE; i++)
309 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
310 if (tvc->fid.Fid.Volume == a_fid->Volume) {
311 tvc->callback = (struct server *)0;
312 tvc->quick.stamp = 0;
314 localFid.Cell = tvc->fid.Cell;
315 tvc->h1.dchint = NULL; /* invalidate hints */
316 ObtainWriteLock(&afs_xcbhash, 449);
317 afs_DequeueCallback(tvc);
318 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
320 if (tvc->fid.Fid.Vnode & 1)
324 ReleaseWriteLock(&afs_xcbhash);
325 if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
326 osi_dnlc_purgedp(tvc);
327 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
328 ICL_TYPE_POINTER, tvc,
329 ICL_TYPE_INT32, tvc->states,
330 ICL_TYPE_INT32, a_fid->Volume);
331 } else if ((tvc->states & CMValid) && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
332 tvc->states &= ~CMValid;
334 localFid.Cell = tvc->mvid->Cell;
339 * XXXX Don't hold any locks here XXXX
341 tv = afs_FindVolume(&localFid, 0);
343 afs_ResetVolumeInfo(tv);
344 afs_PutVolume(tv, 0);
345 /* invalidate mtpoint? */
347 } /*Clear callbacks for whole volume*/
350 * Clear callbacks just for the one file.
353 if (a_fid->Vnode & 1)
354 afs_oddCBs++; /*Could do this on volume basis, too*/
356 afs_evenCBs++; /*A particular fid was specified*/
357 i = VCHash(&localFid);
358 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
359 if (tvc->fid.Fid.Vnode == a_fid->Vnode
360 && tvc->fid.Fid.Volume == a_fid->Volume
361 && tvc->fid.Fid.Unique == a_fid->Unique ) {
362 tvc->callback = (struct server *)0;
363 tvc->quick.stamp = 0;
364 tvc->h1.dchint = NULL; /* invalidate hints */
365 ObtainWriteLock(&afs_xcbhash, 450);
366 afs_DequeueCallback(tvc);
367 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
368 ReleaseWriteLock(&afs_xcbhash);
369 if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
370 osi_dnlc_purgedp(tvc);
371 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
372 ICL_TYPE_POINTER, tvc,
373 ICL_TYPE_INT32, tvc->states, ICL_TYPE_LONG, 0);
375 lastCallBack_vnode = afid->Vnode;
376 lastCallBack_dv = tvc->mstat.DataVersion.low;
377 osi_GetuTime(&lastCallBack_time);
380 } /*Walk through hash table*/
381 } /*Clear callbacks for one file*/
382 } /*Fid has non-zero volume ID*/
385 * Always return a predictable value.
392 /*------------------------------------------------------------------------
393 * EXPORTED SRXAFSCB_CallBack
396 * Routine called by the server-side callback RPC interface to
397 * implement passing in callback information.
401 * a_call : Ptr to Rx call on which this request came in.
402 * a_fids : Ptr to array of fids involved.
403 * a_callbacks : Ptr to matching callback info for the fids.
409 * Nothing interesting.
413 *------------------------------------------------------------------------*/
415 int SRXAFSCB_CallBack(a_call, a_fids, a_callbacks)
416 struct rx_call *a_call;
417 register struct AFSCBFids *a_fids;
418 struct AFSCBs *a_callbacks;
420 { /*SRXAFSCB_CallBack*/
422 register int i; /*Loop variable*/
423 struct AFSFid *tfid; /*Ptr to current fid*/
424 register struct rx_connection *tconn; /*Call's connection*/
428 #ifdef RX_ENABLE_LOCKS
430 #endif /* RX_ENABLE_LOCKS */
432 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
434 AFS_STATCNT(SRXAFSCB_CallBack);
435 if (!(tconn = rx_ConnectionOf(a_call))) return;
436 tfid = (struct AFSFid *) a_fids->AFSCBFids_val;
439 * For now, we ignore callbacks, since the File Server only *breaks*
440 * callbacks at present.
442 for (i = 0; i < a_fids->AFSCBFids_len; i++)
443 ClearCallBack(tconn, &tfid[i]);
447 #ifdef RX_ENABLE_LOCKS
449 #endif /* RX_ENABLE_LOCKS */
453 } /*SRXAFSCB_CallBack*/
456 /*------------------------------------------------------------------------
457 * EXPORTED SRXAFSCB_Probe
460 * Routine called by the server-side callback RPC interface to
461 * implement ``probing'' the Cache Manager, just making sure it's
465 * a_call : Ptr to Rx call on which this request came in.
471 * Nothing interesting.
475 *------------------------------------------------------------------------*/
477 int SRXAFSCB_Probe(a_call)
478 struct rx_call *a_call;
484 #ifdef RX_ENABLE_LOCKS
486 #endif /* RX_ENABLE_LOCKS */
487 AFS_STATCNT(SRXAFSCB_Probe);
489 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
492 #ifdef RX_ENABLE_LOCKS
494 #endif /* RX_ENABLE_LOCKS */
501 /*------------------------------------------------------------------------
502 * EXPORTED SRXAFSCB_InitCallBackState
505 * Routine called by the server-side callback RPC interface to
506 * implement clearing all callbacks from this host.
509 * a_call : Ptr to Rx call on which this request came in.
515 * Nothing interesting.
519 *------------------------------------------------------------------------*/
521 int SRXAFSCB_InitCallBackState(a_call)
522 struct rx_call *a_call;
524 { /*SRXAFSCB_InitCallBackState*/
527 register struct vcache *tvc;
528 register struct rx_connection *tconn;
529 register struct rx_peer *peer;
532 extern int osi_dnlc_purge();
535 #ifdef RX_ENABLE_LOCKS
537 #endif /* RX_ENABLE_LOCKS */
539 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
540 AFS_STATCNT(SRXAFSCB_InitCallBackState);
543 * Find the address of the host making this call
545 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
548 afs_oddCBs++; /*Including any missed via create race*/
549 afs_evenCBs++; /*Including any missed via create race*/
551 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *)0, 0);
553 for (i = 0; i < VCSIZE; i++)
554 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
555 if (tvc->callback == ts) {
556 ObtainWriteLock(&afs_xcbhash, 451);
557 afs_DequeueCallback(tvc);
558 tvc->callback = (struct server *)0;
559 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
560 ReleaseWriteLock(&afs_xcbhash);
567 /* find any volumes residing on this server and flush their state */
569 register struct volume *tv;
572 for (i=0;i<NVOLS;i++)
573 for (tv = afs_volumes[i]; tv; tv=tv->next) {
574 for (j=0; j<MAXHOSTS; j++)
575 if (tv->serverHost[j] == ts)
576 afs_ResetVolumeInfo(tv);
579 osi_dnlc_purge(); /* may be a little bit extreme */
584 #ifdef RX_ENABLE_LOCKS
586 #endif /* RX_ENABLE_LOCKS */
590 } /*SRXAFSCB_InitCallBackState*/
593 /*------------------------------------------------------------------------
594 * EXPORTED SRXAFSCB_XStatsVersion
597 * Routine called by the server-side callback RPC interface to
598 * implement pulling out the xstat version number for the Cache
602 * a_versionP : Ptr to the version number variable to set.
608 * Nothing interesting.
612 *------------------------------------------------------------------------*/
614 int SRXAFSCB_XStatsVersion(a_call, a_versionP)
615 struct rx_call *a_call;
616 afs_int32 *a_versionP;
618 { /*SRXAFSCB_XStatsVersion*/
623 #ifdef RX_ENABLE_LOCKS
625 #endif /* RX_ENABLE_LOCKS */
626 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
628 *a_versionP = AFSCB_XSTAT_VERSION;
632 #ifdef RX_ENABLE_LOCKS
634 #endif /* RX_ENABLE_LOCKS */
637 } /*SRXAFSCB_XStatsVersion*/
640 /*------------------------------------------------------------------------
641 * EXPORTED SRXAFSCB_GetXStats
644 * Routine called by the server-side callback RPC interface to
645 * implement getting the given data collection from the extended
646 * Cache Manager statistics.
649 * a_call : Ptr to Rx call on which this request came in.
650 * a_clientVersionNum : Client version number.
651 * a_opCode : Desired operation.
652 * a_serverVersionNumP : Ptr to version number to set.
653 * a_timeP : Ptr to time value (seconds) to set.
654 * a_dataArray : Ptr to variable array structure to return
661 * Nothing interesting.
665 *------------------------------------------------------------------------*/
667 int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVersionNumP, a_timeP, a_dataP)
668 struct rx_call *a_call;
669 afs_int32 a_clientVersionNum;
670 afs_int32 a_collectionNumber;
671 afs_int32 *a_srvVersionNumP;
673 AFSCB_CollData *a_dataP;
675 { /*SRXAFSCB_GetXStats*/
677 register int code; /*Return value*/
678 afs_int32 *dataBuffP; /*Ptr to data to be returned*/
679 afs_int32 dataBytes; /*Bytes in data buffer*/
682 #ifdef RX_ENABLE_LOCKS
684 #endif /* RX_ENABLE_LOCKS */
686 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
689 * Record the time of day and the server version number.
691 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
692 *a_timeP = osi_Time();
695 * Stuff the appropriate data in there (assume victory)
701 * We're not keeping stats, so just return successfully with
704 a_dataP->AFSCB_CollData_len = 0;
705 a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
707 switch(a_collectionNumber) {
708 case AFSCB_XSTATSCOLL_CALL_INFO:
710 * Pass back all the call-count-related data.
712 * >>> We are forced to allocate a separate area in which to
713 * >>> put this stuff in by the RPC stub generator, since it
714 * >>> will be freed at the tail end of the server stub code.
716 dataBytes = sizeof(struct afs_CMStats);
717 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
718 bcopy((char *)&afs_cmstats, (char *)dataBuffP, dataBytes);
719 a_dataP->AFSCB_CollData_len = dataBytes>>2;
720 a_dataP->AFSCB_CollData_val = dataBuffP;
723 case AFSCB_XSTATSCOLL_PERF_INFO:
725 * Update and then pass back all the performance-related data.
726 * Note: the only performance fields that need to be computed
727 * at this time are the number of accesses for this collection
728 * and the current server record info.
730 * >>> We are forced to allocate a separate area in which to
731 * >>> put this stuff in by the RPC stub generator, since it
732 * >>> will be freed at the tail end of the server stub code.
734 afs_stats_cmperf.numPerfCalls++;
736 dataBytes = sizeof(afs_stats_cmperf);
737 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
738 bcopy((char *)&afs_stats_cmperf, (char *)dataBuffP, dataBytes);
739 a_dataP->AFSCB_CollData_len = dataBytes>>2;
740 a_dataP->AFSCB_CollData_val = dataBuffP;
743 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
745 * Pass back the full range of performance and statistical
746 * data available. We have to bring the normal performance
747 * data collection up to date, then copy that data into
748 * the full collection.
750 * >>> We are forced to allocate a separate area in which to
751 * >>> put this stuff in by the RPC stub generator, since it
752 * >>> will be freed at the tail end of the server stub code.
754 afs_stats_cmperf.numPerfCalls++;
756 bcopy((char *)(&afs_stats_cmperf),
757 (char *)(&(afs_stats_cmfullperf.perf)),
758 sizeof(struct afs_stats_CMPerf));
759 afs_stats_cmfullperf.numFullPerfCalls++;
761 dataBytes = sizeof(afs_stats_cmfullperf);
762 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
763 bcopy((char *)(&afs_stats_cmfullperf), (char *)dataBuffP, dataBytes);
764 a_dataP->AFSCB_CollData_len = dataBytes>>2;
765 a_dataP->AFSCB_CollData_val = dataBuffP;
770 * Illegal collection number.
772 a_dataP->AFSCB_CollData_len = 0;
773 a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
775 } /*Switch on collection number*/
776 #endif /* AFS_NOSTATS */
780 #ifdef RX_ENABLE_LOCKS
782 #endif /* RX_ENABLE_LOCKS */
786 } /*SRXAFSCB_GetXStats*/
789 /*------------------------------------------------------------------------
790 * EXPORTED afs_RXCallBackServer
793 * Body of the thread supporting callback services.
802 * Nothing interesting.
806 *------------------------------------------------------------------------*/
808 int afs_RXCallBackServer()
810 { /*afs_RXCallBackServer*/
811 AFS_STATCNT(afs_RXCallBackServer);
816 afs_osi_Sleep(&afs_server);
820 * Donate this process to Rx.
825 } /*afs_RXCallBackServer*/
828 /*------------------------------------------------------------------------
829 * EXPORTED shutdown_CB
832 * Zero out important Cache Manager data structures.
841 * Nothing interesting.
845 *------------------------------------------------------------------------*/
851 extern int afs_cold_shutdown;
853 AFS_STATCNT(shutdown_CB);
855 if (afs_cold_shutdown) {
856 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps = afs_evenZaps =
857 afs_connectBacks = 0;
864 /*------------------------------------------------------------------------
865 * EXPORTED SRXAFSCB_InitCallBackState2
868 * This routine was used in the AFS 3.5 beta release, but not anymore.
869 * It has since been replaced by SRXAFSCB_InitCallBackState3.
872 * a_call : Ptr to Rx call on which this request came in.
875 * RXGEN_OPCODE (always).
878 * Nothing interesting.
882 *------------------------------------------------------------------------*/
884 int SRXAFSCB_InitCallBackState2(a_call, addr)
885 struct rx_call *a_call;
886 struct interfaceAddr * addr;
891 /*------------------------------------------------------------------------
892 * EXPORTED SRXAFSCB_WhoAreYou
895 * Routine called by the server-side callback RPC interface to
896 * obtain a unique identifier for the client. The server uses
897 * this identifier to figure out whether or not two RX connections
898 * are from the same client, and to find out which addresses go
899 * with which clients.
902 * a_call : Ptr to Rx call on which this request came in.
903 * addr: Ptr to return the list of interfaces for this client.
909 * Nothing interesting.
913 *------------------------------------------------------------------------*/
915 int SRXAFSCB_WhoAreYou(a_call, addr)
916 struct rx_call *a_call;
917 struct interfaceAddr *addr;
923 #ifdef RX_ENABLE_LOCKS
925 #endif /* RX_ENABLE_LOCKS */
927 AFS_STATCNT(SRXAFSCB_WhoAreYou);
929 ObtainReadLock(&afs_xinterface);
931 /* return all network interface addresses */
932 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
933 addr->uuid = afs_cb_interface.uuid;
934 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
935 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
936 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
937 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
940 ReleaseReadLock(&afs_xinterface);
942 #ifdef RX_ENABLE_LOCKS
944 #endif /* RX_ENABLE_LOCKS */
950 /*------------------------------------------------------------------------
951 * EXPORTED SRXAFSCB_InitCallBackState3
954 * Routine called by the server-side callback RPC interface to
955 * implement clearing all callbacks from this host.
958 * a_call : Ptr to Rx call on which this request came in.
964 * Nothing interesting.
968 *------------------------------------------------------------------------*/
970 int SRXAFSCB_InitCallBackState3(a_call, a_uuid)
971 struct rx_call *a_call;
977 * TBD: Lookup the server by the UUID instead of its IP address.
979 code = SRXAFSCB_InitCallBackState(a_call);
985 /*------------------------------------------------------------------------
986 * EXPORTED SRXAFSCB_ProbeUuid
989 * Routine called by the server-side callback RPC interface to
990 * implement ``probing'' the Cache Manager, just making sure it's
991 * still there is still the same client it used to be.
994 * a_call : Ptr to Rx call on which this request came in.
995 * a_uuid : Ptr to UUID that must match the client's UUID.
998 * 0 if a_uuid matches the UUID for this client
1002 * Nothing interesting.
1006 *------------------------------------------------------------------------*/
1008 int SRXAFSCB_ProbeUuid(a_call, a_uuid)
1009 struct rx_call *a_call;
1015 #ifdef RX_ENABLE_LOCKS
1017 #endif /* RX_ENABLE_LOCKS */
1018 AFS_STATCNT(SRXAFSCB_Probe);
1020 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1021 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1022 code = 1; /* failure */
1025 #ifdef RX_ENABLE_LOCKS
1027 #endif /* RX_ENABLE_LOCKS */
1033 /*------------------------------------------------------------------------
1034 * EXPORTED SRXAFSCB_GetServerPrefs
1037 * Routine to list server preferences used by this client.
1040 * a_call : Ptr to Rx call on which this request came in.
1041 * a_index : Input server index
1042 * a_srvr_addr : Output server address in host byte order
1043 * (0xffffffff on last server)
1044 * a_srvr_rank : Output server rank
1050 * Nothing interesting.
1054 *------------------------------------------------------------------------*/
1056 int SRXAFSCB_GetServerPrefs(
1057 struct rx_call *a_call,
1059 afs_int32 *a_srvr_addr,
1060 afs_int32 *a_srvr_rank)
1065 #ifdef RX_ENABLE_LOCKS
1067 #endif /* RX_ENABLE_LOCKS */
1068 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1070 ObtainReadLock(&afs_xserver);
1072 /* Search the hash table for the server with this index */
1073 *a_srvr_addr = 0xffffffff;
1074 *a_srvr_rank = 0xffffffff;
1075 for (i=0, j=0; j < NSERVERS && i <= a_index; j++) {
1076 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1078 *a_srvr_addr = ntohl(sa->sa_ip);
1079 *a_srvr_rank = sa->sa_iprank;
1084 ReleaseReadLock(&afs_xserver);
1086 #ifdef RX_ENABLE_LOCKS
1088 #endif /* RX_ENABLE_LOCKS */
1094 /*------------------------------------------------------------------------
1095 * EXPORTED SRXAFSCB_GetCellServDB
1098 * Routine to list cells configured for this client
1101 * a_call : Ptr to Rx call on which this request came in.
1102 * a_index : Input cell index
1103 * a_name : Output cell name ("" on last cell)
1104 * a_hosts : Output cell database servers in host byte order.
1110 * Nothing interesting.
1114 *------------------------------------------------------------------------*/
1116 int SRXAFSCB_GetCellServDB(
1117 struct rx_call *a_call,
1124 struct afs_q *cq, *tq;
1127 #ifdef RX_ENABLE_LOCKS
1129 #endif /* RX_ENABLE_LOCKS */
1130 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1132 t_name = (char *)rxi_Alloc(AFSNAMEMAX);
1133 if (t_name == NULL) {
1134 #ifdef RX_ENABLE_LOCKS
1136 #endif /* RX_ENABLE_LOCKS */
1141 bzero(a_hosts, AFSMAXCELLHOSTS * sizeof(afs_int32));
1143 /* search the list for the cell with this index */
1144 ObtainReadLock(&afs_xcell);
1145 for (i=0, cq = CellLRU.next; cq != &CellLRU && i<= a_index; cq = tq, i++) {
1149 strcpy(t_name, tcell->cellName);
1150 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++) {
1151 a_hosts[j] = ntohl(tcell->cellHosts[j]->addr->sa_ip);
1155 ReleaseReadLock(&afs_xcell);
1157 #ifdef RX_ENABLE_LOCKS
1159 #endif /* RX_ENABLE_LOCKS */
1166 /*------------------------------------------------------------------------
1167 * EXPORTED SRXAFSCB_GetLocalCell
1170 * Routine to return name of client's local cell
1173 * a_call : Ptr to Rx call on which this request came in.
1174 * a_name : Output cell name
1180 * Nothing interesting.
1184 *------------------------------------------------------------------------*/
1186 int SRXAFSCB_GetLocalCell(
1187 struct rx_call *a_call,
1191 struct afs_q *cq, *tq;
1194 #ifdef RX_ENABLE_LOCKS
1196 #endif /* RX_ENABLE_LOCKS */
1197 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1199 t_name = (char *)rxi_Alloc(AFSNAMEMAX);
1200 if (t_name == NULL) {
1201 #ifdef RX_ENABLE_LOCKS
1203 #endif /* RX_ENABLE_LOCKS */
1209 /* Search the list for the primary cell. Cell number 1 is only
1210 * the primary cell is when no other cell is explicitly marked as
1211 * the primary cell. */
1212 ObtainReadLock(&afs_xcell);
1213 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
1216 if (tcell->states & CPrimary) {
1217 strcpy(t_name, tcell->cellName);
1220 if (tcell->cell == 1) {
1221 strcpy(t_name, tcell->cellName);
1224 ReleaseReadLock(&afs_xcell);
1226 #ifdef RX_ENABLE_LOCKS
1228 #endif /* RX_ENABLE_LOCKS */
1236 * afs_MarshallCacheConfig - marshall client cache configuration
1240 * IN callerVersion - the rpc stat version of the caller.
1242 * IN config - client cache configuration.
1244 * OUT ptr - buffer where configuration is marshalled.
1250 static void afs_MarshallCacheConfig(
1251 afs_uint32 callerVersion,
1252 cm_initparams_v1 *config,
1255 AFS_STATCNT(afs_MarshallCacheConfig);
1257 * We currently only support version 1.
1259 *(ptr++) = config->nChunkFiles;
1260 *(ptr++) = config->nStatCaches;
1261 *(ptr++) = config->nDataCaches;
1262 *(ptr++) = config->nVolumeCaches;
1263 *(ptr++) = config->firstChunkSize;
1264 *(ptr++) = config->otherChunkSize;
1265 *(ptr++) = config->cacheSize;
1266 *(ptr++) = config->setTime;
1267 *(ptr++) = config->memCache;
1272 /*------------------------------------------------------------------------
1273 * EXPORTED SRXAFSCB_GetCacheConfig
1276 * Routine to return parameters used to initialize client cache.
1277 * Client may request any format version. Server may not return
1278 * format version greater than version requested by client.
1281 * a_call: Ptr to Rx call on which this request came in.
1282 * callerVersion: Data format version desired by the client.
1283 * serverVersion: Data format version of output data.
1284 * configCount: Number bytes allocated for output data.
1285 * config: Client cache configuration.
1291 * Nothing interesting.
1295 *------------------------------------------------------------------------*/
1297 int SRXAFSCB_GetCacheConfig(
1298 struct rx_call *a_call,
1299 afs_uint32 callerVersion,
1300 afs_uint32 *serverVersion,
1301 afs_uint32 *configCount,
1302 cacheConfig *config)
1304 afs_uint32 *t_config;
1306 cm_initparams_v1 cm_config;
1308 #ifdef RX_ENABLE_LOCKS
1310 #endif /* RX_ENABLE_LOCKS */
1311 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1314 * Currently only support version 1
1316 allocsize = sizeof(cm_initparams_v1);
1317 t_config = (afs_uint32 *)rxi_Alloc(allocsize);
1318 if (t_config == NULL) {
1319 #ifdef RX_ENABLE_LOCKS
1321 #endif /* RX_ENABLE_LOCKS */
1325 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1326 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1327 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1328 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1329 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1330 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1331 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1332 cm_config.setTime = cm_initParams.cmi_setTime;
1333 cm_config.memCache = cm_initParams.cmi_memCache;
1335 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1337 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1338 *configCount = allocsize;
1339 config->cacheConfig_val = t_config;
1340 config->cacheConfig_len = allocsize/sizeof(afs_uint32);
1342 #ifdef RX_ENABLE_LOCKS
1344 #endif /* RX_ENABLE_LOCKS */