All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, Chen Hanxiao <chenhanxiao@gmail.com>
Subject: [Qemu-devel] [PULL v2 02/24] qga-win: add support for qmp_guest_fsfreeze_freeze_list
Date: Tue, 30 Oct 2018 20:37:59 -0500	[thread overview]
Message-ID: <20181031013821.24023-3-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <20181031013821.24023-1-mdroth@linux.vnet.ibm.com>

From: Chen Hanxiao <chenhanxiao@gmail.com>

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>
---
 qga/commands-win32.c        | 21 ++++-----
 qga/main.c                  |  2 +-
 qga/vss-win32.c             |  5 +-
 qga/vss-win32.h             |  3 +-
 qga/vss-win32/requester.cpp | 92 ++++++++++++++++++++++++++-----------
 qga/vss-win32/requester.h   | 13 ++++--
 6 files changed, 91 insertions(+), 45 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 416343b97b..347577f2a4 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -790,6 +790,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 = NULL;
@@ -804,7 +811,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);
 
-    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;
@@ -822,15 +829,6 @@ 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.
  */
@@ -843,7 +841,7 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp)
         return 0;
     }
 
-    qga_vss_fsfreeze(&i, false, errp);
+    qga_vss_fsfreeze(&i, false, NULL, errp);
 
     ga_unset_frozen(ga_state);
     return i;
@@ -1660,7 +1658,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 = (char **)list_unsupported;
 
diff --git a/qga/main.c b/qga/main.c
index c399320d3c..afcd268ee3 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -151,7 +151,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)
 }
 
 /* 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 = freeze ? "requester_freeze" : "requester_thaw";
     QGAVSSRequesterFunc func;
@@ -164,5 +165,5 @@ void qga_vss_fsfreeze(int *nr_volume, bool freeze, Error **errp)
         return;
     }
 
-    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);
 
-void qga_vss_fsfreeze(int *nr_volume, bool freeze, Error **errp);
+void qga_vss_fsfreeze(int *nr_volume, bool freeze,
+                      strList *mountpints, Error **errp);
 
 #endif
diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp
index 3d9c9716c0..5378c55d23 100644
--- a/qga/vss-win32/requester.cpp
+++ b/qga/vss-win32/requester.cpp
@@ -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;
 
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);
 
-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);
 
 #ifdef __cplusplus
 }
-- 
2.17.1

  parent reply	other threads:[~2018-10-31  1:41 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-31  1:37 [Qemu-devel] [PULL v2 00/24] qemu-ga patch queue for soft-freeze Michael Roth
2018-10-31  1:37 ` [Qemu-devel] [PULL v2 01/24] qga: Support Unicode paths in guest-file-open on win32 Michael Roth
2018-10-31  1:37 ` Michael Roth [this message]
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 03/24] qga: ignore non present cpus when handling qmp_guest_get_vcpus() Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 04/24] configure: add test for libudev Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 05/24] qga: linux: report disk serial number Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 06/24] qga: linux: return disk device in guest-get-fsinfo Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 07/24] qga-win: prevent crash when executing fsinfo command Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 08/24] qga-win: fsinfo: pci-info: allow partial info Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 09/24] build: rename CONFIG_QGA_NTDDDISK to CONFIG_QGA_NTDDSCSI Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 10/24] qga-win: add debugging information Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 11/24] qga-win: refactor disk properties (bus) Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 12/24] qga-win: report disk serial number Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 13/24] qga-win: refactor disk info Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 14/24] qga-win: handle multi-disk volumes Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 15/24] qga-win: return disk device in guest-get-fsinfo Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 16/24] qga-win: demystify namespace stripping Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 17/24] qga: fix an off-by-one issue Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 18/24] qga: group agent init/cleanup init separate routines Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 19/24] qga: hang GAConfig/socket_activation off of GAState global Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 20/24] qga: move w32 service handling out of run_agent() Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 21/24] qga: add --retry-path option for re-initializing channel on failure Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 22/24] qga-win: install service with --retry-path set by default Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 23/24] qga-win: report specific error when failing to open channel Michael Roth
2018-10-31  1:38 ` [Qemu-devel] [PULL v2 24/24] qga-win: changing --retry-path option behavior Michael Roth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181031013821.24023-3-mdroth@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=chenhanxiao@gmail.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.