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>
38 /* Exported variables */
39 afs_rwlock_t afs_xcell; /* allocation lock for cells */
41 afs_int32 afs_cellindex=0;
44 /* Local variables. */
45 struct cell *afs_rootcell = 0;
47 struct cell *afs_GetCellByName(acellName, locktype)
48 register char *acellName;
51 register struct cell *tc;
52 register struct afs_q *cq, *tq;
54 AFS_STATCNT(afs_GetCellByName);
55 ObtainWriteLock(&afs_xcell,100);
56 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
57 tc = QTOC(cq); tq = QNext(cq);
58 if (!strcmp(tc->cellName, acellName)) {
60 QAdd(&CellLRU, &tc->lruq);
61 ReleaseWriteLock(&afs_xcell);
65 ReleaseWriteLock(&afs_xcell);
66 return (struct cell *) 0;
68 } /*afs_GetCellByName*/
71 struct cell *afs_GetCell(acell, locktype)
72 register afs_int32 acell;
75 register struct cell *tc;
76 register struct afs_q *cq, *tq;
78 AFS_STATCNT(afs_GetCell);
79 if (acell == 1 && afs_rootcell) return afs_rootcell;
80 ObtainWriteLock(&afs_xcell,101);
81 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
82 tc = QTOC(cq); tq = QNext(cq);
83 if (tc->cell == acell) {
85 QAdd(&CellLRU, &tc->lruq);
86 ReleaseWriteLock(&afs_xcell);
90 ReleaseWriteLock(&afs_xcell);
91 return (struct cell *) 0;
96 struct cell *afs_GetCellByIndex(cellindex, locktype)
97 register afs_int32 cellindex;
100 register struct cell *tc;
101 register struct afs_q *cq, *tq;
103 AFS_STATCNT(afs_GetCellByIndex);
104 ObtainWriteLock(&afs_xcell,102);
105 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
106 tc = QTOC(cq); tq = QNext(cq);
107 if (tc->cellIndex == cellindex) {
109 QAdd(&CellLRU, &tc->lruq);
110 ReleaseWriteLock(&afs_xcell);
114 ReleaseWriteLock(&afs_xcell);
115 return (struct cell *) 0;
117 } /*afs_GetCellByIndex*/
120 afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport)
123 register afs_int32 *acellHosts;
125 u_short fsport, vlport;
127 register struct cell *tc, *tcl=0;
128 register afs_int32 i, newc=0, code=0;
129 register struct afs_q *cq, *tq;
131 AFS_STATCNT(afs_NewCell);
132 if (*acellHosts == 0)
133 /* need >= one host to gen cell # */
136 ObtainWriteLock(&afs_xcell,103);
138 /* Find the cell and mark its servers as not down but gone */
139 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
140 tc = QTOC(cq); tq = QNext(cq);
141 if (strcmp(tc->cellName, acellName) == 0) {
142 /* we don't want to keep pinging old vlservers which were down,
143 * since they don't matter any more. It's easier to do this than
144 * to remove the server from its various hash tables. */
145 for (i=0; i<MAXCELLHOSTS; i++) {
146 if (!tc->cellHosts[i]) break;
147 tc->cellHosts[i]->flags &= ~SRVR_ISDOWN;
148 tc->cellHosts[i]->flags |= SRVR_ISGONE;
154 if (cq != &CellLRU) {
158 tc = (struct cell *) afs_osi_Alloc(sizeof(struct cell));
159 QAdd(&CellLRU, &tc->lruq); /* put in lruq */
160 tc->cellName = (char *) afs_osi_Alloc(strlen(acellName)+1);
161 strcpy(tc->cellName, acellName);
162 tc->cellIndex = afs_cellindex++;
163 if (aflags & CPrimary) {
164 extern int afs_rootCellIndex;
165 tc->cell = 1; /* primary cell is always 1 */
167 afs_rootCellIndex = tc->cellIndex;
169 tc->cell = *acellHosts; /* won't be reused by another cell */
172 tc->lcellp = (struct cell *)0;
173 tc->fsport = (fsport ? fsport : AFS_FSPORT);
174 tc->vlport = (vlport ? vlport : AFS_VLPORT);
175 afs_stats_cmperf.numCellsVisible++;
179 if (aflags & CLinkedCell) {
184 for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
185 tcl = QTOC(cq); tq = QNext(cq);
186 if (!strcmp(tcl->cellName, linkedcname)) {
195 if (tcl->lcellp) { /* XXX Overwriting if one existed before! XXX */
196 tcl->lcellp->lcellp = (struct cell *)0;
197 tcl->lcellp->states &= ~CLinkedCell;
202 tc->states |= aflags;
204 bzero((char *)tc->cellHosts, sizeof(tc->cellHosts));
205 for (i=0; i<MAXCELLHOSTS; i++) {
207 afs_uint32 temp = acellHosts[i];
209 ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, (afsUUID *)0, 0);
211 ts->flags &= ~SRVR_ISGONE;
212 tc->cellHosts[i] = ts;
213 afs_PutServer(ts, WRITE_LOCK);
215 afs_SortServers(tc->cellHosts, MAXCELLHOSTS); /* randomize servers */
216 ReleaseWriteLock(&afs_xcell);
221 afs_osi_Free(tc->cellName, strlen(tc->cellName)+1);
222 afs_osi_Free((char *)tc, sizeof(struct cell));
224 ReleaseWriteLock(&afs_xcell);
229 afs_RemoveCellEntry(struct server *srvp)
237 /* Remove the server structure from the cell list - if there */
238 ObtainWriteLock(&afs_xcell,200);
239 for (j=k=0; j<MAXCELLHOSTS; j++) {
240 if (!tc->cellHosts[j]) break;
241 if (tc->cellHosts[j] != srvp) {
242 tc->cellHosts[k++] = tc->cellHosts[j];
246 /* What do we do if we remove the last one? */
248 for (; k<MAXCELLHOSTS; k++) {
249 tc->cellHosts[k] = 0;
251 ReleaseWriteLock(&afs_xcell);