]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: query QEMU for migration blockers before our own harcoded checks
authorEugenio Pérez <eperezma@redhat.com>
Wed, 20 Jul 2022 16:05:48 +0000 (18:05 +0200)
committerLaine Stump <laine@redhat.com>
Thu, 21 Jul 2022 04:58:06 +0000 (00:58 -0400)
Since QEMU 6.0, if QEMU knows that a migration would fail,
'query-migrate' will return an array of error strings describing the
migration blockers.  This can be used to check whether there are any
devices/conditions blocking migration.

This patch adds a call to this query at the top of
qemuMigrationSrcIsAllowed().

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
src/qemu/qemu_migration.c

index b096e568247f52886d91d102bae1054c0da9422b..87c26b4e2c7dc1096eaa92bba9947ff266c734d5 100644 (file)
@@ -1415,6 +1415,22 @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def)
 }
 
 
+static int
+qemuDomainGetMigrationBlockers(virQEMUDriver *driver,
+                               virDomainObj *vm,
+                               char ***blockers)
+{
+    qemuDomainObjPrivate *priv = vm->privateData;
+    int rc;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    rc = qemuMonitorGetMigrationBlockers(priv->mon, blockers);
+    qemuDomainObjExitMonitor(vm);
+
+    return rc;
+}
+
+
 /**
  * qemuMigrationSrcIsAllowed:
  * @driver: qemu driver struct
@@ -1440,6 +1456,20 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
     int pauseReason;
     size_t i;
 
+    /* Ask qemu if it has a migration blocker */
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_BLOCKED_REASONS)) {
+        g_auto(GStrv) blockers = NULL;
+        if (qemuDomainGetMigrationBlockers(driver, vm, &blockers) < 0)
+            return false;
+
+        if (blockers && blockers[0]) {
+            g_autofree char *reasons = g_strjoinv("; ", blockers);
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           _("cannot migrate domain: %s"), reasons);
+            return false;
+        }
+    }
+
     /* perform these checks only when migrating to remote hosts */
     if (remote) {
         nsnapshots = virDomainSnapshotObjListNum(vm->snapshots, NULL, 0);