*/
#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:
*
*/
#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:
*
*/
#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:
*
status->downtime) < 0)
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,
VIR_DOMAIN_JOB_DATA_TOTAL,
status->ram_total +
status->ram_remaining) < 0)
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 (virTypedParamsAddULLong(&par, &npar, &maxpar,
VIR_DOMAIN_JOB_MEMORY_CONSTANT,
status->disk_remaining) < 0)
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 (virTypedParamsAddULLong(&par, &npar, &maxpar,
VIR_DOMAIN_JOB_COMPRESSION_CACHE,
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
VIR_DOMAIN_JOB_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",
VIR_DOMAIN_JOB_MEMORY_TOTAL,
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
VIR_DOMAIN_JOB_MEMORY_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) {
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
VIR_DOMAIN_JOB_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) {
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_DOWNTIME "[1])",
ctxt, &status->downtime) == 0)
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])",
ctxt, &status->ram_total);
ctxt, &status->ram_transferred);
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_REMAINING "[1])",
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])",
ctxt, &status->ram_duplicate) == 0)
ctxt, &status->disk_transferred);
virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_REMAINING "[1])",
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])",
ctxt, &status->xbzrle_cache_size) == 0)
/* total or expected depending on status */
bool downtime_set;
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_remaining;
unsigned long long ram_total;
+ unsigned long long ram_bps;
bool ram_duplicate_set;
unsigned long long ram_duplicate;
unsigned long long ram_normal;
unsigned long long disk_transferred;
unsigned long long disk_remaining;
unsigned long long disk_total;
+ unsigned long long disk_bps;
bool xbzrle_set;
unsigned long long xbzrle_cache_size;
virJSONValuePtr ret;
const char *statusstr;
int rc;
+ double mbps;
if (!(ret = virJSONValueObjectGet(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
if (rc == 0)
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 ||
status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
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",
&status->ram_duplicate) == 0)
status->ram_duplicate_set = true;
"data was missing"));
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");
vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory remaining:"), val, unit);
val = vshPrettyCapacity(info.memTotal, &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) {
vshPrint(ctl, "%-17s %-.3lf %s\n", _("File remaining:"), val, unit);
val = vshPrettyCapacity(info.fileTotal, &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,
+ 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,
VIR_DOMAIN_JOB_COMPRESSION_CACHE,
&value)) < 0) {