Skip to content

Commit

Permalink
Merge pull request #1452
Browse files Browse the repository at this point in the history
vss: remove dependency on live system during backup
  • Loading branch information
pstorz committed Jun 27, 2023
2 parents d4a7e21 + 84c308e commit 5cfe96f
Show file tree
Hide file tree
Showing 23 changed files with 1,853 additions and 1,233 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https:
- pr-tool: Add options to be used in CI runs [PR #1488]
- VMware Plugin: improve snapshot cleanup [PR #1484]
- packaging: cleanup SUSE webui dependencies [PR #1493]
- vss: remove dependency on live system during backup [PR #1452]

### Removed
- remove no longer used pkglists [PR #1335]
Expand Down Expand Up @@ -178,6 +179,7 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https:
[PR #1448]: https://github.com/bareos/bareos/pull/1448
[PR #1449]: https://github.com/bareos/bareos/pull/1449
[PR #1450]: https://github.com/bareos/bareos/pull/1450
[PR #1452]: https://github.com/bareos/bareos/pull/1452
[PR #1453]: https://github.com/bareos/bareos/pull/1453
[PR #1454]: https://github.com/bareos/bareos/pull/1454
[PR #1455]: https://github.com/bareos/bareos/pull/1455
Expand Down
4 changes: 0 additions & 4 deletions core/platforms/win32/winbareos.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -1880,8 +1880,6 @@ ${If} ${SectionIsSelected} ${SEC_SD} # if sd is selected, also generate sd snipp
Name = $ClientName$\r$\n \
Address = $ClientAddress$\r$\n \
Password = $\"$ClientPassword$\"$\r$\n \
# uncomment the following if using bacula $\r$\n \
# Catalog = $\"MyCatalog$\"$\r$\n\
}$\r$\n $\r$\n\
Storage {$\r$\n \
Name = $StorageName$\r$\n \
Expand All @@ -1896,8 +1894,6 @@ ${Else}
Name = $ClientName$\r$\n \
Address = $ClientAddress$\r$\n \
Password = $\"$ClientPassword$\"$\r$\n \
# uncomment the following if using bacula $\r$\n \
# Catalog = $\"MyCatalog$\"$\r$\n \
}$\r$\n"
${EndIf}

Expand Down
7 changes: 4 additions & 3 deletions core/src/dird/dird_conf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -688,9 +688,10 @@ struct s_kw ActionOnPurgeOptions[]
*
* name token
*/
struct s_kw VolumeStatus[] = {{"Append", 0}, {"Full", 0}, {"Used", 0},
{"Recycle", 0}, {"Purged", 0}, {"Cleaning", 0},
{"Error", 0}, {"Archive", 0}, {NULL, 0}};
struct s_kw VolumeStatus[]
= {{"Append", 0}, {"Full", 0}, {"Used", 0}, {"Recycle", 0},
{"Purged", 0}, {"Cleaning", 0}, {"Error", 0}, {"Archive", 0},
{"Disabled", 0}, {NULL, 0}};

/**
* Keywords (RHS) permitted in Pool type records
Expand Down
47 changes: 32 additions & 15 deletions core/src/filed/dir_cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1800,7 +1800,7 @@ static bool BackupCmd(JobControlRecord* jcr)
// START VSS ON WIN32
if (jcr->fd_impl->pVSSClient) {
if (jcr->fd_impl->pVSSClient->InitializeForBackup(jcr)) {
int drive_count;
int volume_count;
char szWinDriveLetters[27];
bool onefs_disabled;

Expand All @@ -1812,18 +1812,29 @@ static bool BackupCmd(JobControlRecord* jcr)
// Plugin driver can return drive letters
GeneratePluginEvent(jcr, bEventVssPrepareSnapshot, szWinDriveLetters);

drive_count = get_win32_driveletters(jcr->fd_impl->ff->fileset,
szWinDriveLetters);
std::vector<std::wstring> volumes
= get_win32_volumes(jcr->fd_impl->ff->fileset);

{
char drive[] = "_:";
for (std::size_t i = 0;
i < sizeof(szWinDriveLetters) && szWinDriveLetters[i]; ++i) {
drive[0] = szWinDriveLetters[i];
std::wstring wdrive = FromUtf8(drive);
if (GetDriveTypeW(wdrive.c_str()) == DRIVE_FIXED) {
volumes.emplace_back(std::move(wdrive));
}
}
}

onefs_disabled = win32_onefs_is_disabled(jcr->fd_impl->ff->fileset);

if (drive_count > 0) {
Jmsg(jcr, M_INFO, 0,
_("Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n"),
jcr->fd_impl->pVSSClient->GetDriverName(),
(drive_count) ? szWinDriveLetters : "None");
volume_count = volumes.size();
if (volume_count > 0) {
Jmsg(jcr, M_INFO, 0, _("Generate VSS snapshots. Driver=\"%s\"\n"),
jcr->fd_impl->pVSSClient->GetDriverName());

if (!jcr->fd_impl->pVSSClient->CreateSnapshots(szWinDriveLetters,
if (!jcr->fd_impl->pVSSClient->CreateSnapshots(volumes,
onefs_disabled)) {
BErrNo be;
Jmsg(jcr, M_FATAL, 0,
Expand All @@ -1835,12 +1846,18 @@ static bool BackupCmd(JobControlRecord* jcr)
// Inform about VMPs if we have them
jcr->fd_impl->pVSSClient->ShowVolumeMountPointStats(jcr);

// Tell user if snapshot creation of a specific drive failed
for (int i = 0; i < (int)strlen(szWinDriveLetters); i++) {
if (islower(szWinDriveLetters[i])) {
VSSClient* client = jcr->fd_impl->pVSSClient;

// Tell the user about the created shadow copies
for (auto [mount, vol] : client->mount_to_vol) {
if (auto found = client->vol_to_vss.find(vol);
found != client->vol_to_vss.end()) {
Jmsg(jcr, M_INFO, 0, "(%s)%s -> %s\n", mount.c_str(), vol.c_str(),
found->second.c_str());
} else {
Jmsg(jcr, M_FATAL, 0,
_("Generate VSS snapshot of drive \"%c:\\\" failed.\n"),
szWinDriveLetters[i]);
"No snapshot for volume %s (aka. %s) was generated.\n",
mount.c_str(), vol.c_str());
}
}

Expand All @@ -1856,7 +1873,7 @@ static bool BackupCmd(JobControlRecord* jcr)

} else {
Jmsg(jcr, M_FATAL, 0,
_("No drive letters found for generating VSS snapshots.\n"));
_("No volumes found for generating VSS snapshots.\n"));
}
} else {
BErrNo be;
Expand Down
10 changes: 3 additions & 7 deletions core/src/findlib/attribs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -521,14 +521,10 @@ int encode_attribsEx(JobControlRecord* jcr,
unix_name_to_win32(ff_pkt->sys_fname, ff_pkt->fname);
if (p_GetFileAttributesExW) {
// Try unicode version
POOLMEM* pwszBuf = GetPoolMemory(PM_FNAME);
make_win32_path_UTF8_2_wchar(pwszBuf, ff_pkt->fname);
std::wstring utf16 = make_win32_path_UTF8_2_wchar(ff_pkt->fname);

BOOL b = p_GetFileAttributesExW((LPCWSTR)pwszBuf, GetFileExInfoStandard,
(LPVOID)&atts);
FreePoolMemory(pwszBuf);

if (!b) {
if (!p_GetFileAttributesExW(utf16.c_str(), GetFileExInfoStandard,
(LPVOID)&atts)) {
WinError(jcr, "GetFileAttributesExW:", ff_pkt->sys_fname);
return STREAM_UNIX_ATTRIBUTES;
}
Expand Down
138 changes: 60 additions & 78 deletions core/src/findlib/bfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,6 @@ static inline int BopenEncrypted(BareosFilePacket* bfd,
{
bool is_dir;
ULONG ulFlags = 0;
POOLMEM* win32_fname;
POOLMEM* win32_fname_wchar;

if (!p_OpenEncryptedFileRawA && !p_OpenEncryptedFileRawW) {
Dmsg0(50,
Expand All @@ -500,13 +498,6 @@ static inline int BopenEncrypted(BareosFilePacket* bfd,
is_dir = S_ISDIR(mode);

// Convert to Windows path format
win32_fname = GetPoolMemory(PM_FNAME);
win32_fname_wchar = GetPoolMemory(PM_FNAME);

unix_name_to_win32(win32_fname, (char*)fname);
if (p_OpenEncryptedFileRawW && p_MultiByteToWideChar) {
make_win32_path_UTF8_2_wchar(win32_fname_wchar, fname);
}

// See if we open the file for create or read-write.
if ((flags & O_CREAT) || (flags & O_WRONLY)) {
Expand All @@ -522,24 +513,24 @@ static inline int BopenEncrypted(BareosFilePacket* bfd,
}

if (p_OpenEncryptedFileRawW && p_MultiByteToWideChar) {
std::wstring utf16 = make_win32_path_UTF8_2_wchar(fname);

// Unicode open.
Dmsg1(100, "OpenEncryptedFileRawW=%s\n", win32_fname);
if (p_OpenEncryptedFileRawW((LPCWSTR)win32_fname_wchar, ulFlags,
&(bfd->pvContext))) {
Dmsg1(100, "OpenEncryptedFileRawW=%s\n", FromUtf16(utf16).c_str());
if (p_OpenEncryptedFileRawW(utf16.c_str(), ulFlags, &(bfd->pvContext))) {
bfd->mode = BF_CLOSED;
}
} else {
// ASCII open.
Dmsg1(100, "OpenEncryptedFileRawA=%s\n", win32_fname);
if (p_OpenEncryptedFileRawA(win32_fname_wchar, ulFlags,
PoolMem win32_fname(PM_FNAME);
unix_name_to_win32(win32_fname.addr(), fname);
Dmsg1(100, "OpenEncryptedFileRawA=%s\n", win32_fname.c_str());
if (p_OpenEncryptedFileRawA(win32_fname.c_str(), ulFlags,
&(bfd->pvContext))) {
bfd->mode = BF_CLOSED;
}
}

FreePoolMemory(win32_fname_wchar);
FreePoolMemory(win32_fname);

bfd->encrypted = true;

return bfd->mode == BF_CLOSED ? -1 : 1;
Expand All @@ -550,15 +541,8 @@ static inline int BopenNonencrypted(BareosFilePacket* bfd,
int flags,
mode_t mode)
{
POOLMEM* win32_fname;
POOLMEM* win32_fname_wchar;
DWORD dwaccess, dwflags, dwshare;

// Convert to Windows path format
win32_fname = GetPoolMemory(PM_FNAME);
win32_fname_wchar = GetPoolMemory(PM_FNAME);

unix_name_to_win32(win32_fname, (char*)fname);
if (bfd->cmd_plugin && plugin_bopen) {
int rtnstat;
Dmsg1(50, "call plugin_bopen fname=%s\n", fname);
Expand All @@ -576,8 +560,6 @@ static inline int BopenNonencrypted(BareosFilePacket* bfd,
bfd->mode = BF_CLOSED;
Dmsg1(000, "==== plugin_bopen returned bad status=%d\n", rtnstat);
}
FreePoolMemory(win32_fname_wchar);
FreePoolMemory(win32_fname);
return bfd->mode == BF_CLOSED ? -1 : 1;
}
Dmsg0(50, "=== NO plugin\n");
Expand All @@ -587,10 +569,6 @@ static inline int BopenNonencrypted(BareosFilePacket* bfd,
return 0;
}

if (p_CreateFileW && p_MultiByteToWideChar) {
make_win32_path_UTF8_2_wchar(win32_fname_wchar, fname);
}

if (flags & O_CREAT) { /* Create */
if (bfd->use_backup_api) {
dwaccess = GENERIC_WRITE | FILE_ALL_ACCESS | WRITE_OWNER | WRITE_DAC
Expand All @@ -603,23 +581,25 @@ static inline int BopenNonencrypted(BareosFilePacket* bfd,

// Unicode open for create write
if (p_CreateFileW && p_MultiByteToWideChar) {
Dmsg1(100, "Create CreateFileW=%s\n", win32_fname);
bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
CREATE_ALWAYS, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
std::wstring utf16 = make_win32_path_UTF8_2_wchar(fname);
Dmsg1(100, "Create CreateFileW=%s\n", FromUtf16(utf16).c_str());
bfd->fh = p_CreateFileW(utf16.c_str(), dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
CREATE_ALWAYS, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
} else {
PoolMem ansi(PM_FNAME);
unix_name_to_win32(ansi.addr(), fname);
// ASCII open
Dmsg1(100, "Create CreateFileA=%s\n", win32_fname);
bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
CREATE_ALWAYS, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
Dmsg1(100, "Create CreateFileA=%s\n", ansi.c_str());
bfd->fh = p_CreateFileA(ansi.c_str(), dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
CREATE_ALWAYS, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
}

bfd->mode = BF_WRITE;
Expand All @@ -639,23 +619,25 @@ static inline int BopenNonencrypted(BareosFilePacket* bfd,

if (p_CreateFileW && p_MultiByteToWideChar) {
// unicode open for open existing write
Dmsg1(100, "Write only CreateFileW=%s\n", win32_fname);
bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
std::wstring utf16 = make_win32_path_UTF8_2_wchar(fname);
Dmsg1(100, "Write only CreateFileW=%s\n", FromUtf16(utf16).c_str());
bfd->fh = p_CreateFileW(utf16.c_str(), dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
} else {
PoolMem ansi(PM_FNAME);
unix_name_to_win32(ansi.addr(), fname);
// ASCII open
Dmsg1(100, "Write only CreateFileA=%s\n", win32_fname);
bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
Dmsg1(100, "Write only CreateFileA=%s\n", ansi.c_str());
bfd->fh = p_CreateFileA(ansi.c_str(), dwaccess, /* Requested access */
0, /* Shared mode */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
}

bfd->mode = BF_WRITE;
Expand All @@ -678,23 +660,25 @@ static inline int BopenNonencrypted(BareosFilePacket* bfd,

if (p_CreateFileW && p_MultiByteToWideChar) {
// Unicode open for open existing read
Dmsg1(100, "Read CreateFileW=%s\n", win32_fname);
bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
dwaccess, /* Requested access */
dwshare, /* Share modes */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
std::wstring utf16 = make_win32_path_UTF8_2_wchar(fname);
Dmsg1(100, "Read CreateFileW=%s\n", FromUtf16(utf16).c_str());
bfd->fh = p_CreateFileW(utf16.c_str(), dwaccess, /* Requested access */
dwshare, /* Share modes */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
} else {
// ASCII open for open existing read
Dmsg1(100, "Read CreateFileA=%s\n", win32_fname);
bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */
dwshare, /* Share modes */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
PoolMem ansi(PM_FNAME);
unix_name_to_win32(ansi.addr(), fname);
// ASCII open
Dmsg1(100, "Read CreateFileA=%s\n", ansi.c_str());
bfd->fh = p_CreateFileA(ansi.c_str(), dwaccess, /* Requested access */
dwshare, /* Share modes */
NULL, /* SecurityAttributes */
OPEN_EXISTING, /* CreationDisposition */
dwflags, /* Flags and attributes */
NULL); /* TemplateFile */
}

bfd->mode = BF_READ;
Expand All @@ -711,8 +695,6 @@ static inline int BopenNonencrypted(BareosFilePacket* bfd,
bfd->lplugin_private_context = NULL;
bfd->win32Decomplugin_private_context.bIsInData = false;
bfd->win32Decomplugin_private_context.liNextHeader = 0;
FreePoolMemory(win32_fname_wchar);
FreePoolMemory(win32_fname);

bfd->encrypted = false;

Expand Down
9 changes: 8 additions & 1 deletion core/src/include/baconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,14 @@ int Getdomainname(char* name, int len);
# define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Bareos"
# define PathSeparator '\\'

inline bool IsPathSeparator(int ch) { return ch == '/' || ch == '\\'; }
inline bool IsPathSeparator(int ch)
{
// check that this works regardless of whether one uses
// wchar_t or char
static_assert(int{L'/'} == int{'/'});
static_assert(int{L'\\'} == int{'\\'});
return ch == '/' || ch == '\\';
}
inline char* first_path_separator(char* path) { return strpbrk(path, "/\\"); }
inline const char* first_path_separator(const char* path)
{
Expand Down

0 comments on commit 5cfe96f

Please sign in to comment.