2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2018 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Written by James Harper, October 2008
23 #include "exchange-fd.h"
25 storage_group_node_t::storage_group_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_STORAGE_GROUP, parent_node)
30 restore_environment = NULL;
31 saved_log_path = NULL;
35 storage_group_node_t::~storage_group_node_t()
41 if (file_node != NULL)
47 storage_group_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
51 WCHAR *tmp_logfiles, *tmp_logfile_ptr;
56 _DebugMessage(100, "startBackupNode_STORAGE_GROUP state = %d, name = %s\n", state, name);
63 if (context->job_level == 'F')
65 _DebugMessage(100, "Calling HrESEBackupSetup (BACKUP_TYPE_FULL)\n");
66 result = HrESEBackupSetup(hccx, ibi->hInstanceId, BACKUP_TYPE_FULL);
71 _DebugMessage(100, "Calling HrESEBackupSetup (BACKUP_TYPE_LOGS_ONLY)\n");
72 result = HrESEBackupSetup(hccx, ibi->hInstanceId, BACKUP_TYPE_LOGS_ONLY);
73 if (context->accurate)
80 _JobMessage(M_FATAL, "HrESEBackupSetup failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
86 if (context->path_bits[level + 1] == NULL)
88 _DebugMessage(100, "No specific database specified - backing them all up\n");
89 DATABASE_BACKUP_INFO *dbi = &ibi->rgDatabase[current_dbi];
90 char *tmp = new char[wcslen(dbi->wszDatabaseDisplayName) + 1];
91 wcstombs(tmp, dbi->wszDatabaseDisplayName, wcslen(dbi->wszDatabaseDisplayName) + 1);
92 store_node = new store_node_t(tmp, this);
93 store_node->dbi = dbi;
94 store_node->hccx = hccx;
95 context->current_node = store_node;
99 DATABASE_BACKUP_INFO *dbi = NULL;
101 for (current_dbi = 0; current_dbi < ibi->cDatabase; current_dbi++)
103 dbi = &ibi->rgDatabase[current_dbi];
104 char *tmp = new char[wcslen(dbi->wszDatabaseDisplayName) + 1];
105 wcstombs(tmp, dbi->wszDatabaseDisplayName, wcslen(dbi->wszDatabaseDisplayName) + 1);
106 if (stricmp(tmp, context->path_bits[level + 1]) == 0)
110 if (current_dbi == ibi->cDatabase)
112 _JobMessage(M_FATAL, "Invalid Database '%s'\n", context->path_bits[level + 1]);
115 store_node = new store_node_t(tmp, this);
116 _DebugMessage(100, "Database name = %s\n", store_node->name);
118 store_node->hccx = hccx;
119 store_node->dbi = dbi;
120 context->current_node = store_node;
124 _DebugMessage(100, "Calling HrESEBackupGetLogAndPatchFiles\n");
125 result = HrESEBackupGetLogAndPatchFiles(hccx, &tmp_logfiles);
128 _JobMessage(M_FATAL, "HrESEBackupGetLogAndPatchFiles failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
131 for (len = 0, tmp_logfile_ptr = tmp_logfiles; *tmp_logfile_ptr != 0; tmp_logfile_ptr += wcslen(tmp_logfile_ptr) + 1)
133 len += wcslen(tmp_logfile_ptr) + 1;
135 logfiles = new WCHAR[len + 1];
136 logfile_ptr = logfiles;
137 for (tmp_logfile_ptr = tmp_logfiles; *tmp_logfile_ptr != 0; tmp_logfile_ptr += wcslen(tmp_logfile_ptr) + 1)
139 // check file modification date
141 FILETIME modified_time;
145 include_file = false;
146 handle = INVALID_HANDLE_VALUE;
147 if (context->job_since == 0)
151 handle = CreateFileW(tmp_logfile_ptr, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
152 if (handle == INVALID_HANDLE_VALUE)
154 //_JobMessage(M_WARNING, "Could not open '%S' to check last modified date (0x%08x), including anyway\n", tmp_logfile_ptr, GetLastError());
160 if (GetFileTime(handle, NULL, NULL, &modified_time) == 0)
162 //_JobMessage(M_WARNING, "Could not check last modified date for '%S' (0x%08x), including anyway\n", tmp_logfile_ptr, GetLastError());
168 tmp_time = (((int64_t)modified_time.dwHighDateTime) << 32) | modified_time.dwLowDateTime;
169 tmp_time -= 116444736000000000LL;
170 tmp_time /= 10000000;
171 if (tmp_time > context->job_since)
178 memcpy(logfile_ptr, tmp_logfile_ptr, (wcslen(tmp_logfile_ptr) + 1) * 2);
179 logfile_ptr += wcslen(logfile_ptr) + 1;
180 //_DebugMessage(100, "Including file %S\n", logfile_ptr);
183 /* this is handled via checkFile now */
186 if (context->accurate) {
187 tmp = new char[strlen(full_path) + wcslen(tmp_logfile_ptr) + 1];
188 strcpy(tmp, full_path);
189 wcstombs(tmp + strlen(full_path), tmp_logfile_ptr, wcslen(tmp_logfile_ptr) + 1);
190 bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)tmp);
196 if (handle != INVALID_HANDLE_VALUE)
201 logfile_ptr = logfiles;
205 tmp = new char[wcslen(logfile_ptr) + 1];
206 wcstombs(tmp, logfile_ptr, wcslen(logfile_ptr) + 1);
207 file_node = new file_node_t(tmp, this);
209 file_node->hccx = hccx;
210 file_node->filename = logfile_ptr;
211 context->current_node = file_node;
214 time_t now = time(NULL);
215 sp->fname = full_path;
216 sp->link = full_path;
217 _DebugMessage(100, "fname = %s\n", sp->fname);
218 sp->statp.st_mode = 0700 | S_IFDIR;
219 sp->statp.st_ctime = now;
220 sp->statp.st_mtime = now;
221 sp->statp.st_atime = now;
222 sp->statp.st_size = 0;
223 //sp->statp.st_blocks = 0;
224 sp->type = FT_DIREND;
231 storage_group_node_t::endBackupFile(exchange_fd_context_t *context)
234 bRC retval = bRC_Error;
236 _DebugMessage(100, "endBackupNode_STORAGE_GROUP state = %d\n", state);
241 // should never happen
244 // free node->storage_group_node
245 if (context->path_bits[level + 1] == NULL)
248 if (current_dbi == ibi->cDatabase)
256 // should never happen
260 logfile_ptr += wcslen(logfile_ptr) + 1;
261 if (*logfile_ptr == 0)
266 if (context->truncate_logs)
268 _DebugMessage(100, "Calling HrESEBackupTruncateLogs\n");
269 result = HrESEBackupTruncateLogs(hccx);
272 _JobMessage(M_FATAL, "HrESEBackupTruncateLogs failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
276 _JobMessage(M_INFO, "Truncated database logs for Storage Group %s\n", name);
281 _JobMessage(M_INFO, "Did NOT truncate database logs for Storage Group %s\n", name);
283 _DebugMessage(100, "Calling HrESEBackupInstanceEnd\n");
284 result = HrESEBackupInstanceEnd(hccx, ESE_BACKUP_INSTANCE_END_SUCCESS);
287 _JobMessage(M_FATAL, "HrESEBackupInstanceEnd failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
291 context->current_node = parent;
298 storage_group_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
303 _DebugMessage(100, "createFile_STORAGE_GROUP state = %d\n", state);
305 if (strcmp(context->path_bits[level], name) != 0)
307 _DebugMessage(100, "Different storage group - switching back to parent\n", state);
308 saved_log_path = new WCHAR[wcslen(restore_environment->m_wszRestoreLogPath) + 1];
309 wcscpy(saved_log_path, restore_environment->m_wszRestoreLogPath);
310 _DebugMessage(100, "Calling HrESERestoreSaveEnvironment\n");
311 result = HrESERestoreSaveEnvironment(hccx);
314 _JobMessage(M_FATAL, "HrESERestoreSaveEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
316 rp->create_status = CF_CREATED;
319 _DebugMessage(100, "Calling HrESERestoreClose\n");
320 result = HrESERestoreClose(hccx, RESTORE_CLOSE_NORMAL);
323 _JobMessage(M_FATAL, "HrESERestoreClose failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
325 rp->create_status = CF_CREATED;
328 context->current_node = parent;
331 if (saved_log_path != NULL)
333 _DebugMessage(100, "Calling HrESERestoreReopen\n");
334 result = HrESERestoreReopen(context->computer_name, service_name, saved_log_path, &hccx);
337 _JobMessage(M_FATAL, "HrESERestoreReopen failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
339 saved_log_path = NULL;
340 rp->create_status = CF_CREATED;
343 _DebugMessage(100, "Calling HrESERestoreGetEnvironment\n");
344 result = HrESERestoreGetEnvironment(hccx, &restore_environment);
347 _JobMessage(M_FATAL, "HrESERestoreGetEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
349 saved_log_path = NULL;
350 rp->create_status = CF_CREATED;
353 saved_log_path = NULL;
361 if (context->path_bits[level + 2] == NULL)
363 _JobMessage(M_ERROR, "Unexpected log file '%s%s' - expecting database\n", full_path, context->path_bits[level + 1]);
367 service_name = new WCHAR[strlen(parent->name) + 1];
368 storage_group_name = new WCHAR[strlen(name) + 1];
369 mbstowcs(service_name, parent->name, strlen(parent->name) + 1);
370 mbstowcs(storage_group_name, name, strlen(name) + 1);
371 _DebugMessage(100, "Calling HrESERestoreOpen\n");
372 result = HrESERestoreOpen(context->computer_name, service_name, storage_group_name, NULL, &hccx);
375 _JobMessage(M_FATAL, "HrESERestoreOpen failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
379 _DebugMessage(100, "Calling HrESERestoreGetEnvironment\n");
380 result = HrESERestoreGetEnvironment(hccx, &restore_environment);
383 _JobMessage(M_FATAL, "HrESERestoreGetEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
390 if (context->path_bits[level + 2] == NULL)
395 store_node = new store_node_t(bstrdup(context->path_bits[level + 1]), this);
396 store_node->hccx = hccx;
397 context->current_node = store_node;
400 if (context->path_bits[level + 2] != NULL)
402 _JobMessage(M_ERROR, "Unexpected file '%s'\n", full_path);
406 if (context->path_bits[level + 1] == NULL)
412 file_node = new file_node_t(bstrdup(context->path_bits[level + 1]), this);
413 file_node->hccx = hccx;
415 for (i = strlen(file_node->name) - 1; i >= 0; i--)
417 if (file_node->name[i] == '\\')
423 len = wcslen(restore_environment->m_wszRestoreLogPath) + strlen(file_node->name + i) + 1 + 1;
424 file_node->filename = new WCHAR[len];
425 wcscpy(file_node->filename, restore_environment->m_wszRestoreLogPath);
426 wcscat(file_node->filename, L"\\");
427 mbstowcs(&file_node->filename[wcslen(file_node->filename)], file_node->name + i, strlen(file_node->name + i) + 1);
428 context->current_node = file_node;
431 if (rp->type != FT_DIREND)
433 _JobMessage(M_ERROR, "Unexpected file '%s'\n", full_path);
437 // must be the storage group node
438 _DebugMessage(100, "Calling HrESERestoreSaveEnvironment\n");
439 result = HrESERestoreSaveEnvironment(hccx);
442 _JobMessage(M_FATAL, "HrESERestoreSaveEnvironment failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
447 _DebugMessage(100, "Calling HrESERestoreComplete\n");
448 result = HrESERestoreComplete(hccx, restore_environment->m_wszRestoreLogPath,
449 restore_environment->m_wszRestoreLogPath, storage_group_name, ESE_RESTORE_COMPLETE_ATTACH_DBS);
452 _JobMessage(M_FATAL, "HrESERestoreComplete failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
453 _DebugMessage(100, "Calling HrESERestoreClose\n");
454 result = HrESERestoreClose(hccx, RESTORE_CLOSE_NORMAL);
460 _JobMessage(M_INFO, "Storage Group '%s' restored successfully\n", name);
463 _DebugMessage(100, "Calling HrESERestoreClose\n");
464 result = HrESERestoreClose(hccx, RESTORE_CLOSE_NORMAL);
467 _JobMessage(M_FATAL, "HrESERestoreClose failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
472 rp->create_status = CF_CREATED;
475 rp->create_status = CF_CREATED;
482 storage_group_node_t::endRestoreFile(exchange_fd_context_t *context)
484 _DebugMessage(100, "endRestoreFile_STORAGE_GROUP state = %d\n", state);
494 context->current_node = parent;
497 context->current_node = parent;