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(*cp));
89 memset(cp, 0, sizeof(*cp));
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 */
114 else { /* got cell from DNS */
115 cp->flags |= CM_CELLFLAG_DNS;
116 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
117 cp->timeout = time(0) + ttl;
121 if (cp && code) { /* free newly allocated memory */
128 /* randomise among those vlservers having the same rank*/
129 cm_RandomizeServer(&cp->vlServersp);
133 /* we want to preserve the full name and mutex.
134 * also, cp is already in the cm_allCellsp list
138 #endif /* AFS_AFSDB_ENV */
140 /* otherwise we found the cell, and so we're nearly done */
141 lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
144 cp->namep = malloc(strlen(fullname)+1);
145 strcpy(cp->namep, fullname);
147 /* thread on global list */
148 cp->nextp = cm_allCellsp;
151 cp->cellID = cellCounter++;
155 /* fullname is not valid if cp == NULL */
157 strcpy(newnamep, fullname);
158 lock_ReleaseWrite(&cm_cellLock);
162 cm_cell_t *cm_FindCellByID(long cellID)
168 lock_ObtainWrite(&cm_cellLock);
169 for(cp = cm_allCellsp; cp; cp=cp->nextp) {
170 if (cellID == cp->cellID)
175 /* if it's from DNS, see if it has expired */
176 if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) &&
177 ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout))) {
178 /* must empty cp->vlServersp */
179 cm_FreeServerList(&cp->vlServersp);
180 cp->vlServersp = NULL;
182 code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp);
183 if (code == 0) { /* got cell from DNS */
184 cp->flags |= CM_CELLFLAG_DNS;
185 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
187 fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl);
189 cp->timeout = time(0) + ttl;
191 cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
192 cp = NULL; /* return NULL to indicate failure */
194 /* if we fail to find it this time, we'll just do nothing and leave the
195 * current entry alone
198 #endif /* AFS_AFSDB_ENV */
200 lock_ReleaseWrite(&cm_cellLock);
204 void cm_InitCell(void)
206 static osi_once_t once;
208 if (osi_Once(&once)) {
209 lock_InitializeRWLock(&cm_cellLock, "cell global lock");
214 void cm_ChangeRankCellVLServer(cm_server_t *tsp)
219 cp = tsp->cellp; /* cell that this vlserver belongs to */
222 lock_ObtainMutex(&cp->mx);
223 code = cm_ChangeRankServer(&cp->vlServersp, tsp);
225 if ( !code ) /* if the server list was rearranged */
226 cm_RandomizeServer(&cp->vlServersp);
228 lock_ReleaseMutex(&cp->mx);