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 if (!strcmp(namep,SMB_IOCTL_FILENAME_NOSLASH))
74 lock_ObtainWrite(&cm_cellLock);
75 for (cp = cm_allCellsp; cp; cp=cp->nextp) {
76 if (strcmp(namep, cp->namep) == 0) {
77 strcpy(fullname, cp->namep);
82 if ((!cp && (flags & CM_FLAG_CREATE))
84 /* if it's from DNS, see if it has expired */
85 || (cp && (cp->flags & CM_CELLFLAG_DNS)
86 && ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout)))
91 cp = malloc(sizeof(cm_cell_t));
92 memset(cp, 0, sizeof(cm_cell_t));
96 /* must empty cp->vlServersp */
97 cm_FreeServerList(&cp->vlServersp);
98 cp->vlServersp = NULL;
101 code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
103 afsi_log("in cm_GetCell_gen cm_SearchCellFile(%s) returns code= %d fullname= %s",
104 namep, code, fullname);
107 if (cm_dnsEnabled /*&& cm_DomainValid(namep)*/) {
108 code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, cp);
110 afsi_log("in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
111 namep, code, fullname);
113 cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
114 cp = NULL; /* set cp to NULL to indicate error */
118 else { /* got cell from DNS */
119 cp->flags |= CM_CELLFLAG_DNS;
120 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
121 cp->timeout = time(0) + ttl;
125 if (cp && code) { /* free newly allocated memory */
132 /* randomise among those vlservers having the same rank*/
133 cm_RandomizeServer(&cp->vlServersp);
137 /* we want to preserve the full name and mutex.
138 * also, cp is already in the cm_allCellsp list
142 #endif /* AFS_AFSDB_ENV */
144 /* otherwise we found the cell, and so we're nearly done */
145 lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
148 cp->namep = malloc(strlen(fullname)+1);
149 strcpy(cp->namep, fullname);
151 /* thread on global list */
152 cp->nextp = cm_allCellsp;
155 cp->cellID = cellCounter++;
159 /* fullname is not valid if cp == NULL */
161 strcpy(newnamep, fullname);
162 lock_ReleaseWrite(&cm_cellLock);
166 cm_cell_t *cm_FindCellByID(long cellID)
172 lock_ObtainWrite(&cm_cellLock);
173 for(cp = cm_allCellsp; cp; cp=cp->nextp) {
174 if (cellID == cp->cellID)
179 /* if it's from DNS, see if it has expired */
180 if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) &&
181 ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout))) {
182 /* must empty cp->vlServersp */
183 cm_FreeServerList(&cp->vlServersp);
184 cp->vlServersp = NULL;
186 code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp);
187 if (code == 0) { /* got cell from DNS */
188 cp->flags |= CM_CELLFLAG_DNS;
189 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
191 fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl);
193 cp->timeout = time(0) + ttl;
195 cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
196 cp = NULL; /* return NULL to indicate failure */
198 /* if we fail to find it this time, we'll just do nothing and leave the
199 * current entry alone
202 #endif /* AFS_AFSDB_ENV */
204 lock_ReleaseWrite(&cm_cellLock);
208 void cm_InitCell(void)
210 static osi_once_t once;
212 if (osi_Once(&once)) {
213 lock_InitializeRWLock(&cm_cellLock, "cell global lock");
218 void cm_ChangeRankCellVLServer(cm_server_t *tsp)
223 cp = tsp->cellp; /* cell that this vlserver belongs to */
226 lock_ObtainMutex(&cp->mx);
227 code = cm_ChangeRankServer(&cp->vlServersp, tsp);
229 if ( !code ) /* if the server list was rearranged */
230 cm_RandomizeServer(&cp->vlServersp);
232 lock_ReleaseMutex(&cp->mx);