[libvirt PATCH v4 3/4] qemu_migration: get migration blockers before hardcoded checks

2022-07-20 Thread Eugenio Pérez
since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Enable qemuMigrationSrcIsAllowed to query it.

Signed-off-by: Eugenio Pérez 
Reviewed-by: Jiri Denemark 
---
v4:
* Do not override qemuDomainGetMigrationBlockers error calling again
  virReportError.
* Replace ", " with "; " in blockers separators.

v3:
* Report message with a colon.
* Report all blockers instead of only the first.
---
 src/qemu/qemu_migration.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b12cb518ee..2e3044289a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1414,6 +1414,20 @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def)
 return true;
 }
 
+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:
@@ -1439,6 +1453,22 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 int nsnapshots;
 int pauseReason;
 size_t i;
+int r;
+
+/* Ask qemu if it have a migration blocker */
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_BLOCKED_REASONS)) {
+g_auto(GStrv) blockers = NULL;
+r = qemuDomainGetMigrationBlockers(driver, vm, );
+if (r != 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) {
-- 
2.31.1



[libvirt PATCH v4 1/4] qemu: introduce capability QEMU_CAPS_MIGRATION_BLOCKED_REASONS

2022-07-20 Thread Eugenio Pérez
From: Jonathon Jongsma 

since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Signed-off-by: Jonathon Jongsma 
Signed-off-by: Eugenio Pérez 
Reviewed-by: Jiri Denemark 
---
v3: s/QEMU_MIGRATION_BLOCKED_REASONS/QEMU_CAPS_MIGRATION_BLOCKED_REASONS/
---
 src/qemu/qemu_capabilities.c  | 2 ++
 src/qemu/qemu_capabilities.h  | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml   | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml  | 1 +
 13 files changed, 14 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 30b396d32d..b002fb98ed 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -672,6 +672,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "display-dbus", /* QEMU_CAPS_DISPLAY_DBUS */
   "iothread.thread-pool-max", /* 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX */
   "usb-host.guest-resets-all", /* 
QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL */
+  "migration.blocked-reasons", /* 
QEMU_CAPS_MIGRATION_BLOCKED_REASONS */
 );
 
 
@@ -1622,6 +1623,7 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsQMPSchemaQueries[] = {
 { "chardev-add/arg-type/backend/+qemu-vdagent", 
QEMU_CAPS_CHARDEV_QEMU_VDAGENT },
 { "query-display-options/ret-type/+dbus", QEMU_CAPS_DISPLAY_DBUS },
 { "object-add/arg-type/+iothread/thread-pool-max", 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX },
+{ "query-migrate/ret-type/blocked-reasons", 
QEMU_CAPS_MIGRATION_BLOCKED_REASONS },
 };
 
 typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d979a5ba3b..8f3090e2ce 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -651,6 +651,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_DISPLAY_DBUS, /* -display dbus */
 QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX, /* -object iothread.thread-pool-max */
 QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL, /* -device usb-host.guest-resets-all 
*/
+QEMU_CAPS_MIGRATION_BLOCKED_REASONS, /* query-migrate returns 
'blocked-reasons */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
index 01e30f4e02..4afd7b26ce 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
@@ -187,6 +187,7 @@
   
   
   
+  
   600
   0
   61700242
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
index aa7b5deab5..c9cb85daa0 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
@@ -144,6 +144,7 @@
   
   
   
+  
   600
   0
   39100242
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
index d9e385ab1d..508804521c 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
@@ -229,6 +229,7 @@
   
   
   
+  
   600
   0
   43100242
diff --git a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
index 05f297dfa2..d4a540fafd 100644
--- a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
@@ -234,6 +234,7 @@
   
   
   
+  
   6001000
   0
   43100243
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml 
b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
index 9cb1a32354..71697fac95 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
@@ -199,6 +199,7 @@
   
   
   
+  
   6001050
   0
   61700244
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
index 5df148d787..3f86e03f18 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
@@ -193,6 +193,7 @@
   
   
   
+  
   6002000
   0
   42900244
diff --git a/tests/qemucapabilitiesdata

[libvirt PATCH v4 0/4] Ask qemu about migration blockers

2022-07-20 Thread Eugenio Pérez
There are some hardcoded migration blockers in libvirt, like having a net
vhost-vdpa device. While it's true that they cannot be migrated at the moment,
there are plans to be able to migrate them soon.

They'll put a migration blockers in the cases where you cannot migrate them.
Ask qemu about then before rejecting the migration. In case the question is not
possible, assume they're not migratable.

v4:
* Do not override qemuDomainGetMigrationBlockers error calling again
  virReportError.
* Replace ", " with "; " in blockers separators.

v3:
* Return ok in qemuMonitorJSONGetMigrationBlockers is there are no
  blockers.
* Fix indentation
* Report all blockers instead of only the first.
* Squash some patches
* Move note to function doc.
* s/QEMU_MIGRATION_BLOCKED_REASONS/QEMU_CAPS_MIGRATION_BLOCKED_REASONS/

v2:
* Ask qemu if it has some pending blockers before try the migration

Eugenio Pérez (3):
  qemu_monitor: add support for get qemu migration blockers
  qemu_migration: get migration blockers before hardcoded checks
  qemu_migration: Do not forbid vDPA devices if can query blockers

Jonathon Jongsma (1):
  qemu: introduce capability QEMU_CAPS_MIGRATION_BLOCKED_REASONS

 src/qemu/qemu_capabilities.c  |  2 +
 src/qemu/qemu_capabilities.h  |  1 +
 src/qemu/qemu_migration.c | 34 +-
 src/qemu/qemu_monitor.c   | 11 +
 src/qemu/qemu_monitor.h   |  4 ++
 src/qemu/qemu_monitor_json.c  | 44 +++
 src/qemu/qemu_monitor_json.h  |  3 ++
 .../caps_6.0.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_6.0.0.s390x.xml |  1 +
 .../caps_6.0.0.x86_64.xml |  1 +
 .../caps_6.1.0.x86_64.xml |  1 +
 .../caps_6.2.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml |  1 +
 .../caps_6.2.0.x86_64.xml |  1 +
 .../caps_7.0.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_7.0.0.ppc64.xml |  1 +
 .../caps_7.0.0.x86_64.xml |  1 +
 .../caps_7.1.0.x86_64.xml |  1 +
 18 files changed, 109 insertions(+), 1 deletion(-)

-- 
2.31.1




[libvirt PATCH v4 4/4] qemu_migration: Do not forbid vDPA devices if can query blockers

2022-07-20 Thread Eugenio Pérez
vDPA devices will be migratable soon. Since they are not migratable
before qemu 6.0, and qemu pre-6.0 didn't have the capability of asking
for migration blockers, let it hardcoded in that case.

Otherwise, ask qemu about the explicit blocker.

Signed-off-by: Eugenio Pérez 
Reviewed-by: Jiri Denemark 
---
v3: Fix indentation
---
 src/qemu/qemu_migration.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 2e3044289a..b554027da2 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1454,9 +1454,11 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 int pauseReason;
 size_t i;
 int r;
+bool blockedReasonsCap = virQEMUCapsGet(priv->qemuCaps,
+
QEMU_CAPS_MIGRATION_BLOCKED_REASONS);
 
 /* Ask qemu if it have a migration blocker */
-if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_BLOCKED_REASONS)) {
+if (blockedReasonsCap) {
 g_auto(GStrv) blockers = NULL;
 r = qemuDomainGetMigrationBlockers(driver, vm, );
 if (r != 0)
@@ -1576,7 +1578,7 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 virDomainNetDef *net = vm->def->nets[i];
 qemuSlirp *slirp;
 
-if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
+if (!blockedReasonsCap && net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("vDPA devices cannot be migrated"));
 return false;
-- 
2.31.1



[libvirt PATCH v4 2/4] qemu_monitor: add support for get qemu migration blockers

2022-07-20 Thread Eugenio Pérez
since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Enable qemu monitor to send this query.  This will allow
qemuMigrationSrcIsAllowed to dynamically ask for migration blockers,
reducing duplication.

Signed-off-by: Eugenio Pérez 
Reviewed-by: Jiri Denemark 
---
v4:
* Separate return type into its own line

v3:
* Squash some patches
* Return ok in qemuMonitorJSONGetMigrationBlockers is there are no
  blockers.
* Move note to function doc.
---
 src/qemu/qemu_monitor.c  | 11 +
 src/qemu/qemu_monitor.h  |  4 
 src/qemu/qemu_monitor_json.c | 44 
 src/qemu/qemu_monitor_json.h |  3 +++
 4 files changed, 62 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 109107eaae..e0939beecd 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4486,3 +4486,14 @@ qemuMonitorMigrateRecover(qemuMonitor *mon,
 
 return qemuMonitorJSONMigrateRecover(mon, uri);
 }
+
+int
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers)
+{
+VIR_DEBUG("blockers=%p", blockers);
+
+QEMU_CHECK_MONITOR(mon);
+
+return qemuMonitorJSONGetMigrationBlockers(mon, blockers);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index cc1a0bc8c9..b82f198285 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1543,3 +1543,7 @@ qemuMonitorChangeMemoryRequestedSize(qemuMonitor *mon,
 int
 qemuMonitorMigrateRecover(qemuMonitor *mon,
   const char *uri);
+
+int
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 5e4a86e5ad..6b26dfcb54 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3338,6 +3338,50 @@ int qemuMonitorJSONMigrate(qemuMonitor *mon,
 return 0;
 }
 
+/*
+ * Get the exposed migration blockers.
+ *
+ * This function assume qemu has the capability of request them.
+ *
+ * It returns a NULL terminated array on blockers if there are any, or it set
+ * it to NULL otherwise.
+ */
+int
+qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers)
+{
+g_autoptr(virJSONValue) cmd = NULL;
+g_autoptr(virJSONValue) reply = NULL;
+virJSONValue *data;
+virJSONValue *jblockers;
+size_t i;
+
+*blockers = NULL;
+if (!(cmd = qemuMonitorJSONMakeCommand("query-migrate", NULL)))
+return -1;
+
+if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
+return -1;
+
+if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
+return -1;
+
+data = virJSONValueObjectGetObject(reply, "return");
+
+if (!(jblockers = virJSONValueObjectGetArray(data, "blocked-reasons")))
+return 0;
+
+*blockers = g_new0(char *, virJSONValueArraySize(jblockers) + 1);
+for (i = 0; i < virJSONValueArraySize(jblockers); i++) {
+virJSONValue *jblocker = virJSONValueArrayGet(jblockers, i);
+const char *blocker = virJSONValueGetString(jblocker);
+
+(*blockers)[i] = g_strdup(blocker);
+}
+
+return 0;
+}
+
 int qemuMonitorJSONMigrateCancel(qemuMonitor *mon)
 {
 g_autoptr(virJSONValue) cmd = qemuMonitorJSONMakeCommand("migrate_cancel", 
NULL);
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 2759566892..e4c65e250e 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -184,6 +184,9 @@ qemuMonitorJSONMigrate(qemuMonitor *mon,
unsigned int flags,
const char *uri);
 int
+qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers);
+int
 qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitor *mon,
bool *spice_migrated);
 
-- 
2.31.1



[libvirt PATCH v3 3/4] qemu_migration: get migration blockers before hardcoded checks

2022-07-20 Thread Eugenio Pérez
since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Enable qemuMigrationSrcIsAllowed to query it.

Signed-off-by: Eugenio Pérez 
---
v3:
* Report message with a colon.
* Report all blockers instead of only the first.
---
 src/qemu/qemu_migration.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b12cb518ee..6ac4ef150b 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1414,6 +1414,20 @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def)
 return true;
 }
 
