qemu-ga: add a whitelist for fsfreeze-safe commands
Currently we rely on fsfreeze/thaw commands disabling/enabling logging
then having other commands check whether logging is disabled to avoid
executing if they aren't safe for running while a filesystem is frozen.
Instead, have an explicit whitelist of fsfreeze-safe commands, and
consolidate logging and command enablement/disablement into a pair
of helper functions: ga_set_frozen()/ga_unset_frozen()
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 869d6ee..d58730a 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -316,16 +316,6 @@
#if defined(CONFIG_FSFREEZE)
-static void disable_logging(void)
-{
- ga_disable_logging(ga_state);
-}
-
-static void enable_logging(void)
-{
- ga_enable_logging(ga_state);
-}
-
typedef struct GuestFsfreezeMount {
char *dirname;
char *devtype;
@@ -334,10 +324,6 @@
typedef QTAILQ_HEAD(, GuestFsfreezeMount) GuestFsfreezeMountList;
-struct {
- GuestFsfreezeStatus status;
-} guest_fsfreeze_state;
-
static void guest_fsfreeze_free_mount_list(GuestFsfreezeMountList *mounts)
{
GuestFsfreezeMount *mount, *temp;
@@ -400,7 +386,11 @@
*/
GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
{
- return guest_fsfreeze_state.status;
+ if (ga_is_frozen(ga_state)) {
+ return GUEST_FSFREEZE_STATUS_FROZEN;
+ }
+
+ return GUEST_FSFREEZE_STATUS_THAWED;
}
/*
@@ -424,7 +414,7 @@
}
/* cannot risk guest agent blocking itself on a write in this state */
- disable_logging();
+ ga_set_frozen(ga_state);
QTAILQ_FOREACH(mount, &mounts, next) {
fd = qemu_open(mount->dirname, O_RDONLY);
@@ -459,7 +449,6 @@
close(fd);
}
- guest_fsfreeze_state.status = GUEST_FSFREEZE_STATUS_FROZEN;
guest_fsfreeze_free_mount_list(&mounts);
return i;
@@ -519,23 +508,17 @@
close(fd);
}
- guest_fsfreeze_state.status = GUEST_FSFREEZE_STATUS_THAWED;
- enable_logging();
+ ga_unset_frozen(ga_state);
guest_fsfreeze_free_mount_list(&mounts);
return i;
}
-static void guest_fsfreeze_init(void)
-{
- guest_fsfreeze_state.status = GUEST_FSFREEZE_STATUS_THAWED;
-}
-
static void guest_fsfreeze_cleanup(void)
{
int64_t ret;
Error *err = NULL;
- if (guest_fsfreeze_state.status == GUEST_FSFREEZE_STATUS_FROZEN) {
+ if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
ret = qmp_guest_fsfreeze_thaw(&err);
if (ret < 0 || err) {
slog("failed to clean up frozen filesystems");
@@ -964,7 +947,7 @@
void ga_command_state_init(GAState *s, GACommandState *cs)
{
#if defined(CONFIG_FSFREEZE)
- ga_command_state_add(cs, guest_fsfreeze_init, guest_fsfreeze_cleanup);
+ ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
#endif
ga_command_state_add(cs, guest_file_init, NULL);
}