Skip to content

Commit 0692b03

Browse files
chenhanxiaomdroth
authored andcommitted
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 <[email protected]> Signed-off-by: Chen Hanxiao <[email protected]> Signed-off-by: Michael Roth <[email protected]>
1 parent bad0227 commit 0692b03

File tree

6 files changed

+91
-45
lines changed

6 files changed

+91
-45
lines changed

qga/commands-win32.c

+9-12
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,13 @@ GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
790790
* The frozen state is limited for up to 10 seconds by VSS.
791791
*/
792792
int64_t qmp_guest_fsfreeze_freeze(Error **errp)
793+
{
794+
return qmp_guest_fsfreeze_freeze_list(false, NULL, errp);
795+
}
796+
797+
int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
798+
strList *mountpoints,
799+
Error **errp)
793800
{
794801
int i;
795802
Error *local_err = NULL;
@@ -804,7 +811,7 @@ int64_t qmp_guest_fsfreeze_freeze(Error **errp)
804811
/* cannot risk guest agent blocking itself on a write in this state */
805812
ga_set_frozen(ga_state);
806813

807-
qga_vss_fsfreeze(&i, true, &local_err);
814+
qga_vss_fsfreeze(&i, true, mountpoints, &local_err);
808815
if (local_err) {
809816
error_propagate(errp, local_err);
810817
goto error;
@@ -822,15 +829,6 @@ int64_t qmp_guest_fsfreeze_freeze(Error **errp)
822829
return 0;
823830
}
824831

825-
int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
826-
strList *mountpoints,
827-
Error **errp)
828-
{
829-
error_setg(errp, QERR_UNSUPPORTED);
830-
831-
return 0;
832-
}
833-
834832
/*
835833
* Thaw local file systems using Volume Shadow-copy Service.
836834
*/
@@ -843,7 +841,7 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp)
843841
return 0;
844842
}
845843

846-
qga_vss_fsfreeze(&i, false, errp);
844+
qga_vss_fsfreeze(&i, false, NULL, errp);
847845

848846
ga_unset_frozen(ga_state);
849847
return i;
@@ -1660,7 +1658,6 @@ GList *ga_command_blacklist_init(GList *blacklist)
16601658
"guest-set-vcpus",
16611659
"guest-get-memory-blocks", "guest-set-memory-blocks",
16621660
"guest-get-memory-block-size",
1663-
"guest-fsfreeze-freeze-list",
16641661
NULL};
16651662
char **p = (char **)list_unsupported;
16661663

qga/main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static void quit_handler(int sig)
151151
WaitForSingleObject(hEventTimeout, 0);
152152
CloseHandle(hEventTimeout);
153153
}
154-
qga_vss_fsfreeze(&i, false, &err);
154+
qga_vss_fsfreeze(&i, false, NULL, &err);
155155
if (err) {
156156
g_debug("Error unfreezing filesystems prior to exiting: %s",
157157
error_get_pretty(err));

qga/vss-win32.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ void ga_uninstall_vss_provider(void)
147147
}
148148

149149
/* Call VSS requester and freeze/thaw filesystems and applications */
150-
void qga_vss_fsfreeze(int *nr_volume, bool freeze, Error **errp)
150+
void qga_vss_fsfreeze(int *nr_volume, bool freeze,
151+
strList *mountpoints, Error **errp)
151152
{
152153
const char *func_name = freeze ? "requester_freeze" : "requester_thaw";
153154
QGAVSSRequesterFunc func;
@@ -164,5 +165,5 @@ void qga_vss_fsfreeze(int *nr_volume, bool freeze, Error **errp)
164165
return;
165166
}
166167

167-
func(nr_volume, &errset);
168+
func(nr_volume, mountpoints, &errset);
168169
}

qga/vss-win32.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ bool vss_initialized(void);
2222
int ga_install_vss_provider(void);
2323
void ga_uninstall_vss_provider(void);
2424

25-
void qga_vss_fsfreeze(int *nr_volume, bool freeze, Error **errp);
25+
void qga_vss_fsfreeze(int *nr_volume, bool freeze,
26+
strList *mountpints, Error **errp);
2627

2728
#endif

qga/vss-win32/requester.cpp

+66-26
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ static void AddComponents(ErrorSet *errset)
234234
}
235235
}
236236