+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:
@@ -1439,6 +1453,26 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 int nsnapshots;
 int pauseReason;
 size_t i;
+int r;
+
+/* Ask qemu if it have a migration blocker */
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_BLOCKED_REASONS)) {
+g_auto(GStrv) blockers = NULL;
+r = qemuDomainGetMigrationBlockers(driver, vm, );
+if (r != 0) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("cannot migrate domain: %s"),
+   _("error getting blockers"));
+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) {
-- 
2.31.1



[libvirt PATCH v3 0/4] Ask qemu about migration blockers

2022-07-20 Thread Eugenio Pérez
There are some hardcoded migration blockers in libvirt, like having a net
vhost-vdpa device. While it's true that they cannot be migrated at the moment,
there are plans to be able to migrate them soon.

They'll put a migration blockers in the cases where you cannot migrate them.
Ask qemu about then before rejecting the migration. In case the question is not
possible, assume they're not migratable.

v3:
* Return ok in qemuMonitorJSONGetMigrationBlockers is there are no
  blockers.
* Fix indentation
* Report all blockers instead of only the first.
* Squash some patches
* Move note to function doc.
* s/QEMU_MIGRATION_BLOCKED_REASONS/QEMU_CAPS_MIGRATION_BLOCKED_REASONS/

v2:
* Ask qemu if it has some pending blockers before try the migration

Eugenio Pérez (3):
  qemu_monitor: add support for get qemu migration blockers
  qemu_migration: get migration blockers before hardcoded checks
  qemu_migration: Do not forbid vDPA devices if can query blockers

Jonathon Jongsma (1):
  qemu: introduce capability QEMU_CAPS_MIGRATION_BLOCKED_REASONS

 src/qemu/qemu_capabilities.c  |  2 +
 src/qemu/qemu_capabilities.h  |  1 +
 src/qemu/qemu_migration.c | 38 +++-
 src/qemu/qemu_monitor.c   | 11 +
 src/qemu/qemu_monitor.h   |  4 ++
 src/qemu/qemu_monitor_json.c  | 43 +++
 src/qemu/qemu_monitor_json.h  |  3 ++
 .../caps_6.0.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_6.0.0.s390x.xml |  1 +
 .../caps_6.0.0.x86_64.xml |  1 +
 .../caps_6.1.0.x86_64.xml |  1 +
 .../caps_6.2.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml |  1 +
 .../caps_6.2.0.x86_64.xml |  1 +
 .../caps_7.0.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_7.0.0.ppc64.xml |  1 +
 .../caps_7.0.0.x86_64.xml |  1 +
 .../caps_7.1.0.x86_64.xml |  1 +
 18 files changed, 112 insertions(+), 1 deletion(-)

-- 
2.31.1




[libvirt PATCH v3 1/4] qemu: introduce capability QEMU_CAPS_MIGRATION_BLOCKED_REASONS

2022-07-20 Thread Eugenio Pérez
From: Jonathon Jongsma 

since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Signed-off-by: Jonathon Jongsma 
Signed-off-by: Eugenio Pérez 
---
v3: s/QEMU_MIGRATION_BLOCKED_REASONS/QEMU_CAPS_MIGRATION_BLOCKED_REASONS/
---
 src/qemu/qemu_capabilities.c  | 2 ++
 src/qemu/qemu_capabilities.h  | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml   | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml  | 1 +
 13 files changed, 14 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 30b396d32d..b002fb98ed 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -672,6 +672,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "display-dbus", /* QEMU_CAPS_DISPLAY_DBUS */
   "iothread.thread-pool-max", /* 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX */
   "usb-host.guest-resets-all", /* 
QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL */
+  "migration.blocked-reasons", /* 
QEMU_CAPS_MIGRATION_BLOCKED_REASONS */
 );
 
 
