summary refs log tree commit diff stats
path: root/hw/virtio/vhost.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio/vhost.c')
-rw-r--r--hw/virtio/vhost.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 8087f200e9..60bc516003 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -871,21 +871,42 @@ static int vhost_migration_log(MemoryListener *listener, bool enable)
         dev->log_enabled = enable;
         return 0;
     }
+
+    r = 0;
     if (!enable) {
         r = vhost_dev_set_log(dev, false);
         if (r < 0) {
-            return r;
+            goto check_dev_state;
         }
         vhost_log_put(dev, false);
     } else {
         vhost_dev_log_resize(dev, vhost_get_log_size(dev));
         r = vhost_dev_set_log(dev, true);
         if (r < 0) {
-            return r;
+            goto check_dev_state;
         }
     }
+
+check_dev_state:
     dev->log_enabled = enable;
-    return 0;
+    /*
+     * vhost-user-* devices could change their state during log
+     * initialization due to disconnect. So check dev state after
+     * vhost communication.
+     */
+    if (!dev->started) {
+        /*
+         * Since device is in the stopped state, it is okay for
+         * migration. Return success.
+         */
+        r = 0;
+    }
+    if (r) {
+        /* An error is occured. */
+        dev->log_enabled = false;
+    }
+
+    return r;
 }
 
 static void vhost_log_global_start(MemoryListener *listener)