mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
qemu: Add support for DUMP_COMPLETED event
The event will be fired when the domain memory only dump completes. Fill in a return buffer to store/pass along the dump statistics that will be eventually shared by a query-dump command. Also pass along the status of the filling and any possible error received. Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
2a4d847e77
commit
fd1a9e5c56
@ -210,6 +210,10 @@ VIR_ENUM_IMPL(qemuMonitorBlockIOStatus,
|
||||
QEMU_MONITOR_BLOCK_IO_STATUS_LAST,
|
||||
"ok", "failed", "nospace")
|
||||
|
||||
VIR_ENUM_IMPL(qemuMonitorDumpStatus,
|
||||
QEMU_MONITOR_DUMP_STATUS_LAST,
|
||||
"none", "active", "completed", "failed")
|
||||
|
||||
char *
|
||||
qemuMonitorEscapeArg(const char *in)
|
||||
{
|
||||
@ -1666,6 +1670,23 @@ qemuMonitorEmitBlockThreshold(qemuMonitorPtr mon,
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuMonitorEmitDumpCompleted(qemuMonitorPtr mon,
|
||||
int status,
|
||||
qemuMonitorDumpStatsPtr stats,
|
||||
const char *error)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
VIR_DEBUG("mon=%p", mon);
|
||||
|
||||
QEMU_MONITOR_CALLBACK(mon, ret, domainDumpCompleted, mon->vm,
|
||||
status, stats, error);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuMonitorSetCapabilities(qemuMonitorPtr mon)
|
||||
{
|
||||
|
@ -266,6 +266,13 @@ struct _qemuMonitorDumpStats {
|
||||
unsigned long long total; /* total bytes to be written */
|
||||
};
|
||||
|
||||
typedef int (*qemuMonitorDomainDumpCompletedCallback)(qemuMonitorPtr mon,
|
||||
virDomainObjPtr vm,
|
||||
int status,
|
||||
qemuMonitorDumpStatsPtr stats,
|
||||
const char *error,
|
||||
void *opaque);
|
||||
|
||||
typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks;
|
||||
typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr;
|
||||
struct _qemuMonitorCallbacks {
|
||||
@ -298,6 +305,7 @@ struct _qemuMonitorCallbacks {
|
||||
qemuMonitorDomainMigrationPassCallback domainMigrationPass;
|
||||
qemuMonitorDomainAcpiOstInfoCallback domainAcpiOstInfo;
|
||||
qemuMonitorDomainBlockThresholdCallback domainBlockThreshold;
|
||||
qemuMonitorDomainDumpCompletedCallback domainDumpCompleted;
|
||||
};
|
||||
|
||||
char *qemuMonitorEscapeArg(const char *in);
|
||||
@ -427,6 +435,11 @@ int qemuMonitorEmitBlockThreshold(qemuMonitorPtr mon,
|
||||
unsigned long long threshold,
|
||||
unsigned long long excess);
|
||||
|
||||
int qemuMonitorEmitDumpCompleted(qemuMonitorPtr mon,
|
||||
int status,
|
||||
qemuMonitorDumpStatsPtr stats,
|
||||
const char *error);
|
||||
|
||||
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
|
||||
virConnectPtr conn);
|
||||
int qemuMonitorStopCPUs(qemuMonitorPtr mon);
|
||||
|
@ -90,6 +90,7 @@ static void qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon, virJSONValu
|
||||
static void qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
static void qemuMonitorJSONHandleDumpCompleted(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||
|
||||
typedef struct {
|
||||
const char *type;
|
||||
@ -106,6 +107,7 @@ static qemuEventHandler eventHandlers[] = {
|
||||
{ "BLOCK_WRITE_THRESHOLD", qemuMonitorJSONHandleBlockThreshold, },
|
||||
{ "DEVICE_DELETED", qemuMonitorJSONHandleDeviceDeleted, },
|
||||
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
|
||||
{ "DUMP_COMPLETED", qemuMonitorJSONHandleDumpCompleted, },
|
||||
{ "GUEST_PANICKED", qemuMonitorJSONHandleGuestPanic, },
|
||||
{ "MIGRATION", qemuMonitorJSONHandleMigrationStatus, },
|
||||
{ "MIGRATION_PASS", qemuMonitorJSONHandleMigrationPass, },
|
||||
@ -1143,6 +1145,64 @@ qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr data)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuMonitorJSONExtractDumpStats(virJSONValuePtr result,
|
||||
qemuMonitorDumpStatsPtr ret)
|
||||
{
|
||||
const char *statusstr;
|
||||
|
||||
if (!(statusstr = virJSONValueObjectGetString(result, "status"))) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("incomplete result, failed to get status"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret->status = qemuMonitorDumpStatusTypeFromString(statusstr);
|
||||
if (ret->status < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("incomplete result, unknown status string '%s'"),
|
||||
statusstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberUlong(result, "completed", &ret->completed) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("incomplete result, failed to get completed"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberUlong(result, "total", &ret->total) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("incomplete result, failed to get total"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qemuMonitorJSONHandleDumpCompleted(qemuMonitorPtr mon,
|
||||
virJSONValuePtr data)
|
||||
{
|
||||
virJSONValuePtr result;
|
||||
int status;
|
||||
qemuMonitorDumpStats stats = { 0 };
|
||||
const char *error = NULL;
|
||||
|
||||
if (!(result = virJSONValueObjectGetObject(data, "result"))) {
|
||||
VIR_WARN("missing result in dump completed event");
|
||||
return;
|
||||
}
|
||||
|
||||
status = qemuMonitorJSONExtractDumpStats(result, &stats);
|
||||
|
||||
error = virJSONValueObjectGetString(data, "error");
|
||||
|
||||
qemuMonitorEmitDumpCompleted(mon, status, &stats, error);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
|
||||
const char *cmd_str,
|
||||
|
Loading…
x
Reference in New Issue
Block a user