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"
20 #include "afs/sysincludes.h" /*Standard vendor system headers */
21 #include "afsincludes.h" /*AFS-based standard headers */
22 #define FSINT_COMMON_XG
23 #include "afs/afscbint.h"
24 #include "afs/afs_stats.h" /*Cache Manager stats */
26 #include "afs/afs_args.h"
28 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
29 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs */
30 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files */
31 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
32 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted */
33 afs_int32 afs_evenZaps = 0; /*File cache entries deleted */
34 afs_int32 afs_connectBacks = 0;
37 * Some debugging aids.
39 static struct ltable {
44 "afs_xvcache", (char *)&afs_xvcache}, {
45 "afs_xdcache", (char *)&afs_xdcache}, {
46 "afs_xserver", (char *)&afs_xserver}, {
47 "afs_xvcb", (char *)&afs_xvcb}, {
48 "afs_xbrs", (char *)&afs_xbrs}, {
49 "afs_xcell", (char *)&afs_xcell}, {
50 "afs_xconn", (char *)&afs_xconn}, {
51 "afs_xuser", (char *)&afs_xuser}, {
52 "afs_xvolume", (char *)&afs_xvolume}, {
53 "puttofile", (char *)&afs_puttofileLock}, {
54 "afs_ftf", (char *)&afs_ftf}, {
55 "afs_xcbhash", (char *)&afs_xcbhash}, {
56 "afs_xaxs", (char *)&afs_xaxs}, {
57 "afs_xinterface", (char *)&afs_xinterface},
59 "afs_xsrvAddr", (char *)&afs_xsrvAddr},
61 "afs_xvreclaim", (char *)&afs_xvreclaim},
62 { "afsdb_client_lock", (char *)&afsdb_client_lock},
63 { "afsdb_req_lock", (char *)&afsdb_req_lock},
64 { "afs_discon_lock", (char *)&afs_discon_lock},
65 { "afs_disconDirtyLock", (char *)&afs_disconDirtyLock},
66 { "afs_discon_vc_dirty", (char *)&afs_xvcdirty},
67 { "afs_dynrootDirLock", (char *)&afs_dynrootDirLock},
68 { "afs_dynSymlinkLock", (char *)&afs_dynSymlinkLock},
70 unsigned long lastCallBack_vnode;
71 unsigned int lastCallBack_dv;
72 osi_timeval32_t lastCallBack_time;
74 /* these are for storing alternate interface addresses */
75 struct interfaceAddr afs_cb_interface;
77 /*------------------------------------------------------------------------
78 * EXPORTED SRXAFSCB_GetCE
81 * Routine called by the server-side callback RPC interface to
82 * implement pulling out the contents of the i'th cache entry.
85 * a_call : Ptr to Rx call on which this request came in.
86 * a_index : Index of desired cache entry.
87 * a_result : Ptr to a buffer for the given cache entry.
90 * 0 if everything went fine,
91 * 1 if we were given a bad index.
94 * Nothing interesting.
98 *------------------------------------------------------------------------*/
101 SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
102 struct AFSDBCacheEntry *a_result)
105 int i; /*Loop variable */
106 struct vcache *tvc; /*Ptr to current cache entry */
107 int code; /*Return code */
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 */
131 * Copy out the located entry.
133 a_result->addr = afs_data_pointer_to_int32(tvc);
134 a_result->cell = tvc->f.fid.Cell;
135 a_result->netFid.Volume = tvc->f.fid.Fid.Volume;
136 a_result->netFid.Vnode = tvc->f.fid.Fid.Vnode;
137 a_result->netFid.Unique = tvc->f.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 a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
143 a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
144 a_result->lock.src_indicator = tvc->lock.src_indicator;
145 #ifdef AFS_64BIT_CLIENT
146 a_result->Length = (afs_int32) tvc->f.m.Length & 0xffffffff;
147 #else /* AFS_64BIT_CLIENT */
148 a_result->Length = tvc->f.m.Length;
149 #endif /* AFS_64BIT_CLIENT */
150 a_result->DataVersion = hgetlo(tvc->f.m.DataVersion);
151 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
152 a_result->cbExpires = tvc->cbExpires;
153 if (tvc->f.states & CVInit) {
154 a_result->refCount = 1;
156 #ifdef AFS_DARWIN80_ENV
157 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
159 a_result->refCount = VREFCOUNT(tvc);
162 a_result->opens = tvc->opens;
163 a_result->writers = tvc->execsOrWriters;
164 a_result->mvstat = tvc->mvstat;
165 a_result->states = tvc->f.states;
169 * Return our results.
178 } /*SRXAFSCB_GetCE */
181 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
182 struct AFSDBCacheEntry64 *a_result)
184 int i; /*Loop variable */
185 struct vcache *tvc; /*Ptr to current cache entry */
186 int code; /*Return code */
191 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
193 AFS_STATCNT(SRXAFSCB_GetCE64);
194 for (i = 0; i < VCSIZE; i++) {
195 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
199 } /*Zip through current hash chain */
200 } /*Zip through hash chains */
210 * Copy out the located entry.
212 a_result->addr = afs_data_pointer_to_int32(tvc);
213 a_result->cell = tvc->f.fid.Cell;
214 a_result->netFid.Volume = tvc->f.fid.Fid.Volume;
215 a_result->netFid.Vnode = tvc->f.fid.Fid.Vnode;
216 a_result->netFid.Unique = tvc->f.fid.Fid.Unique;
217 a_result->lock.waitStates = tvc->lock.wait_states;
218 a_result->lock.exclLocked = tvc->lock.excl_locked;
219 a_result->lock.readersReading = tvc->lock.readers_reading;
220 a_result->lock.numWaiting = tvc->lock.num_waiting;
221 a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
222 a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
223 a_result->lock.src_indicator = tvc->lock.src_indicator;
224 a_result->Length = tvc->f.m.Length;
225 a_result->DataVersion = hgetlo(tvc->f.m.DataVersion);
226 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
227 a_result->cbExpires = tvc->cbExpires;
228 if (tvc->f.states & CVInit) {
229 a_result->refCount = 1;
231 #ifdef AFS_DARWIN80_ENV
232 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
234 a_result->refCount = VREFCOUNT(tvc);
237 a_result->opens = tvc->opens;
238 a_result->writers = tvc->execsOrWriters;
239 a_result->mvstat = tvc->mvstat;
240 a_result->states = tvc->f.states;
244 * Return our results.
253 } /*SRXAFSCB_GetCE64 */
256 /*------------------------------------------------------------------------
257 * EXPORTED SRXAFSCB_GetLock
260 * Routine called by the server-side callback RPC interface to
261 * implement pulling out the contents of a lock in the lock
265 * a_call : Ptr to Rx call on which this request came in.
266 * a_index : Index of desired lock.
267 * a_result : Ptr to a buffer for the given lock.
270 * 0 if everything went fine,
271 * 1 if we were given a bad index.
274 * Nothing interesting.
278 *------------------------------------------------------------------------*/
281 SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
282 struct AFSDBLock *a_result)
284 struct ltable *tl; /*Ptr to lock table entry */
285 int nentries; /*Num entries in table */
286 int code; /*Return code */
291 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
293 AFS_STATCNT(SRXAFSCB_GetLock);
294 memset(a_result, 0, sizeof(*a_result));
295 nentries = sizeof(ltable) / sizeof(struct ltable);
296 if (a_index < 0 || a_index >= nentries+afs_cellindex) {
301 } else if (a_index >= nentries) {
302 struct cell *tc = afs_GetCellByIndex(a_index-nentries, 0);
303 strlcpy(a_result->name, tc->cellName, sizeof(a_result->name));
304 a_result->lock.waitStates =
305 ((struct afs_lock *)&(tc->lock))->wait_states;
306 a_result->lock.exclLocked =
307 ((struct afs_lock *)&(tc->lock))->excl_locked;
308 a_result->lock.readersReading =
309 ((struct afs_lock *)&(tc->lock))->readers_reading;
310 a_result->lock.numWaiting =
311 ((struct afs_lock *)&(tc->lock))->num_waiting;
312 a_result->lock.pid_last_reader =
313 MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_last_reader);
314 a_result->lock.pid_writer =
315 MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_writer);
316 a_result->lock.src_indicator =
317 ((struct afs_lock *)&(tc->lock))->src_indicator;
321 * Found it - copy out its contents.
323 tl = <able[a_index];
324 strlcpy(a_result->name, tl->name, sizeof(a_result->name));
325 a_result->lock.waitStates =
326 ((struct afs_lock *)(tl->addr))->wait_states;
327 a_result->lock.exclLocked =
328 ((struct afs_lock *)(tl->addr))->excl_locked;
329 a_result->lock.readersReading =
330 ((struct afs_lock *)(tl->addr))->readers_reading;
331 a_result->lock.numWaiting =
332 ((struct afs_lock *)(tl->addr))->num_waiting;
333 a_result->lock.pid_last_reader =
334 MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_last_reader);
335 a_result->lock.pid_writer =
336 MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_writer);
337 a_result->lock.src_indicator =
338 ((struct afs_lock *)(tl->addr))->src_indicator;
348 } /*SRXAFSCB_GetLock */
351 /*------------------------------------------------------------------------
352 * static ClearCallBack
355 * Clear out callback information for the specified file, or
356 * even a whole volume. Used to worry about callback was from
357 * within the particular cell or not. Now we don't bother with
358 * that anymore; it's not worth the time.
361 * a_conn : Ptr to Rx connection involved.
362 * a_fid : Ptr to AFS fid being cleared.
368 * Nothing interesting.
373 Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
375 *------------------------------------------------------------------------*/
378 ClearCallBack(struct rx_connection *a_conn,
379 struct AFSFid *a_fid)
383 struct VenusFid localFid;
385 #ifdef AFS_DARWIN80_ENV
389 AFS_STATCNT(ClearCallBack);
394 * XXXX Don't hold any server locks here because of callback protocol XXX
397 localFid.Fid.Volume = a_fid->Volume;
398 localFid.Fid.Vnode = a_fid->Vnode;
399 localFid.Fid.Unique = a_fid->Unique;
402 * Volume ID of zero means don't do anything.
404 if (a_fid->Volume != 0) {
405 if (a_fid->Vnode == 0) {
406 struct afs_q *tq, *uq;
408 * Clear callback for the whole volume. Zip through the
409 * hash chain, nullifying entries whose volume ID matches.
412 ObtainReadLock(&afs_xvcache);
413 i = VCHashV(&localFid);
414 for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) {
417 if (tvc->f.fid.Fid.Volume == a_fid->Volume) {
418 tvc->callback = NULL;
420 localFid.Cell = tvc->f.fid.Cell;
421 tvc->dchint = NULL; /* invalidate hints */
422 if (tvc->f.states & CVInit) {
423 ReleaseReadLock(&afs_xvcache);
424 afs_osi_Sleep(&tvc->f.states);
427 #ifdef AFS_DARWIN80_ENV
428 if (tvc->f.states & CDeadVnode) {
429 ReleaseReadLock(&afs_xvcache);
430 afs_osi_Sleep(&tvc->f.states);
443 if (osi_vnhold(tvc) != 0) {
447 ReleaseReadLock(&afs_xvcache);
448 afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
450 if (tvc->f.fid.Fid.Vnode & 1)
454 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
455 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
456 tvc->f.states, ICL_TYPE_INT32,
458 #ifdef AFS_DARWIN80_ENV
459 vnode_put(AFSTOV(tvc));
461 ObtainReadLock(&afs_xvcache);
464 } else if ((tvc->f.states & CMValid)
465 && (tvc->mvid.target_root->Fid.Volume == a_fid->Volume)) {
466 tvc->f.states &= ~CMValid;
468 localFid.Cell = tvc->mvid.target_root->Cell;
471 ReleaseReadLock(&afs_xvcache);
474 * XXXX Don't hold any locks here XXXX
476 tv = afs_FindVolume(&localFid, 0);
478 afs_ResetVolumeInfo(tv);
479 afs_PutVolume(tv, 0);
480 /* invalidate mtpoint? */
482 } /*Clear callbacks for whole volume */
485 * Clear callbacks just for the one file.
489 if (a_fid->Vnode & 1)
490 afs_oddCBs++; /*Could do this on volume basis, too */
492 afs_evenCBs++; /*A particular fid was specified */
494 ObtainReadLock(&afs_xvcache);
495 i = VCHash(&localFid);
496 for (tvc = afs_vhashT[i]; tvc; tvc = uvc) {
498 if (tvc->f.fid.Fid.Vnode == a_fid->Vnode
499 && tvc->f.fid.Fid.Volume == a_fid->Volume
500 && tvc->f.fid.Fid.Unique == a_fid->Unique) {
501 tvc->callback = NULL;
502 tvc->dchint = NULL; /* invalidate hints */
503 if (tvc->f.states & CVInit) {
504 ReleaseReadLock(&afs_xvcache);
505 afs_osi_Sleep(&tvc->f.states);
508 #ifdef AFS_DARWIN80_ENV
509 if (tvc->f.states & CDeadVnode) {
510 ReleaseReadLock(&afs_xvcache);
511 afs_osi_Sleep(&tvc->f.states);
524 if (osi_vnhold(tvc) != 0) {
528 ReleaseReadLock(&afs_xvcache);
529 afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
530 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
531 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
532 tvc->f.states, ICL_TYPE_LONG, 0);
534 lastCallBack_vnode = afid->Vnode;
535 lastCallBack_dv = tvc->mstat.DataVersion.low;
536 osi_GetTime(&lastCallBack_time);
538 #ifdef AFS_DARWIN80_ENV
539 vnode_put(AFSTOV(tvc));
541 ObtainReadLock(&afs_xvcache);
545 } /*Walk through hash table */
546 ReleaseReadLock(&afs_xvcache);
547 } /*Clear callbacks for one file */
550 /*Fid has non-zero volume ID */
552 * Always return a predictable value.
559 /*------------------------------------------------------------------------
560 * EXPORTED SRXAFSCB_CallBack
563 * Routine called by the server-side callback RPC interface to
564 * implement passing in callback information.
568 * a_call : Ptr to Rx call on which this request came in.
569 * a_fids : Ptr to array of fids involved.
570 * a_callbacks : Ptr to matching callback info for the fids.
576 * Nothing interesting.
580 *------------------------------------------------------------------------*/
583 SRXAFSCB_CallBack(struct rx_call *a_call, struct AFSCBFids *a_fids,
584 struct AFSCBs *a_callbacks)
586 int i; /*Loop variable */
587 struct AFSFid *tfid; /*Ptr to current fid */
588 struct rx_connection *tconn; /*Call's connection */
594 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
596 AFS_STATCNT(SRXAFSCB_CallBack);
597 if (!(tconn = rx_ConnectionOf(a_call)))
599 tfid = (struct AFSFid *)a_fids->AFSCBFids_val;
602 * For now, we ignore callbacks, since the File Server only *breaks*
603 * callbacks at present.
605 for (i = 0; i < a_fids->AFSCBFids_len; i++)
606 ClearCallBack(tconn, &tfid[i]);
614 } /*SRXAFSCB_CallBack */
617 /*------------------------------------------------------------------------
618 * EXPORTED SRXAFSCB_Probe
621 * Routine called by the server-side callback RPC interface to
622 * implement ``probing'' the Cache Manager, just making sure it's
626 * a_call : Ptr to Rx call on which this request came in.
632 * Nothing interesting.
636 *------------------------------------------------------------------------*/
639 SRXAFSCB_Probe(struct rx_call *a_call)
645 AFS_STATCNT(SRXAFSCB_Probe);
647 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
654 } /*SRXAFSCB_Probe */
657 /*------------------------------------------------------------------------
658 * EXPORTED SRXAFSCB_InitCallBackState
661 * Routine called by the server-side callback RPC interface to
662 * implement clearing all callbacks from this host.
665 * a_call : Ptr to Rx call on which this request came in.
671 * Nothing interesting.
675 *------------------------------------------------------------------------*/
678 SRXAFSCB_InitCallBackState(struct rx_call *a_call)
682 struct rx_connection *tconn;
683 struct rx_peer *peer;
690 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
691 AFS_STATCNT(SRXAFSCB_InitCallBackState);
694 * Find the address of the host making this call
696 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
699 afs_oddCBs++; /*Including any missed via create race */
700 afs_evenCBs++; /*Including any missed via create race */
702 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *) 0,
705 for (i = 0; i < VCSIZE; i++)
706 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
707 if (tvc->callback == ts) {
708 afs_StaleVCacheFlags(tvc, AFS_STALEVC_NODNLC |
710 CUnique | CBulkFetching);
714 /* capabilities need be requested again */
715 ts->flags &= ~SCAPS_KNOWN;
720 /* find any volumes residing on this server and flush their state */
725 for (i = 0; i < NVOLS; i++)
726 for (tv = afs_volumes[i]; tv; tv = tv->next) {
727 for (j = 0; j < AFS_MAXHOSTS; j++)
728 if (tv->serverHost[j] == ts)
729 afs_ResetVolumeInfo(tv);
732 osi_dnlc_purge(); /* may be a little bit extreme */
741 } /*SRXAFSCB_InitCallBackState */
744 /*------------------------------------------------------------------------
745 * EXPORTED SRXAFSCB_XStatsVersion
748 * Routine called by the server-side callback RPC interface to
749 * implement pulling out the xstat version number for the Cache
753 * a_versionP : Ptr to the version number variable to set.
759 * Nothing interesting.
763 *------------------------------------------------------------------------*/
766 SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 * a_versionP)
773 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
775 *a_versionP = AFSCB_XSTAT_VERSION;
782 } /*SRXAFSCB_XStatsVersion */
785 /*------------------------------------------------------------------------
786 * EXPORTED SRXAFSCB_GetXStats
789 * Routine called by the server-side callback RPC interface to
790 * implement getting the given data collection from the extended
791 * Cache Manager statistics.
794 * a_call : Ptr to Rx call on which this request came in.
795 * a_clientVersionNum : Client version number.
796 * a_opCode : Desired operation.
797 * a_serverVersionNumP : Ptr to version number to set.
798 * a_timeP : Ptr to time value (seconds) to set.
799 * a_dataArray : Ptr to variable array structure to return
806 * Nothing interesting.
810 *------------------------------------------------------------------------*/
813 SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
814 afs_int32 a_collectionNumber, afs_int32 * a_srvVersionNumP,
815 afs_int32 * a_timeP, AFSCB_CollData * a_dataP)
817 int code; /*Return value */
818 afs_int32 *dataBuffP; /*Ptr to data to be returned */
819 afs_int32 dataBytes; /*Bytes in data buffer */
822 opr_StaticAssert(sizeof(osi_timeval32_t) == SIZEOF_OSI_TIMEVAL32_T);
826 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
829 * Record the time of day and the server version number.
831 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
832 *a_timeP = osi_Time();
835 * Stuff the appropriate data in there (assume victory)
841 * We're not keeping stats, so just return successfully with
844 a_dataP->AFSCB_CollData_len = 0;
845 a_dataP->AFSCB_CollData_val = NULL;
847 switch (a_collectionNumber) {
848 case AFSCB_XSTATSCOLL_CALL_INFO:
850 * Pass back all the call-count-related data.
852 * >>> We are forced to allocate a separate area in which to
853 * >>> put this stuff in by the RPC stub generator, since it
854 * >>> will be freed at the tail end of the server stub code.
856 dataBytes = sizeof(struct afs_CMStats);
857 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
858 osi_Assert(dataBuffP != NULL);
859 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
860 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
861 a_dataP->AFSCB_CollData_val = dataBuffP;
864 case AFSCB_XSTATSCOLL_PERF_INFO:
866 * Update and then pass back all the performance-related data.
867 * Note: the only performance fields that need to be computed
868 * at this time are the number of accesses for this collection
869 * and the current server record info.
871 * >>> We are forced to allocate a separate area in which to
872 * >>> put this stuff in by the RPC stub generator, since it
873 * >>> will be freed at the tail end of the server stub code.
875 afs_stats_cmperf.numPerfCalls++;
877 dataBytes = sizeof(afs_stats_cmperf);
878 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
879 osi_Assert(dataBuffP != NULL);
880 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
881 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
882 a_dataP->AFSCB_CollData_val = dataBuffP;
885 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
887 * Pass back the full range of performance and statistical
888 * data available. We have to bring the normal performance
889 * data collection up to date, then copy that data into
890 * the full collection.
892 * >>> We are forced to allocate a separate area in which to
893 * >>> put this stuff in by the RPC stub generator, since it
894 * >>> will be freed at the tail end of the server stub code.
896 afs_stats_cmperf.numPerfCalls++;
898 memcpy((char *)(&(afs_stats_cmfullperf.perf)),
899 (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
900 afs_stats_cmfullperf.numFullPerfCalls++;
902 dataBytes = sizeof(afs_stats_cmfullperf);
903 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
904 osi_Assert(dataBuffP != NULL);
905 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
906 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
907 a_dataP->AFSCB_CollData_val = dataBuffP;
912 * Illegal collection number.
914 a_dataP->AFSCB_CollData_len = 0;
915 a_dataP->AFSCB_CollData_val = NULL;
917 } /*Switch on collection number */
918 #endif /* AFS_NOSTATS */
926 } /*SRXAFSCB_GetXStats */
929 /*------------------------------------------------------------------------
930 * EXPORTED afs_RXCallBackServer
933 * Body of the thread supporting callback services.
942 * Nothing interesting.
946 *------------------------------------------------------------------------*/
949 afs_RXCallBackServer(void)
951 AFS_STATCNT(afs_RXCallBackServer);
956 afs_osi_Sleep(&afs_server);
960 * Donate this process to Rx.
967 } /*afs_RXCallBackServer */
970 /*------------------------------------------------------------------------
971 * EXPORTED shutdown_CB
974 * Zero out important Cache Manager data structures.
983 * Nothing interesting.
987 *------------------------------------------------------------------------*/
992 AFS_STATCNT(shutdown_CB);
994 if (afs_cold_shutdown) {
995 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps =
996 afs_evenZaps = afs_connectBacks = 0;
1003 /*------------------------------------------------------------------------
1004 * EXPORTED SRXAFSCB_InitCallBackState2
1007 * This routine was used in the AFS 3.5 beta release, but not anymore.
1008 * It has since been replaced by SRXAFSCB_InitCallBackState3.
1011 * a_call : Ptr to Rx call on which this request came in.
1014 * RXGEN_OPCODE (always).
1017 * Nothing interesting.
1021 *------------------------------------------------------------------------*/
1024 SRXAFSCB_InitCallBackState2(struct rx_call *a_call,
1025 struct interfaceAddr *addr)
1027 return RXGEN_OPCODE;
1030 /*------------------------------------------------------------------------
1031 * EXPORTED SRXAFSCB_WhoAreYou
1034 * Routine called by the server-side callback RPC interface to
1035 * obtain a unique identifier for the client. The server uses
1036 * this identifier to figure out whether or not two RX connections
1037 * are from the same client, and to find out which addresses go
1038 * with which clients.
1041 * a_call : Ptr to Rx call on which this request came in.
1042 * addr: Ptr to return the list of interfaces for this client.
1048 * Nothing interesting.
1052 *------------------------------------------------------------------------*/
1055 SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
1062 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1064 memset(addr, 0, sizeof(*addr));
1066 ObtainReadLock(&afs_xinterface);
1068 /* return all network interface addresses */
1069 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1070 addr->uuid = afs_cb_interface.uuid;
1071 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1072 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1073 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1074 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1077 ReleaseReadLock(&afs_xinterface);
1085 /*------------------------------------------------------------------------
1086 * EXPORTED SRXAFSCB_InitCallBackState3
1089 * Routine called by the server-side callback RPC interface to
1090 * implement clearing all callbacks from this host.
1093 * a_call : Ptr to Rx call on which this request came in.
1099 * Nothing interesting.
1103 *------------------------------------------------------------------------*/
1106 SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID * a_uuid)
1111 * TBD: Lookup the server by the UUID instead of its IP address.
1113 code = SRXAFSCB_InitCallBackState(a_call);
1119 /*------------------------------------------------------------------------
1120 * EXPORTED SRXAFSCB_ProbeUuid
1123 * Routine called by the server-side callback RPC interface to
1124 * implement ``probing'' the Cache Manager, just making sure it's
1125 * still there is still the same client it used to be.
1128 * a_call : Ptr to Rx call on which this request came in.
1129 * a_uuid : Ptr to UUID that must match the client's UUID.
1132 * 0 if a_uuid matches the UUID for this client
1133 * Non-zero otherwize
1136 * Nothing interesting.
1140 *------------------------------------------------------------------------*/
1143 SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID * a_uuid)
1149 AFS_STATCNT(SRXAFSCB_Probe);
1151 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1152 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1153 code = 1; /* failure */
1162 /*------------------------------------------------------------------------
1163 * EXPORTED SRXAFSCB_GetServerPrefs
1166 * Routine to list server preferences used by this client.
1169 * a_call : Ptr to Rx call on which this request came in.
1170 * a_index : Input server index
1171 * a_srvr_addr : Output server address in host byte order
1172 * (0xffffffff on last server)
1173 * a_srvr_rank : Output server rank
1179 * Nothing interesting.
1183 *------------------------------------------------------------------------*/
1186 SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1187 afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
1193 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1195 ObtainReadLock(&afs_xserver);
1197 /* Search the hash table for the server with this index */
1198 *a_srvr_addr = 0xffffffff;
1199 *a_srvr_rank = 0xffffffff;
1200 for (i = 0, j = 0; j < NSERVERS && i <= a_index; j++) {
1201 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1203 *a_srvr_addr = ntohl(sa->sa_ip);
1204 *a_srvr_rank = sa->sa_iprank;
1209 ReleaseReadLock(&afs_xserver);
1217 /*------------------------------------------------------------------------
1218 * EXPORTED SRXAFSCB_GetCellServDB
1221 * Routine to list cells configured for this client
1224 * a_call : Ptr to Rx call on which this request came in.
1225 * a_index : Input cell index
1226 * a_name : Output cell name ("" on last cell)
1227 * a_hosts : Output cell database servers in host byte order.
1233 * Nothing interesting.
1237 *------------------------------------------------------------------------*/
1240 SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1241 char **a_name, serverList * a_hosts)
1245 char *t_name, *p_name = NULL;
1248 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1250 tcell = afs_GetCellByIndex(a_index, READ_LOCK);
1254 a_hosts->serverList_val = 0;
1255 a_hosts->serverList_len = 0;
1257 p_name = tcell->cellName;
1258 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
1260 a_hosts->serverList_val = afs_osi_Alloc(j * sizeof(afs_int32));
1261 osi_Assert(a_hosts->serverList_val != NULL);
1262 a_hosts->serverList_len = j;
1263 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++)
1264 a_hosts->serverList_val[j] =
1265 ntohl(tcell->cellHosts[j]->addr->sa_ip);
1266 afs_PutCell(tcell, READ_LOCK);
1269 t_name = afs_osi_Alloc(i + 1);
1270 if (t_name == NULL) {
1272 afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
1279 memcpy(t_name, p_name, i);
1288 /*------------------------------------------------------------------------
1289 * EXPORTED SRXAFSCB_GetLocalCell
1292 * Routine to return name of client's local cell
1295 * a_call : Ptr to Rx call on which this request came in.
1296 * a_name : Output cell name
1302 * Nothing interesting.
1306 *------------------------------------------------------------------------*/
1309 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1313 char *t_name, *p_name = NULL;
1316 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1318 /* Search the list for the primary cell. Cell number 1 is only
1319 * the primary cell is when no other cell is explicitly marked as
1320 * the primary cell. */
1321 tcell = afs_GetPrimaryCell(READ_LOCK);
1323 p_name = tcell->cellName;
1325 plen = strlen(p_name);
1328 t_name = afs_osi_Alloc(plen + 1);
1329 if (t_name == NULL) {
1331 afs_PutCell(tcell, READ_LOCK);
1336 t_name[plen] = '\0';
1338 memcpy(t_name, p_name, plen);
1344 afs_PutCell(tcell, READ_LOCK);
1350 * afs_MarshallCacheConfig - marshall client cache configuration
1354 * IN callerVersion - the rpc stat version of the caller.
1356 * IN config - client cache configuration.
1358 * OUT ptr - buffer where configuration is marshalled.
1365 afs_MarshallCacheConfig(afs_uint32 callerVersion, cm_initparams_v1 * config,
1368 AFS_STATCNT(afs_MarshallCacheConfig);
1370 * We currently only support version 1.
1372 *(ptr++) = config->nChunkFiles;
1373 *(ptr++) = config->nStatCaches;
1374 *(ptr++) = config->nDataCaches;
1375 *(ptr++) = config->nVolumeCaches;
1376 *(ptr++) = config->firstChunkSize;
1377 *(ptr++) = config->otherChunkSize;
1378 *(ptr++) = config->cacheSize;
1379 *(ptr++) = config->setTime;
1380 *(ptr++) = config->memCache;
1384 /*------------------------------------------------------------------------
1385 * EXPORTED SRXAFSCB_GetCacheConfig
1388 * Routine to return parameters used to initialize client cache.
1389 * Client may request any format version. Server may not return
1390 * format version greater than version requested by client.
1393 * a_call: Ptr to Rx call on which this request came in.
1394 * callerVersion: Data format version desired by the client.
1395 * serverVersion: Data format version of output data.
1396 * configCount: Number bytes allocated for output data.
1397 * config: Client cache configuration.
1403 * Nothing interesting.
1407 *------------------------------------------------------------------------*/
1410 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1411 afs_uint32 * serverVersion, afs_uint32 * configCount,
1412 cacheConfig * config)
1414 afs_uint32 *t_config;
1416 cm_initparams_v1 cm_config;
1419 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1422 * Currently only support version 1
1424 allocsize = sizeof(cm_initparams_v1);
1425 t_config = afs_osi_Alloc(allocsize);
1426 if (t_config == NULL) {
1431 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1432 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1433 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1434 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1435 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1436 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1437 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1438 cm_config.setTime = cm_initParams.cmi_setTime;
1439 cm_config.memCache = cm_initParams.cmi_memCache;
1441 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1443 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1444 *configCount = allocsize;
1445 config->cacheConfig_val = t_config;
1446 config->cacheConfig_len = allocsize / sizeof(afs_uint32);
1453 /*------------------------------------------------------------------------
1454 * EXPORTED SRXAFSCB_GetCellByNum
1457 * Routine to get information about a cell specified by its
1458 * cell number (returned by GetCE/GetCE64).
1461 * a_call : Ptr to Rx call on which this request came in.
1462 * a_cellnum : Input cell number
1463 * a_name : Output cell name (one zero byte when no such cell).
1464 * a_hosts : Output cell database servers in host byte order.
1470 * Nothing interesting.
1474 *------------------------------------------------------------------------*/
1477 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
1478 char **a_name, serverList * a_hosts)
1484 AFS_STATCNT(SRXAFSCB_GetCellByNum);
1486 a_hosts->serverList_val = 0;
1487 a_hosts->serverList_len = 0;
1489 tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
1491 *a_name = afs_strdup("");
1496 ObtainReadLock(&tcell->lock);
1497 *a_name = afs_strdup(tcell->cellName);
1499 for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++);
1500 a_hosts->serverList_len = sn;
1501 a_hosts->serverList_val = afs_osi_Alloc(sn * sizeof(afs_int32));
1502 osi_Assert(a_hosts->serverList_val != NULL);
1504 for (i = 0; i < sn; i++)
1505 a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
1506 ReleaseReadLock(&tcell->lock);
1507 afs_PutCell(tcell, READ_LOCK);
1514 SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
1515 struct interfaceAddr *addr,
1516 Capabilities * capabilities)
1520 afs_uint32 *dataBuffP;
1521 afs_int32 dataBytes;
1525 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1527 ObtainReadLock(&afs_xinterface);
1529 /* return all network interface addresses */
1530 memset(addr, 0, sizeof(*addr));
1531 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1532 addr->uuid = afs_cb_interface.uuid;
1533 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1534 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1535 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1536 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1539 ReleaseReadLock(&afs_xinterface);
1543 dataBytes = 1 * sizeof(afs_uint32);
1544 dataBuffP = afs_osi_Alloc(dataBytes);
1545 osi_Assert(dataBuffP != NULL);
1546 dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS;
1547 capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32);
1548 capabilities->Capabilities_val = dataBuffP;