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
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 > >
On 10/26/23 11:16, Konstantin Kostiuk wrote: > > 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. Thank you, will pay attention. > > 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? The second command doesn't return a list, it takes a list of mountpoints. Both of the commands freeze local guest filesystems. The first one freezes all the FS, the second one freeze only FS from the given list. > > 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 > -- Best regards, Alexander Ivanov
On Mon, Oct 30, 2023 at 6:32 PM Alexander Ivanov < alexander.ivanov@virtuozzo.com> wrote: > > > On 10/26/23 11:16, Konstantin Kostiuk wrote: > > > > 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. > Thank you, will pay attention. > > > > 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? > The second command doesn't return a list, it takes a list of mountpoints. > Both of the commands freeze local guest filesystems. The first one > freezes all the FS, > the second one freeze only FS from the given list. > Oh, sorry, my mistake. Just comment about VSS limitation. Best Regards, Konstantin Kostiuk. > > > > 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 > > > > -- > Best regards, > Alexander Ivanov > >
© 2016 - 2024 Red Hat, Inc.