mirror of https://gitee.com/openkylin/libvirt.git
qemu: Expose additional migration statistics
RDMA migration uses the 'setup' state in QEMU to optionally lock all memory before the migration starts. The total time spent in this state is exposed as VIR_DOMAIN_JOB_SETUP_TIME. Additionally, QEMU also exports migration throughput (mbps) for both memory and disk, so let's add them too: VIR_DOMAIN_JOB_MEMORY_BPS, VIR_DOMAIN_JOB_DISK_BPS. Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
1cd3765ead
commit
30b24df165
|
@ -4392,6 +4392,15 @@ int virDomainAbortJob(virDomainPtr dom);
|
||||||
*/
|
*/
|
||||||
#define VIR_DOMAIN_JOB_DOWNTIME "downtime"
|
#define VIR_DOMAIN_JOB_DOWNTIME "downtime"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_DOMAIN_JOB_SETUP_TIME:
|
||||||
|
*
|
||||||
|
* virDomainGetJobStats field: total time in milliseconds spent preparing
|
||||||
|
* the migration in the 'setup' phase before the iterations begin, as
|
||||||
|
* VIR_TYPED_PARAM_ULLONG.
|
||||||
|
*/
|
||||||
|
#define VIR_DOMAIN_JOB_SETUP_TIME "setup_time"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VIR_DOMAIN_JOB_DATA_TOTAL:
|
* VIR_DOMAIN_JOB_DATA_TOTAL:
|
||||||
*
|
*
|
||||||
|
@ -4489,6 +4498,14 @@ int virDomainAbortJob(virDomainPtr dom);
|
||||||
*/
|
*/
|
||||||
#define VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES "memory_normal_bytes"
|
#define VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES "memory_normal_bytes"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_DOMAIN_JOB_MEMORY_BPS:
|
||||||
|
*
|
||||||
|
* virDomainGetJobStats field: network throughput used while migrating
|
||||||
|
* memory in Bytes per second, as VIR_TYPED_PARAM_ULLONG.
|
||||||
|
*/
|
||||||
|
#define VIR_DOMAIN_JOB_MEMORY_BPS "memory_bps"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VIR_DOMAIN_JOB_DISK_TOTAL:
|
* VIR_DOMAIN_JOB_DISK_TOTAL:
|
||||||
*
|
*
|
||||||
|
@ -4519,6 +4536,14 @@ int virDomainAbortJob(virDomainPtr dom);
|
||||||
*/
|
*/
|
||||||
#define VIR_DOMAIN_JOB_DISK_REMAINING "disk_remaining"
|
#define VIR_DOMAIN_JOB_DISK_REMAINING "disk_remaining"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_DOMAIN_JOB_DISK_BPS:
|
||||||
|
*
|
||||||
|
* virDomainGetJobStats field: network throughput used while migrating
|
||||||
|
* disks in Bytes per second, as VIR_TYPED_PARAM_ULLONG.
|
||||||
|
*/
|
||||||
|
#define VIR_DOMAIN_JOB_DISK_BPS "disk_bps"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VIR_DOMAIN_JOB_COMPRESSION_CACHE:
|
* VIR_DOMAIN_JOB_COMPRESSION_CACHE:
|
||||||
*
|
*
|
||||||
|
|
|
@ -304,6 +304,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
|
||||||
status->downtime) < 0)
|
status->downtime) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (status->setup_time_set &&
|
||||||
|
virTypedParamsAddULLong(&par, &npar, &maxpar,
|
||||||
|
VIR_DOMAIN_JOB_SETUP_TIME,
|
||||||
|
status->setup_time) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (virTypedParamsAddULLong(&par, &npar, &maxpar,
|
if (virTypedParamsAddULLong(&par, &npar, &maxpar,
|
||||||
VIR_DOMAIN_JOB_DATA_TOTAL,
|
VIR_DOMAIN_JOB_DATA_TOTAL,
|
||||||
status->ram_total +
|
status->ram_total +
|
||||||
|
@ -329,6 +335,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
|
||||||
status->ram_remaining) < 0)
|
status->ram_remaining) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (status->ram_bps &&
|
||||||
|
virTypedParamsAddULLong(&par, &npar, &maxpar,
|
||||||
|
VIR_DOMAIN_JOB_MEMORY_BPS,
|
||||||
|
status->ram_bps) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (status->ram_duplicate_set) {
|
if (status->ram_duplicate_set) {
|
||||||
if (virTypedParamsAddULLong(&par, &npar, &maxpar,
|
if (virTypedParamsAddULLong(&par, &npar, &maxpar,
|
||||||
VIR_DOMAIN_JOB_MEMORY_CONSTANT,
|
VIR_DOMAIN_JOB_MEMORY_CONSTANT,
|
||||||
|
@ -353,6 +365,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
|
||||||
status->disk_remaining) < 0)
|
status->disk_remaining) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (status->disk_bps &&
|
||||||
|
virTypedParamsAddULLong(&par, &npar, &maxpar,
|
||||||
|
VIR_DOMAIN_JOB_DISK_BPS,
|
||||||
|
status->disk_bps) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (status->xbzrle_set) {
|
if (status->xbzrle_set) {
|
||||||
if (virTypedParamsAddULLong(&par, &npar, &maxpar,
|
if (virTypedParamsAddULLong(&par, &npar, &maxpar,
|
||||||
VIR_DOMAIN_JOB_COMPRESSION_CACHE,
|
VIR_DOMAIN_JOB_COMPRESSION_CACHE,
|
||||||
|
|
|
@ -636,6 +636,10 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
|
||||||
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
VIR_DOMAIN_JOB_DOWNTIME,
|
VIR_DOMAIN_JOB_DOWNTIME,
|
||||||
status->downtime);
|
status->downtime);
|
||||||
|
if (status->setup_time_set)
|
||||||
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
|
VIR_DOMAIN_JOB_SETUP_TIME,
|
||||||
|
status->setup_time);
|
||||||
|
|
||||||
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
VIR_DOMAIN_JOB_MEMORY_TOTAL,
|
VIR_DOMAIN_JOB_MEMORY_TOTAL,
|
||||||
|
@ -646,6 +650,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
|
||||||
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
VIR_DOMAIN_JOB_MEMORY_REMAINING,
|
VIR_DOMAIN_JOB_MEMORY_REMAINING,
|
||||||
status->ram_remaining);
|
status->ram_remaining);
|
||||||
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
|
VIR_DOMAIN_JOB_MEMORY_BPS,
|
||||||
|
status->ram_bps);
|
||||||
|
|
||||||
if (status->ram_duplicate_set) {
|
if (status->ram_duplicate_set) {
|
||||||
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
|
@ -668,6 +675,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
|
||||||
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
VIR_DOMAIN_JOB_DISK_REMAINING,
|
VIR_DOMAIN_JOB_DISK_REMAINING,
|
||||||
status->disk_remaining);
|
status->disk_remaining);
|
||||||
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
|
VIR_DOMAIN_JOB_DISK_BPS,
|
||||||
|
status->disk_bps);
|
||||||
|
|
||||||
if (status->xbzrle_set) {
|
if (status->xbzrle_set) {
|
||||||
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
|
||||||
|
@ -904,6 +914,9 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
|
||||||
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_DOWNTIME "[1])",
|
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_DOWNTIME "[1])",
|
||||||
ctxt, &status->downtime) == 0)
|
ctxt, &status->downtime) == 0)
|
||||||
status->downtime_set = true;
|
status->downtime_set = true;
|
||||||
|
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_SETUP_TIME "[1])",
|
||||||
|
ctxt, &status->setup_time) == 0)
|
||||||
|
status->setup_time_set = true;
|
||||||
|
|
||||||
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_TOTAL "[1])",
|
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_TOTAL "[1])",
|
||||||
ctxt, &status->ram_total);
|
ctxt, &status->ram_total);
|
||||||
|
@ -911,6 +924,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
|
||||||
ctxt, &status->ram_transferred);
|
ctxt, &status->ram_transferred);
|
||||||
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_REMAINING "[1])",
|
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_REMAINING "[1])",
|
||||||
ctxt, &status->ram_remaining);
|
ctxt, &status->ram_remaining);
|
||||||
|
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_BPS "[1])",
|
||||||
|
ctxt, &status->ram_bps);
|
||||||
|
|
||||||
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_CONSTANT "[1])",
|
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_CONSTANT "[1])",
|
||||||
ctxt, &status->ram_duplicate) == 0)
|
ctxt, &status->ram_duplicate) == 0)
|
||||||
|
@ -926,6 +941,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
|
||||||
ctxt, &status->disk_transferred);
|
ctxt, &status->disk_transferred);
|
||||||
virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_REMAINING "[1])",
|
virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_REMAINING "[1])",
|
||||||
ctxt, &status->disk_remaining);
|
ctxt, &status->disk_remaining);
|
||||||
|
virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_BPS "[1])",
|
||||||
|
ctxt, &status->disk_bps);
|
||||||
|
|
||||||
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_CACHE "[1])",
|
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_CACHE "[1])",
|
||||||
ctxt, &status->xbzrle_cache_size) == 0)
|
ctxt, &status->xbzrle_cache_size) == 0)
|
||||||
|
|
|
@ -443,10 +443,18 @@ struct _qemuMonitorMigrationStatus {
|
||||||
/* total or expected depending on status */
|
/* total or expected depending on status */
|
||||||
bool downtime_set;
|
bool downtime_set;
|
||||||
unsigned long long downtime;
|
unsigned long long downtime;
|
||||||
|
/*
|
||||||
|
* Duration of the QEMU 'setup' state.
|
||||||
|
* for RDMA, this may be on the order of several seconds
|
||||||
|
* if pinning support is requested before the migration begins.
|
||||||
|
*/
|
||||||
|
bool setup_time_set;
|
||||||
|
unsigned long long setup_time;
|
||||||
|
|
||||||
unsigned long long ram_transferred;
|
unsigned long long ram_transferred;
|
||||||
unsigned long long ram_remaining;
|
unsigned long long ram_remaining;
|
||||||
unsigned long long ram_total;
|
unsigned long long ram_total;
|
||||||
|
unsigned long long ram_bps;
|
||||||
bool ram_duplicate_set;
|
bool ram_duplicate_set;
|
||||||
unsigned long long ram_duplicate;
|
unsigned long long ram_duplicate;
|
||||||
unsigned long long ram_normal;
|
unsigned long long ram_normal;
|
||||||
|
@ -455,6 +463,7 @@ struct _qemuMonitorMigrationStatus {
|
||||||
unsigned long long disk_transferred;
|
unsigned long long disk_transferred;
|
||||||
unsigned long long disk_remaining;
|
unsigned long long disk_remaining;
|
||||||
unsigned long long disk_total;
|
unsigned long long disk_total;
|
||||||
|
unsigned long long disk_bps;
|
||||||
|
|
||||||
bool xbzrle_set;
|
bool xbzrle_set;
|
||||||
unsigned long long xbzrle_cache_size;
|
unsigned long long xbzrle_cache_size;
|
||||||
|
|
|
@ -2519,6 +2519,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||||
virJSONValuePtr ret;
|
virJSONValuePtr ret;
|
||||||
const char *statusstr;
|
const char *statusstr;
|
||||||
int rc;
|
int rc;
|
||||||
|
double mbps;
|
||||||
|
|
||||||
if (!(ret = virJSONValueObjectGet(reply, "return"))) {
|
if (!(ret = virJSONValueObjectGet(reply, "return"))) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
@ -2551,6 +2552,10 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
status->downtime_set = true;
|
status->downtime_set = true;
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberUlong(ret, "setup-time",
|
||||||
|
&status->setup_time) == 0)
|
||||||
|
status->setup_time_set = true;
|
||||||
|
|
||||||
if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE ||
|
if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE ||
|
||||||
status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
|
status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
|
||||||
virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
|
virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
|
||||||
|
@ -2582,6 +2587,12 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberDouble(ram, "mbps", &mbps) == 0 &&
|
||||||
|
mbps > 0) {
|
||||||
|
/* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */
|
||||||
|
status->ram_bps = mbps * (1000 * 1000 / 8);
|
||||||
|
}
|
||||||
|
|
||||||
if (virJSONValueObjectGetNumberUlong(ram, "duplicate",
|
if (virJSONValueObjectGetNumberUlong(ram, "duplicate",
|
||||||
&status->ram_duplicate) == 0)
|
&status->ram_duplicate) == 0)
|
||||||
status->ram_duplicate_set = true;
|
status->ram_duplicate_set = true;
|
||||||
|
@ -2618,6 +2629,12 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||||
"data was missing"));
|
"data was missing"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberDouble(disk, "mbps", &mbps) == 0 &&
|
||||||
|
mbps > 0) {
|
||||||
|
/* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */
|
||||||
|
status->disk_bps = mbps * (1000 * 1000 / 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virJSONValuePtr comp = virJSONValueObjectGet(ret, "xbzrle-cache");
|
virJSONValuePtr comp = virJSONValueObjectGet(ret, "xbzrle-cache");
|
||||||
|
|
|
@ -5518,6 +5518,16 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd)
|
||||||
vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory remaining:"), val, unit);
|
vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory remaining:"), val, unit);
|
||||||
val = vshPrettyCapacity(info.memTotal, &unit);
|
val = vshPrettyCapacity(info.memTotal, &unit);
|
||||||
vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory total:"), val, unit);
|
vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory total:"), val, unit);
|
||||||
|
|
||||||
|
if ((rc = virTypedParamsGetULLong(params, nparams,
|
||||||
|
VIR_DOMAIN_JOB_MEMORY_BPS,
|
||||||
|
&value)) < 0) {
|
||||||
|
goto save_error;
|
||||||
|
} else if (rc && value) {
|
||||||
|
val = vshPrettyCapacity(value, &unit);
|
||||||
|
vshPrint(ctl, "%-17s %-.3lf %s/s\n",
|
||||||
|
_("Memory bandwidth:"), val, unit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.fileTotal || info.fileRemaining || info.fileProcessed) {
|
if (info.fileTotal || info.fileRemaining || info.fileProcessed) {
|
||||||
|
@ -5527,6 +5537,16 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd)
|
||||||
vshPrint(ctl, "%-17s %-.3lf %s\n", _("File remaining:"), val, unit);
|
vshPrint(ctl, "%-17s %-.3lf %s\n", _("File remaining:"), val, unit);
|
||||||
val = vshPrettyCapacity(info.fileTotal, &unit);
|
val = vshPrettyCapacity(info.fileTotal, &unit);
|
||||||
vshPrint(ctl, "%-17s %-.3lf %s\n", _("File total:"), val, unit);
|
vshPrint(ctl, "%-17s %-.3lf %s\n", _("File total:"), val, unit);
|
||||||
|
|
||||||
|
if ((rc = virTypedParamsGetULLong(params, nparams,
|
||||||
|
VIR_DOMAIN_JOB_DISK_BPS,
|
||||||
|
&value)) < 0) {
|
||||||
|
goto save_error;
|
||||||
|
} else if (rc && value) {
|
||||||
|
val = vshPrettyCapacity(value, &unit);
|
||||||
|
vshPrint(ctl, "%-17s %-.3lf %s/s\n",
|
||||||
|
_("File bandwidth:"), val, unit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = virTypedParamsGetULLong(params, nparams,
|
if ((rc = virTypedParamsGetULLong(params, nparams,
|
||||||
|
@ -5566,6 +5586,13 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((rc = virTypedParamsGetULLong(params, nparams,
|
||||||
|
VIR_DOMAIN_JOB_SETUP_TIME,
|
||||||
|
&value)) < 0)
|
||||||
|
goto save_error;
|
||||||
|
else if (rc)
|
||||||
|
vshPrint(ctl, "%-17s %-12llu ms\n", _("Setup time:"), value);
|
||||||
|
|
||||||
if ((rc = virTypedParamsGetULLong(params, nparams,
|
if ((rc = virTypedParamsGetULLong(params, nparams,
|
||||||
VIR_DOMAIN_JOB_COMPRESSION_CACHE,
|
VIR_DOMAIN_JOB_COMPRESSION_CACHE,
|
||||||
&value)) < 0) {
|
&value)) < 0) {
|
||||||
|
|
Loading…
Reference in New Issue