windows-build-updates-20030314
[openafs.git] / src / WINNT / afssvrcfg / get_cur_config.cpp
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 /*
11  * INCLUDES _________________________________________________________________
12  *
13  */
14 extern "C" {
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 }
18
19 #include "afscfg.h"
20 #include "partition_utils.h"
21 #include "resource.h"
22
23 extern "C" {
24 #include "afs_vosAdmin.h"
25 #include "afs\vlserver.h"
26 }
27
28
29 /*
30  * DEFINITIONS _________________________________________________________________
31  *
32  */
33 static LPPROGRESSDISPLAY pProg;
34 static const int MAX_STEPS = 10;
35 static BOOL bCancel;
36 static BOOL bBakConfigured;
37 static vos_vldbEntry_t vldbRootAfsEntry;
38 static vos_vldbEntry_t vldbRootCellEntry;
39
40
41 /*
42  * PROTOTYPES _________________________________________________________________
43  *
44  */
45 BOOL CALLBACK GetCurConfigDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
46 static DWORD CALLBACK GetCurrentConfigState(LPPROGRESSDISPLAY ppd, LPARAM lp);
47 static void SetConfigDefaults();
48 static void ShowMsg(UINT uiMsgID);
49 static void NextStep(UINT uiMsgID);
50
51
52 /*
53  * EXPORTED FUNCTIONS _________________________________________________________________
54  *
55  */
56 int GetCurrentConfig(HWND hParent, BOOL& bCanceled)
57 {
58         pProg = 0;
59         bCancel = FALSE;
60         bBakConfigured = FALSE;
61
62         pProg = new PROGRESSDISPLAY(hParent, IDD_GET_CURRENT_CONFIG, (DLGPROC)GetCurConfigDlgProc);
63         pProg->SetProgressRange(0, MAX_STEPS);
64
65         HWND hLogo = GetDlgItem(pProg->GetWindow(), IDC_LOGO);
66         AfsAppLib_StartAnimation(hLogo);
67
68         pProg->Show(GetCurrentConfigState, 0);
69
70         AfsAppLib_StopAnimation(hLogo);
71
72         int dwResult = pProg->GetStatus();
73
74         pProg->Close();
75
76         bCanceled = bCancel;
77
78         return dwResult;
79 }
80
81
82 /*
83  * STATIC FUNCTIONS _________________________________________________________________
84  *
85  */
86
87
88 /*
89  * Dialog Proc _________________________________________________________________
90  *
91  */
92 static BOOL CALLBACK GetCurConfigDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp)
93 {
94         BOOL bOn = FALSE;
95         
96         switch (msg) {
97                 case WM_INITDIALOG:
98                         bCancel = FALSE;
99                         break;
100
101                 case WM_COMMAND:
102                         switch (LOWORD(wp))
103                         {
104                                 case IDCANCEL:  if (QueryCancelWiz()) {
105                                                                         bCancel = TRUE;
106                                                                         ShowMsg(IDS_CANCEL_GET_CONFIG);
107                                                                 }
108                                                                 break;
109                         }
110                 break;
111         }
112
113         return FALSE;
114 }
115
116 static BOOL IsClientConfigured(BOOL& bConfigured, afs_status_t& nStatus)
117 {
118         if (bCancel)
119                 return FALSE;
120
121         bConfigured = FALSE;
122
123         NextStep(IDS_CHECK_AFS_CLIENT);
124
125         short isInstalled;
126         afs_status_t configStatus;
127         char *pszCellName = 0;
128
129         g_LogFile.Write("Is the AFS Client installed on this machine: ");
130         if (!cfg_ClientQueryStatus(GetHostnameA(), &isInstalled, &g_CfgData.nClientVersion, &configStatus, &pszCellName, &nStatus)) {
131                 ImmediateErrorDialog(nStatus, IDS_ERROR_AFS_CLIENT_CHECK);
132                 return FALSE;
133         }
134
135         g_LogFile.WriteBoolResult((BOOL)isInstalled);
136
137         bConfigured = (BOOL)(configStatus == 0);
138         if (bConfigured)
139                 lstrncpy(g_CfgData.szClientCellName, A2S(pszCellName), MAX_CELL_NAME_LEN);
140         else
141                 g_LogFile.WriteError("The client configuration information on this host is not valid", configStatus);
142
143         if (!isInstalled) {
144                 g_LogFile.Write("ERROR:  AFS Client is not installed.  The AFS Server requires the AFS Client.\r\n");
145                 ImmediateErrorDialog(0, IDS_ERROR_AFS_CLIENT_NOT_INSTALLED);
146                 nStatus = -1;   // Just need something nonzero
147                 return FALSE;
148         }
149
150         return TRUE;
151 }
152
153 /*
154  *      NOTE:   This function has an important side effect.  If this machine
155  *                      is not the first in a new cell, then this function will get the
156  *                      cell name from the config info.  The cell name may be needed in 
157  *                      config calls that come later, and so this function must be called
158  *                      before they are.
159  */
160 static int IsConfigInfoValid(BOOL& bValid, afs_status_t& nStatus)
161 {
162         if (bCancel)
163                 return FALSE;
164         
165         afs_status_t configStatus;
166         char *pszCellName = 0;
167
168         NextStep(IDS_CHECK_CONFIG_INFO);
169
170         bValid = FALSE;
171
172         g_LogFile.Write("Is there valid configuration information on this machine: ");
173         int nResult = cfg_HostQueryStatus(GetHostnameA(), &configStatus, &pszCellName, &nStatus);
174         if (!nResult)
175                 return FALSE;
176
177         g_LogFile.WriteBoolResult((configStatus == 0));
178
179         if (configStatus == 0)
180                 lstrncpy(g_CfgData.szCellName, A2S(pszCellName), MAX_CELL_NAME_LEN);
181         else
182                 g_LogFile.WriteError("The configuration information on this host is not valid", configStatus);
183
184         bValid = (BOOL)(configStatus == 0);
185
186         return TRUE;
187 }
188
189 static int StartBosServer(afs_status_t& nStatus)
190 {
191         short isStarted;
192         short isBosProc;
193
194         g_LogFile.Write("Checking if bos server is running.\r\n");
195         int nResult = cfg_BosServerQueryStatus(g_hServer, &isStarted, &isBosProc, &nStatus);
196         if (!nResult)
197                 return nResult;
198
199         if (!isStarted) {
200                 g_LogFile.Write("Starting the bos server in %s mode.\r\n", g_CfgData.bValidServerInfo ? "auth" : "no auth");
201                 nResult = cfg_BosServerStart(g_hServer, !g_CfgData.bValidServerInfo, BOSSERVER_START_TIMEOUT, &nStatus);
202         }
203
204         return nResult;
205 }
206
207 static BOOL AreWeLastDBServer(BOOL& bLast, afs_status_t& nStatus)
208 {
209         ASSERT(g_CfgData.szHostname[0]);
210
211         char *pszCellname = 0;
212         char *pszCellServDB = 0;
213
214         bLast = FALSE;
215
216         g_LogFile.Write("Checking if this machine is the last DB server in the cell.\r\n");
217
218         g_LogFile.Write("Getting CellServDB from host %s.\r\n", GetHostnameA());
219         int nResult = cfg_CellServDbEnumerate(GetHostnameA(), &pszCellname, &pszCellServDB, &nStatus);
220         if (!nResult)
221                 return FALSE;   
222
223         if (!pszCellServDB) {
224                 g_LogFile.Write("There are no DB servers in CellServDB!!!!!");
225                 ASSERT(FALSE);          // This should not be possible
226                 return FALSE;
227         }
228
229         char *psz = pszCellServDB;
230
231         for (int i = 0; *psz; psz += strlen(psz) + 1)
232                 i++;
233
234         if (i == 1) {
235                 ASSERT(lstrcmp(g_CfgData.szHostname, A2S(pszCellServDB)) == 0);
236                 g_LogFile.Write("This machine IS the last DB server in the cell.\r\n");
237                 bLast = TRUE;
238         } else
239                 g_LogFile.Write("This machine is NOT the last DB server in the cell.\r\n");
240
241         return TRUE;
242 }
243
244 static afs_status_t IsFSConfigured(BOOL& bConfigured)
245 {
246         g_LogFile.Write("Is this machine a file server: ");
247         
248         bConfigured = FALSE;
249
250         short isStarted;
251         afs_status_t nStatus;
252
253         int nResult = cfg_FileServerQueryStatus(g_hServer, &isStarted, &nStatus);
254         if (!nResult)
255                 return nStatus;
256
257         bConfigured = isStarted;        
258         
259         g_LogFile.WriteBoolResult(bConfigured);
260
261         return 0;
262 }
263
264 static afs_status_t IsDBConfigured(BOOL& bConfigured)
265 {
266         g_LogFile.Write("Is this machine a db (or bak) server: ");
267
268         bConfigured = FALSE;
269
270         short isStarted, isBakStarted;
271         afs_status_t nStatus;
272
273         int nResult = cfg_DbServersQueryStatus(g_hServer, &isStarted, &isBakStarted, 0, &nStatus);
274         if (!nResult)
275                 return nStatus;
276
277         bConfigured = isStarted;
278         bBakConfigured = isBakStarted;
279
280         g_LogFile.Write(bConfigured ? "Yes DB" : "No DB");
281         g_LogFile.Write(", %s.\r\n", bBakConfigured ? "Yes Bak" : "No Bak");
282
283         return 0;
284 }
285
286 static afs_status_t IsBakConfigured(BOOL& bConfigured)
287 {
288         bConfigured = bBakConfigured;
289         
290         return 0;
291 }
292
293 static afs_status_t DoesAPartitionExist(BOOL& bExists)
294 {
295         g_LogFile.Write("Does a partition exist on this machine: ");
296
297         bExists = FALSE;
298
299         afs_status_t nStatus;
300
301         int nResult = ReadPartitionTable(&nStatus);
302         if (!nResult)
303                 return nStatus;
304
305         int nNumPartitions = 0;
306
307         cfg_partitionEntry_t *pTable = GetPartitionTable(nNumPartitions);
308
309         bExists = nNumPartitions > 0;
310         if (bExists) {
311                 g_CfgData.chDeviceName = pTable->deviceName[0];
312                 lstrcpy(g_CfgData.szPartitionName, ((TCHAR *)A2S(pTable->partitionName)) + lstrlen(TEXT("/vicep")));
313         }
314
315         g_LogFile.WriteBoolResult(bExists);
316
317         return 0;
318 }
319
320 afs_status_t DoRootVolumesExist(BOOL& bExists)
321 {
322         bExists = FALSE;
323
324         afs_status_t nStatus;
325
326         g_LogFile.Write("Do the root volumes exist: ");
327
328         // Does root.afs exist?  If it does not, the call will fail with the VL_NOENT
329         // status.  Any other error causes this function to fail.
330         int nResult = vos_VLDBGet(g_hCell, 0, 0, "root.afs", &vldbRootAfsEntry, &nStatus);
331         if (nResult) {
332                 g_CfgData.bRootAfsExists = TRUE;
333         g_CfgData.nRootAfsID = vldbRootAfsEntry.volumeId[0];
334         } else if (nStatus != VL_NOENT)
335                 return nStatus;
336
337         // Does root.cell exist?
338         nResult = vos_VLDBGet(g_hCell, 0, 0, "root.cell", &vldbRootCellEntry, &nStatus);
339         if (nResult) {
340                 g_CfgData.bRootCellExists = TRUE;
341         g_CfgData.nRootCellID = vldbRootCellEntry.volumeId[0];
342         } else if (nStatus != VL_NOENT)
343                 return nStatus;
344
345         bExists = g_CfgData.bRootAfsExists && g_CfgData.bRootCellExists;
346
347         g_LogFile.WriteBoolResult(bExists);
348
349         return 0;
350 }
351
352 static BOOL IsVolumeReplicated(vos_vldbEntry_t& vldbEntry)
353 {
354         if (vldbEntry.numServers <= 1)
355                 return FALSE;
356
357         for (int i = 0; i < vldbEntry.numServers; i++) {
358                 if ((vldbEntry.volumeSites[i].serverFlags & VOS_VLDB_READ_ONLY) ||
359                         (vldbEntry.volumeSites[i].serverFlags & VOS_VLDB_NEW_REPSITE))
360                                 return TRUE;
361         }
362
363         return FALSE;
364 }
365
366 afs_status_t AreRootVolumesReplicated(BOOL& bReplicated)
367 {
368         g_LogFile.Write("Are the root volumes replicated: ");
369
370         // Is root.afs replicated?
371         g_CfgData.bRootAfsReplicated = IsVolumeReplicated(vldbRootAfsEntry);
372
373         // Is root.cell replicated?
374         g_CfgData.bRootCellReplicated = IsVolumeReplicated(vldbRootCellEntry);
375
376         bReplicated = g_CfgData.bRootAfsReplicated && g_CfgData.bRootCellReplicated;
377
378         g_LogFile.WriteBoolResult(bReplicated);
379
380         return 0;
381 }
382
383 static afs_status_t IsSCSConfigured(BOOL& bConfigured)
384 {
385         g_LogFile.Write("Is this machine a System Control Server: ");
386         
387         bConfigured = FALSE;
388
389         short isUpserver, isSC, isBin;
390         afs_status_t nStatus;
391
392         int nResult = cfg_UpdateServerQueryStatus(g_hServer, &isUpserver, &isSC, &isBin, &nStatus);
393         if (!nResult)
394                 return nStatus;
395
396         bConfigured = isUpserver && isSC;
397
398         g_LogFile.WriteBoolResult(bConfigured);
399
400         return 0;
401 }
402
403 static afs_status_t IsSCCConfigured(BOOL& bConfigured)
404 {
405         g_LogFile.Write("Is this machine a System Control Client: ");
406         
407         bConfigured = FALSE;
408
409         short isUpclient, isSCC, isBin;
410         afs_status_t nStatus;
411
412         int nResult = cfg_UpdateClientQueryStatus(g_hServer, &isUpclient, &isSCC, &isBin, &nStatus);
413         if (!nResult)
414                 return nStatus;
415
416         bConfigured = isUpclient && isSCC;
417
418         g_LogFile.WriteBoolResult(bConfigured);
419
420         return 0;
421 }
422
423 static void ShowMsg(UINT uiMsgID)
424 {
425         TCHAR szMsg[cchRESOURCE];
426
427         GetString(szMsg, uiMsgID);
428         
429         pProg->SetOperation(szMsg);
430 }
431
432 static void NextStep(UINT uiMsgID)
433 {
434         static nCurStep = 1;
435
436         if (bCancel)
437                 return;
438         
439         ShowMsg(uiMsgID);
440
441         pProg->SetProgress(nCurStep++);
442
443         Sleep(50);
444 }
445
446 static BOOL CheckConfigState(afs_status_t (*ConfigCheckFunc)(BOOL&), CONFIG_STATE& state, afs_status_t& nStatus, UINT uiMsgID)
447 {
448         BOOL bState = FALSE;
449
450         if (bCancel)
451                 return FALSE;
452
453         NextStep(uiMsgID);
454
455         nStatus = ConfigCheckFunc(bState);
456         if (nStatus) {
457                 g_LogFile.WriteError("Config check failed", nStatus);
458                 return FALSE;
459         }
460
461         state = bState ? CS_ALREADY_CONFIGURED : CS_NULL;
462
463         return TRUE;
464 }
465                 
466 static DWORD CALLBACK GetCurrentConfigState(LPPROGRESSDISPLAY ppd, LPARAM lp)
467 {
468         afs_status_t nStatus = 0;
469
470         ASSERT(pProg);
471
472         g_LogFile.Write("Checking this machine's current configuration...\r\n");
473
474         if (!IsClientConfigured(g_CfgData.bValidClientInfo, nStatus))
475                 return nStatus;
476
477         if (!IsConfigInfoValid(g_CfgData.bValidServerInfo, nStatus))
478                 return nStatus;
479
480     // If the server and client have good config info, and the client is in a 
481     // different cell than the server, then the config routines will want to
482     // reconfigure the client.  To do so they need information that we already
483     // know and don't have to ask the user for.  Prefill this information here.
484     if (g_CfgData.bValidClientInfo && g_CfgData.bValidServerInfo && 
485         (lstrcmp(g_CfgData.szCellName, g_CfgData.szClientCellName) != 0))
486     {
487         lstrcpy(g_CfgData.szCellServDbHostname, g_CfgData.szHostname);
488     }
489
490         if (!GetLibHandles(&nStatus))
491                 return nStatus;
492
493         if (!CheckConfigState(DoesAPartitionExist, g_CfgData.configPartition, nStatus, IDS_CHECK_PARTITION))
494                 return nStatus;
495
496         if (g_CfgData.bValidServerInfo) {
497                 // Must check if bos server is running, and start it if it isn't.  We can't determine
498                 // if the services are running except by asking the bosserver.
499                 if (!StartBosServer(nStatus))
500                         return nStatus;
501
502                 if (!CheckConfigState(IsFSConfigured, g_CfgData.configFS, nStatus, IDS_CHECK_FS_CONFIG))
503                         return nStatus;
504
505                 if (!CheckConfigState(IsDBConfigured, g_CfgData.configDB, nStatus, IDS_CHECK_DB_CONFIG))
506                         return nStatus;
507
508                 if (g_CfgData.configDB == CS_ALREADY_CONFIGURED) {
509                         if (!AreWeLastDBServer(g_CfgData.bLastDBServer, nStatus))
510                                 return nStatus;
511                 }
512
513                 if (!CheckConfigState(IsBakConfigured, g_CfgData.configBak, nStatus, IDS_CHECK_BAK_CONFIG))
514                         return nStatus;
515
516                 if (!CheckConfigState(DoRootVolumesExist, g_CfgData.configRootVolumes, nStatus, IDS_CHECK_ROOT_AFS))
517             return nStatus;
518
519         g_CfgData.bRootVolumesExistanceKnown = TRUE;
520
521                 if (!CheckConfigState(AreRootVolumesReplicated, g_CfgData.configRep, nStatus, IDS_CHECK_REP))
522             return nStatus;
523         
524         g_CfgData.bRootVolumesReplicationKnown = TRUE;
525
526                 if (!CheckConfigState(IsSCSConfigured, g_CfgData.configSCS, nStatus, IDS_CHECK_SCS))
527                         return nStatus;
528
529                 if (!CheckConfigState(IsSCCConfigured, g_CfgData.configSCC, nStatus, IDS_CHECK_SCC))
530                         return nStatus;
531         }
532
533         if (!bCancel)
534                 pProg->SetProgress(MAX_STEPS);
535         
536         return 0;
537 }
538