@@ -1622,6 +1623,7 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsQMPSchemaQueries[] = {
 { "chardev-add/arg-type/backend/+qemu-vdagent", 
QEMU_CAPS_CHARDEV_QEMU_VDAGENT },
 { "query-display-options/ret-type/+dbus", QEMU_CAPS_DISPLAY_DBUS },
 { "object-add/arg-type/+iothread/thread-pool-max", 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX },
+{ "query-migrate/ret-type/blocked-reasons", 
QEMU_CAPS_MIGRATION_BLOCKED_REASONS },
 };
 
 typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d979a5ba3b..8f3090e2ce 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -651,6 +651,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_DISPLAY_DBUS, /* -display dbus */
 QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX, /* -object iothread.thread-pool-max */
 QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL, /* -device usb-host.guest-resets-all 
*/
+QEMU_CAPS_MIGRATION_BLOCKED_REASONS, /* query-migrate returns 
'blocked-reasons */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
index 01e30f4e02..4afd7b26ce 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
@@ -187,6 +187,7 @@
   
   
   
+  
   600
   0
   61700242
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
index aa7b5deab5..c9cb85daa0 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
@@ -144,6 +144,7 @@
   
   
   
+  
   600
   0
   39100242
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
index d9e385ab1d..508804521c 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
@@ -229,6 +229,7 @@
   
   
   
+  
   600
   0
   43100242
diff --git a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
index 05f297dfa2..d4a540fafd 100644
--- a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
@@ -234,6 +234,7 @@
   
   
   
+  
   6001000
   0
   43100243
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml 
b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
index 9cb1a32354..71697fac95 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
@@ -199,6 +199,7 @@
   
   
   
+  
   6001050
   0
   61700244
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
index 5df148d787..3f86e03f18 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
@@ -193,6 +193,7 @@
   
   
   
+  
   6002000
   0
   42900244
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml 

[libvirt PATCH v3 2/4] qemu_monitor: add support for get qemu migration blockers

2022-07-20 Thread Eugenio Pérez
since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Enable qemu monitor to send this query.  This will allow
qemuMigrationSrcIsAllowed to dynamically ask for migration blockers,
reducing duplication.

Signed-off-by: Eugenio Pérez 
---
v3:
* Squash some patches
* Return ok in qemuMonitorJSONGetMigrationBlockers is there are no
  blockers.
* Move note to function doc.
---
 src/qemu/qemu_monitor.c  | 11 +
 src/qemu/qemu_monitor.h  |  4 
 src/qemu/qemu_monitor_json.c | 43 
 src/qemu/qemu_monitor_json.h |  3 +++
 4 files changed, 61 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 109107eaae..e0939beecd 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4486,3 +4486,14 @@ qemuMonitorMigrateRecover(qemuMonitor *mon,
 
 return qemuMonitorJSONMigrateRecover(mon, uri);
 }
