qemu: query QEMU for migration blockers before our own harcoded checks

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>
This commit is contained in:
Eugenio Pérez 2022-07-20 18:05:48 +02:00 committed by Laine Stump
parent 7e52c4839f
commit 156e99f686

View 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: * qemuMigrationSrcIsAllowed:
* @driver: qemu driver struct * @driver: qemu driver struct
@ -1440,6 +1456,20 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
int pauseReason; int pauseReason;
size_t i; 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 */ /* perform these checks only when migrating to remote hosts */
if (remote) { if (remote) {
nsnapshots = virDomainSnapshotObjListNum(vm->snapshots, NULL, 0); nsnapshots = virDomainSnapshotObjListNum(vm->snapshots, NULL, 0);