Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / WINNT / afsd / cm_daemon.c
1 /* 
2  * Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
3  *
4  * (C) COPYRIGHT IBM CORPORATION 1987, 1988
5  * LICENSED MATERIALS - PROPERTY OF IBM
6  *
7  *
8  */
9
10 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #include <windows.h>
14 #include <winsock2.h>
15 #include <stdlib.h>
16 #include <malloc.h>
17 #include <string.h>
18
19 #include <rx/rx.h>
20
21 #include "afsd.h"
22
23 long cm_daemonCheckInterval = 30;
24 long cm_daemonTokenCheckInterval = 180;
25
26 osi_rwlock_t cm_daemonLock;
27
28 long cm_bkgQueueCount;          /* # of queued requests */
29
30 int cm_bkgWaitingForCount;      /* true if someone's waiting for cm_bkgQueueCount to drop */
31
32 cm_bkgRequest_t *cm_bkgListp;           /* first elt in the list of requests */
33 cm_bkgRequest_t *cm_bkgListEndp;        /* last elt in the list of requests */
34
35 void cm_BkgDaemon(long parm)
36 {
37         cm_bkgRequest_t *rp;
38
39         lock_ObtainWrite(&cm_daemonLock);
40         while(1) {
41                 if (!cm_bkgListEndp) {
42                         osi_SleepW((long) &cm_bkgListp, &cm_daemonLock);
43                         lock_ObtainWrite(&cm_daemonLock);
44                         continue;
45                 }
46                 
47                 /* we found a request */
48                 rp = cm_bkgListEndp;
49                 cm_bkgListEndp = (cm_bkgRequest_t *) osi_QPrev(&rp->q);
50                 osi_QRemove((osi_queue_t **) &cm_bkgListp, &rp->q);
51                 osi_assert(cm_bkgQueueCount-- > 0);
52                 lock_ReleaseWrite(&cm_daemonLock);
53                 
54                 (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp);
55                 
56                 cm_ReleaseUser(rp->userp);
57                 cm_ReleaseSCache(rp->scp);
58                 free(rp);
59
60                 lock_ObtainWrite(&cm_daemonLock);
61         }
62 }
63
64 void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, long p1, long p2, long p3, long p4,
65         cm_user_t *userp)
66 {
67         cm_bkgRequest_t *rp;
68         
69         rp = malloc(sizeof(*rp));
70         memset(rp, 0, sizeof(*rp));
71         
72         rp->scp = scp;
73         cm_HoldSCache(scp);
74         rp->userp = userp;
75         cm_HoldUser(userp);
76         rp->procp = procp;
77         rp->p1 = p1;
78         rp->p2 = p2;
79         rp->p3 = p3;
80         rp->p4 = p4;
81         
82         lock_ObtainWrite(&cm_daemonLock);
83         cm_bkgQueueCount++;
84         osi_QAdd((osi_queue_t **) &cm_bkgListp, &rp->q);
85         if (!cm_bkgListEndp) cm_bkgListEndp = rp;
86         lock_ReleaseWrite(&cm_daemonLock);
87         
88         osi_Wakeup((long) &cm_bkgListp);
89 }
90
91 /* periodic check daemon */
92 void cm_Daemon(long parm)
93 {
94         long now;
95         long lastLockCheck;
96         long lastVolCheck;
97         long lastCBExpirationCheck;
98         long lastDownServerCheck;
99         long lastUpServerCheck;
100         long lastTokenCacheCheck;
101         char thostName[200];
102         long code;
103         struct hostent *thp;
104
105         /* ping all file servers, up or down, with unauthenticated connection,
106          * to find out whether we have all our callbacks from the server still.
107          * Also, ping down VLDBs.
108          */
109         /*
110          * Seed the random number generator with our own address, so that
111          * clients starting at the same time don't all do vol checks at the
112          * same time.
113          */
114         gethostname(thostName, sizeof(thostName));
115         thp = gethostbyname(thostName);
116         memcpy(&code, thp->h_addr_list[0], 4);
117         srand(ntohl(code));
118
119         now = osi_Time();
120         lastVolCheck = now - 1800 + (rand() % 3600);
121         lastCBExpirationCheck = now - 60 + (rand() % 60);
122         lastLockCheck = now - 60 + (rand() % 60);
123         lastDownServerCheck = now - cm_daemonCheckInterval/2 + (rand() % cm_daemonCheckInterval);
124         lastUpServerCheck = now - 1800 + (rand() % 3600);
125         lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval);
126         
127         while (1) {
128                 Sleep(30 * 1000);               /* sleep 30 seconds */
129                 
130                 /* find out what time it is */
131                 now = osi_Time();
132
133                 /* check down servers */
134                 if (now > lastDownServerCheck + cm_daemonCheckInterval) {
135                         lastDownServerCheck = now;
136                         cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, NULL);
137                 }
138
139                 /* check up servers */
140                 if (now > lastUpServerCheck + 3600) {
141                         lastUpServerCheck = now;
142                         cm_CheckServers(CM_FLAG_CHECKUPSERVERS, NULL);
143                 }
144
145                 if (now > lastVolCheck + 3600) {
146                         lastVolCheck = now;
147                         cm_CheckVolumes();
148                 }
149                 
150                 if (now > lastCBExpirationCheck + 60) {
151                         lastCBExpirationCheck = now;
152                         cm_CheckCBExpiration();
153                 }
154                 
155                 if (now > lastLockCheck + 60) {
156                         lastLockCheck = now;
157                         cm_CheckLocks();
158                 }
159
160                 if (now > lastTokenCacheCheck + cm_daemonTokenCheckInterval) {
161                         lastTokenCacheCheck = now;
162                         cm_CheckTokenCache(now);
163                 }
164         }
165 }
166
167 void cm_InitDaemon(int nDaemons)
168 {
169         static osi_once_t once;
170         long pid;
171         HANDLE phandle;
172         int i;
173         
174         if (osi_Once(&once)) {
175                 lock_InitializeRWLock(&cm_daemonLock, "cm_daemonLock");
176                 osi_EndOnce(&once);
177                 
178                 /* creating pinging daemon */
179                 phandle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
180                         (LPTHREAD_START_ROUTINE) cm_Daemon, 0, 0, &pid);
181                 osi_assert(phandle != NULL);
182
183                 CloseHandle(phandle);
184                 for(i=0; i < nDaemons; i++) {
185                         phandle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
186                                 (LPTHREAD_START_ROUTINE) cm_BkgDaemon, 0, 0, &pid);
187                         osi_assert(phandle != NULL);
188                         CloseHandle(phandle);
189                 }
190         }
191 }