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
13 #include "../afs/param.h" /* Should be always first */
14 #include "../afs/stds.h"
15 #include "../afs/sysincludes.h" /* Standard vendor system headers */
19 #include <netinet/in.h>
22 #include "../h/hashing.h"
24 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV)
25 #include <netinet/in_var.h>
26 #endif /* ! ASF_HPUX110_ENV */
27 #endif /* !defined(UKERNEL) */
29 #include "../afs/afsincludes.h" /* Afs-based standard headers */
30 #include "../afs/afs_stats.h" /* afs statistics */
32 #if defined(AFS_SUN56_ENV)
34 #include <inet/common.h>
35 #if defined(AFS_SUN58_ENV)
36 #include <netinet/ip6.h>
41 /* Exported variables */
42 afs_rwlock_t afs_xcell; /* allocation lock for cells */
44 afs_int32 afs_cellindex=0;
47 /* Local variables. */
48 struct cell *afs_rootcell = 0;
50 struct cell *afs_GetCellByName(acellName, locktype)
51 register char *acellName;
54 register struct cell *tc;
55 register struct afs_q *cq, *tq;
57 AFS_STATCNT(afs_GetCellByName);
58 ObtainWriteLock(&afs_xcell,100);
59 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
60 tc = QTOC(cq); tq = QNext(cq);
61 if (!strcmp(tc->cellName, acellName)) {
63 QAdd(&CellLRU, &tc->lruq);
64 ReleaseWriteLock(&afs_xcell);
68 ReleaseWriteLock(&afs_xcell);
69 return (struct cell *) 0;
71 } /*afs_GetCellByName*/
74 struct cell *afs_GetCell(acell, locktype)
75 register afs_int32 acell;
78 register struct cell *tc;
79 register struct afs_q *cq, *tq;
81 AFS_STATCNT(afs_GetCell);
82 if (acell == 1 && afs_rootcell) return afs_rootcell;
83 ObtainWriteLock(&afs_xcell,101);
84 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
85 tc = QTOC(cq); tq = QNext(cq);
86 if (tc->cell == acell) {
88 QAdd(&CellLRU, &tc->lruq);
89 ReleaseWriteLock(&afs_xcell);
93 ReleaseWriteLock(&afs_xcell);
94 return (struct cell *) 0;
99 struct cell *afs_GetCellByIndex(cellindex, locktype)
100 register afs_int32 cellindex;
103 register struct cell *tc;
104 register struct afs_q *cq, *tq;
106 AFS_STATCNT(afs_GetCellByIndex);
107 ObtainWriteLock(&afs_xcell,102);
108 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
109 tc = QTOC(cq); tq = QNext(cq);
110 if (tc->cellIndex == cellindex) {
112 QAdd(&CellLRU, &tc->lruq);
113 ReleaseWriteLock(&afs_xcell);
117 ReleaseWriteLock(&afs_xcell);
118 return (struct cell *) 0;
120 } /*afs_GetCellByIndex*/
123 afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport)
126 register afs_int32 *acellHosts;
128 u_short fsport, vlport;
130 register struct cell *tc, *tcl=0;
131 register afs_int32 i, newc=0, code=0;
132 register struct afs_q *cq, *tq;
134 AFS_STATCNT(afs_NewCell);
135 if (*acellHosts == 0)
136 /* need >= one host to gen cell # */
139 ObtainWriteLock(&afs_xcell,103);
141 /* Find the cell and mark its servers as not down but gone */
142 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
143 tc = QTOC(cq); tq = QNext(cq);
144 if (strcmp(tc->cellName, acellName) == 0) {
145 /* we don't want to keep pinging old vlservers which were down,
146 * since they don't matter any more. It's easier to do this than
147 * to remove the server from its various hash tables. */
148 for (i=0; i<MAXCELLHOSTS; i++) {
149 if (!tc->cellHosts[i]) break;
150 tc->cellHosts[i]->flags &= ~SRVR_ISDOWN;
151 tc->cellHosts[i]->flags |= SRVR_ISGONE;
157 if (cq != &CellLRU) {
161 tc = (struct cell *) afs_osi_Alloc(sizeof(struct cell));
162 QAdd(&CellLRU, &tc->lruq); /* put in lruq */
163 tc->cellName = (char *) afs_osi_Alloc(strlen(acellName)+1);
164 strcpy(tc->cellName, acellName);
165 tc->cellIndex = afs_cellindex++;
166 if (aflags & CPrimary) {
167 extern int afs_rootCellIndex;
168 tc->cell = 1; /* primary cell is always 1 */
170 afs_rootCellIndex = tc->cellIndex;
172 tc->cell = *acellHosts; /* won't be reused by another cell */
175 tc->lcellp = (struct cell *)0;
176 tc->fsport = (fsport ? fsport : AFS_FSPORT);
177 tc->vlport = (vlport ? vlport : AFS_VLPORT);
178 afs_stats_cmperf.numCellsVisible++;
182 if (aflags & CLinkedCell) {
187 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
188 tcl = QTOC(cq); tq = QNext(cq);
189 if (!strcmp(tcl->cellName, linkedcname)) {
198 if (tcl->lcellp) { /* XXX Overwriting if one existed before! XXX */
199 tcl->lcellp->lcellp = (struct cell *)0;
200 tcl->lcellp->states &= ~CLinkedCell;
205 tc->states |= aflags;
207 bzero((char *)tc->cellHosts, sizeof(tc->cellHosts));
208 for (i=0; i<MAXCELLHOSTS; i++) {
210 afs_uint32 temp = acellHosts[i];
212 ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, (afsUUID *)0, 0);
214 ts->flags &= ~SRVR_ISGONE;
215 tc->cellHosts[i] = ts;
216 afs_PutServer(ts, WRITE_LOCK);
218 afs_SortServers(tc->cellHosts, MAXCELLHOSTS); /* randomize servers */
219 ReleaseWriteLock(&afs_xcell);
224 afs_osi_Free(tc->cellName, strlen(tc->cellName)+1);
225 afs_osi_Free((char *)tc, sizeof(struct cell));
227 ReleaseWriteLock(&afs_xcell);
232 afs_RemoveCellEntry(struct server *srvp)
240 /* Remove the server structure from the cell list - if there */
241 ObtainWriteLock(&afs_xcell,200);
242 for (j=k=0; j<MAXCELLHOSTS; j++) {
243 if (!tc->cellHosts[j]) break;
244 if (tc->cellHosts[j] != srvp) {
245 tc->cellHosts[k++] = tc->cellHosts[j];
249 /* What do we do if we remove the last one? */
251 for (; k<MAXCELLHOSTS; k++) {
252 tc->cellHosts[k] = 0;
254 ReleaseWriteLock(&afs_xcell);