[libvirt] [PATCH 0/9] qemu: monitor: Pepare APIs for blockdev (blockdev-add saga)

This contains set of monitor adjustments needed for supporting the block job APIs with -blockdev. Note that the last patch does not contain tests as there is a extensive testsuite added with the actual formatter of the JSON properties which are used with that API which will be posted later. I can and probably will hold-off pushing this series together with the rest once I iron out a few wrinkles. Peter Krempa (9): qemu: monitor: Add new fields for 'block-stream' command qemu: monitor: Add new fields for 'block-commit' command qemu: monitor: Add new fields for 'blockdev-mirror' command qemu: monitor: Add support for 'job-dismiss' command qemu: monitor: Add support for 'job-cancel' command qemu: monitor: Add support for 'job-complete' command qemu: monitor: Add infrastructure for 'query-jobs' qemu: monitor: Implement support for 'JOB_STATUS_CHANGE' event qemu: monitor: Add APIs for 'blockdev-create' src/qemu/qemu_driver.c | 8 +- src/qemu/qemu_migration.c | 2 +- src/qemu/qemu_monitor.c | 150 ++++++++++- src/qemu/qemu_monitor.h | 86 ++++++- src/qemu/qemu_monitor_json.c | 243 +++++++++++++++++- src/qemu/qemu_monitor_json.h | 33 ++- .../query-jobs-create.json | 20 ++ .../query-jobs-create.result | 11 + .../qemumonitorjsondata/query-jobs-empty.json | 1 + .../query-jobs-empty.result | 0 tests/qemumonitorjsontest.c | 97 ++++++- 11 files changed, 625 insertions(+), 26 deletions(-) create mode 100644 tests/qemumonitorjsondata/query-jobs-create.json create mode 100644 tests/qemumonitorjsondata/query-jobs-create.result create mode 100644 tests/qemumonitorjsondata/query-jobs-empty.json create mode 100644 tests/qemumonitorjsondata/query-jobs-empty.result -- 2.21.0

