mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
qemu: Parse more fields from query-migrate QMP command
As a side effect, this also fixes reporting disk migration process. It was added to memory migration progress, which was wrong. Disk progress has dedicated fields in virDomainJobInfo structure.
This commit is contained in:
parent
38ab12251e
commit
4121a77c1a
@ -160,6 +160,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
|
||||
job->start = 0;
|
||||
job->dump_memory_only = false;
|
||||
job->asyncAbort = false;
|
||||
memset(&job->status, 0, sizeof(job->status));
|
||||
memset(&job->info, 0, sizeof(job->info));
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,8 @@ struct qemuDomainJobObj {
|
||||
unsigned long long mask; /* Jobs allowed during async job */
|
||||
unsigned long long start; /* When the async job started */
|
||||
bool dump_memory_only; /* use dump-guest-memory to do dump */
|
||||
virDomainJobInfo info; /* Async job progress data */
|
||||
qemuMonitorMigrationStatus status; /* Raw async job progress data */
|
||||
virDomainJobInfo info; /* Processed async job progress data */
|
||||
bool asyncAbort; /* abort of async job requested */
|
||||
};
|
||||
|
||||
|
@ -1198,12 +1198,11 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
int ret;
|
||||
int status;
|
||||
bool wait_for_spice = false;
|
||||
bool spice_migrated = false;
|
||||
unsigned long long memProcessed;
|
||||
unsigned long long memRemaining;
|
||||
unsigned long long memTotal;
|
||||
qemuMonitorMigrationStatus status;
|
||||
|
||||
memset(&status, 0, sizeof(status));
|
||||
|
||||
/* If guest uses SPICE and supports seamles_migration we have to hold up
|
||||
* migration finish until SPICE server transfers its data */
|
||||
@ -1217,20 +1216,19 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
|
||||
/* Guest already exited; nothing further to update. */
|
||||
return -1;
|
||||
}
|
||||
ret = qemuMonitorGetMigrationStatus(priv->mon,
|
||||
&status,
|
||||
&memProcessed,
|
||||
&memRemaining,
|
||||
&memTotal);
|
||||
ret = qemuMonitorGetMigrationStatus(priv->mon, &status);
|
||||
|
||||
/* If qemu says migrated, check spice */
|
||||
if (wait_for_spice && (ret == 0) &&
|
||||
(status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED))
|
||||
if (wait_for_spice &&
|
||||
ret == 0 &&
|
||||
status.status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED)
|
||||
ret = qemuMonitorGetSpiceMigrationStatus(priv->mon,
|
||||
&spice_migrated);
|
||||
|
||||
qemuDomainObjExitMonitor(driver, vm);
|
||||
|
||||
priv->job.status = status;
|
||||
|
||||
if (ret < 0 || virTimeMillisNow(&priv->job.info.timeElapsed) < 0) {
|
||||
priv->job.info.type = VIR_DOMAIN_JOB_FAILED;
|
||||
return -1;
|
||||
@ -1238,7 +1236,7 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
|
||||
priv->job.info.timeElapsed -= priv->job.start;
|
||||
|
||||
ret = -1;
|
||||
switch (status) {
|
||||
switch (priv->job.status.status) {
|
||||
case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
|
||||
priv->job.info.type = VIR_DOMAIN_JOB_NONE;
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
@ -1246,13 +1244,21 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
|
||||
break;
|
||||
|
||||
case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
|
||||
priv->job.info.dataTotal = memTotal;
|
||||
priv->job.info.dataRemaining = memRemaining;
|
||||
priv->job.info.dataProcessed = memProcessed;
|
||||
priv->job.info.fileTotal = priv->job.status.disk_total;
|
||||
priv->job.info.fileRemaining = priv->job.status.disk_remaining;
|
||||
priv->job.info.fileProcessed = priv->job.status.disk_transferred;
|
||||
|
||||
priv->job.info.memTotal = memTotal;
|
||||
priv->job.info.memRemaining = memRemaining;
|
||||
priv->job.info.memProcessed = memProcessed;
|
||||
priv->job.info.memTotal = priv->job.status.ram_total;
|
||||
priv->job.info.memRemaining = priv->job.status.ram_remaining;
|
||||
priv->job.info.memProcessed = priv->job.status.ram_transferred;
|
||||
|
||||
priv->job.info.dataTotal =
|
||||
priv->job.status.ram_total + priv->job.status.disk_total;
|
||||
priv->job.info.dataRemaining =
|
||||
priv->job.status.ram_remaining + priv->job.status.disk_remaining;
|
||||
priv->job.info.dataProcessed =
|
||||
priv->job.status.ram_transferred +
|
||||
priv->job.status.disk_transferred;
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
|
@ -1805,10 +1805,7 @@ int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
|
||||
|
||||
|
||||
int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
|
||||
int *status,
|
||||
unsigned long long *transferred,
|
||||
unsigned long long *remaining,
|
||||
unsigned long long *total)
|
||||
qemuMonitorMigrationStatusPtr status)
|
||||
{
|
||||
int ret;
|
||||
VIR_DEBUG("mon=%p", mon);
|
||||
@ -1820,15 +1817,9 @@ int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
|
||||
}
|
||||
|
||||
if (mon->json)
|
||||
ret = qemuMonitorJSONGetMigrationStatus(mon, status,
|
||||
transferred,
|
||||
remaining,
|
||||
total);
|
||||
ret = qemuMonitorJSONGetMigrationStatus(mon, status);
|
||||
else
|
||||
ret = qemuMonitorTextGetMigrationStatus(mon, status,
|
||||
transferred,
|
||||
remaining,
|
||||
total);
|
||||
ret = qemuMonitorTextGetMigrationStatus(mon, status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -338,11 +338,37 @@ enum {
|
||||
|
||||
VIR_ENUM_DECL(qemuMonitorMigrationStatus)
|
||||
|
||||
typedef struct _qemuMonitorMigrationStatus qemuMonitorMigrationStatus;
|
||||
typedef qemuMonitorMigrationStatus *qemuMonitorMigrationStatusPtr;
|
||||
struct _qemuMonitorMigrationStatus {
|
||||
int status;
|
||||
unsigned long long total_time;
|
||||
/* total or expected depending on status */
|
||||
bool downtime_set;
|
||||
unsigned long long downtime;
|
||||
|
||||
unsigned long long ram_transferred;
|
||||
unsigned long long ram_remaining;
|
||||
unsigned long long ram_total;
|
||||
bool ram_duplicate_set;
|
||||
unsigned long long ram_duplicate;
|
||||
unsigned long long ram_normal;
|
||||
unsigned long long ram_normal_bytes;
|
||||
|
||||
unsigned long long disk_transferred;
|
||||
unsigned long long disk_remaining;
|
||||
unsigned long long disk_total;
|
||||
|
||||
bool xbzrle_set;
|
||||
unsigned long long xbzrle_cache_size;
|
||||
unsigned long long xbzrle_bytes;
|
||||
unsigned long long xbzrle_pages;
|
||||
unsigned long long xbzrle_cache_miss;
|
||||
unsigned long long xbzrle_overflow;
|
||||
};
|
||||
|
||||
int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
|
||||
int *status,
|
||||
unsigned long long *transferred,
|
||||
unsigned long long *remaining,
|
||||
unsigned long long *total);
|
||||
qemuMonitorMigrationStatusPtr status);
|
||||
int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
|
||||
bool *spice_migrated);
|
||||
|
||||
|
@ -2258,14 +2258,11 @@ int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
|
||||
|
||||
static int
|
||||
qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||
int *status,
|
||||
unsigned long long *transferred,
|
||||
unsigned long long *remaining,
|
||||
unsigned long long *total)
|
||||
qemuMonitorMigrationStatusPtr status)
|
||||
{
|
||||
virJSONValuePtr ret;
|
||||
const char *statusstr;
|
||||
unsigned long long t;
|
||||
int rc;
|
||||
|
||||
if (!(ret = virJSONValueObjectGet(reply, "return"))) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
@ -2279,13 +2276,25 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*status = qemuMonitorMigrationStatusTypeFromString(statusstr)) < 0) {
|
||||
status->status = qemuMonitorMigrationStatusTypeFromString(statusstr);
|
||||
if (status->status < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unexpected migration status in %s"), statusstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
|
||||
virJSONValueObjectGetNumberUlong(ret, "total-time", &status->total_time);
|
||||
if (status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
|
||||
rc = virJSONValueObjectGetNumberUlong(ret, "downtime",
|
||||
&status->downtime);
|
||||
} else {
|
||||
rc = virJSONValueObjectGetNumberUlong(ret, "expected-downtime",
|
||||
&status->downtime);
|
||||
}
|
||||
if (rc == 0)
|
||||
status->downtime_set = true;
|
||||
|
||||
if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
|
||||
virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
|
||||
if (!ram) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
@ -2294,51 +2303,112 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberUlong(ram, "transferred",
|
||||
transferred) < 0) {
|
||||
&status->ram_transferred) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("migration was active, but RAM 'transferred' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
}
|
||||
if (virJSONValueObjectGetNumberUlong(ram, "remaining", remaining) < 0) {
|
||||
if (virJSONValueObjectGetNumberUlong(ram, "remaining",
|
||||
&status->ram_remaining) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("migration was active, but RAM 'remaining' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
}
|
||||
if (virJSONValueObjectGetNumberUlong(ram, "total", total) < 0) {
|
||||
if (virJSONValueObjectGetNumberUlong(ram, "total",
|
||||
&status->ram_total) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("migration was active, but RAM 'total' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberUlong(ram, "duplicate",
|
||||
&status->ram_duplicate) == 0)
|
||||
status->ram_duplicate_set = true;
|
||||
virJSONValueObjectGetNumberUlong(ram, "normal", &status->ram_normal);
|
||||
virJSONValueObjectGetNumberUlong(ram, "normal-bytes",
|
||||
&status->ram_normal_bytes);
|
||||
|
||||
virJSONValuePtr disk = virJSONValueObjectGet(ret, "disk");
|
||||
if (!disk) {
|
||||
return 0;
|
||||
if (disk) {
|
||||
rc = virJSONValueObjectGetNumberUlong(disk, "transferred",
|
||||
&status->disk_transferred);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("disk migration was active, but "
|
||||
"'transferred' data was missing"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = virJSONValueObjectGetNumberUlong(disk, "remaining",
|
||||
&status->disk_remaining);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("disk migration was active, but 'remaining' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = virJSONValueObjectGetNumberUlong(disk, "total",
|
||||
&status->disk_total);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("disk migration was active, but 'total' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberUlong(disk, "transferred", &t) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("disk migration was active, but 'transferred' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
virJSONValuePtr comp = virJSONValueObjectGet(ret, "xbzrle-cache");
|
||||
if (comp) {
|
||||
status->xbzrle_set = true;
|
||||
rc = virJSONValueObjectGetNumberUlong(comp, "cache-size",
|
||||
&status->xbzrle_cache_size);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("XBZRLE is active, but 'cache-size' data "
|
||||
"was missing"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = virJSONValueObjectGetNumberUlong(comp, "bytes",
|
||||
&status->xbzrle_bytes);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("XBZRLE is active, but 'bytes' data "
|
||||
"was missing"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = virJSONValueObjectGetNumberUlong(comp, "pages",
|
||||
&status->xbzrle_pages);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("XBZRLE is active, but 'pages' data "
|
||||
"was missing"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = virJSONValueObjectGetNumberUlong(comp, "cache-miss",
|
||||
&status->xbzrle_cache_miss);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("XBZRLE is active, but 'cache-miss' data "
|
||||
"was missing"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = virJSONValueObjectGetNumberUlong(comp, "overflow",
|
||||
&status->xbzrle_overflow);
|
||||
if (rc < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("XBZRLE is active, but 'overflow' data "
|
||||
"was missing"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*transferred += t;
|
||||
if (virJSONValueObjectGetNumberUlong(disk, "remaining", &t) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("disk migration was active, but 'remaining' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
}
|
||||
*remaining += t;
|
||||
if (virJSONValueObjectGetNumberUlong(disk, "total", &t) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("disk migration was active, but 'total' "
|
||||
"data was missing"));
|
||||
return -1;
|
||||
}
|
||||
*total += t;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2346,18 +2416,14 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||
|
||||
|
||||
int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
|
||||
int *status,
|
||||
unsigned long long *transferred,
|
||||
unsigned long long *remaining,
|
||||
unsigned long long *total)
|
||||
qemuMonitorMigrationStatusPtr status)
|
||||
{
|
||||
int ret;
|
||||
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-migrate",
|
||||
NULL);
|
||||
virJSONValuePtr reply = NULL;
|
||||
|
||||
*status = 0;
|
||||
*transferred = *remaining = *total = 0;
|
||||
memset(status, 0, sizeof(*status));
|
||||
|
||||
if (!cmd)
|
||||
return -1;
|
||||
@ -2368,13 +2434,11 @@ int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
|
||||
ret = qemuMonitorJSONCheckError(cmd, reply);
|
||||
|
||||
if (ret == 0 &&
|
||||
qemuMonitorJSONGetMigrationStatusReply(reply,
|
||||
status,
|
||||
transferred,
|
||||
remaining,
|
||||
total) < 0)
|
||||
qemuMonitorJSONGetMigrationStatusReply(reply, status) < 0)
|
||||
ret = -1;
|
||||
|
||||
if (ret < 0)
|
||||
memset(status, 0, sizeof(*status));
|
||||
virJSONValueFree(cmd);
|
||||
virJSONValueFree(reply);
|
||||
return ret;
|
||||
|
@ -121,10 +121,7 @@ int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
|
||||
unsigned long long downtime);
|
||||
|
||||
int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
|
||||
int *status,
|
||||
unsigned long long *transferred,
|
||||
unsigned long long *remaining,
|
||||
unsigned long long *total);
|
||||
qemuMonitorMigrationStatusPtr status);
|
||||
|
||||
int qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon,
|
||||
qemuMonitorMigrationCaps capability);
|
||||
|
@ -1474,22 +1474,14 @@ cleanup:
|
||||
#define MIGRATION_DISK_TOTAL_PREFIX "total disk: "
|
||||
|
||||
int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
|
||||
int *status,
|
||||
unsigned long long *transferred,
|
||||
unsigned long long *remaining,
|
||||
unsigned long long *total) {
|
||||
qemuMonitorMigrationStatusPtr status)
|
||||
{
|
||||
char *reply;
|
||||
char *tmp;
|
||||
char *end;
|
||||
unsigned long long disk_transferred = 0;
|
||||
unsigned long long disk_remaining = 0;
|
||||
unsigned long long disk_total = 0;
|
||||
int ret = -1;
|
||||
|
||||
*status = QEMU_MONITOR_MIGRATION_STATUS_INACTIVE;
|
||||
*transferred = 0;
|
||||
*remaining = 0;
|
||||
*total = 0;
|
||||
memset(status, 0, sizeof(*status));
|
||||
|
||||
if (qemuMonitorHMPCommand(mon, "info migrate", &reply) < 0)
|
||||
return -1;
|
||||
@ -1504,52 +1496,54 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
|
||||
}
|
||||
*end = '\0';
|
||||
|
||||
if ((*status = qemuMonitorMigrationStatusTypeFromString(tmp)) < 0) {
|
||||
status->status = qemuMonitorMigrationStatusTypeFromString(tmp);
|
||||
if (status->status < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unexpected migration status in %s"), reply);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (*status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
|
||||
if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
|
||||
tmp = end + 1;
|
||||
|
||||
if (!(tmp = strstr(tmp, MIGRATION_TRANSFER_PREFIX)))
|
||||
goto done;
|
||||
tmp += strlen(MIGRATION_TRANSFER_PREFIX);
|
||||
|
||||
if (virStrToLong_ull(tmp, &end, 10, transferred) < 0) {
|
||||
if (virStrToLong_ull(tmp, &end, 10,
|
||||
&status->ram_transferred) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse migration data transferred "
|
||||
"statistic %s"), tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
*transferred *= 1024;
|
||||
status->ram_transferred *= 1024;
|
||||
tmp = end;
|
||||
|
||||
if (!(tmp = strstr(tmp, MIGRATION_REMAINING_PREFIX)))
|
||||
goto done;
|
||||
tmp += strlen(MIGRATION_REMAINING_PREFIX);
|
||||
|
||||
if (virStrToLong_ull(tmp, &end, 10, remaining) < 0) {
|
||||
if (virStrToLong_ull(tmp, &end, 10, &status->ram_remaining) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse migration data remaining "
|
||||
"statistic %s"), tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
*remaining *= 1024;
|
||||
status->ram_remaining *= 1024;
|
||||
tmp = end;
|
||||
|
||||
if (!(tmp = strstr(tmp, MIGRATION_TOTAL_PREFIX)))
|
||||
goto done;
|
||||
tmp += strlen(MIGRATION_TOTAL_PREFIX);
|
||||
|
||||
if (virStrToLong_ull(tmp, &end, 10, total) < 0) {
|
||||
if (virStrToLong_ull(tmp, &end, 10, &status->ram_total) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse migration data total "
|
||||
"statistic %s"), tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
*total *= 1024;
|
||||
status->ram_total *= 1024;
|
||||
tmp = end;
|
||||
|
||||
/*
|
||||
@ -1559,39 +1553,40 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
|
||||
goto done;
|
||||
tmp += strlen(MIGRATION_DISK_TRANSFER_PREFIX);
|
||||
|
||||
if (virStrToLong_ull(tmp, &end, 10, &disk_transferred) < 0) {
|
||||
if (virStrToLong_ull(tmp, &end, 10,
|
||||
&status->disk_transferred) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse disk migration data "
|
||||
"transferred statistic %s"), tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
*transferred += disk_transferred * 1024;
|
||||
status->disk_transferred *= 1024;
|
||||
tmp = end;
|
||||
|
||||
if (!(tmp = strstr(tmp, MIGRATION_DISK_REMAINING_PREFIX)))
|
||||
goto done;
|
||||
tmp += strlen(MIGRATION_DISK_REMAINING_PREFIX);
|
||||
|
||||
if (virStrToLong_ull(tmp, &end, 10, &disk_remaining) < 0) {
|
||||
if (virStrToLong_ull(tmp, &end, 10, &status->disk_remaining) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse disk migration data remaining "
|
||||
"statistic %s"), tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
*remaining += disk_remaining * 1024;
|
||||
status->disk_remaining *= 1024;
|
||||
tmp = end;
|
||||
|
||||
if (!(tmp = strstr(tmp, MIGRATION_DISK_TOTAL_PREFIX)))
|
||||
goto done;
|
||||
tmp += strlen(MIGRATION_DISK_TOTAL_PREFIX);
|
||||
|
||||
if (virStrToLong_ull(tmp, &end, 10, &disk_total) < 0) {
|
||||
if (virStrToLong_ull(tmp, &end, 10, &status->disk_total) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse disk migration data total "
|
||||
"statistic %s"), tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
*total += disk_total * 1024;
|
||||
status->disk_total *= 1024;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1600,6 +1595,8 @@ done:
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(reply);
|
||||
if (ret < 0)
|
||||
memset(status, 0, sizeof(*status));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -117,10 +117,7 @@ int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
|
||||
unsigned long long downtime);
|
||||
|
||||
int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
|
||||
int *status,
|
||||
unsigned long long *transferred,
|
||||
unsigned long long *remaining,
|
||||
unsigned long long *total);
|
||||
qemuMonitorMigrationStatusPtr status);
|
||||
|
||||
int qemuMonitorTextMigrate(qemuMonitorPtr mon,
|
||||
unsigned int flags,
|
||||
|
Loading…
x
Reference in New Issue
Block a user