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);
53 /* drop the allocation reference */
54 lock_ObtainWrite(&cm_serverLock);
56 lock_ReleaseWrite(&cm_serverLock);
60 /* load up a cell structure from the cell database, afsdcell.ini */
61 cm_cell_t *cm_GetCell(char *namep, long flags)
63 return cm_GetCell_Gen(namep, NULL, flags);
66 cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
70 static cellCounter = 1; /* locked by cm_cellLock */
72 char fullname[200]="";
74 if (!strcmp(namep,SMB_IOCTL_FILENAME_NOSLASH))
77 lock_ObtainWrite(&cm_cellLock);
78 for (cp = cm_allCellsp; cp; cp=cp->nextp) {
79 if (strcmp(namep, cp->namep) == 0) {
80 strcpy(fullname, cp->namep);
85 if ((!cp && (flags & CM_FLAG_CREATE))
87 /* if it's from DNS, see if it has expired */
88 || (cp && (cp->flags & CM_CELLFLAG_DNS)
89 && ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout)))
94 cp = malloc(sizeof(cm_cell_t));
95 memset(cp, 0, sizeof(cm_cell_t));
99 /* must empty cp->vlServersp */
100 lock_ObtainWrite(&cp->mx);
101 cm_FreeServerList(&cp->vlServersp);
102 cp->vlServersp = NULL;
103 lock_ReleaseWrite(&cp->mx);
106 code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
108 osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellFile(%s) returns code= %d fullname= %s",
109 namep, code, fullname);
112 if (cm_dnsEnabled /*&& cm_DomainValid(namep)*/) {
113 code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, cp);
115 osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
116 namep, code, fullname);
118 cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
119 cp = NULL; /* set cp to NULL to indicate error */
123 else { /* got cell from DNS */
124 cp->flags |= CM_CELLFLAG_DNS;
125 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
126 cp->timeout = time(0) + ttl;
130 if (cp && code) { /* free newly allocated memory */
137 /* randomise among those vlservers having the same rank*/
138 cm_RandomizeServer(&cp->vlServersp);
142 /* we want to preserve the full name and mutex.
143 * also, cp is already in the cm_allCellsp list
147 #endif /* AFS_AFSDB_ENV */
149 /* otherwise we found the cell, and so we're nearly done */
150 lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
153 cp->namep = malloc(strlen(fullname)+1);
154 strcpy(cp->namep, fullname);
156 /* thread on global list */
157 cp->nextp = cm_allCellsp;
160 cp->cellID = cellCounter++;
164 /* fullname is not valid if cp == NULL */
166 strcpy(newnamep, fullname);
167 lock_ReleaseWrite(&cm_cellLock);
171 cm_cell_t *cm_FindCellByID(long cellID)
177 lock_ObtainWrite(&cm_cellLock);
178 for(cp = cm_allCellsp; cp; cp=cp->nextp) {
179 if (cellID == cp->cellID)
184 /* if it's from DNS, see if it has expired */
185 if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) &&
186 ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout))) {
187 /* must empty cp->vlServersp */
188 cm_FreeServerList(&cp->vlServersp);
189 cp->vlServersp = NULL;
191 code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp);
192 if (code == 0) { /* got cell from DNS */
193 cp->flags |= CM_CELLFLAG_DNS;
194 cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
196 fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl);
198 cp->timeout = time(0) + ttl;
200 cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
201 cp = NULL; /* return NULL to indicate failure */
203 /* if we fail to find it this time, we'll just do nothing and leave the
204 * current entry alone
207 #endif /* AFS_AFSDB_ENV */
209 lock_ReleaseWrite(&cm_cellLock);
213 void cm_InitCell(void)
215 static osi_once_t once;
217 if (osi_Once(&once)) {
218 lock_InitializeRWLock(&cm_cellLock, "cell global lock");
223 void cm_ChangeRankCellVLServer(cm_server_t *tsp)
228 cp = tsp->cellp; /* cell that this vlserver belongs to */
231 lock_ObtainMutex(&cp->mx);
232 code = cm_ChangeRankServer(&cp->vlServersp, tsp);
234 if ( !code ) /* if the server list was rearranged */
235 cm_RandomizeServer(&cp->vlServersp);
237 lock_ReleaseMutex(&cp->mx);