+
+int
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers)
+{
+VIR_DEBUG("blockers=%p", blockers);
+
+QEMU_CHECK_MONITOR(mon);
+
+return qemuMonitorJSONGetMigrationBlockers(mon, blockers);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index cc1a0bc8c9..b82f198285 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1543,3 +1543,7 @@ qemuMonitorChangeMemoryRequestedSize(qemuMonitor *mon,
 int
 qemuMonitorMigrateRecover(qemuMonitor *mon,
   const char *uri);
+
+int
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 5e4a86e5ad..6d15a458a3 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3338,6 +3338,49 @@ int qemuMonitorJSONMigrate(qemuMonitor *mon,
 return 0;
 }
 
+/*
+ * Get the exposed migration blockers.
+ *
+ * This function assume qemu has the capability of request them.
+ *
+ * It returns a NULL terminated array on blockers if there are any, or it set
+ * it to NULL otherwise.
+ */
+int qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers)
+{
+g_autoptr(virJSONValue) cmd = NULL;
+g_autoptr(virJSONValue) reply = NULL;
+virJSONValue *data;
+virJSONValue *jblockers;
+size_t i;
+
+*blockers = NULL;
+if (!(cmd = qemuMonitorJSONMakeCommand("query-migrate", NULL)))
+return -1;
+
+if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
+return -1;
+
+if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
+return -1;
+
+data = virJSONValueObjectGetObject(reply, "return");
+
+if (!(jblockers = virJSONValueObjectGetArray(data, "blocked-reasons")))
+return 0;
+
+*blockers = g_new0(char *, virJSONValueArraySize(jblockers) + 1);
+for (i = 0; i < virJSONValueArraySize(jblockers); i++) {
+virJSONValue *jblocker = virJSONValueArrayGet(jblockers, i);
+const char *blocker = virJSONValueGetString(jblocker);
+
+(*blockers)[i] = g_strdup(blocker);
+}
+
+return 0;
+}
+
 int qemuMonitorJSONMigrateCancel(qemuMonitor *mon)
 {
 g_autoptr(virJSONValue) cmd = qemuMonitorJSONMakeCommand("migrate_cancel", 
NULL);
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 2759566892..e4c65e250e 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -184,6 +184,9 @@ qemuMonitorJSONMigrate(qemuMonitor *mon,
unsigned int flags,
const char *uri);
 int
+qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers);
+int
 qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitor *mon,
bool *spice_migrated);
 
-- 
2.31.1



[libvirt PATCH v3 4/4] qemu_migration: Do not forbid vDPA devices if can query blockers

2022-07-20 Thread Eugenio Pérez
vDPA devices will be migratable soon. Since they are not migratable
before qemu 6.0, and qemu pre-6.0 didn't have the capability of asking
for migration blockers, let it hardcoded in that case.

Otherwise, ask qemu about the explicit blocker.

Signed-off-by: Eugenio Pérez 
---
v3: Fix indentation
---
 src/qemu/qemu_migration.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 6ac4ef150b..45e16242f0 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1454,9 +1454,11 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 int pauseReason;
 size_t i;
 int r;
+bool blockedReasonsCap = virQEMUCapsGet(priv->qemuCaps,
+
QEMU_CAPS_MIGRATION_BLOCKED_REASONS);
 
 /* Ask qemu if it have a migration blocker */