Allow using the node name to specify the base of the 'stream' operation, allow specifying explicit job name and add support for delayed dismiss of the job so that we can reap the state even if libvirtd was not running when qemu emitted the job completion event. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_monitor.c | 18 +++++++++++++++--- src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 14 ++++++++++++++ src/qemu/qemu_monitor_json.h | 3 +++ tests/qemumonitorjsontest.c | 2 +- 6 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ec08dd939e..f6178ddd0b 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17080,8 +17080,8 @@ qemuDomainBlockPullCommon(virQEMUDriverPtr driver, basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src, baseSource); if (!baseSource || basePath) - ret = qemuMonitorBlockStream(priv->mon, device, basePath, backingPath, - speed); + ret = qemuMonitorBlockStream(priv->mon, device, NULL, false, basePath, + NULL, backingPath, speed); if (qemuDomainObjExitMonitor(driver, vm) < 0) ret = -1; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 731be2e5a6..e1ccb324b4 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3365,16 +3365,28 @@ qemuMonitorScreendump(qemuMonitorPtr mon, int qemuMonitorBlockStream(qemuMonitorPtr mon, const char *device, + const char *jobname, + bool persistjob, const char *base, + const char *baseNode, const char *backingName, unsigned long long bandwidth) { - VIR_DEBUG("device=%s, base=%s, backingName=%s, bandwidth=%lluB", - device, NULLSTR(base), NULLSTR(backingName), bandwidth); + VIR_DEBUG("device=%s, jobname=%s, persistjob=%d, base=%s, baseNode=%s, " + "backingName=%s, bandwidth=%lluB", + device, NULLSTR(jobname), persistjob, NULLSTR(base), + NULLSTR(baseNode), NULLSTR(backingName), bandwidth); QEMU_CHECK_MONITOR(mon); - return qemuMonitorJSONBlockStream(mon, device, base, backingName, bandwidth); + if (base && baseNode) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("'base' and 'baseNode' can't be used together")); + return -1; + } + + return qemuMonitorJSONBlockStream(mon, device, jobname, persistjob, base, + baseNode, backingName, bandwidth); } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index c41428b048..572a5f84cf 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -949,7 +949,10 @@ int qemuMonitorSendKey(qemuMonitorPtr mon, int qemuMonitorBlockStream(qemuMonitorPtr mon, const char *device, + const char *jobname, + bool persistjob, const char *base, + const char *baseNode, const char *backingName, unsigned long long bandwidth) ATTRIBUTE_NONNULL(2); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 8723ff49c7..e946c0aeb1 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4907,19 +4907,33 @@ qemuMonitorJSONBlockJobError(virJSONValuePtr cmd, int qemuMonitorJSONBlockStream(qemuMonitorPtr mon, const char *device, + const char *jobname, + bool persistjob, const char *base, + const char *baseNode, const char *backingName, unsigned long long speed) { int ret = -1; virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; + virTristateBool autofinalize = VIR_TRISTATE_BOOL_ABSENT; + virTristateBool autodismiss = VIR_TRISTATE_BOOL_ABSENT; + + if (persistjob) { + autofinalize = VIR_TRISTATE_BOOL_YES; + autodismiss = VIR_TRISTATE_BOOL_NO; + } if (!(cmd = qemuMonitorJSONMakeCommand("block-stream", "s:device", device, + "S:job-id", jobname, "Y:speed", speed, "S:base", base, + "S:base-node", baseNode, "S:backing-file", backingName, + "T:auto-finalize", autofinalize, + "T:auto-dismiss", autodismiss, NULL))) return -1; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index d0b519c88e..72255eefbb 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -302,7 +302,10 @@ int qemuMonitorJSONScreendump(qemuMonitorPtr mon, int qemuMonitorJSONBlockStream(qemuMonitorPtr mon, const char *device, + const char *jobname, + bool persistjob, const char *base, + const char *baseNode, const char *backingName, unsigned long long speed) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 2ed9133c06..b60df6f35b 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1326,7 +1326,7 @@ GEN_TEST_FUNC(qemuMonitorJSONDelDevice, "ide0") GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr") GEN_TEST_FUNC(qemuMonitorJSONDriveMirror, "vdb", "/foo/bar", "formatstr", 1024, 1234, 31234, true, true) GEN_TEST_FUNC(qemuMonitorJSONBlockdevMirror, "jobname", "vdb", "targetnode", 1024, 1234, 31234, true) -GEN_TEST_FUNC(qemuMonitorJSONBlockStream, "vdb", "/foo/bar1", "backingfilename", 1024) +GEN_TEST_FUNC(qemuMonitorJSONBlockStream, "vdb", "jobname", true, "/foo/bar1", "backingnode", "backingfilename", 1024) GEN_TEST_FUNC(qemuMonitorJSONBlockCommit, "vdb", "/foo/bar1", "/foo/bar2", "backingfilename", 1024) GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb") GEN_TEST_FUNC(qemuMonitorJSONScreendump, "devicename", 1, "/foo/bar") -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:48PM +0200, Peter Krempa wrote:
Allow using the node name to specify the base of the 'stream' operation, allow specifying explicit job name and add support for delayed dismiss of the job so that we can reap the state even if libvirtd was not running when qemu emitted the job completion event.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_monitor.c | 18 +++++++++++++++--- src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 14 ++++++++++++++ src/qemu/qemu_monitor_json.h | 3 +++ tests/qemumonitorjsontest.c | 2 +- 6 files changed, 38 insertions(+), 6 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Allow using the node name to specify the base and top of the 'commit' operation, allow specifying explicit job name and add support for delayed dismiss of the job so that we can reap the state even if libvirtd was not running when qemu emitted the job completion event. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_monitor.c | 21 +++++++++++++++------ src/qemu/qemu_monitor.h | 6 +++++- src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++-- src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 +- 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f6178ddd0b..25977dc900 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18046,8 +18046,8 @@ qemuDomainBlockCommit(virDomainPtr dom, topPath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src, topSource); if (basePath && topPath) - ret = qemuMonitorBlockCommit(priv->mon, device, - topPath, basePath, backingPath, + ret = qemuMonitorBlockCommit(priv->mon, device, NULL, false, + topPath, NULL, basePath, NULL, backingPath, speed); if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0) { ret = -1; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index e1ccb324b4..3862a00d7b 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3257,18 +3257,27 @@ qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr *actions) /* Start a block-commit block job. bandwidth is in bytes/sec. */ int -qemuMonitorBlockCommit(qemuMonitorPtr mon, const char *device, - const char *top, const char *base, +qemuMonitorBlockCommit(qemuMonitorPtr mon, + const char *device, + const char *jobname, + bool persistjob, + const char *top, + const char *topNode, + const char *base, + const char *baseNode, const char *backingName, unsigned long long bandwidth) { - VIR_DEBUG("device=%s, top=%s, base=%s, backingName=%s, bandwidth=%llu", - device, top, base, NULLSTR(backingName), bandwidth); + VIR_DEBUG("device=%s, jobname=%s, persistjob=%d, top=%s, topNode=%s, " + "base=%s, baseNode=%s, backingName=%s, bandwidth=%llu", + device, NULLSTR(jobname), persistjob, NULLSTR(top), NULLSTR(topNode), + NULLSTR(base), NULLSTR(baseNode), NULLSTR(backingName), bandwidth); QEMU_CHECK_MONITOR(mon); - return qemuMonitorJSONBlockCommit(mon, device, top, base, - backingName, bandwidth); + return qemuMonitorJSONBlockCommit(mon, device, jobname, persistjob, top, + topNode, base, baseNode, backingName, + bandwidth); } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 572a5f84cf..53b5777a84 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -918,11 +918,15 @@ int qemuMonitorDrivePivot(qemuMonitorPtr mon, int qemuMonitorBlockCommit(qemuMonitorPtr mon, const char *device, + const char *jobname, + bool persistjob, const char *top, + const char *topNode, const char *base, + const char *baseNode, const char *backingName, unsigned long long bandwidth) - ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); + ATTRIBUTE_NONNULL(2); bool qemuMonitorSupportsActiveCommit(qemuMonitorPtr mon); char *qemuMonitorDiskNameLookup(qemuMonitorPtr mon, const char *device, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index e946c0aeb1..4edf4f8dbc 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4507,21 +4507,39 @@ qemuMonitorJSONSupportsActiveCommit(qemuMonitorPtr mon) /* speed is in bytes/sec. Returns 0 on success, -1 with error message * emitted on failure. */ int -qemuMonitorJSONBlockCommit(qemuMonitorPtr mon, const char *device, - const char *top, const char *base, +qemuMonitorJSONBlockCommit(qemuMonitorPtr mon, + const char *device, + const char *jobname, + bool persistjob, + const char *top, + const char *topNode, + const char *base, + const char *baseNode, const char *backingName, unsigned long long speed) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; + virTristateBool autofinalize = VIR_TRISTATE_BOOL_ABSENT; + virTristateBool autodismiss = VIR_TRISTATE_BOOL_ABSENT; + + if (persistjob) { + autofinalize = VIR_TRISTATE_BOOL_YES; + autodismiss = VIR_TRISTATE_BOOL_NO; + } cmd = qemuMonitorJSONMakeCommand("block-commit", "s:device", device, + "S:job-id", jobname, "Y:speed", speed, "S:top", top, + "S:top-node", topNode, "S:base", base, + "S:base-node", baseNode, "S:backing-file", backingName, + "T:auto-finalize", autofinalize, + "T:auto-dismiss", autodismiss, NULL); if (!cmd) return -1; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 72255eefbb..2e242a4923 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -270,8 +270,12 @@ bool qemuMonitorJSONSupportsActiveCommit(qemuMonitorPtr mon) int qemuMonitorJSONBlockCommit(qemuMonitorPtr mon, const char *device, + const char *jobname, + bool persistjob, const char *top, + const char *topNode, const char *base, + const char *baseNode, const char *backingName, unsigned long long bandwidth) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index b60df6f35b..f77f4da9a3 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1327,7 +1327,7 @@ GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr") GEN_TEST_FUNC(qemuMonitorJSONDriveMirror, "vdb", "/foo/bar", "formatstr", 1024, 1234, 31234, true, true) GEN_TEST_FUNC(qemuMonitorJSONBlockdevMirror, "jobname", "vdb", "targetnode", 1024, 1234, 31234, true) GEN_TEST_FUNC(qemuMonitorJSONBlockStream, "vdb", "jobname", true, "/foo/bar1", "backingnode", "backingfilename", 1024) -GEN_TEST_FUNC(qemuMonitorJSONBlockCommit, "vdb", "/foo/bar1", "/foo/bar2", "backingfilename", 1024) +GEN_TEST_FUNC(qemuMonitorJSONBlockCommit, "vdb", "jobname", true, "/foo/bar1", "topnode", "/foo/bar2", "basenode", "backingfilename", 1024) GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb") GEN_TEST_FUNC(qemuMonitorJSONScreendump, "devicename", 1, "/foo/bar") GEN_TEST_FUNC(qemuMonitorJSONOpenGraphics, "spice", "spicefd", false) -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:49PM +0200, Peter Krempa wrote:
Allow using the node name to specify the base and top of the 'commit' operation, allow specifying explicit job name and add support for delayed dismiss of the job so that we can reap the state even if libvirtd was not running when qemu emitted the job completion event.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_monitor.c | 21 +++++++++++++++------ src/qemu/qemu_monitor.h | 6 +++++- src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++-- src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 +- 6 files changed, 47 insertions(+), 12 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Allow using the delayed dismiss of the job so that we can reap the state even if libvirtd was not running when qemu emitted the job completion event. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration.c | 2 +- src/qemu/qemu_monitor.c | 9 +++++---- src/qemu/qemu_monitor.h | 3 ++- src/qemu/qemu_monitor_json.c | 10 ++++++++++ src/qemu/qemu_monitor_json.h | 3 ++- tests/qemumonitorjsontest.c | 2 +- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 2436f5051b..1fb88c11b6 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -840,7 +840,7 @@ qemuMigrationSrcNBDStorageCopyBlockdev(virQEMUDriverPtr driver, mon_ret = qemuBlockStorageSourceAttachApply(qemuDomainGetMonitor(vm), data); if (mon_ret == 0) - mon_ret = qemuMonitorBlockdevMirror(qemuDomainGetMonitor(vm), NULL, + mon_ret = qemuMonitorBlockdevMirror(qemuDomainGetMonitor(vm), NULL, false, diskAlias, copysrc->nodeformat, mirror_speed, 0, 0, mirror_shallow); diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 3862a00d7b..1a7cfd291b 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3224,6 +3224,7 @@ qemuMonitorDriveMirror(qemuMonitorPtr mon, int qemuMonitorBlockdevMirror(qemuMonitorPtr mon, const char *jobname, + bool persistjob, const char *device, const char *target, unsigned long long bandwidth, @@ -3231,15 +3232,15 @@ qemuMonitorBlockdevMirror(qemuMonitorPtr mon, unsigned long long buf_size, bool shallow) { - VIR_DEBUG("jobname=%s, device=%s, target=%s, bandwidth=%lld, " + VIR_DEBUG("jobname=%s, persistjob=%d, device=%s, target=%s, bandwidth=%lld, " "granularity=%#x, buf_size=%lld, shallow=%d", - NULLSTR(jobname), device, target, bandwidth, granularity, + NULLSTR(jobname), persistjob, device, target, bandwidth, granularity, buf_size, shallow); QEMU_CHECK_MONITOR(mon); - return qemuMonitorJSONBlockdevMirror(mon, jobname, device, target, bandwidth, - granularity, buf_size, shallow); + return qemuMonitorJSONBlockdevMirror(mon, jobname, persistjob, device, target, + bandwidth, granularity, buf_size, shallow); } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 53b5777a84..42d6e36b4d 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -905,13 +905,14 @@ int qemuMonitorDriveMirror(qemuMonitorPtr mon, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); int qemuMonitorBlockdevMirror(qemuMonitorPtr mon, const char *jobname, + bool persistjob, const char *device, const char *target, unsigned long long bandwidth, unsigned int granularity, unsigned long long buf_size, bool shallow) - ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); + ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); int qemuMonitorDrivePivot(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(2); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 4edf4f8dbc..98846740e5 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4415,6 +4415,7 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon, int qemuMonitorJSONBlockdevMirror(qemuMonitorPtr mon, const char *jobname, + bool persistjob, const char *device, const char *target, unsigned long long speed, @@ -4424,6 +4425,13 @@ qemuMonitorJSONBlockdevMirror(qemuMonitorPtr mon, { VIR_AUTOPTR(virJSONValue) cmd = NULL; VIR_AUTOPTR(virJSONValue) reply = NULL; + virTristateBool autofinalize = VIR_TRISTATE_BOOL_ABSENT; + virTristateBool autodismiss = VIR_TRISTATE_BOOL_ABSENT; + + if (persistjob) { + autofinalize = VIR_TRISTATE_BOOL_YES; + autodismiss = VIR_TRISTATE_BOOL_NO; + } cmd = qemuMonitorJSONMakeCommand("blockdev-mirror", "S:job-id", jobname, @@ -4433,6 +4441,8 @@ qemuMonitorJSONBlockdevMirror(qemuMonitorPtr mon, "z:granularity", granularity, "P:buf-size", buf_size, "s:sync", shallow ? "top" : "full", + "T:auto-finalize", autofinalize, + "T:auto-dismiss", autodismiss, NULL); if (!cmd) return -1; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 2e242a4923..069f6dca62 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -254,13 +254,14 @@ int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); int qemuMonitorJSONBlockdevMirror(qemuMonitorPtr mon, const char *jobname, + bool persistjob, const char *device, const char *target, unsigned long long speed, unsigned int granularity, unsigned long long buf_size, bool shallow) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); int qemuMonitorJSONDrivePivot(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index f77f4da9a3..07dd746850 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1325,7 +1325,7 @@ GEN_TEST_FUNC(qemuMonitorJSONRemoveNetdev, "net0") GEN_TEST_FUNC(qemuMonitorJSONDelDevice, "ide0") GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr") GEN_TEST_FUNC(qemuMonitorJSONDriveMirror, "vdb", "/foo/bar", "formatstr", 1024, 1234, 31234, true, true) -GEN_TEST_FUNC(qemuMonitorJSONBlockdevMirror, "jobname", "vdb", "targetnode", 1024, 1234, 31234, true) +GEN_TEST_FUNC(qemuMonitorJSONBlockdevMirror, "jobname", true, "vdb", "targetnode", 1024, 1234, 31234, true) GEN_TEST_FUNC(qemuMonitorJSONBlockStream, "vdb", "jobname", true, "/foo/bar1", "backingnode", "backingfilename", 1024) GEN_TEST_FUNC(qemuMonitorJSONBlockCommit, "vdb", "jobname", true, "/foo/bar1", "topnode", "/foo/bar2", "basenode", "backingfilename", 1024) GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb") -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:50PM +0200, Peter Krempa wrote:
Allow using the delayed dismiss of the job so that we can reap the state even if libvirtd was not running when qemu emitted the job completion event.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration.c | 2 +- src/qemu/qemu_monitor.c | 9 +++++---- src/qemu/qemu_monitor.h | 3 ++- src/qemu/qemu_monitor_json.c | 10 ++++++++++ src/qemu/qemu_monitor_json.h | 3 ++- tests/qemumonitorjsontest.c | 2 +- 6 files changed, 21 insertions(+), 8 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This belongs to the new job management API for generic jobs. The dismiss command is meant to remove a concluded job after we were able to get the final status. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 12 ++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 44 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 1a7cfd291b..d9196434ba 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3463,6 +3463,18 @@ qemuMonitorGetBlockJobInfo(qemuMonitorPtr mon, } +int +qemuMonitorJobDismiss(qemuMonitorPtr mon, + const char *jobname) +{ + VIR_DEBUG("jobname=%s", jobname); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONJobDismiss(mon, jobname); +} + + int qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon, const char *drivealias, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 42d6e36b4d..56c68683f5 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -987,6 +987,10 @@ int qemuMonitorGetBlockJobInfo(qemuMonitorPtr mon, qemuMonitorBlockJobInfoPtr info) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +int qemuMonitorJobDismiss(qemuMonitorPtr mon, + const char *jobname) + ATTRIBUTE_NONNULL(2); + int qemuMonitorOpenGraphics(qemuMonitorPtr mon, const char *protocol, int fd, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 98846740e5..2ef2299a68 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5066,6 +5066,28 @@ qemuMonitorJSONDrivePivot(qemuMonitorPtr mon, } +int +qemuMonitorJSONJobDismiss(qemuMonitorPtr mon, + const char *jobname) +{ + VIR_AUTOPTR(virJSONValue) cmd = NULL; + VIR_AUTOPTR(virJSONValue) reply = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("job-dismiss", + "s:id", jobname, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return -1; + + if (qemuMonitorJSONBlockJobError(cmd, reply, jobname) < 0) + return -1; + + return 0; +} + + int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon, const char *protocol, const char *fdname, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 069f6dca62..1719509ec8 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -328,6 +328,10 @@ virHashTablePtr qemuMonitorJSONGetAllBlockJobInfo(qemuMonitorPtr mon, bool rawjobname) ATTRIBUTE_NONNULL(1); +int qemuMonitorJSONJobDismiss(qemuMonitorPtr mon, + const char *jobname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + int qemuMonitorJSONSetLink(qemuMonitorPtr mon, const char *name, virDomainNetInterfaceLinkState state); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 07dd746850..e872f93490 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1340,6 +1340,7 @@ GEN_TEST_FUNC(qemuMonitorJSONBlockdevMediumInsert, "foodev", "newnode") GEN_TEST_FUNC(qemuMonitorJSONAddBitmap, "node", "bitmap", true) GEN_TEST_FUNC(qemuMonitorJSONEnableBitmap, "node", "bitmap") GEN_TEST_FUNC(qemuMonitorJSONDeleteBitmap, "node", "bitmap") +GEN_TEST_FUNC(qemuMonitorJSONJobDismiss, "jobname") static int testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque) @@ -3057,6 +3058,7 @@ mymain(void) DO_TEST_GEN(qemuMonitorJSONAddBitmap); DO_TEST_GEN(qemuMonitorJSONEnableBitmap); DO_TEST_GEN(qemuMonitorJSONDeleteBitmap); + DO_TEST_GEN(qemuMonitorJSONJobDismiss); DO_TEST(qemuMonitorJSONGetBalloonInfo); DO_TEST(qemuMonitorJSONGetBlockInfo); DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo); -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:51PM +0200, Peter Krempa wrote:
This belongs to the new job management API for generic jobs.
The dismiss command is meant to remove a concluded job after we were able to get the final status.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 12 ++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 44 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This belongs to the new job management API which can manage also non-block based jobs. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 12 ++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 44 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index d9196434ba..815ce58b69 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3475,6 +3475,18 @@ qemuMonitorJobDismiss(qemuMonitorPtr mon, } +int +qemuMonitorJobCancel(qemuMonitorPtr mon, + const char *jobname) +{ + VIR_DEBUG("jobname=%s", jobname); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONJobCancel(mon, jobname); +} + + int qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon, const char *drivealias, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 56c68683f5..b306ff0314 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -991,6 +991,10 @@ int qemuMonitorJobDismiss(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(2); +int qemuMonitorJobCancel(qemuMonitorPtr mon, + const char *jobname) + ATTRIBUTE_NONNULL(2); + int qemuMonitorOpenGraphics(qemuMonitorPtr mon, const char *protocol, int fd, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 2ef2299a68..84b5c30577 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5088,6 +5088,28 @@ qemuMonitorJSONJobDismiss(qemuMonitorPtr mon, } +int +qemuMonitorJSONJobCancel(qemuMonitorPtr mon, + const char *jobname) +{ + VIR_AUTOPTR(virJSONValue) cmd = NULL; + VIR_AUTOPTR(virJSONValue) reply = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("job-cancel", + "s:id", jobname, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return -1; + + if (qemuMonitorJSONBlockJobError(cmd, reply, jobname) < 0) + return -1; + + return 0; +} + + int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon, const char *protocol, const char *fdname, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 1719509ec8..aeaf332943 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -332,6 +332,10 @@ int qemuMonitorJSONJobDismiss(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int qemuMonitorJSONJobCancel(qemuMonitorPtr mon, + const char *jobname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + int qemuMonitorJSONSetLink(qemuMonitorPtr mon, const char *name, virDomainNetInterfaceLinkState state); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index e872f93490..eabd834861 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1341,6 +1341,7 @@ GEN_TEST_FUNC(qemuMonitorJSONAddBitmap, "node", "bitmap", true) GEN_TEST_FUNC(qemuMonitorJSONEnableBitmap, "node", "bitmap") GEN_TEST_FUNC(qemuMonitorJSONDeleteBitmap, "node", "bitmap") GEN_TEST_FUNC(qemuMonitorJSONJobDismiss, "jobname") +GEN_TEST_FUNC(qemuMonitorJSONJobCancel, "jobname") static int testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque) @@ -3059,6 +3060,7 @@ mymain(void) DO_TEST_GEN(qemuMonitorJSONEnableBitmap); DO_TEST_GEN(qemuMonitorJSONDeleteBitmap); DO_TEST_GEN(qemuMonitorJSONJobDismiss); + DO_TEST_GEN(qemuMonitorJSONJobCancel); DO_TEST(qemuMonitorJSONGetBalloonInfo); DO_TEST(qemuMonitorJSONGetBlockInfo); DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo); -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:52PM +0200, Peter Krempa wrote:
This belongs to the new job management API which can manage also non-block based jobs.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 12 ++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 44 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This belongs to the new job management API which can manage also non-block based jobs. Since we'll need to be able to attempt to cancel jobs which potentially were not started (during reconnect) the 'quiet' flag allows to suppress errors reported. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- This version allows cancelling jobs quietly which is required for weird-state cleanup during reconnect. src/qemu/qemu_monitor.c | 13 +++++++++++++ src/qemu/qemu_monitor.h | 5 +++++ src/qemu/qemu_monitor_json.c | 28 ++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 5 +++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 53 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index d9196434ba..2b9a5426b8 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3475,6 +3475,19 @@ qemuMonitorJobDismiss(qemuMonitorPtr mon, } +int +qemuMonitorJobCancel(qemuMonitorPtr mon, + const char *jobname, + bool quiet) +{ + VIR_DEBUG("jobname='%s' quiet=%d", jobname, quiet); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONJobCancel(mon, jobname, quiet); +} + + int qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon, const char *drivealias, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 56c68683f5..bed15aea0f 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -991,6 +991,11 @@ int qemuMonitorJobDismiss(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(2); +int qemuMonitorJobCancel(qemuMonitorPtr mon, + const char *jobname, + bool quiet) + ATTRIBUTE_NONNULL(2); + int qemuMonitorOpenGraphics(qemuMonitorPtr mon, const char *protocol, int fd, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 2ef2299a68..c318f1620b 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5088,6 +5088,34 @@ qemuMonitorJSONJobDismiss(qemuMonitorPtr mon, } +int +qemuMonitorJSONJobCancel(qemuMonitorPtr mon, + const char *jobname, + bool quiet) +{ + VIR_AUTOPTR(virJSONValue) cmd = NULL; + VIR_AUTOPTR(virJSONValue) reply = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("job-cancel", + "s:id", jobname, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return -1; + + if (quiet) { + if (virJSONValueObjectHasKey(reply, "error") != 0) + return -1; + } else { + if (qemuMonitorJSONBlockJobError(cmd, reply, jobname) < 0) + return -1; + } + + return 0; +} + + int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon, const char *protocol, const char *fdname, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 1719509ec8..453c2e1af6 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -332,6 +332,11 @@ int qemuMonitorJSONJobDismiss(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int qemuMonitorJSONJobCancel(qemuMonitorPtr mon, + const char *jobname, + bool quiet) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + int qemuMonitorJSONSetLink(qemuMonitorPtr mon, const char *name, virDomainNetInterfaceLinkState state); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index e872f93490..88dc84a1f1 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1341,6 +1341,7 @@ GEN_TEST_FUNC(qemuMonitorJSONAddBitmap, "node", "bitmap", true) GEN_TEST_FUNC(qemuMonitorJSONEnableBitmap, "node", "bitmap") GEN_TEST_FUNC(qemuMonitorJSONDeleteBitmap, "node", "bitmap") GEN_TEST_FUNC(qemuMonitorJSONJobDismiss, "jobname") +GEN_TEST_FUNC(qemuMonitorJSONJobCancel, "jobname", false) static int testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque) @@ -3059,6 +3060,7 @@ mymain(void) DO_TEST_GEN(qemuMonitorJSONEnableBitmap); DO_TEST_GEN(qemuMonitorJSONDeleteBitmap); DO_TEST_GEN(qemuMonitorJSONJobDismiss); + DO_TEST_GEN(qemuMonitorJSONJobCancel); DO_TEST(qemuMonitorJSONGetBalloonInfo); DO_TEST(qemuMonitorJSONGetBlockInfo); DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo); -- 2.21.0

On Thu, Jul 11, 2019 at 06:26:16PM +0200, Peter Krempa wrote:
This belongs to the new job management API which can manage also non-block based jobs. Since we'll need to be able to attempt to cancel jobs which potentially were not started (during reconnect) the 'quiet' flag allows to suppress errors reported.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- This version allows cancelling jobs quietly which is required for weird-state cleanup during reconnect.
src/qemu/qemu_monitor.c | 13 +++++++++++++ src/qemu/qemu_monitor.h | 5 +++++ src/qemu/qemu_monitor_json.c | 28 ++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 5 +++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 53 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This belongs to the new job management API which can manage also non-block based jobs. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 12 ++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 44 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 815ce58b69..3cd037fdba 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3487,6 +3487,18 @@ qemuMonitorJobCancel(qemuMonitorPtr mon, } +int +qemuMonitorJobComplete(qemuMonitorPtr mon, + const char *jobname) +{ + VIR_DEBUG("jobname=%s", jobname); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONJobComplete(mon, jobname); +} + + int qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon, const char *drivealias, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index b306ff0314..e3a3c212fd 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -995,6 +995,10 @@ int qemuMonitorJobCancel(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(2); +int qemuMonitorJobComplete(qemuMonitorPtr mon, + const char *jobname) + ATTRIBUTE_NONNULL(2); + int qemuMonitorOpenGraphics(qemuMonitorPtr mon, const char *protocol, int fd, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 84b5c30577..33ee026fe1 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5110,6 +5110,28 @@ qemuMonitorJSONJobCancel(qemuMonitorPtr mon, } +int +qemuMonitorJSONJobComplete(qemuMonitorPtr mon, + const char *jobname) +{ + VIR_AUTOPTR(virJSONValue) cmd = NULL; + VIR_AUTOPTR(virJSONValue) reply = NULL; + + if (!(cmd = qemuMonitorJSONMakeCommand("job-complete", + "s:id", jobname, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return -1; + + if (qemuMonitorJSONBlockJobError(cmd, reply, jobname) < 0) + return -1; + + return 0; +} + + int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon, const char *protocol, const char *fdname, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index aeaf332943..c2b47e6129 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -336,6 +336,10 @@ int qemuMonitorJSONJobCancel(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int qemuMonitorJSONJobComplete(qemuMonitorPtr mon, + const char *jobname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + int qemuMonitorJSONSetLink(qemuMonitorPtr mon, const char *name, virDomainNetInterfaceLinkState state); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index eabd834861..798b7beca3 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1342,6 +1342,7 @@ GEN_TEST_FUNC(qemuMonitorJSONEnableBitmap, "node", "bitmap") GEN_TEST_FUNC(qemuMonitorJSONDeleteBitmap, "node", "bitmap") GEN_TEST_FUNC(qemuMonitorJSONJobDismiss, "jobname") GEN_TEST_FUNC(qemuMonitorJSONJobCancel, "jobname") +GEN_TEST_FUNC(qemuMonitorJSONJobComplete, "jobname") static int testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque) @@ -3061,6 +3062,7 @@ mymain(void) DO_TEST_GEN(qemuMonitorJSONDeleteBitmap); DO_TEST_GEN(qemuMonitorJSONJobDismiss); DO_TEST_GEN(qemuMonitorJSONJobCancel); + DO_TEST_GEN(qemuMonitorJSONJobComplete); DO_TEST(qemuMonitorJSONGetBalloonInfo); DO_TEST(qemuMonitorJSONGetBlockInfo); DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo); -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:53PM +0200, Peter Krempa wrote:
This belongs to the new job management API which can manage also non-block based jobs.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 12 ++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 22 ++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++++ tests/qemumonitorjsontest.c | 2 ++ 5 files changed, 44 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 23 +++++ src/qemu/qemu_monitor.h | 49 +++++++++++ src/qemu/qemu_monitor_json.c | 79 +++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++ .../query-jobs-create.json | 20 +++++ .../query-jobs-create.result | 11 +++ .../qemumonitorjsondata/query-jobs-empty.json | 1 + .../query-jobs-empty.result | 0 tests/qemumonitorjsontest.c | 85 +++++++++++++++++++ 9 files changed, 274 insertions(+) create mode 100644 tests/qemumonitorjsondata/query-jobs-create.json create mode 100644 tests/qemumonitorjsondata/query-jobs-create.result create mode 100644 tests/qemumonitorjsondata/query-jobs-empty.json create mode 100644 tests/qemumonitorjsondata/query-jobs-empty.result diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 3cd037fdba..c9dbc67f53 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4584,3 +4584,26 @@ qemuMonitorDeleteBitmap(qemuMonitorPtr mon, 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); +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index e3a3c212fd..4cbe185c5c 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -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); void qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info); void qemuMonitorEventRdmaGidStatusFree(qemuMonitorRdmaGidStatusPtr info); @@ -1278,3 +1320,10 @@ struct _qemuMonitorCurrentMachineInfo { int qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon, qemuMonitorCurrentMachineInfoPtr info); +void qemuMonitorJobInfoFree(qemuMonitorJobInfoPtr job); + +VIR_DEFINE_AUTOPTR_FUNC(qemuMonitorJobInfo, qemuMonitorJobInfoFree); + +int qemuMonitorGetJobInfo(qemuMonitorPtr mon, + qemuMonitorJobInfoPtr **jobs, + size_t *njobs); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 33ee026fe1..68780a5a4f 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -56,6 +56,14 @@ VIR_LOG_INIT("qemu.qemu_monitor_json"); #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 qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data); @@ -9038,3 +9046,74 @@ qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon, virJSONValueFree(reply); 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; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index c2b47e6129..a50d4d7b23 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -319,6 +319,12 @@ int qemuMonitorJSONBlockJobCancel(qemuMonitorPtr mon, const char *jobname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int +qemuMonitorJSONGetJobInfo(qemuMonitorPtr mon, + qemuMonitorJobInfoPtr **jobs, + size_t *njobs); + + int qemuMonitorJSONBlockJobSetSpeed(qemuMonitorPtr mon, const char *jobname, unsigned long long speed) diff --git a/tests/qemumonitorjsondata/query-jobs-create.json b/tests/qemumonitorjsondata/query-jobs-create.json new file mode 100644 index 0000000000..fbc7c4b15d --- /dev/null +++ b/tests/qemumonitorjsondata/query-jobs-create.json @@ -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" +} diff --git a/tests/qemumonitorjsondata/query-jobs-create.result b/tests/qemumonitorjsondata/query-jobs-create.result new file mode 100644 index 0000000000..a43282fe67 --- /dev/null +++ b/tests/qemumonitorjsondata/query-jobs-create.result @@ -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> diff --git a/tests/qemumonitorjsondata/query-jobs-empty.json b/tests/qemumonitorjsondata/query-jobs-empty.json new file mode 100644 index 0000000000..c1ede999e5 --- /dev/null +++ b/tests/qemumonitorjsondata/query-jobs-empty.json @@ -0,0 +1 @@ +{ "return": [] } diff --git a/tests/qemumonitorjsondata/query-jobs-empty.result b/tests/qemumonitorjsondata/query-jobs-empty.result new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 798b7beca3..171a7cc104 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -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 mymain(void) { @@ -3199,6 +3272,18 @@ mymain(void) #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: VIR_FREE(metaschemastr); virJSONValueFree(metaschema); -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:54PM +0200, Peter Krempa wrote:
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 23 +++++ src/qemu/qemu_monitor.h | 49 +++++++++++ src/qemu/qemu_monitor_json.c | 79 +++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++ .../query-jobs-create.json | 20 +++++ .../query-jobs-create.result | 11 +++ .../qemumonitorjsondata/query-jobs-empty.json | 1 + .../query-jobs-empty.result | 0 tests/qemumonitorjsontest.c | 85 +++++++++++++++++++ 9 files changed, 274 insertions(+) create mode 100644 tests/qemumonitorjsondata/query-jobs-create.json create mode 100644 tests/qemumonitorjsondata/query-jobs-create.result create mode 100644 tests/qemumonitorjsondata/query-jobs-empty.json create mode 100644 tests/qemumonitorjsondata/query-jobs-empty.result
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This new event is a superset of the BLOCK_JOB* events and also covers jobs which don't bind to a VM disk. In this patch the monitor part is implemented. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 13 +++++++++++++ src/qemu/qemu_monitor.h | 9 +++++++++ src/qemu/qemu_monitor_json.c | 26 ++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index c9dbc67f53..9358d0b1e2 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1503,6 +1503,19 @@ qemuMonitorEmitBlockJob(qemuMonitorPtr mon, } +int +qemuMonitorEmitJobStatusChange(qemuMonitorPtr mon, + const char *jobname, + qemuMonitorJobStatus status) +{ + int ret = -1; + VIR_DEBUG("mon=%p", mon); + + QEMU_MONITOR_CALLBACK(mon, ret, jobStatusChange, mon->vm, jobname, status); + return ret; +} + + int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon, unsigned long long actual) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 4cbe185c5c..c6dddd1e9e 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -230,6 +230,11 @@ typedef int (*qemuMonitorDomainBlockJobCallback)(qemuMonitorPtr mon, int status, const char *error, void *opaque); +typedef int (*qemuMonitorDomainJobStatusChangeCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *jobname, + int status, + void *opaque); typedef int (*qemuMonitorDomainTrayChangeCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, const char *devAlias, @@ -357,6 +362,7 @@ struct _qemuMonitorCallbacks { qemuMonitorDomainIOErrorCallback domainIOError; qemuMonitorDomainGraphicsCallback domainGraphics; qemuMonitorDomainBlockJobCallback domainBlockJob; + qemuMonitorDomainJobStatusChangeCallback jobStatusChange; qemuMonitorDomainTrayChangeCallback domainTrayChange; qemuMonitorDomainPMWakeupCallback domainPMWakeup; qemuMonitorDomainPMSuspendCallback domainPMSuspend; @@ -467,6 +473,9 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon, int type, int status, const char *error); +int qemuMonitorEmitJobStatusChange(qemuMonitorPtr mon, + const char *jobname, + qemuMonitorJobStatus status); int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon, unsigned long long actual); int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 68780a5a4f..04538bc46c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -84,6 +84,7 @@ static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr d static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSONValuePtr data); +static void qemuMonitorJSONHandleJobStatusChange(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONValuePtr data); @@ -116,6 +117,7 @@ static qemuEventHandler eventHandlers[] = { { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, }, { "DUMP_COMPLETED", qemuMonitorJSONHandleDumpCompleted, }, { "GUEST_PANICKED", qemuMonitorJSONHandleGuestPanic, }, + { "JOB_STATUS_CHANGE", qemuMonitorJSONHandleJobStatusChange, }, { "MIGRATION", qemuMonitorJSONHandleMigrationStatus, }, { "MIGRATION_PASS", qemuMonitorJSONHandleMigrationPass, }, { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, }, @@ -1156,6 +1158,30 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon, qemuMonitorEmitBlockJob(mon, device, type, event, error); } + +static void +qemuMonitorJSONHandleJobStatusChange(qemuMonitorPtr mon, + virJSONValuePtr data) +{ + const char *jobname = virJSONValueObjectGetString(data, "id"); + const char *statusstr = virJSONValueObjectGetString(data, "status"); + int status; + + if (!jobname) { + VIR_WARN("missing job name in JOB_STATUS_CHANGE event"); + return; + } + + if ((status = qemuMonitorJobStatusTypeFromString(statusstr)) < 0) { + VIR_WARN("unknown job status '%s' for job '%s' in JOB_STATUS_CHANGE event", + statusstr, jobname); + return; + } + + qemuMonitorEmitJobStatusChange(mon, jobname, status); +} + + static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data) -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:55PM +0200, Peter Krempa wrote:
This new event is a superset of the BLOCK_JOB* events and also covers jobs which don't bind to a VM disk.
In this patch the monitor part is implemented.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 13 +++++++++++++ src/qemu/qemu_monitor.h | 9 +++++++++ src/qemu/qemu_monitor_json.c | 26 ++++++++++++++++++++++++++ 3 files changed, 48 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The 'blockdev-create' starts a job which creates a storage volume using the given protocol or formats an existing (added) volume with one of the supported storage formats. This patch adds the monitor interaction bits. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 30 ++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 26 ++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 5 +++++ 4 files changed, 65 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 9358d0b1e2..90cd5ea9bd 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4418,6 +4418,36 @@ qemuMonitorSetWatchdogAction(qemuMonitorPtr mon, } +/** + * qemuMonitorBlockdevCreate: + * @mon: monitor object + * @jobname: name of the job + * @props: JSON object describing the blockdev to add + * + * Instructs qemu to create/format a new stroage or format layer. Note that + * the job does not add the created/formatted image into qemu and + * qemuMonitorBlockdevAdd needs to be called separately with corresponding + * arguments. Note that the argumetns for creating and adding are different. + * + * Note that @props is always consumed by this function and should not be + * accessed after calling this function. + */ +int +qemuMonitorBlockdevCreate(qemuMonitorPtr mon, + const char *jobname, + virJSONValuePtr props) +{ + VIR_DEBUG("jobname=%s props=%p", jobname, props); + + QEMU_CHECK_MONITOR_GOTO(mon, error); + + return qemuMonitorJSONBlockdevCreate(mon, jobname, props); + + error: + virJSONValueFree(props); + return -1; +} + /** * qemuMonitorBlockdevAdd: * @mon: monitor object diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index c6dddd1e9e..aafea6350c 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1289,6 +1289,10 @@ virJSONValuePtr qemuMonitorQueryNamedBlockNodes(qemuMonitorPtr mon); int qemuMonitorSetWatchdogAction(qemuMonitorPtr mon, const char *action); +int qemuMonitorBlockdevCreate(qemuMonitorPtr mon, + const char *jobname, + virJSONValuePtr props); + int qemuMonitorBlockdevAdd(qemuMonitorPtr mon, virJSONValuePtr props); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 04538bc46c..22fbd84e90 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -8616,6 +8616,32 @@ qemuMonitorJSONSetWatchdogAction(qemuMonitorPtr mon, } +int +qemuMonitorJSONBlockdevCreate(qemuMonitorPtr mon, + const char *jobname, + virJSONValuePtr props) +{ + VIR_AUTOPTR(virJSONValue) cmd = NULL; + VIR_AUTOPTR(virJSONValue) reply = NULL; + + cmd = qemuMonitorJSONMakeCommand("blockdev-create", + "s:job-id", jobname, + "a:options", &props, + NULL); + virJSONValueFree(props); + if (!cmd) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return -1; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + return -1; + + return 0; +} + + int qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon, virJSONValuePtr props) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index a50d4d7b23..00e6b3d68f 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -580,6 +580,11 @@ int qemuMonitorJSONSetWatchdogAction(qemuMonitorPtr mon, const char *action) ATTRIBUTE_NONNULL(1); +int qemuMonitorJSONBlockdevCreate(qemuMonitorPtr mon, + const char *jobname, + virJSONValuePtr props) + ATTRIBUTE_NONNULL(1); + int qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon, virJSONValuePtr props) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -- 2.21.0

On Mon, Jun 24, 2019 at 05:54:56PM +0200, Peter Krempa wrote:
The 'blockdev-create' starts a job which creates a storage volume using the given protocol or formats an existing (added) volume with one of the supported storage formats.
This patch adds the monitor interaction bits.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_monitor.c | 30 ++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 26 ++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 5 +++++ 4 files changed, 65 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 9358d0b1e2..90cd5ea9bd 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4418,6 +4418,36 @@ qemuMonitorSetWatchdogAction(qemuMonitorPtr mon, }
+/** + * qemuMonitorBlockdevCreate: + * @mon: monitor object + * @jobname: name of the job + * @props: JSON object describing the blockdev to add + * + * Instructs qemu to create/format a new stroage or format layer. Note that + * the job does not add the created/formatted image into qemu and + * qemuMonitorBlockdevAdd needs to be called separately with corresponding + * arguments. Note that the argumetns for creating and adding are different.
*arguments
+ * + * Note that @props is always consumed by this function and should not be + * accessed after calling this function. + */
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa