diff mbox series

RFC: qemu-ga: skip loop mount fs to avoid qemu-ga hang

Message ID 20200706165828.273523-1-marcandre.lureau@redhat.com
State New
Headers show
Series RFC: qemu-ga: skip loop mount fs to avoid qemu-ga hang | expand

Commit Message

Marc-André Lureau July 6, 2020, 4:58 p.m. UTC
If the underlying filesystem is already frozen, ioctl(FIFREEZE) might hang.

guest-fsfreeze is done in reverse order of /proc/self/mountinfo list,
but it seems insufficient to prevent that situation.

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1782626

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qga/commands-posix.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
diff mbox series

Patch

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index cdbeb59dccd..c4dce400302 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -623,6 +623,7 @@  typedef struct FsMount {
     char *dirname;
     char *devtype;
     unsigned int devmajor, devminor;
+    bool is_loop;
     QTAILQ_ENTRY(FsMount) next;
 } FsMount;
 
@@ -668,6 +669,11 @@  static int dev_major_minor(const char *devpath,
     return -1;
 }
 
+static bool
+fsname_is_loop_device(const char *fsname)
+{
+    return g_str_has_prefix(fsname, "/dev/loop");
+}
 /*
  * Walk the mount table and build a list of local file systems
  */
@@ -707,6 +713,7 @@  static void build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp)
         mount->devtype = g_strdup(ment->mnt_type);
         mount->devmajor = devmajor;
         mount->devminor = devminor;
+        mount->is_loop = fsname_is_loop_device(ment->mnt_fsname);
 
         QTAILQ_INSERT_TAIL(mounts, mount, next);
     }
@@ -786,6 +793,7 @@  static void build_fs_mount_list(FsMountList *mounts, Error **errp)
         mount->devtype = g_strdup(dash + type_s);
         mount->devmajor = devmajor;
         mount->devminor = devminor;
+        mount->is_loop = fsname_is_loop_device(dash + dev_s);
 
         QTAILQ_INSERT_TAIL(mounts, mount, next);
     }
@@ -1304,6 +1312,10 @@  int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
             }
         }
 
+        if (mount->is_loop) {
+            continue;
+        }
+
         fd = qemu_open(mount->dirname, O_RDONLY);
         if (fd == -1) {
             error_setg_errno(errp, errno, "failed to open %s", mount->dirname);