-if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_BLOCKED_REASONS)) {
+if (blockedReasonsCap) {
 g_auto(GStrv) blockers = NULL;
 r = qemuDomainGetMigrationBlockers(driver, vm, );
 if (r != 0) {
@@ -1467,7 +1469,7 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 }
 
 if (blockers && blockers[0]) {
-g_autofree char *reasons = g_strjoinv(", ", blockers);
+g_autofree char *reasons = g_strjoinv("; ", blockers);
 virReportError(VIR_ERR_OPERATION_INVALID,
_("cannot migrate domain: %s"), reasons);
 return false;
@@ -1580,7 +1582,7 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 virDomainNetDef *net = vm->def->nets[i];
 qemuSlirp *slirp;
 
-if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
+if (!blockedReasonsCap && net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("vDPA devices cannot be migrated"));
 return false;
-- 
2.31.1



[libvirt PATCH v2 4/5] qemu_migration: get migration blockers before hardcoded checks

2022-07-20 Thread Eugenio Pérez
since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Enable qemuMigrationSrcIsAllowed to query it.

Signed-off-by: Eugenio Pérez 
---
 src/qemu/qemu_migration.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b12cb518ee..4224339f39 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1414,6 +1414,20 @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def)
 return true;
 }
 
+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:
@@ -1439,6 +1453,25 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 int nsnapshots;
 int pauseReason;
 size_t i;
+int r;
+
+/* Ask qemu if it have a migration blocker */
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_BLOCKED_REASONS)) {
+g_auto(GStrv) blockers = NULL;
+r = qemuDomainGetMigrationBlockers(driver, vm, );
+if (r != 0) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("cannot migrate domain, %s"),
+   _("error getting blockers"));
+return false;
+}
+
+if (blockers[0]) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("cannot migrate domain, %s"), blockers[0]);
+return false;
+}
+}
 
 /* perform these checks only when migrating to remote hosts */
 if (remote) {
-- 
2.31.1



[libvirt PATCH v2 2/5] qemu_monitor_json: Add qemuMonitorJSONGetMigrationBlockers

2022-07-20 Thread Eugenio Pérez
This will allow qemuMigrationSrcIsAllowed to dynamically ask for
migration blockers, reducing duplication.

Signed-off-by: Eugenio Pérez 
---
 src/qemu/qemu_monitor_json.c | 35 +++
 src/qemu/qemu_monitor_json.h |  3 +++
 2 files changed, 38 insertions(+)

diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 5e4a86e5ad..a53d721720 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3338,6 +3338,41 @@ int qemuMonitorJSONMigrate(qemuMonitor *mon,
 return 0;
 }
 
+int qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers)
+{
+g_autoptr(virJSONValue) cmd = NULL;
+g_autoptr(virJSONValue) reply = NULL;
+virJSONValue *data;
+virJSONValue *jblockers;
+size_t i;
+
+if (!(cmd = qemuMonitorJSONMakeCommand("query-migrate", NULL)))
+return -1;
+
+if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
+return -1;
+
+if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
+return -1;
+
+data = virJSONValueObjectGetObject(reply, "return");
+
+if (!(jblockers = virJSONValueObjectGetArray(data, "blocked-reasons")))
+return -1;
+
+/* NULL terminated array */
+*blockers = g_new0(char *, virJSONValueArraySize(jblockers) + 1);
+for (i = 0; i < virJSONValueArraySize(jblockers); i++) {
+virJSONValue *jblocker = virJSONValueArrayGet(jblockers, i);
+const char *blocker = virJSONValueGetString(jblocker);
+
+(*blockers)[i] = g_strdup(blocker);
+}
+
+return 0;
+}
+
 int qemuMonitorJSONMigrateCancel(qemuMonitor *mon)
 {
 g_autoptr(virJSONValue) cmd = qemuMonitorJSONMakeCommand("migrate_cancel", 
NULL);
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 2759566892..e4c65e250e 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -184,6 +184,9 @@ qemuMonitorJSONMigrate(qemuMonitor *mon,
unsigned int flags,
const char *uri);
 int
+qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers);
+int
 qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitor *mon,
bool *spice_migrated);
 
-- 
2.31.1



[libvirt PATCH v2 5/5] qemu_migrate: Do not forbif vDPA devices if can query blockers

2022-07-20 Thread Eugenio Pérez
vDPA devices will be migratable soon. Since they are not migratable
before qemu 6.0, and qemu pre-6.0 didn't have the capability of asking
for migration blockers, let it hardcoded in that case.

Otherwise, ask qemu about the explicit blocker.

Signed-off-by: Eugenio Pérez 
---
 src/qemu/qemu_migration.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 4224339f39..2f5c1d8121 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1454,9 +1454,11 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 int pauseReason;
 size_t i;
 int r;
+bool blockedReasonsCap = virQEMUCapsGet(priv->qemuCaps,
+  QEMU_CAPS_MIGRATION_BLOCKED_REASONS);
 
 /* Ask qemu if it have a migration blocker */
