From nobody Wed Nov 5 07:15:24 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=126.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1533863788995775.3132888565416; Thu, 9 Aug 2018 18:16:28 -0700 (PDT) Received: from localhost ([::1]:53821 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fnw2M-0004Bf-IJ for importer@patchew.org; Thu, 09 Aug 2018 21:16:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56061) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fnw1G-0002yd-KF for qemu-devel@nongnu.org; Thu, 09 Aug 2018 21:15:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fnw1D-0004ds-BK for qemu-devel@nongnu.org; Thu, 09 Aug 2018 21:15:10 -0400 Received: from m15-112.126.com ([220.181.15.112]:54365) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fnw1C-0004bK-KA for qemu-devel@nongnu.org; Thu, 09 Aug 2018 21:15:07 -0400 Received: from localhost.localdomain (unknown [58.213.111.46]) by smtp2 (Coremail) with SMTP id DMmowADXrTYN52xbW+BbEw--.36540S2; Fri, 10 Aug 2018 09:14:58 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-Id; bh=O4px9j8BAy1rHuQL8O uNZFutfbi5WZfKG0Pyxl7ef4E=; b=elefItqa0i2R9fN0iAUDx7+J/m6Tf7nUXB KuEqkht+75X0GRN+w4WjgyJJN4rnM+qAdUz0DXILT9ATVXDIcAvd1RoYBkkjJphy PjRpQtxHMT5463H10gp/oeZHTjrJoh2UjK9N+YocWAutVylYme+QY0MysvQ4liee bg4Ov/9xM= From: Chen Hanxiao To: qemu-devel@nongnu.org Date: Fri, 10 Aug 2018 09:13:48 +0800 Message-Id: <20180810011348.8952-1-chen_han_xiao@126.com> X-Mailer: git-send-email 2.17.1 X-CM-TRANSID: DMmowADXrTYN52xbW+BbEw--.36540S2 X-Coremail-Antispam: 1Uf129KBjvJXoW3Jr4rZFy8uw45Xw4xuF18AFb_yoW3uFy5pr sxGrn3Kr40qr17tryxWw1rAFyrGa95A3W8Cr1qk342v3ZYqF95AwsFkFy5uF1xCr48X3yS va95XrWruw4UCr7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jQJ5rUUUUU= X-Originating-IP: [58.213.111.46] X-CM-SenderInfo: xfkh0spkdqs5xldrqiyswou0bp/1tbi4xyerlpD6fN7GgABss X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 220.181.15.112 Subject: [Qemu-devel] [resend][PATCH] qga-win: add support for qmp_guest_fsfreeze_freeze_list X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mdroth@linux.vnet.ibm.com, Chen Hanxiao Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Chen Hanxiao 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-vsback= up-ivssbackupcomponents-addtosnapshotset Cc: Michael Roth Signed-off-by: Chen Hanxiao --- qga/commands-win32.c | 21 ++++++-------- qga/main.c | 2 +- qga/vss-win32.c | 5 ++-- qga/vss-win32.h | 3 +- qga/vss-win32/requester.cpp | 56 +++++++++++++++++++++++++++++++------ qga/vss-win32/requester.h | 13 +++++++-- 6 files changed, 72 insertions(+), 28 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 98d9735389..1d627f73c1 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -776,6 +776,13 @@ GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **= errp) * 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 =3D NULL; @@ -790,7 +797,7 @@ int64_t qmp_guest_fsfreeze_freeze(Error **errp) /* cannot risk guest agent blocking itself on a write in this state */ ga_set_frozen(ga_state); =20 - 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; @@ -808,15 +815,6 @@ error: return 0; } =20 -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. */ @@ -829,7 +827,7 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp) return 0; } =20 - qga_vss_fsfreeze(&i, false, errp); + qga_vss_fsfreeze(&i, false, NULL, errp); =20 ga_unset_frozen(ga_state); return i; @@ -1646,7 +1644,6 @@ GList *ga_command_blacklist_init(GList *blacklist) "guest-set-vcpus", "guest-get-memory-blocks", "guest-set-memory-blocks", "guest-get-memory-block-size", - "guest-fsfreeze-freeze-list", NULL}; char **p =3D (char **)list_unsupported; =20 diff --git a/qga/main.c b/qga/main.c index 87372d40ef..098c783f1f 100644 --- a/qga/main.c +++ b/qga/main.c @@ -152,7 +152,7 @@ static void quit_handler(int sig) WaitForSingleObject(hEventTimeout, 0); CloseHandle(hEventTimeout); } - qga_vss_fsfreeze(&i, false, &err); + qga_vss_fsfreeze(&i, false, NULL, &err); if (err) { g_debug("Error unfreezing filesystems prior to exiting: %s", error_get_pretty(err)); diff --git a/qga/vss-win32.c b/qga/vss-win32.c index a541f3ae01..f444a25a70 100644 --- a/qga/vss-win32.c +++ b/qga/vss-win32.c @@ -147,7 +147,8 @@ void ga_uninstall_vss_provider(void) } =20 /* Call VSS requester and freeze/thaw filesystems and applications */ -void qga_vss_fsfreeze(int *nr_volume, bool freeze, Error **errp) +void qga_vss_fsfreeze(int *nr_volume, bool freeze, + strList *mountpoints, Error **errp) { const char *func_name =3D freeze ? "requester_freeze" : "requester_tha= w"; QGAVSSRequesterFunc func; @@ -164,5 +165,5 @@ void qga_vss_fsfreeze(int *nr_volume, bool freeze, Erro= r **errp) return; } =20 - func(nr_volume, &errset); + func(nr_volume, mountpoints, &errset); } diff --git a/qga/vss-win32.h b/qga/vss-win32.h index 4f8e39aa5c..ce2abe5a72 100644 --- a/qga/vss-win32.h +++ b/qga/vss-win32.h @@ -22,6 +22,7 @@ bool vss_initialized(void); int ga_install_vss_provider(void); void ga_uninstall_vss_provider(void); =20 -void qga_vss_fsfreeze(int *nr_volume, bool freeze, Error **errp); +void qga_vss_fsfreeze(int *nr_volume, bool freeze, + strList *mountpints, Error **errp); =20 #endif diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp index 3d9c9716c0..0bd170eddc 100644 --- a/qga/vss-win32/requester.cpp +++ b/qga/vss-win32/requester.cpp @@ -234,7 +234,7 @@ out: } } =20 -void requester_freeze(int *num_vols, ErrorSet *errset) +void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset) { COMPointer pAsync; HANDLE volume; @@ -245,7 +245,9 @@ void requester_freeze(int *num_vols, ErrorSet *errset) SECURITY_ATTRIBUTES sa; WCHAR short_volume_name[64], *display_name =3D short_volume_name; DWORD wait_status; + PWCHAR WStr =3D NULL; int num_fixed_drives =3D 0, i; + int num_mount_points =3D 0; =20 if (vss_ctx.pVssbc) { /* already frozen */ *num_vols =3D 0; @@ -337,12 +339,42 @@ void requester_freeze(int *num_vols, ErrorSet *errset) goto out; } =20 - volume =3D FindFirstVolumeW(short_volume_name, sizeof(short_volume_nam= e)); - if (volume =3D=3D INVALID_HANDLE_VALUE) { - err_set(errset, hr, "failed to find first volume"); + if (mountpoints) { + for (volList *list =3D (volList *)mountpoints; list; list =3D list= ->next) { + size_t len =3D strlen(list->value) + 1; + size_t converted =3D 0; + VSS_ID pid; + + WStr =3D new wchar_t[len]; + mbstowcs_s(&converted, WStr, len, list->value, _TRUNCATE); + + hr =3D vss_ctx.pVssbc->AddToSnapshotSet(WStr, + g_gProviderId, &pid); + if (FAILED(hr)) { + err_set(errset, hr, "failed to add %S to snapshot set", WS= tr); + goto out; + } + num_mount_points++; + + delete WStr; + } + } + + if (mountpoints && num_mount_points =3D=3D 0) { + /* If there is no valid mount points, just exit. */ goto out; } - for (;;) { + + + if (!mountpoints) { + volume =3D FindFirstVolumeW(short_volume_name, sizeof(short_volume= _name)); + if (volume =3D=3D INVALID_HANDLE_VALUE) { + err_set(errset, hr, "failed to find first volume"); + goto out; + } + } + + while (!mountpoints) { if (GetDriveTypeW(short_volume_name) =3D=3D DRIVE_FIXED) { VSS_ID pid; hr =3D vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name, @@ -355,7 +387,7 @@ void requester_freeze(int *num_vols, ErrorSet *errset) display_name =3D volume_path_name; } err_set(errset, hr, "failed to add %S to snapshot set", - display_name); + display_name); FindVolumeClose(volume); goto out; } @@ -368,7 +400,7 @@ void requester_freeze(int *num_vols, ErrorSet *errset) } } =20 - if (num_fixed_drives =3D=3D 0) { + if (!mountpoints && num_fixed_drives =3D=3D 0) { goto out; /* If there is no fixed drive, just exit. */ } =20 @@ -435,13 +467,19 @@ void requester_freeze(int *num_vols, ErrorSet *errset) goto out; } =20 - *num_vols =3D vss_ctx.cFrozenVols =3D num_fixed_drives; + if (mountpoints) { + *num_vols =3D vss_ctx.cFrozenVols =3D num_mount_points; + } else { + *num_vols =3D vss_ctx.cFrozenVols =3D num_fixed_drives; + } + return; =20 out: if (vss_ctx.pVssbc) { vss_ctx.pVssbc->AbortBackup(); } + delete WStr; =20 out1: requester_cleanup(); @@ -449,7 +487,7 @@ out1: } =20 =20 -void requester_thaw(int *num_vols, ErrorSet *errset) +void requester_thaw(int *num_vols, void *mountpints, ErrorSet *errset) { COMPointer pAsync; =20 diff --git a/qga/vss-win32/requester.h b/qga/vss-win32/requester.h index 2a39d734a2..5a8e8faf0c 100644 --- a/qga/vss-win32/requester.h +++ b/qga/vss-win32/requester.h @@ -34,9 +34,16 @@ typedef struct ErrorSet { STDAPI requester_init(void); STDAPI requester_deinit(void); =20 -typedef void (*QGAVSSRequesterFunc)(int *, ErrorSet *); -void requester_freeze(int *num_vols, ErrorSet *errset); -void requester_thaw(int *num_vols, ErrorSet *errset); +typedef struct volList volList; + +struct volList { + volList *next; + char *value; +}; + +typedef void (*QGAVSSRequesterFunc)(int *, void *, ErrorSet *); +void requester_freeze(int *num_vols, void *volList, ErrorSet *errset); +void requester_thaw(int *num_vols, void *volList, ErrorSet *errset); =20 #ifdef __cplusplus } --=20 2.17.1