qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 5/6] qga: Add timeout for fsfreeze


From: Konstantin Kostiuk
Subject: Re: [PATCH 5/6] qga: Add timeout for fsfreeze
Date: Thu, 26 Oct 2023 12:16:09 +0300


I think it is better to check that timeout <= 10 sec in the case of Windows.
Anyway this is a VSS limitation and FS will be unfrozen earlier if timeout > 10 sec,
this can cause some misunderstanding from a user.

timeout option sounds good in the guest-fsfreeze-freeze command.
In guest-fsfreeze-freeze-list, it looks strange to me. Command returns 
list but takes timeout option. Can you explain timeout usage in this command?

On Wed, Oct 25, 2023 at 5:01 PM Alexander Ivanov <alexander.ivanov@virtuozzo.com> wrote:
In some cases it would be useful to thaw a filesystem by timeout after
freezing this filesystem by guest-fsfreeze-freeze-list. Add an optional
argument "timeout" to the command.

Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
---
 qga/commands-posix.c   | 21 ++++++++++++++++++---
 qga/commands-win32.c   | 16 ++++++++++++++--
 qga/guest-agent-core.h |  3 ++-
 qga/main.c             | 19 ++++++++++++++++++-
 qga/qapi-schema.json   |  9 ++++++++-
 5 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 26711a1a72..e8a79e0a41 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -707,13 +707,17 @@ GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
     return GUEST_FSFREEZE_STATUS_THAWED;
 }

-int64_t qmp_guest_fsfreeze_freeze(Error **errp)
+int64_t qmp_guest_fsfreeze_freeze(bool has_timeout, int64_t timeout,
+                                  Error **errp)
 {
-    return qmp_guest_fsfreeze_freeze_list(false, NULL, errp);
+    return qmp_guest_fsfreeze_freeze_list(false, NULL, has_timeout, timeout,
+                                          errp);
 }

 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
                                        strList *mountpoints,
+                                       bool has_timeout,
+                                       int64_t timeout,
                                        Error **errp)
 {
     int ret;
@@ -734,8 +738,11 @@ int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
         return -1;
     }

+    if (!has_timeout || timeout < 0) {
+        timeout = 0;
+    }
     /* cannot risk guest agent blocking itself on a write in this state */
-    ga_set_frozen(ga_state);
+    ga_set_frozen(ga_state, timeout);

     ret = qmp_guest_fsfreeze_do_freeze_list(has_mountpoints, mountpoints,
                                             mounts, errp);
@@ -780,6 +787,12 @@ static void guest_fsfreeze_cleanup(void)
         }
     }
 }
+
+gboolean ga_frozen_timeout_cb(gpointer data)
+{
+    guest_fsfreeze_cleanup();
+    return G_SOURCE_REMOVE;
+}
 #endif

 /* linux-specific implementations. avoid this if at all possible. */
@@ -3119,6 +3132,8 @@ int64_t qmp_guest_fsfreeze_freeze(Error **errp)

 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
                                        strList *mountpoints,
