* The frozen state is limited for up to 10 seconds by VSS.
*/
int64_t qmp_guest_fsfreeze_freeze(Error **errp)
+{
+ return qmp_guest_fsfreeze_freeze_list(false, NULL, errp);
+}
+
+int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
+ strList *mountpoints,
+ Error **errp)
{
int i;
Error *local_err = NULL;
/* cannot risk guest agent blocking itself on a write in this state */
ga_set_frozen(ga_state);
- qga_vss_fsfreeze(&i, true, &local_err);
+ qga_vss_fsfreeze(&i, true, mountpoints, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto error;
return 0;
}
-int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
- strList *mountpoints,
- Error **errp)
-{
- error_setg(errp, QERR_UNSUPPORTED);
-
- return 0;
-}
-
/*
* Thaw local file systems using Volume Shadow-copy Service.
*/
return 0;
}
- qga_vss_fsfreeze(&i, false, errp);
+ qga_vss_fsfreeze(&i, false, NULL, errp);
ga_unset_frozen(ga_state);
return i;
"guest-set-vcpus",
"guest-get-memory-blocks", "guest-set-memory-blocks",
"guest-get-memory-block-size",
- "guest-fsfreeze-freeze-list",
NULL};
char **p = (char **)list_unsupported;
}
}
-void requester_freeze(int *num_vols, ErrorSet *errset)
+void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
{
COMPointer<IVssAsync> pAsync;
HANDLE volume;
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;
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());
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:
}
-void requester_thaw(int *num_vols, ErrorSet *errset)
+void requester_thaw(int *num_vols, void *mountpints, ErrorSet *errset)
{
COMPointer<IVssAsync> pAsync;