Windows: AFSTearDownExtents may experience active extents
[openafs.git] / src / WINNT / afssvrcfg / salvage_dlg.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 #include <winsock2.h>
15 #include <ws2tcpip.h>
16
17 extern "C" {
18 #include <afsconfig.h>
19 #include <afs/param.h>
20 #include <afs/stds.h>
21 #include <roken.h>
22 }
23
24 #include "afscfg.h"             // Main header for this application
25 #include "resource.h"
26 extern "C" {
27 #include <afs/afs_bosAdmin.h>
28 }
29 #include "admin_info_dlg.h"
30
31
32 /*
33  * DEFINITIONS _________________________________________________________________
34  *
35  */
36 static const int DEFAULT_NUM_PROCESSES          = 4;
37 static const char *DEFAULT_LOG_FILE                     = "";
38 static const int NUM_PROCS_BUF_SIZE                     = 5;
39 static const int MIN_NUM_PROCESSES                      = 1;
40 static const int MAX_NUM_PROCESSES                      = 32;
41
42 static HWND hDlg = 0;                                           // HWND for this page's dialog
43 static BOOL bAdvanced;
44 static TCHAR szPartitionName[25];
45 static TCHAR szVolumeName[cchRESOURCE];
46 static TCHAR szNumProcesses[NUM_PROCS_BUF_SIZE];
47 static TCHAR szTempDir[_MAX_PATH];
48 static LPTSTR pszPartitionName;
49 static LPTSTR pszVolumeName;
50 static int nNumProcesses;
51
52
53 /*
54  * PROTOTYPES _________________________________________________________________
55  *
56  */
57 static void OnInitDialog(HWND hwndDlg);
58 static void OnAdvanced();
59 static void UpdateControls();
60 static BOOL OnSalvage();
61 static DWORD WINAPI Salvage(LPVOID param);
62
63 BOOL CALLBACK SalvageDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
64
65
66 /*
67  * EXPORTED FUNCTIONS _________________________________________________________
68  *
69  */
70 BOOL ShowSalvageDlg(HWND hParent, LPCTSTR pszPartitionName)
71 {
72     ASSERT(pszPartitionName);
73
74     lstrcpy(szPartitionName, pszPartitionName);
75
76     int nResult = ModalDialog(IDD_SALVAGE, hParent, (DLGPROC)SalvageDlgProc);
77
78     if (nResult != IDOK)
79         return FALSE;
80
81     // Create a thread to perform the salvage
82     DWORD dwThreadID;
83     g_CfgData.hSalvageThread = CreateThread(0, 0, Salvage, 0, 0, &dwThreadID);
84
85     return (g_CfgData.hSalvageThread != 0);
86 }
87
88
89 /*
90  * Dialog Proc _________________________________________________________________
91  *
92  */
93 BOOL CALLBACK SalvageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp)
94 {
95     if (AfsAppLib_HandleHelp(IDD_SALVAGE, hwndDlg, msg, wp, lp))
96         return TRUE;
97
98     switch (msg) {
99     case WM_INITDIALOG:
100         OnInitDialog(hwndDlg);
101         break;
102
103     case WM_COMMAND:
104         switch (LOWORD(wp)) {
105         case IDC_VOLUME_NAME:
106         case IDC_NUM_PROCESSES:
107         case IDC_LOG_FILE:
108         case IDC_TEMP_DIR:
109             if (HIWORD(wp) == EN_CHANGE)
110                 UpdateControls();
111             break;
112
113         case IDC_SERVER:
114         case IDC_PARTITION:
115         case IDC_VOLUME:
116         case IDC_NUM_PROCESSES_CHECKBOX:
117             UpdateControls();
118             break;
119
120         case IDC_ADVANCED:
121             OnAdvanced();
122             break;
123
124         case IDCANCEL:
125             EndDialog(hDlg, IDCANCEL);
126             break;
127
128         case IDOK:
129             if (OnSalvage())
130                 EndDialog(hDlg, IDOK);
131             break;
132         }
133         break;
134     }
135
136     return FALSE;
137 }
138
139
140 /*
141  * STATIC FUNCTIONS _________________________________________________________________
142  *
143  */
144
145 /*
146  * Event Handler Functions _________________________________________________________________
147  *
148  */
149 static void OnInitDialog(HWND hwndDlg)
150 {
151     hDlg = hwndDlg;
152
153     bAdvanced = TRUE;
154
155     TCHAR szNumProcesses[32];
156     _itot(DEFAULT_NUM_PROCESSES, szNumProcesses, 10);
157
158     SetWndText(hDlg, IDC_NUM_PROCESSES, szNumProcesses);
159     SetCheck(hDlg, IDC_NUM_PROCESSES_CHECKBOX);
160     SetWndText(hDlg, IDC_LOG_FILE, A2S(DEFAULT_LOG_FILE));
161
162     // If a partition name isn't selected, then only allow the salvage server option
163     if (szPartitionName[0] == 0) {
164         SetEnable(hDlg, IDC_PARTITION, ES_DISABLE);
165         SetEnable(hDlg, IDC_VOLUME, ES_DISABLE);
166         SetCheck(hDlg, IDC_SERVER);
167     } else
168         SetCheck(hDlg, IDC_PARTITION);
169
170     // Close the Advanced portion of the dialog
171     OnAdvanced();
172 }
173
174 static void OnAdvanced()
175 {
176     static int nOffset = 0;
177
178     bAdvanced = !bAdvanced;
179
180     ShowAndEnable(hDlg, IDC_ADVANCED_FRAME, bAdvanced);
181     ShowAndEnable(hDlg, IDC_LOG_FILE, bAdvanced);
182     ShowAndEnable(hDlg, IDC_LOG_FILE_LABEL, bAdvanced);
183     ShowAndEnable(hDlg, IDC_NUM_PROCESSES, bAdvanced);
184     ShowAndEnable(hDlg, IDC_TEMP_DIR, bAdvanced);
185     ShowAndEnable(hDlg, IDC_TEMP_DIR_LABEL, bAdvanced);
186     ShowAndEnable(hDlg, IDC_NUM_PROCESSES_CHECKBOX, bAdvanced);
187     ShowAndEnable(hDlg, IDC_DAMAGED_VOLUMES, bAdvanced);
188     ShowAndEnable(hDlg, IDC_SMALL_BLOCK_READS, bAdvanced);
189     ShowAndEnable(hDlg, IDC_FORCE_SALVAGE, bAdvanced);
190     ShowAndEnable(hDlg, IDC_FORCE_REBUILD, bAdvanced);
191     ShowAndEnable(hDlg, IDC_LIST_DAMAGED_INODES, bAdvanced);
192     ShowAndEnable(hDlg, IDC_LIST_OWNED_INDOES, bAdvanced);
193
194     // To show or hide the advanced section, we have to resize the dialog
195
196     // Get current position of the dialog
197     RECT rectDlg;
198     GetWindowRect(hDlg, &rectDlg);
199
200     // Figure out offset between full dialog and short dialog
201     if (nOffset == 0) {
202         // Find the frame containing the things we will hide or show
203         HWND hFrame = GetDlgItem(hDlg, IDC_ADVANCED_FRAME);
204
205         // Get its dimensions
206         RECT rectFrame;
207         GetWindowRect(hFrame, &rectFrame);
208
209         // Find the distance between the bottom of the dialog and the top of the frame
210         nOffset = rectDlg.bottom - rectFrame.top - 3;
211     }
212
213     int nCurOffset = nOffset;
214
215     if (!bAdvanced)
216         nCurOffset *= -1;
217
218     // Adjust dialog position
219     MoveWindow(hDlg, rectDlg.left, rectDlg.top, rectDlg.right - rectDlg.left, rectDlg.bottom - rectDlg.top + nCurOffset, TRUE);
220
221     SetWndText(hDlg, IDC_ADVANCED, bAdvanced ? IDS_ADVANCED_OPEN : IDS_ADVANCED_CLOSED);
222 }
223
224 static void UpdateControls()
225 {
226     // Update volume name controls
227     BOOL bVolume = IsButtonChecked(hDlg, IDC_VOLUME);
228     ENABLE_STATE es = bVolume ? ES_ENABLE : ES_DISABLE;
229     SetEnable(hDlg, IDC_VOLUME_NAME, es);
230     SetEnable(hDlg, IDC_VOLUME_NAME_LABEL, es);
231     GetWndText(hDlg, IDC_VOLUME_NAME, szVolumeName);
232
233     // Num processes edit control
234     BOOL bParallel = IsButtonChecked(hDlg, IDC_NUM_PROCESSES_CHECKBOX);
235     SetEnable(hDlg, IDC_NUM_PROCESSES, (ENABLE_STATE)bParallel);
236     GetWndText(hDlg, IDC_NUM_PROCESSES, szNumProcesses, NUM_PROCS_BUF_SIZE);
237
238     GetWndText(hDlg, IDC_LOG_FILE, g_CfgData.szSalvageLogFileName, _MAX_PATH);
239     GetWndText(hDlg, IDC_TEMP_DIR, szTempDir, _MAX_PATH);
240
241     // Should OK button be enabled or disabled?
242     BOOL bEnable = TRUE;
243
244     if (bVolume)
245         bEnable = !!lstrlen(szVolumeName);
246
247     if (bEnable && bParallel)
248         bEnable = !!lstrlen(szNumProcesses);
249
250     SetEnable(hDlg, IDOK, (ENABLE_STATE)bEnable);
251 }
252
253 /*
254  * Utility Functions _________________________________________________________________
255  *
256  */
257 static BOOL OnSalvage()
258 {
259     if (IsButtonChecked(hDlg, IDC_SERVER)) {
260         pszPartitionName = 0;
261         pszVolumeName = 0;
262     } else if (IsButtonChecked(hDlg, IDC_PARTITION)) {
263         pszPartitionName = szPartitionName;
264         pszVolumeName = 0;
265     } else if (IsButtonChecked(hDlg, IDC_VOLUME)) {
266         pszPartitionName = szPartitionName;
267         pszVolumeName = szVolumeName;
268     }
269
270     nNumProcesses = DEFAULT_NUM_PROCESSES;
271     if (IsButtonChecked(hDlg, IDC_NUM_PROCESSES_CHECKBOX)) {
272         nNumProcesses = _ttoi(szNumProcesses);
273         if ((nNumProcesses < MIN_NUM_PROCESSES) || (nNumProcesses > MAX_NUM_PROCESSES)) {
274             ShowError(hDlg, 0, IDS_INVALID_NUM_SALVAGE_PROCESSSES);
275             return FALSE;
276         }
277     }
278
279     if (!g_CfgData.bReuseAdminInfo) {
280         if (!GetAdminInfo(hDlg, GAIO_LOGIN_ONLY))
281             return FALSE;
282
283         if (!GetHandles(hDlg))
284             return FALSE;
285     }
286
287     return TRUE;
288 }
289
290 static DWORD WINAPI Salvage(LPVOID param)
291 {
292     afs_status_t nStatus;
293     void *hServer;
294     int nResult;
295
296     nResult = bos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
297     if (!nResult) {
298         ShowError(hDlg, nStatus, IDS_BOS_OPEN_FAILED);
299         return FALSE;
300     }
301
302     nResult = bos_Salvage(g_hCell, hServer, S2A(pszPartitionName), S2A(pszVolumeName), nNumProcesses, S2A(szTempDir), 0, VOS_NORMAL,
303                            BOS_SALVAGE_DAMAGED_VOLUMES, BOS_SALVAGE_DONT_WRITE_INODES, BOS_SALVAGE_DONT_WRITE_ROOT_INODES,
304                            BOS_SALVAGE_DONT_FORCE_DIRECTORIES, BOS_SALVAGE_DONT_FORCE_BLOCK_READS, &nStatus);
305     if (!nResult)
306         ShowError(hDlg, nStatus, IDS_SALVAGE_ERROR);
307
308     bos_ServerClose(hServer, &nStatus);
309
310     g_CfgData.bReuseAdminInfo = nResult;
311
312     return nResult;
313 }
314