-if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_BLOCKED_REASONS)) {
+if (blockedReasonsCap) {
 g_auto(GStrv) blockers = NULL;
 r = qemuDomainGetMigrationBlockers(driver, vm, );
 if (r != 0) {
@@ -1579,7 +1581,8 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 virDomainNetDef *net = vm->def->nets[i];
 qemuSlirp *slirp;
 
-if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
+
+if (!blockedReasonsCap && net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("vDPA devices cannot be migrated"));
 return false;
-- 
2.31.1



[libvirt PATCH v2 3/5] qemu_monitor: add support for get qemu migration blockers

2022-07-20 Thread Eugenio Pérez
since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Enable qemu monitor to send this query.

Signed-off-by: Eugenio Pérez 
---
 src/qemu/qemu_monitor.c | 11 +++
 src/qemu/qemu_monitor.h |  4 
 2 files changed, 15 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 109107eaae..e0939beecd 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4486,3 +4486,14 @@ qemuMonitorMigrateRecover(qemuMonitor *mon,
 
 return qemuMonitorJSONMigrateRecover(mon, uri);
 }
+
+int
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers)
+{
+VIR_DEBUG("blockers=%p", blockers);
+
+QEMU_CHECK_MONITOR(mon);
+
+return qemuMonitorJSONGetMigrationBlockers(mon, blockers);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index cc1a0bc8c9..b82f198285 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1543,3 +1543,7 @@ qemuMonitorChangeMemoryRequestedSize(qemuMonitor *mon,
 int
 qemuMonitorMigrateRecover(qemuMonitor *mon,
   const char *uri);
+
+int
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
+char ***blockers);
-- 
2.31.1



[libvirt PATCH v2 0/5] Ask qemu about migration blockers

2022-07-20 Thread Eugenio Pérez
There are some hardcoded migration blockers in libvirt, like having a net
vhost-vdpa device. While it's true that they cannot be migrated at the moment,
there are plans to be able to migrate them soon.

They'll put a migration blockers in the cases where you cannot migrate them.
Ask qemu about then before rejecting the migration. In case the question is not
possible, assume they're not migratable.

Eugenio Pérez (4):
  qemu_monitor_json: Add qemuMonitorJSONGetMigrationBlockers
  qemu_monitor: add support for get qemu migration blockers
  qemu_migration: get migration blockers before hardcoded checks
  qemu_migrate: Do not forbif vDPA devices if can query blockers

Jonathon Jongsma (1):
  qemu: introduce capability QEMU_MIGRATION_BLOCKED_REASONS

 src/qemu/qemu_capabilities.c  |  2 +
 src/qemu/qemu_capabilities.h  |  1 +
 src/qemu/qemu_migration.c | 38 ++-
 src/qemu/qemu_monitor.c   | 11 ++
 src/qemu/qemu_monitor.h   |  4 ++
 src/qemu/qemu_monitor_json.c  | 35 +
 src/qemu/qemu_monitor_json.h  |  3 ++
 .../caps_6.0.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_6.0.0.s390x.xml |  1 +
 .../caps_6.0.0.x86_64.xml |  1 +
 .../caps_6.1.0.x86_64.xml |  1 +
 .../caps_6.2.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_6.2.0.ppc64.xml |  1 +
 .../caps_6.2.0.x86_64.xml |  1 +
 .../caps_7.0.0.aarch64.xml|  1 +
 .../qemucapabilitiesdata/caps_7.0.0.ppc64.xml |  1 +
 .../caps_7.0.0.x86_64.xml |  1 +
 .../caps_7.1.0.x86_64.xml |  1 +
 18 files changed, 104 insertions(+), 1 deletion(-)

-- 
2.31.1




[libvirt PATCH v2 1/5] qemu: introduce capability QEMU_MIGRATION_BLOCKED_REASONS

2022-07-20 Thread Eugenio Pérez
From: Jonathon Jongsma 

since qemu 6.0, if migration is blocked for some reason, 'query-migrate'
will return an array of error strings describing the migration blockers.
This can be used to check whether there are any devices blocking
migration, etc.

Signed-off-by: Jonathon Jongsma 
Signed-off-by: Eugenio Pérez 
---
 src/qemu/qemu_capabilities.c  | 2 ++
 src/qemu/qemu_capabilities.h  | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml   | 1 +
 tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.ppc64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml  | 1 +
 13 files changed, 14 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 30b396d32d..b002fb98ed 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -672,6 +672,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "display-dbus", /* QEMU_CAPS_DISPLAY_DBUS */
   "iothread.thread-pool-max", /* 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX */
   "usb-host.guest-resets-all", /* 
QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL */
+  "migration.blocked-reasons", /* 
QEMU_CAPS_MIGRATION_BLOCKED_REASONS */
 );
 
 
@@ -1622,6 +1623,7 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsQMPSchemaQueries[] = {
 { "chardev-add/arg-type/backend/+qemu-vdagent", 
QEMU_CAPS_CHARDEV_QEMU_VDAGENT },
 { "query-display-options/ret-type/+dbus", QEMU_CAPS_DISPLAY_DBUS },
 { "object-add/arg-type/+iothread/thread-pool-max", 
QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX },
+{ "query-migrate/ret-type/blocked-reasons", 
QEMU_CAPS_MIGRATION_BLOCKED_REASONS },
 };
 
 typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d979a5ba3b..8f3090e2ce 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -651,6 +651,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_DISPLAY_DBUS, /* -display dbus */
 QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX, /* -object iothread.thread-pool-max */
 QEMU_CAPS_USB_HOST_GUESTS_RESETS_ALL, /* -device usb-host.guest-resets-all 
*/
+QEMU_CAPS_MIGRATION_BLOCKED_REASONS, /* query-migrate returns 
'blocked-reasons */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
index 01e30f4e02..4afd7b26ce 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.aarch64.xml
@@ -187,6 +187,7 @@
   
   
   
+  
   600
   0
   61700242
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
index aa7b5deab5..c9cb85daa0 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.s390x.xml
@@ -144,6 +144,7 @@
   
   
   
+  
   600
   0
   39100242
diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
index d9e385ab1d..508804521c 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.xml
@@ -229,6 +229,7 @@
   
   
   
+  
   600
   0
   43100242
diff --git a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
index 05f297dfa2..d4a540fafd 100644
--- a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml
@@ -234,6 +234,7 @@
   
   
   
+  
   6001000
   0
   43100243
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml 
b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
index 9cb1a32354..71697fac95 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.aarch64.xml
@@ -199,6 +199,7 @@
   
   
   
+  
   6001050
   0
   61700244
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
index 5df148d787..3f86e03f18 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.ppc64.xml
@@ -193,6 +193,7 @@
   
   
   
+  
   6002000
   0
   42900244
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml
index dd011f8408..1a1a

[libvirt PATCH] qemu_migration: Delete vDPA check

2022-07-15 Thread Eugenio Pérez
Currently, the migration code denies migration as long as the VM has a
vhost-vDPA device.

While it's true that vhost-vDPA devices cannot be migrated at the moment, there 
are plans to be able to migrate them soon.

Libvirt must treat it equal to vhost-kernel devices: Not all of them can
be migrated (the ones that do not expose the feature VHOST_F_LOG_ALL
cannot be migrated). So checks like this one should work for all vhost
devices equally.

A more accurate solution is to ask qemu if it has an active migration
blocker at that moment. Hoever, that require synchronization to avoid
qemu to add one between the query and the actual migration command.

Signed-off-by: Eugenio Pérez 
---
 src/qemu/qemu_migration.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 9c3fd41761..4ddf027c83 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1546,12 +1546,6 @@ qemuMigrationSrcIsAllowed(virQEMUDriver *driver,
 virDomainNetDef *net = vm->def->nets[i];
 qemuSlirp *slirp;
 
-if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) {
-virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-   _("vDPA devices cannot be migrated"));
-return false;
-}
-
 slirp = QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp;
 
 if (slirp && !qemuSlirpHasFeature(slirp, 
QEMU_SLIRP_FEATURE_MIGRATE)) {
-- 
2.31.1



Re: [RFC v2 1/1] memory: Delete assertion in memory_region_unregister_iommu_notifier

2020-08-03 Thread Eugenio Pérez
On Fri, 2020-07-03 at 15:24 +0800, Jason Wang wrote:
> On 2020/7/2 下午11:45, Peter Xu wrote:
> > On Thu, Jul 02, 2020 at 11:01:54AM +0800, Jason Wang wrote:
> > > So I think we agree that a new notifier is needed?
> > Good to me, or a new flag should be easier (IOMMU_NOTIFIER_DEV_IOTLB)?
> 
> That should work but I wonder something as following is better.
> 
> Instead of introducing new flags, how about carry the type of event in 
> the notifier then the device (vhost) can choose the message it want to 
> process like:
> 
> static vhost_iommu_event(IOMMUNotifier *n, IOMMUTLBEvent *event)
> 
> {
> 
> switch (event->type) {
> 
> case IOMMU_MAP:
> case IOMMU_UNMAP:
> case IOMMU_DEV_IOTLB_UNMAP:
> ...
> 
> }
> 
> Thanks
> 
> 

Hi!

Sorry, I thought I had this clear but now it seems not so clear to me. Do you 
mean to add that switch to the current
vhost_iommu_unmap_notify, and then the "type" field to the IOMMUTLBEntry? Is 
that the scope of the changes, or there is
something I'm missing?

If that is correct, what is the advantage for vhost or other notifiers? I 
understand that move the IOMMUTLBEntry (addr,
len) -> (iova, mask) split/transformation to the different notifiers 
implementation could pollute them, but this is even a deeper change and vhost 
is not insterested in other events but IOMMU_UNMAP, isn't?

On the other hand, who decide what type of event is? If I follow the backtrace 
of the assert in 
https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg01015.html, it seems 
to me that it should be
vtd_process_device_iotlb_desc. How do I know if it should be IOMMU_UNMAP or 
IOMMU_DEV_IOTLB_UNMAP? If I set it in some
function of memory.c, I should decide the type looking the actual notifier, 
isn't?

Thanks!