initial-solaris8-support-20001105
[openafs.git] / src / afs / afs_cell.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11  * Implements:
12  */
13 #include "../afs/param.h"       /* Should be always first */
14 #include "../afs/stds.h"
15 #include "../afs/sysincludes.h" /* Standard vendor system headers */
16
17 #if !defined(UKERNEL)
18 #include <net/if.h>
19 #include <netinet/in.h>
20
21 #ifdef AFS_SGI62_ENV
22 #include "../h/hashing.h"
23 #endif
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) */
28
29 #include "../afs/afsincludes.h" /* Afs-based standard headers */
30 #include "../afs/afs_stats.h"   /* afs statistics */
31
32 #if     defined(AFS_SUN56_ENV)
33 #include <inet/led.h>
34 #include <inet/common.h>
35 #if     defined(AFS_SUN58_ENV)
36 #include <netinet/ip6.h>
37 #endif
38 #include <inet/ip.h>
39 #endif
40
41 /* Exported variables */
42 afs_rwlock_t afs_xcell;                 /* allocation lock for cells */
43 struct afs_q CellLRU;
44 afs_int32 afs_cellindex=0;
45
46
47 /* Local variables. */
48 struct cell *afs_rootcell = 0;
49
50 struct cell *afs_GetCellByName(acellName, locktype)
51     register char *acellName;
52     afs_int32 locktype;
53 {
54     register struct cell *tc;
55     register struct afs_q *cq, *tq;
56
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)) {
62             QRemove(&tc->lruq);
63             QAdd(&CellLRU, &tc->lruq);
64             ReleaseWriteLock(&afs_xcell);
65             return tc;
66         }
67     }
68     ReleaseWriteLock(&afs_xcell);
69     return (struct cell *) 0;
70
71 } /*afs_GetCellByName*/
72
73
74 struct cell *afs_GetCell(acell, locktype)
75     register afs_int32 acell;
76     afs_int32 locktype;
77 {
78     register struct cell *tc;
79     register struct afs_q *cq, *tq;
80
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) {
87             QRemove(&tc->lruq);
88             QAdd(&CellLRU, &tc->lruq);
89             ReleaseWriteLock(&afs_xcell);
90             return tc;
91         }
92     }
93     ReleaseWriteLock(&afs_xcell);
94     return (struct cell *) 0;
95
96 } /*afs_GetCell*/
97
98
99 struct cell *afs_GetCellByIndex(cellindex, locktype)
100     register afs_int32 cellindex;
101     afs_int32 locktype;
102 {
103     register struct cell *tc;
104     register struct afs_q *cq, *tq;
105
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) {
111             QRemove(&tc->lruq);
112             QAdd(&CellLRU, &tc->lruq);
113             ReleaseWriteLock(&afs_xcell);
114             return tc;
115         }
116     }
117     ReleaseWriteLock(&afs_xcell);
118     return (struct cell *) 0;
119
120 } /*afs_GetCellByIndex*/
121
122
123 afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport)
124     int aflags;
125     char *acellName;
126     register afs_int32 *acellHosts;
127     char *linkedcname;
128     u_short fsport, vlport;
129 {
130     register struct cell *tc, *tcl=0;
131     register afs_int32 i, newc=0, code=0;
132     register struct afs_q *cq, *tq;
133
134     AFS_STATCNT(afs_NewCell);
135     if (*acellHosts == 0)
136         /* need >= one host to gen cell # */
137         return EINVAL;
138
139     ObtainWriteLock(&afs_xcell,103);
140
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;
152             }
153             break;
154         }
155     }
156
157     if (cq != &CellLRU) {
158         aflags &= ~CNoSUID;
159     }
160     else {
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 */
169             afs_rootcell = tc;
170             afs_rootCellIndex = tc->cellIndex;
171         } else {
172             tc->cell = *acellHosts; /* won't be reused by another cell */
173         }
174         tc->states = 0;
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++;
179         newc++;
180     }
181
182     if (aflags & CLinkedCell) {
183         if (!linkedcname) {
184             code = EINVAL;
185             goto bad;
186         }
187         for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
188             tcl = QTOC(cq); tq = QNext(cq);
189             if (!strcmp(tcl->cellName, linkedcname)) {
190                 break;
191             }
192             tcl = 0;
193         }
194         if (!tcl) {
195             code = ENOENT;
196             goto bad;
197         }
198         if (tcl->lcellp) {      /* XXX Overwriting if one existed before! XXX */
199             tcl->lcellp->lcellp = (struct cell *)0;
200             tcl->lcellp->states &= ~CLinkedCell;
201         }
202         tc->lcellp = tcl;
203         tcl->lcellp = tc;
204     }
205     tc->states |= aflags;
206  
207     bzero((char *)tc->cellHosts, sizeof(tc->cellHosts));
208     for (i=0; i<MAXCELLHOSTS; i++) {
209         struct server *ts;
210         afs_uint32 temp = acellHosts[i];
211         if (!temp) break;
212         ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, (afsUUID *)0, 0);
213         ts->cell = tc;
214         ts->flags &= ~SRVR_ISGONE;
215         tc->cellHosts[i] = ts;
216         afs_PutServer(ts, WRITE_LOCK);
217     }
218     afs_SortServers(tc->cellHosts, MAXCELLHOSTS);       /* randomize servers */
219     ReleaseWriteLock(&afs_xcell);
220     return 0;
221 bad:
222     if (newc) {
223         QRemove(&tc->lruq);
224         afs_osi_Free(tc->cellName, strlen(tc->cellName)+1);
225         afs_osi_Free((char *)tc, sizeof(struct cell));
226     }
227     ReleaseWriteLock(&afs_xcell);
228     return code;
229
230 } /*afs_NewCell*/
231
232 afs_RemoveCellEntry(struct server *srvp)
233 {
234   struct cell *tc;
235   afs_int32 j, k;
236
237   tc = srvp->cell;
238   if (!tc) return;
239
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];
246      }
247   }
248   if (k == 0) {
249      /* What do we do if we remove the last one? */
250   }
251   for (; k<MAXCELLHOSTS; k++) {
252      tc->cellHosts[k] = 0;
253   }
254   ReleaseWriteLock(&afs_xcell);
255 }
256