fc2f6632c0a973cb28c7cf2ee9dbb3eb7ad8ea41
[openafs.git] / src / WINNT / afsd / cm_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 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #include <windows.h>
14 #include <nb30.h>
15 #include <winsock2.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <malloc.h>
19 #include <osi.h>
20 #include <string.h>
21
22 #include "afsd.h"
23
24 osi_rwlock_t cm_cellLock;
25
26 cm_cell_t *cm_allCellsp;
27
28 /* function called as callback proc from cm_SearchCellFile.  Return 0 to
29  * continue processing.
30  */
31 long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *namep)
32 {
33         cm_server_t *tsp;
34         cm_serverRef_t *tsrp;
35         cm_cell_t *cellp;
36         
37         cellp = rockp;
38
39         /* if this server was previously created by fs setserverprefs */
40         if ( tsp = cm_FindServer(addrp, CM_SERVER_VLDB))
41         {
42                 if ( !tsp->cellp )
43                         tsp->cellp = cellp;
44         }
45         else
46                 tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp);
47
48         /* Insert the vlserver into a sorted list, sorted by server rank */
49         tsrp = cm_NewServerRef(tsp);
50         cm_InsertServerList(&cellp->vlServersp, tsrp);
51
52         return 0;
53 }
54
55 /* load up a cell structure from the cell database, afsdcell.ini */
56 cm_cell_t *cm_GetCell(char *namep, long flags)
57 {
58         cm_cell_t *cp;
59         long code;
60         static cellCounter = 1;         /* locked by cm_cellLock */
61
62         lock_ObtainWrite(&cm_cellLock);
63         for(cp = cm_allCellsp; cp; cp=cp->nextp) {
64                 if (strcmp(namep, cp->namep) == 0) break;
65         }
66         if (!cp && (flags & CM_FLAG_CREATE)) {
67                 cp = malloc(sizeof(*cp));
68                 memset(cp, 0, sizeof(*cp));
69                 code = cm_SearchCellFile(namep, NULL, cm_AddCellProc, cp);
70                 if (code) {
71                         free(cp);
72                         cp = NULL;
73                         goto done;
74                 }
75
76                 /* randomise among those vlservers having the same rank*/ 
77                 cm_RandomizeServer(&cp->vlServersp);
78
79                 /* otherwise we found the cell, and so we're nearly done */
80                 lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
81
82                 /* copy in name */
83                 cp->namep = malloc(strlen(namep)+1);
84                 strcpy(cp->namep, namep);
85
86                 /* thread on global list */
87                 cp->nextp = cm_allCellsp;
88                 cm_allCellsp = cp;
89                 
90                 cp->cellID = cellCounter++;
91         }
92
93 done:
94         lock_ReleaseWrite(&cm_cellLock);
95         return cp;
96 }
97
98 cm_cell_t *cm_FindCellByID(long cellID)
99 {
100         cm_cell_t *cp;
101
102         lock_ObtainWrite(&cm_cellLock);
103         for(cp = cm_allCellsp; cp; cp=cp->nextp) {
104                 if (cellID == cp->cellID) break;
105         }
106         lock_ReleaseWrite(&cm_cellLock);        
107         
108         return cp;
109 }
110
111 void cm_InitCell(void)
112 {
113         static osi_once_t once;
114         
115         if (osi_Once(&once)) {
116                 lock_InitializeRWLock(&cm_cellLock, "cell global lock");
117                 cm_allCellsp = NULL;
118                 osi_EndOnce(&once);
119         }
120 }
121 void cm_ChangeRankCellVLServer(cm_server_t       *tsp)
122 {
123         cm_cell_t *cp;
124         int code;
125
126         cp = tsp->cellp;        /* cell that this vlserver belongs to */
127         osi_assert(cp);
128
129         lock_ObtainMutex(&cp->mx);
130         code = cm_ChangeRankServer(&cp->vlServersp, tsp);
131
132         if ( !code )            /* if the server list was rearranged */
133             cm_RandomizeServer(&cp->vlServersp);
134
135         lock_ReleaseMutex(&cp->mx);
136 }
137