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
10 #include <afs/param.h>
26 osi_rwlock_t cm_cellLock;
28 cm_cell_t *cm_allCellsp;
30 /* function called as callback proc from cm_SearchCellFile. Return 0 to
31 * continue processing.
33 long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *namep)
41 /* if this server was previously created by fs setserverprefs */
42 if ( tsp = cm_FindServer(addrp, CM_SERVER_VLDB))
48 tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp);
50 /* Insert the vlserver into a sorted list, sorted by server rank */
51 tsrp = cm_NewServerRef(tsp);
52 cm_InsertServerList(&cellp->vlServersp, tsrp);
57 /* load up a cell structure from the cell database, afsdcell.ini */
58 cm_cell_t *cm_GetCell(char *namep, long flags)
60 return cm_GetCell_Gen(namep, NULL, flags);
63 cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
67 static cellCounter = 1; /* locked by cm_cellLock */
69 char fullname[200]="";
71 lock_ObtainWrite(&cm_cellLock);
72 for (cp = cm_allCellsp; cp; cp=cp->nextp) {
73 if (strcmp(namep, cp->namep) == 0) {
74 strcpy(fullname, cp->namep);
79 if ((!cp && (flags & CM_FLAG_CREATE))
81 /* if it's from DNS, see if it has expired */
82 || (cp && (cp->flags & CM_CELLFLAG_DNS)
83 && ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout)))
88 cp = malloc(sizeof(cm_cell_t));
89 memset(cp, 0, sizeof(cm_cell_t));
93 /* must empty cp->vlServersp */
94 cm_FreeServerList(&cp->vlServersp);
95 cp->vlServersp = NULL;
98 code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
100 afsi_log("in cm_GetCell_gen cm_SearchCellFile(%s) returns code= %d fullname= %s",
101 namep, code, fullname);
104 if (cm_dnsEnabled /*&& cm_DomainValid(namep)*/) {
105 code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, cp);
107 afsi_log("in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
108 namep, code, fullname);
110 cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
111 cp = NULL; /* set cp to NULL to indicate error */
115 else { /* got cell from DNS */
116 cp->flags |= CM_CELLFLAG_DNS;
117 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
118 cp->timeout = time(0) + ttl;
122 if (cp && code) { /* free newly allocated memory */
129 /* randomise among those vlservers having the same rank*/
130 cm_RandomizeServer(&cp->vlServersp);
134 /* we want to preserve the full name and mutex.
135 * also, cp is already in the cm_allCellsp list
139 #endif /* AFS_AFSDB_ENV */
141 /* otherwise we found the cell, and so we're nearly done */
142 lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
145 cp->namep = malloc(strlen(fullname)+1);
146 strcpy(cp->namep, fullname);
148 /* thread on global list */
149 cp->nextp = cm_allCellsp;
152 cp->cellID = cellCounter++;
156 /* fullname is not valid if cp == NULL */
158 strcpy(newnamep, fullname);
159 lock_ReleaseWrite(&cm_cellLock);
163 cm_cell_t *cm_FindCellByID(long cellID)
169 lock_ObtainWrite(&cm_cellLock);
170 for(cp = cm_allCellsp; cp; cp=cp->nextp) {
171 if (cellID == cp->cellID)
176 /* if it's from DNS, see if it has expired */
177 if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) &&
178 ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout))) {
179 /* must empty cp->vlServersp */
180 cm_FreeServerList(&cp->vlServersp);
181 cp->vlServersp = NULL;
183 code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp);
184 if (code == 0) { /* got cell from DNS */
185 cp->flags |= CM_CELLFLAG_DNS;
186 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
188 fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl);
190 cp->timeout = time(0) + ttl;
192 cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
193 cp = NULL; /* return NULL to indicate failure */
195 /* if we fail to find it this time, we'll just do nothing and leave the
196 * current entry alone
199 #endif /* AFS_AFSDB_ENV */
201 lock_ReleaseWrite(&cm_cellLock);
205 void cm_InitCell(void)
207 static osi_once_t once;
209 if (osi_Once(&once)) {
210 lock_InitializeRWLock(&cm_cellLock, "cell global lock");
215 void cm_ChangeRankCellVLServer(cm_server_t *tsp)
220 cp = tsp->cellp; /* cell that this vlserver belongs to */
223 lock_ObtainMutex(&cp->mx);
224 code = cm_ChangeRankServer(&cp->vlServersp, tsp);
226 if ( !code ) /* if the server list was rearranged */
227 cm_RandomizeServer(&cp->vlServersp);
229 lock_ReleaseMutex(&cp->mx);