+                                       bool has_timeout,
+                                       int64_t timeout,
                                        Error **errp)
 {
     error_setg(errp, QERR_UNSUPPORTED);
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 618d862c00..51fd6dcd58 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -1221,13 +1221,16 @@ GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
  * Freeze local file systems using Volume Shadow-copy Service.
  * The frozen state is limited for up to 10 seconds by VSS.
  */
-int64_t qmp_guest_fsfreeze_freeze(Error **errp)
+int64_t qmp_guest_fsfreeze_freeze(bool has_timeout, int64_t timeout,
+                                  Error **errp)
 {
     return qmp_guest_fsfreeze_freeze_list(false, NULL, errp);
 }

 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
                                        strList *mountpoints,
+                                       bool has_timeout,
+                                       int64_t timeout,
                                        Error **errp)
 {
     int i;
@@ -1240,8 +1243,11 @@ int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,

     slog("guest-fsfreeze called");

+    if (!has_timeout || timeout < 0) {
+        timeout = 0;
+    }
     /* cannot risk guest agent blocking itself on a write in this state */
-    ga_set_frozen(ga_state);
+    ga_set_frozen(ga_state, timeout);

     qga_vss_fsfreeze(&i, true, mountpoints, &local_err);
     if (local_err) {
@@ -1299,6 +1305,12 @@ static void guest_fsfreeze_cleanup(void)
     vss_deinit(true);
 }

+gboolean ga_frozen_timeout_cb(gpointer data)
+{
+    guest_fsfreeze_cleanup();
+    return G_SOURCE_REMOVE;
+}
+
 /*
  * Walk list of mounted file systems in the guest, and discard unused
  * areas.
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index b4e7c52c61..d8d1bb9505 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -39,8 +39,9 @@ void ga_enable_logging(GAState *s);
 void G_GNUC_PRINTF(1, 2) slog(const gchar *fmt, ...);
 void ga_set_response_delimited(GAState *s);
 bool ga_is_frozen(GAState *s);
-void ga_set_frozen(GAState *s);
+void ga_set_frozen(GAState *s, int64_t timeout);
 void ga_unset_frozen(GAState *s);
+gboolean ga_frozen_timeout_cb(gpointer data);
 const char *ga_fsfreeze_hook(GAState *s);
 int64_t ga_get_fd_handle(GAState *s, Error **errp);
 int ga_parse_whence(GuestFileWhence *whence, Error **errp);
diff --git a/qga/main.c b/qga/main.c
index 8668b9f3d3..6c7c7d68d8 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -94,6 +94,7 @@ struct GAState {
         const char *pid_filepath;
     } deferred_options;
 #ifdef CONFIG_FSFREEZE
+    guint frozen_timeout_id;
     const char *fsfreeze_hook;
 #endif
     gchar *pstate_filepath;
@@ -478,7 +479,7 @@ bool ga_is_frozen(GAState *s)
     return s->frozen;
 }

-void ga_set_frozen(GAState *s)
+void ga_set_frozen(GAState *s, int64_t timeout)
 {
     if (ga_is_frozen(s)) {
         return;
@@ -492,6 +493,15 @@ void ga_set_frozen(GAState *s)
         g_warning("unable to create %s, fsfreeze may not function properly",
                   s->state_filepath_isfrozen);
     }
+#ifdef CONFIG_FSFREEZE
+    if (timeout) {
+        s->frozen_timeout_id = g_timeout_add_seconds(timeout,
+                                                     ga_frozen_timeout_cb,
+                                                     NULL);
+    } else {
+        s->frozen_timeout_id = 0;
+    }
+#endif
 }

 void ga_unset_frozen(GAState *s)
@@ -500,6 +510,13 @@ void ga_unset_frozen(GAState *s)
         return;
     }

+#ifdef CONFIG_FSFREEZE
+    /* remove timeout callback */
+    if (s->frozen_timeout_id) {
+        g_source_remove(s->frozen_timeout_id);
+    }
+#endif
+
     /* if we delayed creation/opening of pid/log files due to being
      * in a frozen state at start up, do it now
      */
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index e96d463639..29ad342f0a 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -440,6 +440,9 @@
 # command succeeded, you may call @guest-fsfreeze-thaw later to
 # unfreeze.
 #
+# @timeout: after this period in seconds filesystems will be thawed
+#     (since 8.2)
+#
 # Note: On Windows, the command is implemented with the help of a
 #     Volume Shadow-copy Service DLL helper.  The frozen state is
 #     limited for up to 10 seconds by VSS.
@@ -452,6 +455,7 @@
 # Since: 0.15.0
 ##
 { 'command': 'guest-fsfreeze-freeze',
+  'data':    { '*timeout': 'int' },
   'returns': 'int' }

 ##
@@ -464,13 +468,16 @@
 #     If omitted, every mounted filesystem is frozen.  Invalid mount
 #     points are ignored.
 #
+# @timeout: after this period in seconds filesystems will be thawed
+#     (since 8.2)
+#
 # Returns: Number of file systems currently frozen.  On error, all
 #     filesystems will be thawed.
 #
 # Since: 2.2
 ##
 { 'command': 'guest-fsfreeze-freeze-list',
-  'data':    { '*mountpoints': ['str'] },
+  'data':    { '*mountpoints': ['str'], '*timeout': 'int' },
   'returns': 'int' }

 ##
--
2.34.1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]