qga-win: add support for qmp_guest_fsfreeze_freeze_list

This patch add support for freeze specified fs.

The valid mountpoints list member are [1]:

  The path of a mounted folder, for example, Y:\MountX\
  A drive letter, for example, D:\
  A volume GUID path of the form \\?\Volume{GUID}\,
      where GUID identifies the volume
  A UNC path that specifies a remote file share,
      for example, \\Clusterx\Share1\

[1] https://docs.microsoft.com/en-us/windows/desktop/api/vsbackup/nf-vsbackup-ivssbackupcomponents-addtosnapshotset

Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
Chen Hanxiao 2018-08-31 14:22:50 +08:00 committed by Michael Roth
parent bad0227d3a
commit 0692b03ee1
6 changed files with 91 additions and 45 deletions

View file

@ -234,7 +234,7 @@ out:
}
}
void requester_freeze(int *num_vols, ErrorSet *errset)
void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
{
COMPointer<IVssAsync> pAsync;
HANDLE volume;
@ -246,6 +246,7 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
WCHAR short_volume_name[64], *display_name = short_volume_name;
DWORD wait_status;
int num_fixed_drives = 0, i;
int num_mount_points = 0;
if (vss_ctx.pVssbc) { /* already frozen */
*num_vols = 0;
@ -337,39 +338,73 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
goto out;
}
volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name));
if (volume == INVALID_HANDLE_VALUE) {
err_set(errset, hr, "failed to find first volume");
goto out;
}
for (;;) {
if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) {
if (mountpoints) {
PWCHAR volume_name_wchar;
for (volList *list = (volList *)mountpoints; list; list = list->next) {
size_t len = strlen(list->value) + 1;
size_t converted = 0;
VSS_ID pid;
hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name,
volume_name_wchar = new wchar_t[len];
mbstowcs_s(&converted, volume_name_wchar, len,
list->value, _TRUNCATE);
hr = vss_ctx.pVssbc->AddToSnapshotSet(volume_name_wchar,
g_gProviderId, &pid);
if (FAILED(hr)) {
WCHAR volume_path_name[PATH_MAX];
if (GetVolumePathNamesForVolumeNameW(
short_volume_name, volume_path_name,
sizeof(volume_path_name), NULL) && *volume_path_name) {
display_name = volume_path_name;
}
err_set(errset, hr, "failed to add %S to snapshot set",
display_name);
FindVolumeClose(volume);
volume_name_wchar);
delete volume_name_wchar;
goto out;
}
num_fixed_drives++;
num_mount_points++;
delete volume_name_wchar;
}
if (!FindNextVolumeW(volume, short_volume_name,
sizeof(short_volume_name))) {
FindVolumeClose(volume);
break;
if (num_mount_points == 0) {
/* If there is no valid mount points, just exit. */
goto out;
}
}
if (num_fixed_drives == 0) {
goto out; /* If there is no fixed drive, just exit. */
if (!mountpoints) {
volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name));
if (volume == INVALID_HANDLE_VALUE) {
err_set(errset, hr, "failed to find first volume");
goto out;
}
for (;;) {
if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) {
VSS_ID pid;
hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name,
g_gProviderId, &pid);
if (FAILED(hr)) {
WCHAR volume_path_name[PATH_MAX];
if (GetVolumePathNamesForVolumeNameW(
short_volume_name, volume_path_name,
sizeof(volume_path_name), NULL) &&
*volume_path_name) {
display_name = volume_path_name;
}
err_set(errset, hr, "failed to add %S to snapshot set",
display_name);
FindVolumeClose(volume);
goto out;
}
num_fixed_drives++;
}
if (!FindNextVolumeW(volume, short_volume_name,
sizeof(short_volume_name))) {
FindVolumeClose(volume);
break;
}
}
if (num_fixed_drives == 0) {
goto out; /* If there is no fixed drive, just exit. */
}
}
hr = vss_ctx.pVssbc->PrepareForBackup(pAsync.replace());
@ -435,7 +470,12 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
goto out;
}
*num_vols = vss_ctx.cFrozenVols = num_fixed_drives;
if (mountpoints) {
*num_vols = vss_ctx.cFrozenVols = num_mount_points;
} else {
*num_vols = vss_ctx.cFrozenVols = num_fixed_drives;
}
return;
out:
@ -449,7 +489,7 @@ out1:
}
void requester_thaw(int *num_vols, ErrorSet *errset)
void requester_thaw(int *num_vols, void *mountpints, ErrorSet *errset)
{
COMPointer<IVssAsync> pAsync;