237-
void requester_freeze(int *num_vols, ErrorSet *errset)
237+
void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
238238
{
239239
COMPointer<IVssAsync> pAsync;
240240
HANDLE volume;
@@ -246,6 +246,7 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
246246
WCHAR short_volume_name[64], *display_name = short_volume_name;
247247
DWORD wait_status;
248248
int num_fixed_drives = 0, i;
249+
int num_mount_points = 0;
249250

250251
if (vss_ctx.pVssbc) { /* already frozen */
251252
*num_vols = 0;
@@ -337,39 +338,73 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
337338
goto out;
338339
}
339340

340-
volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name));
341-
if (volume == INVALID_HANDLE_VALUE) {
342-
err_set(errset, hr, "failed to find first volume");
343-
goto out;
344-
}
345-
for (;;) {
346-
if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) {
341+
if (mountpoints) {
342+
PWCHAR volume_name_wchar;
343+
for (volList *list = (volList *)mountpoints; list; list = list->next) {
344+
size_t len = strlen(list->value) + 1;
345+
size_t converted = 0;
347346
VSS_ID pid;
348-
hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name,
347+
348+
volume_name_wchar = new wchar_t[len];
349+
mbstowcs_s(&converted, volume_name_wchar, len,
350+
list->value, _TRUNCATE);
351+
352+
hr = vss_ctx.pVssbc->AddToSnapshotSet(volume_name_wchar,
349353
g_gProviderId, &pid);
350354
if (FAILED(hr)) {
351-
WCHAR volume_path_name[PATH_MAX];
352-
if (GetVolumePathNamesForVolumeNameW(
353-
short_volume_name, volume_path_name,
354-
sizeof(volume_path_name), NULL) && *volume_path_name) {
355-
display_name = volume_path_name;
356-
}
357355
err_set(errset, hr, "failed to add %S to snapshot set",
358-
display_name);
359-
FindVolumeClose(volume);
356+
volume_name_wchar);
357+
delete volume_name_wchar;
360358
goto out;
361359
}
362-
num_fixed_drives++;
360+
num_mount_points++;
361+
362+
delete volume_name_wchar;
363363
}
364-
if (!FindNextVolumeW(volume, short_volume_name,
365-
sizeof(short_volume_name))) {
366-
FindVolumeClose(volume);
367-
break;
364+
365+
if (num_mount_points == 0) {
366+
/* If there is no valid mount points, just exit. */
367+
goto out;
368368
}
369369
}
370370

371-
if (num_fixed_drives == 0) {
372-
goto out; /* If there is no fixed drive, just exit. */
371+
if (!mountpoints) {
372+
volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name));
373+
if (volume == INVALID_HANDLE_VALUE) {
374+
err_set(errset, hr, "failed to find first volume");
375+
goto out;
376+
}
377+
378+
for (;;) {
379+
if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) {
380+
VSS_ID pid;
381+
hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name,
382+
g_gProviderId, &pid);
383+
if (FAILED(hr)) {
384+
WCHAR volume_path_name[PATH_MAX];
385+
if (GetVolumePathNamesForVolumeNameW(
386+
short_volume_name, volume_path_name,
387+
sizeof(volume_path_name), NULL) &&
388+
*volume_path_name) {
389+
display_name = volume_path_name;
390+
}
391+
err_set(errset, hr, "failed to add %S to snapshot set",
392+
display_name);
393+
FindVolumeClose(volume);
394+
goto out;
395+
}
396+
num_fixed_drives++;
397+
}
398+
if (!FindNextVolumeW(volume, short_volume_name,
399+
sizeof(short_volume_name))) {
400+
FindVolumeClose(volume);
401+
break;
402+
}
403+
}
404+
405+
if (num_fixed_drives == 0) {
406+
goto out; /* If there is no fixed drive, just exit. */
407+
}
373408
}
374409

375410
hr = vss_ctx.pVssbc->PrepareForBackup(pAsync.replace());
@@ -435,7 +470,12 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
435470
goto out;
436471
}
437472

438-
*num_vols = vss_ctx.cFrozenVols = num_fixed_drives;
473+
if (mountpoints) {
474+
*num_vols = vss_ctx.cFrozenVols = num_mount_points;
475+
} else {
476+
*num_vols = vss_ctx.cFrozenVols = num_fixed_drives;
477+
}
478+
439479
return;
440480

441481
out:
@@ -449,7 +489,7 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
449489
}
450490

451491

452-
void requester_thaw(int *num_vols, ErrorSet *errset)
492+
void requester_thaw(int *num_vols, void *mountpints, ErrorSet *errset)
453493
{
454494
COMPointer<IVssAsync> pAsync;
455495

qga/vss-win32/requester.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,16 @@ typedef struct ErrorSet {
3434
STDAPI requester_init(void);
3535
STDAPI requester_deinit(void);
3636

37-
typedef void (*QGAVSSRequesterFunc)(int *, ErrorSet *);
38-
void requester_freeze(int *num_vols, ErrorSet *errset);
39-
void requester_thaw(int *num_vols, ErrorSet *errset);
37+
typedef struct volList volList;
38+
39+
struct volList {
40+
volList *next;
41+
char *value;
42+
};
43+
44+
typedef void (*QGAVSSRequesterFunc)(int *, void *, ErrorSet *);
45+
void requester_freeze(int *num_vols, void *volList, ErrorSet *errset);
46+
void requester_thaw(int *num_vols, void *volList, ErrorSet *errset);
4047

4148
#ifdef __cplusplus
4249
}

0 commit comments

Comments
 (0)