diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 9caf4722b19030c8b5ab4767cb58ec8a7207445e..7ea93aa8df141c9b8ee429aae8f7675424486f14 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2985,6 +2985,14 @@ int virDomainAbortJob(virDomainPtr dom); */ # define VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW "compression_overflow" +/** + * VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE: + * + * virDomainGetJobStats field: current percentage guest CPUs are throttled + * to when auto-convergence decided migration was not converging, as + * VIR_TYPED_PARAM_INT. + */ +# define VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE "auto_converge_throttle" /** diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8f19fb5616becbe2bd3727cbc193709f30dec9c6..e3267e4ed1ac46ffb2e96b227c2c19bec385c986 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -458,6 +458,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo, goto error; } + if (stats->cpu_throttle_percentage && + virTypedParamsAddInt(&par, &npar, &maxpar, + VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE, + stats->cpu_throttle_percentage) < 0) + goto error; + *type = jobInfo->type; *params = par; *nparams = npar; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index b26f36376882340ade52861592a483fb84857eb9..c411dab6129a869b3abf1c53f4e18d94353d8972 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -807,6 +807,10 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf, stats->xbzrle_overflow); } + virBufferAsprintf(buf, "<%1$s>%2$d\n", + VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE, + stats->cpu_throttle_percentage); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "\n"); } @@ -1152,6 +1156,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt) virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW "[1])", ctxt, &stats->xbzrle_overflow); + virXPathInt("string(./" VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE "[1])", + ctxt, &stats->cpu_throttle_percentage); cleanup: ctxt->node = save_ctxt; return jobInfo; diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6fecca79a78824f1c9604883dda487861d7c7c5d..cb4cca8b2fe2f4292019df60f46f9c141e927431 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -562,6 +562,8 @@ struct _qemuMonitorMigrationStats { unsigned long long xbzrle_pages; unsigned long long xbzrle_cache_miss; unsigned long long xbzrle_overflow; + + int cpu_throttle_percentage; }; int qemuMonitorGetMigrationStats(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 66b9c4cd84861ca0f0cbeee5ed35cf507c1f5ee9..bb426dcabfb24a35ee49e8573105fc7dd87e273b 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2673,6 +2673,9 @@ qemuMonitorJSONGetMigrationStatsReply(virJSONValuePtr reply, &stats->setup_time) == 0) stats->setup_time_set = true; + ignore_value(virJSONValueObjectGetNumberInt(ret, "cpu-throttle-percentage", + &stats->cpu_throttle_percentage)); + switch ((qemuMonitorMigrationStatus) stats->status) { case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE: case QEMU_MONITOR_MIGRATION_STATUS_SETUP: diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index a28fffebd980312c4e84204a4a2c297dca573d96..dbdee5be0ca9a6579381c195c5dc4b028dc6b09b 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -5759,6 +5759,7 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd) int nparams = 0; unsigned long long value; unsigned int flags = 0; + int ivalue; int rc; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) @@ -5994,6 +5995,14 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%-17s %-13llu\n", _("Compression overflows:"), value); } + if ((rc = virTypedParamsGetInt(params, nparams, + VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE, + &ivalue)) < 0) { + goto save_error; + } else if (rc) { + vshPrint(ctl, "%-17s %-13d\n", _("Auto converge throttle:"), ivalue); + } + ret = true; cleanup: