summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2011-04-06 20:53:52 +0000
committerChris Wilson <chris+github@qwirx.com>2011-04-06 20:53:52 +0000
commitd22fc3f49b5c1d1e1ccf0d250d7123b1a281dc18 (patch)
treef861dfa5cfef0b8a4163b7f8e304a9474c44d0f3 /bin
parente51e14397af27d3a19e4e56a82be78046352ec90 (diff)
Add VSS: prefix to VSS log messages.
Start a snapshot set and add backup locations as volumes. Modularise IVssAsync waiting code.
Diffstat (limited to 'bin')
-rw-r--r--bin/bbackupd/BackupDaemon.cpp235
-rw-r--r--bin/bbackupd/BackupDaemon.h2
2 files changed, 190 insertions, 47 deletions
diff --git a/bin/bbackupd/BackupDaemon.cpp b/bin/bbackupd/BackupDaemon.cpp
index 20cee30d..fdaf344f 100644
--- a/bin/bbackupd/BackupDaemon.cpp
+++ b/bin/bbackupd/BackupDaemon.cpp
@@ -40,6 +40,7 @@
#endif
#include <iostream>
+#include <set>
#include "Configuration.h"
#include "IOStream.h"
@@ -129,6 +130,28 @@
StringFromGUID2(guid, buf, sizeof(buf));
return WideStringToString(buf);
}
+
+ std::ostream& operator<< (std::ostream& o, const BSTR arg)
+ {
+ if(arg == NULL)
+ {
+ o << "(null)";
+ }
+ else
+ {
+ // Extract the *long* before where the arg points to
+ long len = ((long *)arg)[-1];
+ std::wstring wstr((WCHAR *)arg, len);
+ std::string str;
+ if(!ConvertFromWideString(wstr, &str, CP_UTF8))
+ {
+ throw std::exception("string conversion failed");
+ }
+ o << str;
+ }
+
+ return o;
+ }
# endif
#endif
@@ -1009,12 +1032,50 @@ void BackupDaemon::RunSyncNow()
}
#ifdef ENABLE_VSS
+bool BackupDaemon::WaitForAsync(IVssAsync *pAsync,
+ const std::string& description)
+{
+ BOX_INFO("VSS: waiting for " << description << " to complete");
+ HRESULT result;
+
+ do
+ {
+ result = pAsync->Wait(1000);
+ if(result != S_OK)
+ {
+ BOX_ERROR("VSS: Failed to wait for " << description <<
+ " to complete: " << GetMsgForHresult(result));
+ break;
+ }
+
+ HRESULT result2;
+ result = pAsync->QueryStatus(&result2, NULL);
+ if(result != S_OK)
+ {
+ BOX_ERROR("VSS: Failed to query " << description <<
+ " status: " << GetMsgForHresult(result));
+ break;
+ }
+
+ result = result2;
+ BOX_INFO("VSS: " << description << " status: " <<
+ GetMsgForHresult(result));
+ }
+ while(result == VSS_S_ASYNC_PENDING);
+
+ pAsync->Release();
+
+ return (result == VSS_S_ASYNC_FINISHED);
+}
+
void BackupDaemon::CreateVssBackupComponents()
{
+ std::set<char> volumesIncluded;
+
HRESULT result = CoInitialize(NULL);
if(result != S_OK)
{
- BOX_ERROR("Failed to initialize COM for VSS: " <<
+ BOX_ERROR("VSS: Failed to initialize COM: " <<
GetMsgForHresult(result));
return;
}
@@ -1022,7 +1083,7 @@ void BackupDaemon::CreateVssBackupComponents()
result = ::CreateVssBackupComponents(&mpVssBackupComponents);
if(result != S_OK)
{
- BOX_ERROR("Failed to create VSS backup components: " <<
+ BOX_ERROR("VSS: Failed to create backup components: " <<
GetMsgForHresult(result));
return;
}
@@ -1040,19 +1101,19 @@ void BackupDaemon::CreateVssBackupComponents()
"are running";
}
- BOX_ERROR("Failed to initialize VSS for backup: " << message);
+ BOX_ERROR("VSS: Failed to initialize for backup: " << message);
goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
}
result = mpVssBackupComponents->SetContext(VSS_CTX_BACKUP);
if(result == E_NOTIMPL)
{
- BOX_INFO("Failed to set VSS context to VSS_CTX_BACKUP: "
+ BOX_INFO("VSS: Failed to set context to VSS_CTX_BACKUP: "
"not implemented, probably Windows XP, ignored.");
}
else if(result != S_OK)
{
- BOX_ERROR("Failed to set VSS context to VSS_CTX_BACKUP: " <<
+ BOX_ERROR("VSS: Failed to set context to VSS_CTX_BACKUP: " <<
GetMsgForHresult(result));
goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
}
@@ -1064,62 +1125,32 @@ void BackupDaemon::CreateVssBackupComponents()
false /* what is Partial File Support? */);
if(result != S_OK)
{
- BOX_ERROR("Failed to set VSS backup state: " <<
+ BOX_ERROR("VSS: Failed to set backup state: " <<
GetMsgForHresult(result));
goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
}
- IVssAsync *pAsync;
- result = mpVssBackupComponents->GatherWriterMetadata(&pAsync);
- if(result != S_OK)
{
- BOX_ERROR("Failed to set VSS backup state: " <<
- GetMsgForHresult(result));
- goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
- }
-
- BOX_INFO("VSS: waiting for GatherWriterMetadata() to complete");
-
- do
- {
- result = pAsync->Wait(1000);
+ IVssAsync *pAsync;
+ result = mpVssBackupComponents->GatherWriterMetadata(&pAsync);
if(result != S_OK)
{
- BOX_ERROR("VSS: Failed to wait for GatherWriterMetadata() "
- "to complete: " << GetMsgForHresult(result));
- goto CreateVssBackupComponents_cleanup_pAsync;
+ BOX_ERROR("VSS: Failed to set backup state: " <<
+ GetMsgForHresult(result));
+ goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
}
- HRESULT result2;
- result = pAsync->QueryStatus(&result2, NULL);
- if(result != S_OK)
+ if(!WaitForAsync(pAsync, "GatherWriterMetadata()"))
{
- BOX_ERROR("VSS: Failed to query GatherWriterMetadata() "
- "status: " << GetMsgForHresult(result));
- goto CreateVssBackupComponents_cleanup_pAsync;
+ goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
}
-
- result = result2;
- BOX_INFO("VSS: GatherWriterMetadata() status: " <<
- GetMsgForHresult(result));
- }
- while(result == VSS_S_ASYNC_PENDING);
-
- pAsync->Release();
- pAsync = NULL;
-
- if(result != VSS_S_ASYNC_FINISHED)
- {
- BOX_ERROR("VSS: GatherWriterMetadata() failed: " <<
- GetMsgForHresult(result));
- goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
}
UINT writerCount;
result = mpVssBackupComponents->GetWriterMetadataCount(&writerCount);
if(result != S_OK)
{
- BOX_ERROR("Failed to get VSS writer count: " <<
+ BOX_ERROR("VSS: Failed to get writer count: " <<
GetMsgForHresult(result));
goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
}
@@ -1173,6 +1204,42 @@ void BackupDaemon::CreateVssBackupComponents()
continue;
}
+ BOX_INFO("VSS: writer " << iWriter << " component " <<
+ iComponent << " info:");
+ switch(pComponentInfo->type)
+ {
+ case VSS_CT_UNDEFINED: BOX_INFO("VSS: type: undefined"); break;
+ case VSS_CT_DATABASE: BOX_INFO("VSS: type: database"); break;
+ case VSS_CT_FILEGROUP: BOX_INFO("VSS: type: filegroup"); break;
+ default:
+ BOX_WARNING("VSS: type: unknown (" << pComponentInfo->type << ")");
+ }
+
+ BOX_INFO("VSS: logical path: " <<
+ pComponentInfo->bstrLogicalPath);
+ BOX_INFO("VSS: component name: " <<
+ pComponentInfo->bstrComponentName);
+ BOX_INFO("VSS: caption: " <<
+ pComponentInfo->bstrCaption);
+ BOX_INFO("VSS: restore metadata: " <<
+ pComponentInfo->bRestoreMetadata);
+ BOX_INFO("VSS: notify on complete: " <<
+ pComponentInfo->bRestoreMetadata);
+ BOX_INFO("VSS: selectable: " <<
+ pComponentInfo->bSelectable);
+ BOX_INFO("VSS: selectable for restore: " <<
+ pComponentInfo->bSelectableForRestore);
+ BOX_INFO("VSS: component flags: " <<
+ BOX_FORMAT_HEX32(pComponentInfo->dwComponentFlags));
+ BOX_INFO("VSS: file count: " <<
+ pComponentInfo->cFileCount);
+ BOX_INFO("VSS: databases: " <<
+ pComponentInfo->cDatabases);
+ BOX_INFO("VSS: log files: " <<
+ pComponentInfo->cLogFiles);
+ BOX_INFO("VSS: dependencies: " <<
+ pComponentInfo->cDependencies);
+
pComponent->FreeComponentInfo(pComponentInfo);
pComponent->Release();
}
@@ -1180,6 +1247,83 @@ void BackupDaemon::CreateVssBackupComponents()
pMetadata->Release();
}
+ VSS_ID snapshotSetId;
+ result = mpVssBackupComponents->StartSnapshotSet(&snapshotSetId);
+ if(result != S_OK)
+ {
+ BOX_ERROR("VSS: Failed to start snapshot set: " <<
+ GetMsgForHresult(result));
+ goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
+ }
+
+ // Add all volumes included as backup locations to the snapshot set
+ for(std::vector<Location *>::iterator
+ iLocation = mLocations.begin();
+ iLocation != mLocations.end();
+ iLocation++)
+ {
+ Location& rLocation(**iLocation);
+ std::string path = rLocation.mPath;
+ // convert to absolute and remove leading \\?\
+ path = ConvertPathToAbsoluteUnicode(path.c_str()).substr(4);
+
+ if(path.length() >= 3 && path[1] == ':' && path[2] == '\\')
+ {
+ std::string volumeRoot = path.substr(0, 3);
+
+ if(volumesIncluded.find(path[0]) == volumesIncluded.end())
+ {
+ std::wstring volumeRootWide;
+ volumeRootWide[0] = (WCHAR) path[0];
+ volumeRootWide[1] = (WCHAR) ':';
+ volumeRootWide[2] = (WCHAR) '\\';
+ VSS_ID newVolumeId;
+ result = mpVssBackupComponents->AddToSnapshotSet(
+ (VSS_PWSZ)(volumeRootWide.c_str()), GUID_NULL,
+ &newVolumeId);
+ if(result == S_OK)
+ {
+ BOX_TRACE("VSS: Added volume " << volumeRoot <<
+ " for backup location " << path <<
+ " to snapshot set");
+ }
+ else
+ {
+ BOX_ERROR("VSS: Failed to add volume " <<
+ volumeRoot << " to snapshot set: " <<
+ GetMsgForHresult(result));
+ goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
+ }
+ }
+ else
+ {
+ BOX_TRACE("VSS: Skipping already included volume " <<
+ volumeRoot << " for backup location " << path);
+ }
+ }
+ else
+ {
+ BOX_WARNING("VSS: Skipping backup location " << path <<
+ " which does not start with a volume specification");
+ }
+ }
+
+ {
+ IVssAsync *pAsync;
+ result = mpVssBackupComponents->PrepareForBackup(&pAsync);
+ if(result != S_OK)
+ {
+ BOX_ERROR("VSS: Failed to prepare for backup: " <<
+ GetMsgForHresult(result));
+ goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
+ }
+
+ if(!WaitForAsync(pAsync, "PrepareForBackup()"))
+ {
+ goto CreateVssBackupComponents_cleanup_mpVssBackupComponents;
+ }
+ }
+
IVssEnumObject *pEnum;
result = mpVssBackupComponents->Query(GUID_NULL, VSS_OBJECT_NONE,
VSS_OBJECT_SNAPSHOT, &pEnum);
@@ -1278,9 +1422,6 @@ void BackupDaemon::CreateVssBackupComponents()
pEnum->Release();
-CreateVssBackupComponents_cleanup_pAsync:
- pAsync->Release();
-
CreateVssBackupComponents_cleanup_mpVssBackupComponents:
mpVssBackupComponents->Release();
mpVssBackupComponents = NULL;
diff --git a/bin/bbackupd/BackupDaemon.h b/bin/bbackupd/BackupDaemon.h
index 3cad256f..a3bbbf3b 100644
--- a/bin/bbackupd/BackupDaemon.h
+++ b/bin/bbackupd/BackupDaemon.h
@@ -33,6 +33,7 @@
#ifdef ENABLE_VSS
class IVssBackupComponents;
+ struct IVssAsync;
#endif
class BackupClientDirectoryRecord;
@@ -530,6 +531,7 @@ public:
#ifdef ENABLE_VSS
IVssBackupComponents* mpVssBackupComponents;
void CreateVssBackupComponents();
+ bool WaitForAsync(IVssAsync *pAsync, const std::string& description);
#endif
};