mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-20 04:59:49 +00:00
qemu: monitor: Add infrastructure for 'query-jobs'
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
93de886b10
commit
ed56851f1b
@ -4585,3 +4585,26 @@ qemuMonitorDeleteBitmap(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
return qemuMonitorJSONDeleteBitmap(mon, node, bitmap);
|
return qemuMonitorJSONDeleteBitmap(mon, node, bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuMonitorJobInfoFree(qemuMonitorJobInfoPtr job)
|
||||||
|
{
|
||||||
|
if (!job)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VIR_FREE(job->id);
|
||||||
|
VIR_FREE(job->error);
|
||||||
|
VIR_FREE(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorGetJobInfo(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorJobInfoPtr **jobs,
|
||||||
|
size_t *njobs)
|
||||||
|
{
|
||||||
|
QEMU_CHECK_MONITOR(mon);
|
||||||
|
|
||||||
|
return qemuMonitorJSONGetJobInfo(mon, jobs, njobs);
|
||||||
|
}
|
||||||
|
@ -117,6 +117,48 @@ struct _qemuMonitorRdmaGidStatus {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QEMU_MONITOR_JOB_TYPE_UNKNOWN, /* internal value, not exposed by qemu */
|
||||||
|
QEMU_MONITOR_JOB_TYPE_COMMIT,
|
||||||
|
QEMU_MONITOR_JOB_TYPE_STREAM,
|
||||||
|
QEMU_MONITOR_JOB_TYPE_MIRROR,
|
||||||
|
QEMU_MONITOR_JOB_TYPE_BACKUP,
|
||||||
|
QEMU_MONITOR_JOB_TYPE_CREATE,
|
||||||
|
QEMU_MONITOR_JOB_TYPE_LAST
|
||||||
|
} qemuMonitorJobType;
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(qemuMonitorJob);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QEMU_MONITOR_JOB_STATUS_UNKNOWN, /* internal value, not exposed by qemu */
|
||||||
|
QEMU_MONITOR_JOB_STATUS_CREATED,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_RUNNING,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_PAUSED,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_READY,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_STANDBY,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_WAITING,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_PENDING,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_ABORTING,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_CONCLUDED,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_UNDEFINED, /* the job states below should not be visible outside of qemu */
|
||||||
|
QEMU_MONITOR_JOB_STATUS_NULL,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_LAST
|
||||||
|
} qemuMonitorJobStatus;
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(qemuMonitorJobStatus);
|
||||||
|
|
||||||
|
typedef struct _qemuMonitorJobInfo qemuMonitorJobInfo;
|
||||||
|
typedef qemuMonitorJobInfo *qemuMonitorJobInfoPtr;
|
||||||
|
struct _qemuMonitorJobInfo {
|
||||||
|
char *id;
|
||||||
|
qemuMonitorJobType type;
|
||||||
|
qemuMonitorJobStatus status;
|
||||||
|
char *error;
|
||||||
|
long long progressCurrent;
|
||||||
|
long long progressTotal;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
char *qemuMonitorGuestPanicEventInfoFormatMsg(qemuMonitorEventPanicInfoPtr info);
|
char *qemuMonitorGuestPanicEventInfoFormatMsg(qemuMonitorEventPanicInfoPtr info);
|
||||||
void qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info);
|
void qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info);
|
||||||
void qemuMonitorEventRdmaGidStatusFree(qemuMonitorRdmaGidStatusPtr info);
|
void qemuMonitorEventRdmaGidStatusFree(qemuMonitorRdmaGidStatusPtr info);
|
||||||
@ -1279,3 +1321,10 @@ struct _qemuMonitorCurrentMachineInfo {
|
|||||||
|
|
||||||
int qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon,
|
int qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon,
|
||||||
qemuMonitorCurrentMachineInfoPtr info);
|
qemuMonitorCurrentMachineInfoPtr info);
|
||||||
|
void qemuMonitorJobInfoFree(qemuMonitorJobInfoPtr job);
|
||||||
|
|
||||||
|
VIR_DEFINE_AUTOPTR_FUNC(qemuMonitorJobInfo, qemuMonitorJobInfoFree);
|
||||||
|
|
||||||
|
int qemuMonitorGetJobInfo(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorJobInfoPtr **jobs,
|
||||||
|
size_t *njobs);
|
||||||
|
@ -56,6 +56,30 @@ VIR_LOG_INIT("qemu.qemu_monitor_json");
|
|||||||
|
|
||||||
#define LINE_ENDING "\r\n"
|
#define LINE_ENDING "\r\n"
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(qemuMonitorJob,
|
||||||
|
QEMU_MONITOR_JOB_TYPE_LAST,
|
||||||
|
"",
|
||||||
|
"commit",
|
||||||
|
"stream",
|
||||||
|
"mirror",
|
||||||
|
"backup",
|
||||||
|
"create");
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(qemuMonitorJobStatus,
|
||||||
|
QEMU_MONITOR_JOB_STATUS_LAST,
|
||||||
|
"",
|
||||||
|
"created",
|
||||||
|
"running",
|
||||||
|
"paused",
|
||||||
|
"ready",
|
||||||
|
"standby",
|
||||||
|
"waiting",
|
||||||
|
"pending",
|
||||||
|
"aborting",
|
||||||
|
"concluded",
|
||||||
|
"undefined",
|
||||||
|
"null");
|
||||||
|
|
||||||
static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data);
|
static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||||
static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data);
|
static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||||
static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data);
|
static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||||
@ -9044,3 +9068,74 @@ qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon,
|
|||||||
virJSONValueFree(reply);
|
virJSONValueFree(reply);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static qemuMonitorJobInfoPtr
|
||||||
|
qemuMonitorJSONGetJobInfoOne(virJSONValuePtr data)
|
||||||
|
{
|
||||||
|
const char *id = virJSONValueObjectGetString(data, "id");
|
||||||
|
const char *type = virJSONValueObjectGetString(data, "type");
|
||||||
|
const char *status = virJSONValueObjectGetString(data, "status");
|
||||||
|
const char *errmsg = virJSONValueObjectGetString(data, "error");
|
||||||
|
int tmp;
|
||||||
|
VIR_AUTOPTR(qemuMonitorJobInfo) job = NULL;
|
||||||
|
qemuMonitorJobInfoPtr ret = NULL;
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(job) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((tmp = qemuMonitorJobTypeFromString(type)) < 0)
|
||||||
|
tmp = QEMU_MONITOR_JOB_TYPE_UNKNOWN;
|
||||||
|
|
||||||
|
job->type = tmp;
|
||||||
|
|
||||||
|
if ((tmp = qemuMonitorJobStatusTypeFromString(status)) < 0)
|
||||||
|
tmp = QEMU_MONITOR_JOB_STATUS_UNKNOWN;
|
||||||
|
|
||||||
|
job->status = tmp;
|
||||||
|
|
||||||
|
if (VIR_STRDUP(job->id, id) < 0 ||
|
||||||
|
VIR_STRDUP(job->error, errmsg) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
VIR_STEAL_PTR(ret, job);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorJSONGetJobInfo(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorJobInfoPtr **jobs,
|
||||||
|
size_t *njobs)
|
||||||
|
{
|
||||||
|
virJSONValuePtr data;
|
||||||
|
VIR_AUTOPTR(virJSONValue) cmd = NULL;
|
||||||
|
VIR_AUTOPTR(virJSONValue) reply = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!(cmd = qemuMonitorJSONMakeCommand("query-jobs", NULL)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
data = virJSONValueObjectGetArray(reply, "return");
|
||||||
|
|
||||||
|
for (i = 0; i < virJSONValueArraySize(data); i++) {
|
||||||
|
qemuMonitorJobInfoPtr job = NULL;
|
||||||
|
|
||||||
|
if (!(job = qemuMonitorJSONGetJobInfoOne(virJSONValueArrayGet(data, i))))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(*jobs, *njobs, job) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -319,6 +319,12 @@ int qemuMonitorJSONBlockJobCancel(qemuMonitorPtr mon,
|
|||||||
const char *jobname)
|
const char *jobname)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorJSONGetJobInfo(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorJobInfoPtr **jobs,
|
||||||
|
size_t *njobs);
|
||||||
|
|
||||||
|
|
||||||
int qemuMonitorJSONBlockJobSetSpeed(qemuMonitorPtr mon,
|
int qemuMonitorJSONBlockJobSetSpeed(qemuMonitorPtr mon,
|
||||||
const char *jobname,
|
const char *jobname,
|
||||||
unsigned long long speed)
|
unsigned long long speed)
|
||||||
|
20
tests/qemumonitorjsondata/query-jobs-create.json
Normal file
20
tests/qemumonitorjsondata/query-jobs-create.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"return": [
|
||||||
|
{
|
||||||
|
"current-progress": 1,
|
||||||
|
"status": "concluded",
|
||||||
|
"total-progress": 1,
|
||||||
|
"type": "create",
|
||||||
|
"id": "createjob-fail",
|
||||||
|
"error": "Image size must be a multiple of 512 bytes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"current-progress": 1,
|
||||||
|
"status": "concluded",
|
||||||
|
"total-progress": 1,
|
||||||
|
"type": "create",
|
||||||
|
"id": "createjob"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "libvirt-24"
|
||||||
|
}
|
11
tests/qemumonitorjsondata/query-jobs-create.result
Normal file
11
tests/qemumonitorjsondata/query-jobs-create.result
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[job]
|
||||||
|
id=createjob-fail
|
||||||
|
type=create
|
||||||
|
status=concluded
|
||||||
|
error=Image size must be a multiple of 512 bytes
|
||||||
|
|
||||||
|
[job]
|
||||||
|
id=createjob
|
||||||
|
type=create
|
||||||
|
status=concluded
|
||||||
|
error=<null>
|
1
tests/qemumonitorjsondata/query-jobs-empty.json
Normal file
1
tests/qemumonitorjsondata/query-jobs-empty.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{ "return": [] }
|
0
tests/qemumonitorjsondata/query-jobs-empty.result
Normal file
0
tests/qemumonitorjsondata/query-jobs-empty.result
Normal file
@ -2925,6 +2925,79 @@ testQAPISchemaValidate(const void *opaque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
testQueryJobsPrintJob(virBufferPtr buf,
|
||||||
|
qemuMonitorJobInfoPtr job)
|
||||||
|
{
|
||||||
|
virBufferAddLit(buf, "[job]\n");
|
||||||
|
virBufferAsprintf(buf, "id=%s\n", NULLSTR(job->id));
|
||||||
|
virBufferAsprintf(buf, "type=%s\n", NULLSTR(qemuMonitorJobTypeToString(job->type)));
|
||||||
|
virBufferAsprintf(buf, "status=%s\n", NULLSTR(qemuMonitorJobStatusTypeToString(job->status)));
|
||||||
|
virBufferAsprintf(buf, "error=%s\n", NULLSTR(job->error));
|
||||||
|
virBufferAddLit(buf, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct testQueryJobsData {
|
||||||
|
const char *name;
|
||||||
|
virDomainXMLOptionPtr xmlopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
testQueryJobs(const void *opaque)
|
||||||
|
{
|
||||||
|
const struct testQueryJobsData *data = opaque;
|
||||||
|
qemuMonitorTestPtr test = qemuMonitorTestNewSimple(data->xmlopt);
|
||||||
|
VIR_AUTOFREE(char *) filenameJSON = NULL;
|
||||||
|
VIR_AUTOFREE(char *) fileJSON = NULL;
|
||||||
|
VIR_AUTOFREE(char *) filenameResult = NULL;
|
||||||
|
VIR_AUTOFREE(char *) actual = NULL;
|
||||||
|
qemuMonitorJobInfoPtr *jobs = NULL;
|
||||||
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
|
size_t njobs = 0;
|
||||||
|
size_t i;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (virAsprintf(&filenameJSON,
|
||||||
|
abs_srcdir "/qemumonitorjsondata/query-jobs-%s.json",
|
||||||
|
data->name) < 0 ||
|
||||||
|
virAsprintf(&filenameResult,
|
||||||
|
abs_srcdir "/qemumonitorjsondata/query-jobs-%s.result",
|
||||||
|
data->name) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virTestLoadFile(filenameJSON, &fileJSON) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorTestAddItem(test, "query-jobs", fileJSON) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONGetJobInfo(qemuMonitorTestGetMonitor(test),
|
||||||
|
&jobs, &njobs) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; i < njobs; i++)
|
||||||
|
testQueryJobsPrintJob(&buf, jobs[i]);
|
||||||
|
|
||||||
|
virBufferTrim(&buf, "\n", -1);
|
||||||
|
|
||||||
|
if (virBufferCheckError(&buf) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
actual = virBufferContentAndReset(&buf);
|
||||||
|
|
||||||
|
if (virTestCompareToFile(actual, filenameResult) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
qemuMonitorTestFree(test);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mymain(void)
|
mymain(void)
|
||||||
{
|
{
|
||||||
@ -3199,6 +3272,18 @@ mymain(void)
|
|||||||
|
|
||||||
#undef DO_TEST_QAPI_VALIDATE
|
#undef DO_TEST_QAPI_VALIDATE
|
||||||
|
|
||||||
|
#define DO_TEST_QUERY_JOBS(name) \
|
||||||
|
do { \
|
||||||
|
struct testQueryJobsData data = { name, driver.xmlopt}; \
|
||||||
|
if (virTestRun("query-jobs-" name, testQueryJobs, &data) < 0) \
|
||||||
|
ret = -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
DO_TEST_QUERY_JOBS("empty");
|
||||||
|
DO_TEST_QUERY_JOBS("create");
|
||||||
|
|
||||||
|
#undef DO_TEST_QUERY_JOBS
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(metaschemastr);
|
VIR_FREE(metaschemastr);
|
||||||
virJSONValueFree(metaschema);
|
virJSONValueFree(metaschema);
|
||||||
|
Loading…
Reference in New Issue
Block a user