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 "afsincludes.h" /*AFS-based standard headers*/
23 #include "afs/afs_stats.h" /*Cache Manager stats*/
24 #include "afs/afs_args.h"
26 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
27 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs*/
28 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files*/
29 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
30 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted*/
31 afs_int32 afs_evenZaps = 0; /*File cache entries deleted*/
32 afs_int32 afs_connectBacks = 0;
35 * Some debugging aids.
37 static struct ltable {
41 {"afs_xvcache", (char *)&afs_xvcache},
42 {"afs_xdcache", (char *)&afs_xdcache},
43 {"afs_xserver", (char *)&afs_xserver},
44 {"afs_xvcb", (char *)&afs_xvcb},
45 {"afs_xbrs", (char *)&afs_xbrs},
46 {"afs_xcell", (char *)&afs_xcell},
47 {"afs_xconn", (char *)&afs_xconn},
48 {"afs_xuser", (char *)&afs_xuser},
49 {"afs_xvolume", (char *)&afs_xvolume},
50 {"puttofile", (char *)&afs_puttofileLock},
51 {"afs_ftf", (char *)&afs_ftf},
52 {"afs_xcbhash", (char *)&afs_xcbhash},
53 {"afs_xaxs", (char *)&afs_xaxs},
54 {"afs_xinterface", (char *)&afs_xinterface},
56 {"afs_xosi", (char *)&afs_xosi},
58 {"afs_xsrvAddr",(char *)&afs_xsrvAddr}
60 unsigned long lastCallBack_vnode;
61 unsigned int lastCallBack_dv;
62 osi_timeval_t lastCallBack_time;
64 /* these are for storing alternate interface addresses */
65 struct interfaceAddr afs_cb_interface;
67 /*------------------------------------------------------------------------
68 * EXPORTED SRXAFSCB_GetCE
71 * Routine called by the server-side callback RPC interface to
72 * implement pulling out the contents of the i'th cache entry.
75 * a_call : Ptr to Rx call on which this request came in.
76 * a_index : Index of desired cache entry.
77 * a_result : Ptr to a buffer for the given cache entry.
80 * 0 if everything went fine,
81 * 1 if we were given a bad index.
84 * Nothing interesting.
88 *------------------------------------------------------------------------*/
90 int SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index, struct AFSDBCacheEntry *a_result)
93 register int i; /*Loop variable*/
94 register struct vcache *tvc; /*Ptr to current cache entry*/
95 int code; /*Return code*/
100 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
102 AFS_STATCNT(SRXAFSCB_GetCE);
103 for (i = 0; i < VCSIZE; i++) {
104 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
108 } /*Zip through current hash chain*/
109 } /*Zip through hash chains*/
119 * Copy out the located entry.
121 a_result->addr = afs_data_pointer_to_int32(tvc);
122 a_result->cell = tvc->fid.Cell;
123 a_result->netFid.Volume = tvc->fid.Fid.Volume;
124 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
125 a_result->netFid.Unique = tvc->fid.Fid.Unique;
126 a_result->lock.waitStates = tvc->lock.wait_states;
127 a_result->lock.exclLocked = tvc->lock.excl_locked;
128 a_result->lock.readersReading = tvc->lock.readers_reading;
129 a_result->lock.numWaiting = tvc->lock.num_waiting;
130 #if defined(INSTRUMENT_LOCKS)
131 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
132 a_result->lock.pid_writer = tvc->lock.pid_writer;
133 a_result->lock.src_indicator = tvc->lock.src_indicator;
135 /* On osf20 , the vcache does not maintain these three fields */
136 a_result->lock.pid_last_reader = 0;
137 a_result->lock.pid_writer = 0;
138 a_result->lock.src_indicator = 0;
139 #endif /* AFS_OSF20_ENV */
140 #ifdef AFS_64BIT_CLIENT
141 a_result->Length = (afs_int32) tvc->m.Length & 0xffffffff;
142 #else /* AFS_64BIT_CLIENT */
143 a_result->Length = tvc->m.Length;
144 #endif /* AFS_64BIT_CLIENT */
145 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
146 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
147 a_result->cbExpires = tvc->cbExpires;
148 a_result->refCount = VREFCOUNT(tvc);
149 a_result->opens = tvc->opens;
150 a_result->writers = tvc->execsOrWriters;
151 a_result->mvstat = tvc->mvstat;
152 a_result->states = tvc->states;
156 * Return our results.
167 int SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index, struct AFSDBCacheEntry64 *a_result)
169 register int i; /*Loop variable*/
170 register struct vcache *tvc; /*Ptr to current cache entry*/
171 int code; /*Return code*/
176 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
178 AFS_STATCNT(SRXAFSCB_GetCE64);
179 for (i = 0; i < VCSIZE; i++) {
180 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
184 } /*Zip through current hash chain*/
185 } /*Zip through hash chains*/
195 * Copy out the located entry.
197 a_result->addr = afs_data_pointer_to_int32(tvc);
198 a_result->cell = tvc->fid.Cell;
199 a_result->netFid.Volume = tvc->fid.Fid.Volume;
200 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
201 a_result->netFid.Unique = tvc->fid.Fid.Unique;
202 a_result->lock.waitStates = tvc->lock.wait_states;
203 a_result->lock.exclLocked = tvc->lock.excl_locked;
204 a_result->lock.readersReading = tvc->lock.readers_reading;
205 a_result->lock.numWaiting = tvc->lock.num_waiting;
206 #if defined(INSTRUMENT_LOCKS)
207 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
208 a_result->lock.pid_writer = tvc->lock.pid_writer;
209 a_result->lock.src_indicator = tvc->lock.src_indicator;
211 /* On osf20 , the vcache does not maintain these three fields */
212 a_result->lock.pid_last_reader = 0;
213 a_result->lock.pid_writer = 0;
214 a_result->lock.src_indicator = 0;
215 #endif /* AFS_OSF20_ENV */
217 a_result->Length = tvc->m.Length;
218 #else /* AFS_64BIT_ENV */
219 #ifdef AFS_64BIT_CLIENT
220 a_result->Length = tvc->m.Length;
221 #else /* AFS_64BIT_CLIENT */
222 a_result->Length.high = 0;
223 a_result->Length.low = tvc->m.Length;
224 #endif /* AFS_64BIT_CLIENT */
225 #endif /* AFS_64BIT_ENV */
226 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
227 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
228 a_result->cbExpires = tvc->cbExpires;
229 a_result->refCount = VREFCOUNT(tvc);
230 a_result->opens = tvc->opens;
231 a_result->writers = tvc->execsOrWriters;
232 a_result->mvstat = tvc->mvstat;
233 a_result->states = tvc->states;
237 * Return our results.
246 } /*SRXAFSCB_GetCE64*/
249 /*------------------------------------------------------------------------
250 * EXPORTED SRXAFSCB_GetLock
253 * Routine called by the server-side callback RPC interface to
254 * implement pulling out the contents of a lock in the lock
258 * a_call : Ptr to Rx call on which this request came in.
259 * a_index : Index of desired lock.
260 * a_result : Ptr to a buffer for the given lock.
263 * 0 if everything went fine,
264 * 1 if we were given a bad index.
267 * Nothing interesting.
271 *------------------------------------------------------------------------*/
273 int SRXAFSCB_GetLock (struct rx_call *a_call, afs_int32 a_index, struct AFSDBLock *a_result)
275 struct ltable *tl; /*Ptr to lock table entry*/
276 int nentries; /*Num entries in table*/
277 int code; /*Return code*/
282 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
284 AFS_STATCNT(SRXAFSCB_GetLock);
285 nentries = sizeof(ltable)/sizeof(struct ltable);
286 if (a_index < 0 || a_index >= nentries) {
294 * Found it - copy out its contents.
296 tl = <able[a_index];
297 strcpy(a_result->name, tl->name);
298 a_result->lock.waitStates = ((struct afs_lock *)(tl->addr))->wait_states;
299 a_result->lock.exclLocked = ((struct afs_lock *)(tl->addr))->excl_locked;
300 a_result->lock.readersReading = ((struct afs_lock *)(tl->addr))->readers_reading;
301 a_result->lock.numWaiting = ((struct afs_lock *)(tl->addr))->num_waiting;
302 #ifdef INSTRUMENT_LOCKS
303 a_result->lock.pid_last_reader = ((struct afs_lock *)(tl->addr))->pid_last_reader;
304 a_result->lock.pid_writer = ((struct afs_lock *)(tl->addr))->pid_writer;
305 a_result->lock.src_indicator = ((struct afs_lock *)(tl->addr))->src_indicator;
307 a_result->lock.pid_last_reader = 0;
308 a_result->lock.pid_writer = 0;
309 a_result->lock.src_indicator = 0;
320 } /*SRXAFSCB_GetLock*/
323 /*------------------------------------------------------------------------
324 * static ClearCallBack
327 * Clear out callback information for the specified file, or
328 * even a whole volume. Used to worry about callback was from
329 * within the particular cell or not. Now we don't bother with
330 * that anymore; it's not worth the time.
333 * a_conn : Ptr to Rx connection involved.
334 * a_fid : Ptr to AFS fid being cleared.
340 * Nothing interesting.
345 Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
347 *------------------------------------------------------------------------*/
349 static int ClearCallBack(register struct rx_connection *a_conn, register struct AFSFid *a_fid)
351 register struct vcache *tvc;
353 struct VenusFid localFid;
356 AFS_STATCNT(ClearCallBack);
361 * XXXX Don't hold any server locks here because of callback protocol XXX
364 localFid.Fid.Volume = a_fid->Volume;
365 localFid.Fid.Vnode = a_fid->Vnode;
366 localFid.Fid.Unique = a_fid->Unique;
369 * Volume ID of zero means don't do anything.
371 if (a_fid->Volume != 0) {
372 if (a_fid->Vnode == 0) {
374 * Clear callback for the whole volume. Zip through the
375 * hash chain, nullifying entries whose volume ID matches.
377 for (i = 0; i < VCSIZE; i++)
378 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
379 if (tvc->fid.Fid.Volume == a_fid->Volume) {
380 tvc->callback = NULL;
381 tvc->quick.stamp = 0;
383 localFid.Cell = tvc->fid.Cell;
384 tvc->h1.dchint = NULL; /* invalidate hints */
385 ObtainWriteLock(&afs_xcbhash, 449);
386 afs_DequeueCallback(tvc);
387 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
389 if (tvc->fid.Fid.Vnode & 1)
393 ReleaseWriteLock(&afs_xcbhash);
394 if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
395 osi_dnlc_purgedp(tvc);
396 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
397 ICL_TYPE_POINTER, tvc,
398 ICL_TYPE_INT32, tvc->states,
399 ICL_TYPE_INT32, a_fid->Volume);
400 } else if ((tvc->states & CMValid) && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
401 tvc->states &= ~CMValid;
403 localFid.Cell = tvc->mvid->Cell;
408 * XXXX Don't hold any locks here XXXX
410 tv = afs_FindVolume(&localFid, 0);
412 afs_ResetVolumeInfo(tv);
413 afs_PutVolume(tv, 0);
414 /* invalidate mtpoint? */
416 } /*Clear callbacks for whole volume*/
419 * Clear callbacks just for the one file.
422 if (a_fid->Vnode & 1)
423 afs_oddCBs++; /*Could do this on volume basis, too*/
425 afs_evenCBs++; /*A particular fid was specified*/
426 i = VCHash(&localFid);
427 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
428 if (tvc->fid.Fid.Vnode == a_fid->Vnode
429 && tvc->fid.Fid.Volume == a_fid->Volume
430 && tvc->fid.Fid.Unique == a_fid->Unique ) {
431 tvc->callback = NULL;
432 tvc->quick.stamp = 0;
433 tvc->h1.dchint = NULL; /* invalidate hints */
434 ObtainWriteLock(&afs_xcbhash, 450);
435 afs_DequeueCallback(tvc);
436 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
437 ReleaseWriteLock(&afs_xcbhash);
438 if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
439 osi_dnlc_purgedp(tvc);
440 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
441 ICL_TYPE_POINTER, tvc,
442 ICL_TYPE_INT32, tvc->states, ICL_TYPE_LONG, 0);
444 lastCallBack_vnode = afid->Vnode;
445 lastCallBack_dv = tvc->mstat.DataVersion.low;
446 osi_GetuTime(&lastCallBack_time);
449 } /*Walk through hash table*/
450 } /*Clear callbacks for one file*/
451 } /*Fid has non-zero volume ID*/
454 * Always return a predictable value.
461 /*------------------------------------------------------------------------
462 * EXPORTED SRXAFSCB_CallBack
465 * Routine called by the server-side callback RPC interface to
466 * implement passing in callback information.
470 * a_call : Ptr to Rx call on which this request came in.
471 * a_fids : Ptr to array of fids involved.
472 * a_callbacks : Ptr to matching callback info for the fids.
478 * Nothing interesting.
482 *------------------------------------------------------------------------*/
484 int SRXAFSCB_CallBack(struct rx_call *a_call, register struct AFSCBFids *a_fids, struct AFSCBs *a_callbacks)
486 register int i; /*Loop variable*/
487 struct AFSFid *tfid; /*Ptr to current fid*/
488 register struct rx_connection *tconn; /*Call's connection*/
494 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
496 AFS_STATCNT(SRXAFSCB_CallBack);
497 if (!(tconn = rx_ConnectionOf(a_call))) return(0);
498 tfid = (struct AFSFid *) a_fids->AFSCBFids_val;
501 * For now, we ignore callbacks, since the File Server only *breaks*
502 * callbacks at present.
504 for (i = 0; i < a_fids->AFSCBFids_len; i++)
505 ClearCallBack(tconn, &tfid[i]);
513 } /*SRXAFSCB_CallBack*/
516 /*------------------------------------------------------------------------
517 * EXPORTED SRXAFSCB_Probe
520 * Routine called by the server-side callback RPC interface to
521 * implement ``probing'' the Cache Manager, just making sure it's
525 * a_call : Ptr to Rx call on which this request came in.
531 * Nothing interesting.
535 *------------------------------------------------------------------------*/
537 int SRXAFSCB_Probe(struct rx_call *a_call)
543 AFS_STATCNT(SRXAFSCB_Probe);
545 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
555 /*------------------------------------------------------------------------
556 * EXPORTED SRXAFSCB_InitCallBackState
559 * Routine called by the server-side callback RPC interface to
560 * implement clearing all callbacks from this host.
563 * a_call : Ptr to Rx call on which this request came in.
569 * Nothing interesting.
573 *------------------------------------------------------------------------*/
575 int SRXAFSCB_InitCallBackState(struct rx_call *a_call)
578 register struct vcache *tvc;
579 register struct rx_connection *tconn;
580 register struct rx_peer *peer;
587 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
588 AFS_STATCNT(SRXAFSCB_InitCallBackState);
591 * Find the address of the host making this call
593 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
596 afs_oddCBs++; /*Including any missed via create race*/
597 afs_evenCBs++; /*Including any missed via create race*/
599 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *)0, 0);
601 for (i = 0; i < VCSIZE; i++)
602 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
603 if (tvc->callback == ts) {
604 ObtainWriteLock(&afs_xcbhash, 451);
605 afs_DequeueCallback(tvc);
606 tvc->callback = NULL;
607 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
608 ReleaseWriteLock(&afs_xcbhash);
615 /* find any volumes residing on this server and flush their state */
617 register struct volume *tv;
620 for (i=0;i<NVOLS;i++)
621 for (tv = afs_volumes[i]; tv; tv=tv->next) {
622 for (j=0; j<MAXHOSTS; j++)
623 if (tv->serverHost[j] == ts)
624 afs_ResetVolumeInfo(tv);
627 osi_dnlc_purge(); /* may be a little bit extreme */
636 } /*SRXAFSCB_InitCallBackState*/
639 /*------------------------------------------------------------------------
640 * EXPORTED SRXAFSCB_XStatsVersion
643 * Routine called by the server-side callback RPC interface to
644 * implement pulling out the xstat version number for the Cache
648 * a_versionP : Ptr to the version number variable to set.
654 * Nothing interesting.
658 *------------------------------------------------------------------------*/
660 int SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 *a_versionP)
667 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
669 *a_versionP = AFSCB_XSTAT_VERSION;
676 } /*SRXAFSCB_XStatsVersion*/
679 /*------------------------------------------------------------------------
680 * EXPORTED SRXAFSCB_GetXStats
683 * Routine called by the server-side callback RPC interface to
684 * implement getting the given data collection from the extended
685 * Cache Manager statistics.
688 * a_call : Ptr to Rx call on which this request came in.
689 * a_clientVersionNum : Client version number.
690 * a_opCode : Desired operation.
691 * a_serverVersionNumP : Ptr to version number to set.
692 * a_timeP : Ptr to time value (seconds) to set.
693 * a_dataArray : Ptr to variable array structure to return
700 * Nothing interesting.
704 *------------------------------------------------------------------------*/
706 int SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
707 afs_int32 a_collectionNumber, afs_int32 *a_srvVersionNumP,
708 afs_int32 *a_timeP, AFSCB_CollData *a_dataP)
710 register int code; /*Return value*/
711 afs_int32 *dataBuffP; /*Ptr to data to be returned*/
712 afs_int32 dataBytes; /*Bytes in data buffer*/
717 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
720 * Record the time of day and the server version number.
722 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
723 *a_timeP = osi_Time();
726 * Stuff the appropriate data in there (assume victory)
732 * We're not keeping stats, so just return successfully with
735 a_dataP->AFSCB_CollData_len = 0;
736 a_dataP->AFSCB_CollData_val = NULL;
738 switch(a_collectionNumber) {
739 case AFSCB_XSTATSCOLL_CALL_INFO:
741 * Pass back all the call-count-related data.
743 * >>> We are forced to allocate a separate area in which to
744 * >>> put this stuff in by the RPC stub generator, since it
745 * >>> will be freed at the tail end of the server stub code.
747 dataBytes = sizeof(struct afs_CMStats);
748 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
749 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
750 a_dataP->AFSCB_CollData_len = dataBytes>>2;
751 a_dataP->AFSCB_CollData_val = dataBuffP;
754 case AFSCB_XSTATSCOLL_PERF_INFO:
756 * Update and then pass back all the performance-related data.
757 * Note: the only performance fields that need to be computed
758 * at this time are the number of accesses for this collection
759 * and the current server record info.
761 * >>> We are forced to allocate a separate area in which to
762 * >>> put this stuff in by the RPC stub generator, since it
763 * >>> will be freed at the tail end of the server stub code.
765 afs_stats_cmperf.numPerfCalls++;
767 dataBytes = sizeof(afs_stats_cmperf);
768 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
769 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
770 a_dataP->AFSCB_CollData_len = dataBytes>>2;
771 a_dataP->AFSCB_CollData_val = dataBuffP;
774 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
776 * Pass back the full range of performance and statistical
777 * data available. We have to bring the normal performance
778 * data collection up to date, then copy that data into
779 * the full collection.
781 * >>> We are forced to allocate a separate area in which to
782 * >>> put this stuff in by the RPC stub generator, since it
783 * >>> will be freed at the tail end of the server stub code.
785 afs_stats_cmperf.numPerfCalls++;
787 memcpy((char *)(&(afs_stats_cmfullperf.perf)), (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
788 afs_stats_cmfullperf.numFullPerfCalls++;
790 dataBytes = sizeof(afs_stats_cmfullperf);
791 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
792 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
793 a_dataP->AFSCB_CollData_len = dataBytes>>2;
794 a_dataP->AFSCB_CollData_val = dataBuffP;
799 * Illegal collection number.
801 a_dataP->AFSCB_CollData_len = 0;
802 a_dataP->AFSCB_CollData_val = NULL;
804 } /*Switch on collection number*/
805 #endif /* AFS_NOSTATS */
813 } /*SRXAFSCB_GetXStats*/
816 /*------------------------------------------------------------------------
817 * EXPORTED afs_RXCallBackServer
820 * Body of the thread supporting callback services.
829 * Nothing interesting.
833 *------------------------------------------------------------------------*/
835 int afs_RXCallBackServer(void)
837 AFS_STATCNT(afs_RXCallBackServer);
842 afs_osi_Sleep(&afs_server);
846 * Donate this process to Rx.
851 } /*afs_RXCallBackServer*/
854 /*------------------------------------------------------------------------
855 * EXPORTED shutdown_CB
858 * Zero out important Cache Manager data structures.
867 * Nothing interesting.
871 *------------------------------------------------------------------------*/
873 int shutdown_CB(void)
875 AFS_STATCNT(shutdown_CB);
877 if (afs_cold_shutdown) {
878 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps = afs_evenZaps =
879 afs_connectBacks = 0;
886 /*------------------------------------------------------------------------
887 * EXPORTED SRXAFSCB_InitCallBackState2
890 * This routine was used in the AFS 3.5 beta release, but not anymore.
891 * It has since been replaced by SRXAFSCB_InitCallBackState3.
894 * a_call : Ptr to Rx call on which this request came in.
897 * RXGEN_OPCODE (always).
900 * Nothing interesting.
904 *------------------------------------------------------------------------*/
906 int SRXAFSCB_InitCallBackState2(struct rx_call *a_call, struct interfaceAddr *addr)
911 /*------------------------------------------------------------------------
912 * EXPORTED SRXAFSCB_WhoAreYou
915 * Routine called by the server-side callback RPC interface to
916 * obtain a unique identifier for the client. The server uses
917 * this identifier to figure out whether or not two RX connections
918 * are from the same client, and to find out which addresses go
919 * with which clients.
922 * a_call : Ptr to Rx call on which this request came in.
923 * addr: Ptr to return the list of interfaces for this client.
929 * Nothing interesting.
933 *------------------------------------------------------------------------*/
935 int SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
942 AFS_STATCNT(SRXAFSCB_WhoAreYou);
944 ObtainReadLock(&afs_xinterface);
946 /* return all network interface addresses */
947 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
948 addr->uuid = afs_cb_interface.uuid;
949 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
950 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
951 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
952 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
955 ReleaseReadLock(&afs_xinterface);
963 /*------------------------------------------------------------------------
964 * EXPORTED SRXAFSCB_InitCallBackState3
967 * Routine called by the server-side callback RPC interface to
968 * implement clearing all callbacks from this host.
971 * a_call : Ptr to Rx call on which this request came in.
977 * Nothing interesting.
981 *------------------------------------------------------------------------*/
983 int SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID *a_uuid)
988 * TBD: Lookup the server by the UUID instead of its IP address.
990 code = SRXAFSCB_InitCallBackState(a_call);
996 /*------------------------------------------------------------------------
997 * EXPORTED SRXAFSCB_ProbeUuid
1000 * Routine called by the server-side callback RPC interface to
1001 * implement ``probing'' the Cache Manager, just making sure it's
1002 * still there is still the same client it used to be.
1005 * a_call : Ptr to Rx call on which this request came in.
1006 * a_uuid : Ptr to UUID that must match the client's UUID.
1009 * 0 if a_uuid matches the UUID for this client
1010 * Non-zero otherwize
1013 * Nothing interesting.
1017 *------------------------------------------------------------------------*/
1019 int SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID *a_uuid)
1025 AFS_STATCNT(SRXAFSCB_Probe);
1027 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1028 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1029 code = 1; /* failure */
1038 /*------------------------------------------------------------------------
1039 * EXPORTED SRXAFSCB_GetServerPrefs
1042 * Routine to list server preferences used by this client.
1045 * a_call : Ptr to Rx call on which this request came in.
1046 * a_index : Input server index
1047 * a_srvr_addr : Output server address in host byte order
1048 * (0xffffffff on last server)
1049 * a_srvr_rank : Output server rank
1055 * Nothing interesting.
1059 *------------------------------------------------------------------------*/
1061 int SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1062 afs_int32 *a_srvr_addr, afs_int32 *a_srvr_rank)
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);
1092 /*------------------------------------------------------------------------
1093 * EXPORTED SRXAFSCB_GetCellServDB
1096 * Routine to list cells configured for this client
1099 * a_call : Ptr to Rx call on which this request came in.
1100 * a_index : Input cell index
1101 * a_name : Output cell name ("" on last cell)
1102 * a_hosts : Output cell database servers in host byte order.
1108 * Nothing interesting.
1112 *------------------------------------------------------------------------*/
1114 int SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1115 char **a_name, serverList *a_hosts)
1119 char *t_name, *p_name = NULL;
1122 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1124 tcell = afs_GetCellByIndex(a_index, READ_LOCK);
1128 a_hosts->serverList_val = 0;
1129 a_hosts->serverList_len = 0;
1131 p_name = tcell->cellName;
1132 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++)
1135 a_hosts->serverList_val = (afs_int32 *)afs_osi_Alloc(j*sizeof(afs_int32));
1136 a_hosts->serverList_len = j;
1137 for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++)
1138 a_hosts->serverList_val[j] = ntohl(tcell->cellHosts[j]->addr->sa_ip);
1139 afs_PutCell(tcell, READ_LOCK);
1142 t_name = (char *)afs_osi_Alloc(i+1);
1143 if (t_name == NULL) {
1144 afs_osi_Free(a_hosts->serverList_val, (j*sizeof(afs_int32)));
1151 memcpy(t_name, p_name, i);
1160 /*------------------------------------------------------------------------
1161 * EXPORTED SRXAFSCB_GetLocalCell
1164 * Routine to return name of client's local cell
1167 * a_call : Ptr to Rx call on which this request came in.
1168 * a_name : Output cell name
1174 * Nothing interesting.
1178 *------------------------------------------------------------------------*/
1180 int SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1184 char *t_name, *p_name = NULL;
1187 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1189 /* Search the list for the primary cell. Cell number 1 is only
1190 * the primary cell is when no other cell is explicitly marked as
1191 * the primary cell. */
1192 tcell = afs_GetPrimaryCell(READ_LOCK);
1194 p_name = tcell->cellName;
1196 plen = strlen(p_name);
1199 t_name = (char *)afs_osi_Alloc(plen+1);
1200 if (t_name == NULL) {
1201 if (tcell) afs_PutCell(tcell, READ_LOCK);
1206 t_name[plen] = '\0';
1208 memcpy(t_name, p_name, plen);
1213 if (tcell) afs_PutCell(tcell, READ_LOCK);
1219 * afs_MarshallCacheConfig - marshall client cache configuration
1223 * IN callerVersion - the rpc stat version of the caller.
1225 * IN config - client cache configuration.
1227 * OUT ptr - buffer where configuration is marshalled.
1233 static void afs_MarshallCacheConfig(afs_uint32 callerVersion,
1234 cm_initparams_v1 *config, afs_uint32 *ptr)
1236 AFS_STATCNT(afs_MarshallCacheConfig);
1238 * We currently only support version 1.
1240 *(ptr++) = config->nChunkFiles;
1241 *(ptr++) = config->nStatCaches;
1242 *(ptr++) = config->nDataCaches;
1243 *(ptr++) = config->nVolumeCaches;
1244 *(ptr++) = config->firstChunkSize;
1245 *(ptr++) = config->otherChunkSize;
1246 *(ptr++) = config->cacheSize;
1247 *(ptr++) = config->setTime;
1248 *(ptr++) = config->memCache;
1252 /*------------------------------------------------------------------------
1253 * EXPORTED SRXAFSCB_GetCacheConfig
1256 * Routine to return parameters used to initialize client cache.
1257 * Client may request any format version. Server may not return
1258 * format version greater than version requested by client.
1261 * a_call: Ptr to Rx call on which this request came in.
1262 * callerVersion: Data format version desired by the client.
1263 * serverVersion: Data format version of output data.
1264 * configCount: Number bytes allocated for output data.
1265 * config: Client cache configuration.
1271 * Nothing interesting.
1275 *------------------------------------------------------------------------*/
1277 int SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1278 afs_uint32 *serverVersion, afs_uint32 *configCount, cacheConfig *config)
1280 afs_uint32 *t_config;
1282 cm_initparams_v1 cm_config;
1285 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1288 * Currently only support version 1
1290 allocsize = sizeof(cm_initparams_v1);
1291 t_config = (afs_uint32 *)afs_osi_Alloc(allocsize);
1292 if (t_config == NULL) {
1297 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1298 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1299 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1300 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1301 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1302 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1303 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1304 cm_config.setTime = cm_initParams.cmi_setTime;
1305 cm_config.memCache = cm_initParams.cmi_memCache;
1307 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1309 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1310 *configCount = allocsize;
1311 config->cacheConfig_val = t_config;
1312 config->cacheConfig_len = allocsize/sizeof(afs_uint32);
1319 /*------------------------------------------------------------------------
1320 * EXPORTED SRXAFSCB_FetchData
1323 * Routine to do third party move from a remioserver to the original
1324 * issuer of an ArchiveData request. Presently supported only by the
1325 * "fs" command, not by the AFS client.
1328 * rxcall: Ptr to Rx call on which this request came in.
1329 * Fid: pointer to AFSFid structure.
1330 * Fd: File descriptor inside fs command.
1331 * Position: Offset in the file.
1332 * Length: Data length to transfer.
1333 * TotalLength: Pointer to total file length field
1339 * Nothing interesting.
1342 *------------------------------------------------------------------------*/
1343 int SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1344 afs_int64 Position, afs_int64 Length, afs_int64 *TotalLength)
1349 /*------------------------------------------------------------------------
1350 * EXPORTED SRXAFSCB_StoreData
1353 * Routine to do third party move from a remioserver to the original
1354 * issuer of a RetrieveData request. Presently supported only by the
1355 * "fs" command, not by the AFS client.
1358 * rxcall: Ptr to Rx call on which this request came in.
1359 * Fid: pointer to AFSFid structure.
1360 * Fd: File descriptor inside fs command.
1361 * Position: Offset in the file.
1362 * Length: Data length to transfer.
1363 * TotalLength: Pointer to total file length field
1369 * Nothing interesting.
1373 *------------------------------------------------------------------------*/
1374 int SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1375 afs_int64 Position, afs_int64 Length, afs_int64 *TotalLength)
1380 /*------------------------------------------------------------------------
1381 * EXPORTED SRXAFSCB_GetCellByNum
1384 * Routine to get information about a cell specified by its
1385 * cell number (returned by GetCE/GetCE64).
1388 * a_call : Ptr to Rx call on which this request came in.
1389 * a_cellnum : Input cell number
1390 * a_name : Output cell name (one zero byte when no such cell).
1391 * a_hosts : Output cell database servers in host byte order.
1397 * Nothing interesting.
1401 *------------------------------------------------------------------------*/
1403 int SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
1404 char **a_name, serverList *a_hosts)
1410 AFS_STATCNT(SRXAFSCB_GetCellByNum);
1412 a_hosts->serverList_val = 0;
1413 a_hosts->serverList_len = 0;
1415 tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
1417 *a_name = afs_strdup("");
1422 ObtainReadLock(&tcell->lock);
1423 *a_name = afs_strdup(tcell->cellName);
1425 for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++)
1427 a_hosts->serverList_len = sn;
1428 a_hosts->serverList_val = (afs_int32 *) afs_osi_Alloc(sn*sizeof(afs_int32));
1430 for (i = 0; i < sn; i++)
1431 a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
1432 ReleaseReadLock(&tcell->lock);
1433 afs_PutCell(tcell, READ_LOCK);
1439 int SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
1440 struct interfaceAddr *addr,
1441 Capabilities *capabilities)
1445 afs_int32 *dataBuffP;
1446 afs_int32 dataBytes;
1450 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1452 ObtainReadLock(&afs_xinterface);
1454 /* return all network interface addresses */
1455 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1456 addr->uuid = afs_cb_interface.uuid;
1457 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
1458 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1459 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1460 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1463 ReleaseReadLock(&afs_xinterface);
1467 dataBytes = 1 * sizeof(afs_int32);
1468 dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
1469 dataBuffP[0] = CAPABILITY_ERRORTRANS;
1470 capabilities->Capabilities_len = dataBytes/sizeof(afs_int32);
1471 capabilities->Capabilities_val = dataBuffP;