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"
22 #include "afs/sysincludes.h" /*Standard vendor system headers */
23 #include "afsincludes.h" /*AFS-based standard headers */
24 #include "afs/afs_stats.h" /*Cache Manager stats */
25 #include "afs/afs_args.h"
27 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
28 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs */
29 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files */
30 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
31 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted */
32 afs_int32 afs_evenZaps = 0; /*File cache entries deleted */
33 afs_int32 afs_connectBacks = 0;
36 * Some debugging aids.
38 static struct ltable {
43 "afs_xvcache", (char *)&afs_xvcache}, {
44 "afs_xdcache", (char *)&afs_xdcache}, {
45 "afs_xserver", (char *)&afs_xserver}, {
46 "afs_xvcb", (char *)&afs_xvcb}, {
47 "afs_xbrs", (char *)&afs_xbrs}, {
48 "afs_xcell", (char *)&afs_xcell}, {
49 "afs_xconn", (char *)&afs_xconn}, {
50 "afs_xuser", (char *)&afs_xuser}, {
51 "afs_xvolume", (char *)&afs_xvolume}, {
52 "puttofile", (char *)&afs_puttofileLock}, {
53 "afs_ftf", (char *)&afs_ftf}, {
54 "afs_xcbhash", (char *)&afs_xcbhash}, {
55 "afs_xaxs", (char *)&afs_xaxs}, {
56 "afs_xinterface", (char *)&afs_xinterface},
59 "afs_xosi", (char *)&afs_xosi},
62 "afs_xsrvAddr", (char *)&afs_xsrvAddr}
64 unsigned long lastCallBack_vnode;
65 unsigned int lastCallBack_dv;
66 osi_timeval_t lastCallBack_time;
68 /* these are for storing alternate interface addresses */
69 struct interfaceAddr afs_cb_interface;
71 /*------------------------------------------------------------------------
72 * EXPORTED SRXAFSCB_GetCE
75 * Routine called by the server-side callback RPC interface to
76 * implement pulling out the contents of the i'th cache entry.
79 * a_call : Ptr to Rx call on which this request came in.
80 * a_index : Index of desired cache entry.
81 * a_result : Ptr to a buffer for the given cache entry.
84 * 0 if everything went fine,
85 * 1 if we were given a bad index.
88 * Nothing interesting.
92 *------------------------------------------------------------------------*/
95 SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
96 struct AFSDBCacheEntry *a_result)
99 register int i; /*Loop variable */
100 register struct vcache *tvc; /*Ptr to current cache entry */
101 int code; /*Return code */
106 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
108 AFS_STATCNT(SRXAFSCB_GetCE);
109 for (i = 0; i < VCSIZE; i++) {
110 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
114 } /*Zip through current hash chain */
115 } /*Zip through hash chains */
125 * Copy out the located entry.
127 a_result->addr = afs_data_pointer_to_int32(tvc);
128 a_result->cell = tvc->fid.Cell;
129 a_result->netFid.Volume = tvc->fid.Fid.Volume;
130 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
131 a_result->netFid.Unique = tvc->fid.Fid.Unique;
132 a_result->lock.waitStates = tvc->lock.wait_states;
133 a_result->lock.exclLocked = tvc->lock.excl_locked;
134 a_result->lock.readersReading = tvc->lock.readers_reading;
135 a_result->lock.numWaiting = tvc->lock.num_waiting;
136 #if defined(INSTRUMENT_LOCKS)
137 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
138 a_result->lock.pid_writer = tvc->lock.pid_writer;
139 a_result->lock.src_indicator = tvc->lock.src_indicator;
141 /* On osf20 , the vcache does not maintain these three fields */
142 a_result->lock.pid_last_reader = 0;
143 a_result->lock.pid_writer = 0;
144 a_result->lock.src_indicator = 0;
145 #endif /* AFS_OSF20_ENV */
146 #ifdef AFS_64BIT_CLIENT
147 a_result->Length = (afs_int32) tvc->m.Length & 0xffffffff;
148 #else /* AFS_64BIT_CLIENT */
149 a_result->Length = tvc->m.Length;
150 #endif /* AFS_64BIT_CLIENT */
151 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
152 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
153 a_result->cbExpires = tvc->cbExpires;
154 #ifdef AFS_DARWIN80_ENV
155 a_result->refCount = vnode_isinuse(AFSTOV(tvc))?1:0; /* XXX fix */
157 a_result->refCount = VREFCOUNT(tvc);
159 a_result->opens = tvc->opens;
160 a_result->writers = tvc->execsOrWriters;
161 a_result->mvstat = tvc->mvstat;
162 a_result->states = tvc->states;
166 * Return our results.
175 } /*SRXAFSCB_GetCE */
178 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
179 struct AFSDBCacheEntry64 *a_result)
181 register int i; /*Loop variable */
182 register struct vcache *tvc; /*Ptr to current cache entry */
183 int code; /*Return code */
188 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
190 AFS_STATCNT(SRXAFSCB_GetCE64);
191 for (i = 0; i < VCSIZE; i++) {
192 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
196 } /*Zip through current hash chain */
197 } /*Zip through hash chains */
207 * Copy out the located entry.
209 a_result->addr = afs_data_pointer_to_int32(tvc);
210 a_result->cell = tvc->fid.Cell;
211 a_result->netFid.Volume = tvc->fid.Fid.Volume;
212 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
213 a_result->netFid.Unique = tvc->fid.Fid.Unique;
214 a_result->lock.waitStates = tvc->lock.wait_states;
215 a_result->lock.exclLocked = tvc->lock.excl_locked;
216 a_result->lock.readersReading = tvc->lock.readers_reading;
217 a_result->lock.numWaiting = tvc->lock.num_waiting;
218 #if defined(INSTRUMENT_LOCKS)
219 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
220 a_result->lock.pid_writer = tvc->lock.pid_writer;
221 a_result->lock.src_indicator = tvc->lock.src_indicator;
223 /* On osf20 , the vcache does not maintain these three fields */
224 a_result->lock.pid_last_reader = 0;
225 a_result->lock.pid_writer = 0;
226 a_result->lock.src_indicator = 0;
227 #endif /* AFS_OSF20_ENV */
228 #if !defined(AFS_64BIT_ENV)
229 a_result->Length.high = 0;
230 a_result->Length.low = tvc->m.Length;
232 a_result->Length = tvc->m.Length;
234 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
235 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
236 a_result->cbExpires = tvc->cbExpires;
237 #ifdef AFS_DARWIN80_ENV
238 a_result->refCount = vnode_isinuse(AFSTOV(tvc))?1:0; /* XXX fix */
240 a_result->refCount = VREFCOUNT(tvc);
242 a_result->opens = tvc->opens;
243 a_result->writers = tvc->execsOrWriters;
244 a_result->mvstat = tvc->mvstat;
245 a_result->states = tvc->states;
249 * Return our results.
258 } /*SRXAFSCB_GetCE64 */
261 /*------------------------------------------------------------------------
262 * EXPORTED SRXAFSCB_GetLock
265 * Routine called by the server-side callback RPC interface to
266 * implement pulling out the contents of a lock in the lock
270 * a_call : Ptr to Rx call on which this request came in.
271 * a_index : Index of desired lock.
272 * a_result : Ptr to a buffer for the given lock.
275 * 0 if everything went fine,
276 * 1 if we were given a bad index.
279 * Nothing interesting.
283 *------------------------------------------------------------------------*/
286 SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
287 struct AFSDBLock *a_result)
289 struct ltable *tl; /*Ptr to lock table entry */
290 int nentries; /*Num entries in table */
291 int code; /*Return code */
296 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
298 AFS_STATCNT(SRXAFSCB_GetLock);
299 nentries = sizeof(ltable) / sizeof(struct ltable);
300 if (a_index < 0 || a_index >= nentries) {
307 * Found it - copy out its contents.
309 tl = <able[a_index];
310 strcpy(a_result->name, tl->name);
311 a_result->lock.waitStates =
312 ((struct afs_lock *)(tl->addr))->wait_states;
313 a_result->lock.exclLocked =
314 ((struct afs_lock *)(tl->addr))->excl_locked;
315 a_result->lock.readersReading =
316 ((struct afs_lock *)(tl->addr))->readers_reading;
317 a_result->lock.numWaiting =
318 ((struct afs_lock *)(tl->addr))->num_waiting;
319 #ifdef INSTRUMENT_LOCKS
320 a_result->lock.pid_last_reader =
321 ((struct afs_lock *)(tl->addr))->pid_last_reader;
322 a_result->lock.pid_writer =
323 ((struct afs_lock *)(tl->addr))->pid_writer;
324 a_result->lock.src_indicator =
325 ((struct afs_lock *)(tl->addr))->src_indicator;
327 a_result->lock.pid_last_reader = 0;
328 a_result->lock.pid_writer = 0;
329 a_result->lock.src_indicator = 0;
340 } /*SRXAFSCB_GetLock */
343 /*------------------------------------------------------------------------
344 * static ClearCallBack
347 * Clear out callback information for the specified file, or
348 * even a whole volume. Used to worry about callback was from
349 * within the particular cell or not. Now we don't bother with
350 * that anymore; it's not worth the time.
353 * a_conn : Ptr to Rx connection involved.
354 * a_fid : Ptr to AFS fid being cleared.
360 * Nothing interesting.
365 Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
367 *------------------------------------------------------------------------*/
370 ClearCallBack(register struct rx_connection *a_conn,
371 register struct AFSFid *a_fid)
373 register struct vcache *tvc;
375 struct VenusFid localFid;
378 AFS_STATCNT(ClearCallBack);
383 * XXXX Don't hold any server locks here because of callback protocol XXX
386 localFid.Fid.Volume = a_fid->Volume;
387 localFid.Fid.Vnode = a_fid->Vnode;
388 localFid.Fid.Unique = a_fid->Unique;
391 * Volume ID of zero means don't do anything.
393 if (a_fid->Volume != 0) {
394 if (a_fid->Vnode == 0) {
396 * Clear callback for the whole volume. Zip through the
397 * hash chain, nullifying entries whose volume ID matches.
399 for (i = 0; i < VCSIZE; i++)
400 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
401 if (tvc->fid.Fid.Volume == a_fid->Volume) {
402 tvc->callback = NULL;
403 tvc->quick.stamp = 0;
405 localFid.Cell = tvc->fid.Cell;
406 tvc->h1.dchint = NULL; /* invalidate hints */
407 ObtainWriteLock(&afs_xcbhash, 449);
408 afs_DequeueCallback(tvc);
409 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
411 if (tvc->fid.Fid.Vnode & 1)
415 ReleaseWriteLock(&afs_xcbhash);
416 if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
417 osi_dnlc_purgedp(tvc);
418 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
419 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
420 tvc->states, ICL_TYPE_INT32,
422 } else if ((tvc->states & CMValid)
423 && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
424 tvc->states &= ~CMValid;
426 localFid.Cell = tvc->mvid->Cell;
431 * XXXX Don't hold any locks here XXXX
433 tv = afs_FindVolume(&localFid, 0);
435 afs_ResetVolumeInfo(tv);
436 afs_PutVolume(tv, 0);
437 /* invalidate mtpoint? */
439 } /*Clear callbacks for whole volume */
442 * Clear callbacks just for the one file.
445 if (a_fid->Vnode & 1)
446 afs_oddCBs++; /*Could do this on volume basis, too */
448 afs_evenCBs++; /*A particular fid was specified */
449 i = VCHash(&localFid);
450 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
451 if (tvc->fid.Fid.Vnode == a_fid->Vnode
452 && tvc->fid.Fid.Volume == a_fid->Volume
453 && tvc->fid.Fid.Unique == a_fid->Unique) {
454 tvc->callback = NULL;
455 tvc->quick.stamp = 0;
456 tvc->h1.dchint = NULL; /* invalidate hints */
457 ObtainWriteLock(&afs_xcbhash, 450);
458 afs_DequeueCallback(tvc);
459 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
460 ReleaseWriteLock(&afs_xcbhash);
461 if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
462 osi_dnlc_purgedp(tvc);
463 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
464 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
465 tvc->states, ICL_TYPE_LONG, 0);
467 lastCallBack_vnode = afid->Vnode;
468 lastCallBack_dv = tvc->mstat.DataVersion.low;
469 osi_GetuTime(&lastCallBack_time);
472 } /*Walk through hash table */
473 } /*Clear callbacks for one file */
476 /*Fid has non-zero volume ID */
478 * Always return a predictable value.
485 /*------------------------------------------------------------------------
486 * EXPORTED SRXAFSCB_CallBack
489 * Routine called by the server-side callback RPC interface to
490 * implement passing in callback information.
494 * a_call : Ptr to Rx call on which this request came in.
495 * a_fids : Ptr to array of fids involved.
496 * a_callbacks : Ptr to matching callback info for the fids.
502 * Nothing interesting.
506 *------------------------------------------------------------------------*/
509 SRXAFSCB_CallBack(struct rx_call *a_call, register struct AFSCBFids *a_fids,
510 struct AFSCBs *a_callbacks)
512 register int i; /*Loop variable */
513 struct AFSFid *tfid; /*Ptr to current fid */
514 register struct rx_connection *tconn; /*Call's connection */
520 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
522 AFS_STATCNT(SRXAFSCB_CallBack);
523 if (!(tconn = rx_ConnectionOf(a_call)))
525 tfid = (struct AFSFid *)a_fids->AFSCBFids_val;
528 * For now, we ignore callbacks, since the File Server only *breaks*
529 * callbacks at present.
531 for (i = 0; i < a_fids->AFSCBFids_len; i++)
532 ClearCallBack(tconn, &tfid[i]);
540 } /*SRXAFSCB_CallBack */
543 /*------------------------------------------------------------------------
544 * EXPORTED SRXAFSCB_Probe
547 * Routine called by the server-side callback RPC interface to
548 * implement ``probing'' the Cache Manager, just making sure it's
552 * a_call : Ptr to Rx call on which this request came in.
558 * Nothing interesting.
562 *------------------------------------------------------------------------*/
565 SRXAFSCB_Probe(struct rx_call *a_call)
571 AFS_STATCNT(SRXAFSCB_Probe);
573 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
580 } /*SRXAFSCB_Probe */
583 /*------------------------------------------------------------------------
584 * EXPORTED SRXAFSCB_InitCallBackState
587 * Routine called by the server-side callback RPC interface to
588 * implement clearing all callbacks from this host.
591 * a_call : Ptr to Rx call on which this request came in.
597 * Nothing interesting.
601 *------------------------------------------------------------------------*/
604 SRXAFSCB_InitCallBackState(struct rx_call *a_call)
607 register struct vcache *tvc;
608 register struct rx_connection *tconn;
609 register struct rx_peer *peer;
616 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
617 AFS_STATCNT(SRXAFSCB_InitCallBackState);
620 * Find the address of the host making this call
622 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
625 afs_oddCBs++; /*Including any missed via create race */
626 afs_evenCBs++; /*Including any missed via create race */
628 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *) 0,
631 for (i = 0; i < VCSIZE; i++)
632 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
633 if (tvc->callback == ts) {
634 ObtainWriteLock(&afs_xcbhash, 451);
635 afs_DequeueCallback(tvc);
636 tvc->callback = NULL;
637 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
638 ReleaseWriteLock(&afs_xcbhash);
645 /* find any volumes residing on this server and flush their state */
647 register struct volume *tv;
650 for (i = 0; i < NVOLS; i++)
651 for (tv = afs_volumes[i]; tv; tv = tv->next) {
652 for (j = 0; j < MAXHOSTS; j++)
653 if (tv->serverHost[j] == ts)
654 afs_ResetVolumeInfo(tv);
657 osi_dnlc_purge(); /* may be a little bit extreme */
666 } /*SRXAFSCB_InitCallBackState */
669 /*------------------------------------------------------------------------
670 * EXPORTED SRXAFSCB_XStatsVersion
673 * Routine called by the server-side callback RPC interface to
674 * implement pulling out the xstat version number for the Cache
678 * a_versionP : Ptr to the version number variable to set.
684 * Nothing interesting.
688 *------------------------------------------------------------------------*/
691 SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 * a_versionP)
698 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
700 *a_versionP = AFSCB_XSTAT_VERSION;
707 } /*SRXAFSCB_XStatsVersion */
710 /*------------------------------------------------------------------------
711 * EXPORTED SRXAFSCB_GetXStats
714 * Routine called by the server-side callback RPC interface to
715 * implement getting the given data collection from the extended
716 * Cache Manager statistics.
719 * a_call : Ptr to Rx call on which this request came in.
720 * a_clientVersionNum : Client version number.
721 * a_opCode : Desired operation.
722 * a_serverVersionNumP : Ptr to version number to set.
723 * a_timeP : Ptr to time value (seconds) to set.
724 * a_dataArray : Ptr to variable array structure to return
731 * Nothing interesting.
735 *------------------------------------------------------------------------*/
738 SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
739 afs_int32 a_collectionNumber, afs_int32 * a_srvVersionNumP,
740 afs_int32 * a_timeP, AFSCB_CollData * a_dataP)
742 register int code; /*Return value */
743 afs_int32 *dataBuffP; /*Ptr to data to be returned */
744 afs_int32 dataBytes; /*Bytes in data buffer */
749 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
752 * Record the time of day and the server version number.
754 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
755 *a_timeP = osi_Time();
758 * Stuff the appropriate data in there (assume victory)
764 * We're not keeping stats, so just return successfully with
767 a_dataP->AFSCB_CollData_len = 0;
768 a_dataP->AFSCB_CollData_val = NULL;
770 switch (a_collectionNumber) {
771 case AFSCB_XSTATSCOLL_CALL_INFO:
773 * Pass back all the call-count-related data.
775 * >>> We are forced to allocate a separate area in which to
776 * >>> put this stuff in by the RPC stub generator, since it
777 * >>> will be freed at the tail end of the server stub code.
779 dataBytes = sizeof(struct afs_CMStats);
780 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
781 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
782 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
783 a_dataP->AFSCB_CollData_val = dataBuffP;
786 case AFSCB_XSTATSCOLL_PERF_INFO:
788 * Update and then pass back all the performance-related data.
789 * Note: the only performance fields that need to be computed
790 * at this time are the number of accesses for this collection
791 * and the current server record info.
793 * >>> We are forced to allocate a separate area in which to
794 * >>> put this stuff in by the RPC stub generator, since it
795 * >>> will be freed at the tail end of the server stub code.
797 afs_stats_cmperf.numPerfCalls++;
799 dataBytes = sizeof(afs_stats_cmperf);
800 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
801 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
802 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
803 a_dataP->AFSCB_CollData_val = dataBuffP;
806 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
808 * Pass back the full range of performance and statistical
809 * data available. We have to bring the normal performance
810 * data collection up to date, then copy that data into
811 * the full collection.
813 * >>> We are forced to allocate a separate area in which to
814 * >>> put this stuff in by the RPC stub generator, since it
815 * >>> will be freed at the tail end of the server stub code.
817 afs_stats_cmperf.numPerfCalls++;
819 memcpy((char *)(&(afs_stats_cmfullperf.perf)),
820 (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
821 afs_stats_cmfullperf.numFullPerfCalls++;
823 dataBytes = sizeof(afs_stats_cmfullperf);
824 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
825 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
826 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
827 a_dataP->AFSCB_CollData_val = dataBuffP;
832 * Illegal collection number.
834 a_dataP->AFSCB_CollData_len = 0;
835 a_dataP->AFSCB_CollData_val = NULL;
837 } /*Switch on collection number */
838 #endif /* AFS_NOSTATS */
846 } /*SRXAFSCB_GetXStats */
849 /*------------------------------------------------------------------------
850 * EXPORTED afs_RXCallBackServer
853 * Body of the thread supporting callback services.
862 * Nothing interesting.
866 *------------------------------------------------------------------------*/
869 afs_RXCallBackServer(void)
871 AFS_STATCNT(afs_RXCallBackServer);
876 afs_osi_Sleep(&afs_server);
880 * Donate this process to Rx.
885 } /*afs_RXCallBackServer */
888 /*------------------------------------------------------------------------
889 * EXPORTED shutdown_CB
892 * Zero out important Cache Manager data structures.
901 * Nothing interesting.
905 *------------------------------------------------------------------------*/
910 AFS_STATCNT(shutdown_CB);
912 if (afs_cold_shutdown) {
913 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps =
914 afs_evenZaps = afs_connectBacks = 0;
921 /*------------------------------------------------------------------------
922 * EXPORTED SRXAFSCB_InitCallBackState2
925 * This routine was used in the AFS 3.5 beta release, but not anymore.
926 * It has since been replaced by SRXAFSCB_InitCallBackState3.
929 * a_call : Ptr to Rx call on which this request came in.
932 * RXGEN_OPCODE (always).
935 * Nothing interesting.
939 *------------------------------------------------------------------------*/
942 SRXAFSCB_InitCallBackState2(struct rx_call *a_call,
943 struct interfaceAddr *addr)
948 /*------------------------------------------------------------------------
949 * EXPORTED SRXAFSCB_WhoAreYou
952 * Routine called by the server-side callback RPC interface to
953 * obtain a unique identifier for the client. The server uses
954 * this identifier to figure out whether or not two RX connections
955 * are from the same client, and to find out which addresses go
956 * with which clients.
959 * a_call : Ptr to Rx call on which this request came in.
960 * addr: Ptr to return the list of interfaces for this client.
966 * Nothing interesting.
970 *------------------------------------------------------------------------*/
973 SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
980 AFS_STATCNT(SRXAFSCB_WhoAreYou);
982 memset(addr, 0, sizeof(*addr));
984 ObtainReadLock(&afs_xinterface);
986 /* return all network interface addresses */
987 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
988 addr->uuid = afs_cb_interface.uuid;
989 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
990 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
991 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
992 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
995 ReleaseReadLock(&afs_xinterface);
1003 /*------------------------------------------------------------------------
1004 * EXPORTED SRXAFSCB_InitCallBackState3
1007 * Routine called by the server-side callback RPC interface to
1008 * implement clearing all callbacks from this host.
1011 * a_call : Ptr to Rx call on which this request came in.
1017 * Nothing interesting.
1021 *------------------------------------------------------------------------*/
1024 SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID * a_uuid)
1029 * TBD: Lookup the server by the UUID instead of its IP address.
1031 code = SRXAFSCB_InitCallBackState(a_call);
1037 /*------------------------------------------------------------------------
1038 * EXPORTED SRXAFSCB_ProbeUuid
1041 * Routine called by the server-side callback RPC interface to
1042 * implement ``probing'' the Cache Manager, just making sure it's
1043 * still there is still the same client it used to be.
1046 * a_call : Ptr to Rx call on which this request came in.
1047 * a_uuid : Ptr to UUID that must match the client's UUID.
1050 * 0 if a_uuid matches the UUID for this client
1051 * Non-zero otherwize
1054 * Nothing interesting.
1058 *------------------------------------------------------------------------*/
1061 SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID * a_uuid)
1067 AFS_STATCNT(SRXAFSCB_Probe);
1069 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1070 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1071 code = 1; /* failure */
1080 /*------------------------------------------------------------------------
1081 * EXPORTED SRXAFSCB_GetServerPrefs
1084 * Routine to list server preferences used by this client.
1087 * a_call : Ptr to Rx call on which this request came in.
1088 * a_index : Input server index
1089 * a_srvr_addr : Output server address in host byte order
1090 * (0xffffffff on last server)
1091 * a_srvr_rank : Output server rank
1097 * Nothing interesting.
1101 *------------------------------------------------------------------------*/
1104 SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1105 afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
1111 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1113 ObtainReadLock(&afs_xserver);
1115 /* Search the hash table for the server with this index */
1116 *a_srvr_addr = 0xffffffff;
1117 *a_srvr_rank = 0xffffffff;
1118 for (i = 0, j = 0; j < NSERVERS && i <= a_index; j++) {
1119 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1121 *a_srvr_addr = ntohl(sa->sa_ip);
1122 *a_srvr_rank = sa->sa_iprank;
1127 ReleaseReadLock(&afs_xserver);
1135 /*------------------------------------------------------------------------
1136 * EXPORTED SRXAFSCB_GetCellServDB
1139 * Routine to list cells configured for this client
1142 * a_call : Ptr to Rx call on which this request came in.
1143 * a_index : Input cell index
1144 * a_name : Output cell name ("" on last cell)
1145 * a_hosts : Output cell database servers in host byte order.
1151 * Nothing interesting.
1155 *------------------------------------------------------------------------*/
1158 SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1159 char **a_name, serverList * a_hosts)
1163 char *t_name, *p_name = NULL;
1166 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1168 tcell = afs_GetCellByIndex(a_index, READ_LOCK);
1172 a_hosts->serverList_val = 0;
1173 a_hosts->serverList_len = 0;
1175 p_name = tcell->cellName;
1176 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
1178 a_hosts->serverList_val =
1179 (afs_int32 *) afs_osi_Alloc(j * sizeof(afs_int32));
1180 a_hosts->serverList_len = j;
1181 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++)
1182 a_hosts->serverList_val[j] =
1183 ntohl(tcell->cellHosts[j]->addr->sa_ip);
1184 afs_PutCell(tcell, READ_LOCK);
1187 t_name = (char *)afs_osi_Alloc(i + 1);
1188 if (t_name == NULL) {
1189 afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
1196 memcpy(t_name, p_name, i);
1205 /*------------------------------------------------------------------------
1206 * EXPORTED SRXAFSCB_GetLocalCell
1209 * Routine to return name of client's local cell
1212 * a_call : Ptr to Rx call on which this request came in.
1213 * a_name : Output cell name
1219 * Nothing interesting.
1223 *------------------------------------------------------------------------*/
1226 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1230 char *t_name, *p_name = NULL;
1233 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1235 /* Search the list for the primary cell. Cell number 1 is only
1236 * the primary cell is when no other cell is explicitly marked as
1237 * the primary cell. */
1238 tcell = afs_GetPrimaryCell(READ_LOCK);
1240 p_name = tcell->cellName;
1242 plen = strlen(p_name);
1245 t_name = (char *)afs_osi_Alloc(plen + 1);
1246 if (t_name == NULL) {
1248 afs_PutCell(tcell, READ_LOCK);
1253 t_name[plen] = '\0';
1255 memcpy(t_name, p_name, plen);
1261 afs_PutCell(tcell, READ_LOCK);
1267 * afs_MarshallCacheConfig - marshall client cache configuration
1271 * IN callerVersion - the rpc stat version of the caller.
1273 * IN config - client cache configuration.
1275 * OUT ptr - buffer where configuration is marshalled.
1282 afs_MarshallCacheConfig(afs_uint32 callerVersion, cm_initparams_v1 * config,
1285 AFS_STATCNT(afs_MarshallCacheConfig);
1287 * We currently only support version 1.
1289 *(ptr++) = config->nChunkFiles;
1290 *(ptr++) = config->nStatCaches;
1291 *(ptr++) = config->nDataCaches;
1292 *(ptr++) = config->nVolumeCaches;
1293 *(ptr++) = config->firstChunkSize;
1294 *(ptr++) = config->otherChunkSize;
1295 *(ptr++) = config->cacheSize;
1296 *(ptr++) = config->setTime;
1297 *(ptr++) = config->memCache;
1301 /*------------------------------------------------------------------------
1302 * EXPORTED SRXAFSCB_GetCacheConfig
1305 * Routine to return parameters used to initialize client cache.
1306 * Client may request any format version. Server may not return
1307 * format version greater than version requested by client.
1310 * a_call: Ptr to Rx call on which this request came in.
1311 * callerVersion: Data format version desired by the client.
1312 * serverVersion: Data format version of output data.
1313 * configCount: Number bytes allocated for output data.
1314 * config: Client cache configuration.
1320 * Nothing interesting.
1324 *------------------------------------------------------------------------*/
1327 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1328 afs_uint32 * serverVersion, afs_uint32 * configCount,
1329 cacheConfig * config)
1331 afs_uint32 *t_config;
1333 cm_initparams_v1 cm_config;
1336 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1339 * Currently only support version 1
1341 allocsize = sizeof(cm_initparams_v1);
1342 t_config = (afs_uint32 *) afs_osi_Alloc(allocsize);
1343 if (t_config == NULL) {
1348 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1349 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1350 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1351 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1352 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1353 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1354 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1355 cm_config.setTime = cm_initParams.cmi_setTime;
1356 cm_config.memCache = cm_initParams.cmi_memCache;
1358 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1360 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1361 *configCount = allocsize;
1362 config->cacheConfig_val = t_config;
1363 config->cacheConfig_len = allocsize / sizeof(afs_uint32);
1370 /*------------------------------------------------------------------------
1371 * EXPORTED SRXAFSCB_FetchData
1374 * Routine to do third party move from a remioserver to the original
1375 * issuer of an ArchiveData request. Presently supported only by the
1376 * "fs" command, not by the AFS client.
1379 * rxcall: Ptr to Rx call on which this request came in.
1380 * Fid: pointer to AFSFid structure.
1381 * Fd: File descriptor inside fs command.
1382 * Position: Offset in the file.
1383 * Length: Data length to transfer.
1384 * TotalLength: Pointer to total file length field
1390 * Nothing interesting.
1393 *------------------------------------------------------------------------*/
1395 SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1396 afs_int64 Position, afs_int64 Length,
1397 afs_int64 * TotalLength)
1402 /*------------------------------------------------------------------------
1403 * EXPORTED SRXAFSCB_StoreData
1406 * Routine to do third party move from a remioserver to the original
1407 * issuer of a RetrieveData request. Presently supported only by the
1408 * "fs" command, not by the AFS client.
1411 * rxcall: Ptr to Rx call on which this request came in.
1412 * Fid: pointer to AFSFid structure.
1413 * Fd: File descriptor inside fs command.
1414 * Position: Offset in the file.
1415 * Length: Data length to transfer.
1416 * TotalLength: Pointer to total file length field
1422 * Nothing interesting.
1426 *------------------------------------------------------------------------*/
1428 SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1429 afs_int64 Position, afs_int64 Length,
1430 afs_int64 * TotalLength)
1435 /*------------------------------------------------------------------------
1436 * EXPORTED SRXAFSCB_GetCellByNum
1439 * Routine to get information about a cell specified by its
1440 * cell number (returned by GetCE/GetCE64).
1443 * a_call : Ptr to Rx call on which this request came in.
1444 * a_cellnum : Input cell number
1445 * a_name : Output cell name (one zero byte when no such cell).
1446 * a_hosts : Output cell database servers in host byte order.
1452 * Nothing interesting.
1456 *------------------------------------------------------------------------*/
1459 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
1460 char **a_name, serverList * a_hosts)
1466 AFS_STATCNT(SRXAFSCB_GetCellByNum);
1468 a_hosts->serverList_val = 0;
1469 a_hosts->serverList_len = 0;
1471 tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
1473 *a_name = afs_strdup("");
1478 ObtainReadLock(&tcell->lock);
1479 *a_name = afs_strdup(tcell->cellName);
1481 for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++);
1482 a_hosts->serverList_len = sn;
1483 a_hosts->serverList_val =
1484 (afs_int32 *) afs_osi_Alloc(sn * sizeof(afs_int32));
1486 for (i = 0; i < sn; i++)
1487 a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
1488 ReleaseReadLock(&tcell->lock);
1489 afs_PutCell(tcell, READ_LOCK);
1496 SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
1497 struct interfaceAddr *addr,
1498 Capabilities * capabilities)
1502 afs_int32 *dataBuffP;
1503 afs_int32 dataBytes;
1507 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1509 ObtainReadLock(&afs_xinterface);
1511 /* return all network interface addresses */
1512 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1513 addr->uuid = afs_cb_interface.uuid;
1514 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1515 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1516 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1517 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1520 ReleaseReadLock(&afs_xinterface);
1524 dataBytes = 1 * sizeof(afs_int32);
1525 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
1526 dataBuffP[0] = CAPABILITY_ERRORTRANS;
1527 capabilities->Capabilities_len = dataBytes / sizeof(afs_int32);
1528 capabilities->Capabilities_val = dataBuffP;