Patchwork [v3,08/16] block: introduce BLOCK_JOB_READY event

login
register
mail settings
Submitter Paolo Bonzini
Date Oct. 18, 2012, 2:49 p.m.
Message ID <1350571770-9836-9-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/192372/
State New
Headers show

Comments

Paolo Bonzini - Oct. 18, 2012, 2:49 p.m.
Even for jobs that need to be manually completed, management may want
to take care itself of the completion, not requiring the user to issue
a command to terminate the job.  In this case we want to avoid that
they poll us continuously, waiting for completion to become available.
Thus, add a new event that signals the phase switch and the availability
of the block-job-complete command.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 QMP/qmp-events.txt | 20 ++++++++++++++++++++
 blockdev.c         | 14 --------------
 blockjob.c         | 21 +++++++++++++++++++++
 blockjob.h         | 16 ++++++++++++++++
 monitor.c          |  1 +
 monitor.h          |  1 +
 qapi-schema.json   |  3 ++-
 7 file modificati, 61 inserzioni(+), 15 rimozioni(-)
Eric Blake - Oct. 18, 2012, 4:58 p.m.
On 10/18/2012 08:49 AM, Paolo Bonzini wrote:
> Even for jobs that need to be manually completed, management may want
> to take care itself of the completion, not requiring the user to issue
> a command to terminate the job.  In this case we want to avoid that
> they poll us continuously, waiting for completion to become available.
> Thus, add a new event that signals the phase switch and the availability
> of the block-job-complete command.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

> +BLOCK_JOB_READY
> +---------------
> +
> +Emitted when a block job is ready to complete.
> +
> +Data:
> +
> +- "device": device name (json-string)
> +
> +Example:
> +
> +{ "event": "BLOCK_JOB_READY",
> +    "data": { "device": "ide0-hd1",
> +              "operation": "write",
> +              "action": "stop" },

This example does not match the Data above ('operation' and 'action'
were not documented.

> +    "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }

Just a reminder that libvirt would still like a followup patch later in
your series but prior to qemu 1.3 that adds a 'type':'str' (or even an
enum, with 'stream', 'commit', and 'mirror').  But we already agreed it
need not hold up this particular patch.

Patch

diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index 987c575..6d9bc12 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -118,6 +118,26 @@  Example:
               "action": "stop" },
     "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
 
+BLOCK_JOB_READY
+---------------
+
+Emitted when a block job is ready to complete.
+
+Data:
+
+- "device": device name (json-string)
+
+Example:
+
+{ "event": "BLOCK_JOB_READY",
+    "data": { "device": "ide0-hd1",
+              "operation": "write",
+              "action": "stop" },
+    "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+
+Note: The "ready to complete" status is always reset by a BLOCK_JOB_ERROR
+event.
+
 DEVICE_TRAY_MOVED
 -----------------
 
diff --git a/blockdev.c b/blockdev.c
index 87dabbe..1068960 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1056,20 +1056,6 @@  void qmp_block_resize(const char *device, int64_t size, Error **errp)
     }
 }
 
-static QObject *qobject_from_block_job(BlockJob *job)
-{
-    return qobject_from_jsonf("{ 'type': %s,"
-                              "'device': %s,"
-                              "'len': %" PRId64 ","
-                              "'offset': %" PRId64 ","
-                              "'speed': %" PRId64 " }",
-                              job->job_type->job_type,
-                              bdrv_get_device_name(job->bs),
-                              job->len,
-                              job->offset,
-                              job->speed);
-}
-
 static void block_job_cb(void *opaque, int ret)
 {
     BlockDriverState *bs = opaque;
diff --git a/blockjob.c b/blockjob.c
index c93a0e0..fbb7e1c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -225,6 +225,27 @@  static void block_job_iostatus_set_err(BlockJob *job, int error)
 }
 
 
+QObject *qobject_from_block_job(BlockJob *job)
+{
+    return qobject_from_jsonf("{ 'type': %s,"
+                              "'device': %s,"
+                              "'len': %" PRId64 ","
+                              "'offset': %" PRId64 ","
+                              "'speed': %" PRId64 " }",
+                              job->job_type->job_type,
+                              bdrv_get_device_name(job->bs),
+                              job->len,
+                              job->offset,
+                              job->speed);
+}
+
+void block_job_ready(BlockJob *job)
+{
+    QObject *data = qobject_from_block_job(job);
+    monitor_protocol_event(QEVENT_BLOCK_JOB_READY, data);
+    qobject_decref(data);
+}
+
 BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
                                         BlockdevOnError on_err,
                                         int is_read, int error)
diff --git a/blockjob.h b/blockjob.h
index c44e2ea..fb2392e 100644
--- a/blockjob.h
+++ b/blockjob.h
@@ -211,6 +211,22 @@  void block_job_pause(BlockJob *job);
 void block_job_resume(BlockJob *job);
 
 /**
+ * qobject_from_block_job:
+ * @job: The job whose information is requested.
+ *
+ * Return a QDict corresponding to @job's query-block-jobs entry.
+ */
+QObject *qobject_from_block_job(BlockJob *job);
+
+/**
+ * block_job_ready:
+ * @job: The job which is now ready to complete.
+ *
+ * Send a BLOCK_JOB_READY event for the specified job.
+ */
+void block_job_ready(BlockJob *job);
+
+/**
  * block_job_is_paused:
  * @job: The job being queried.
  *
diff --git a/monitor.c b/monitor.c
index 131b325..0a07c2d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -451,6 +451,7 @@  static const char *monitor_event_names[] = {
     [QEVENT_BLOCK_JOB_COMPLETED] = "BLOCK_JOB_COMPLETED",
     [QEVENT_BLOCK_JOB_CANCELLED] = "BLOCK_JOB_CANCELLED",
     [QEVENT_BLOCK_JOB_ERROR] = "BLOCK_JOB_ERROR",
+    [QEVENT_BLOCK_JOB_READY] = "BLOCK_JOB_READY",
     [QEVENT_DEVICE_TRAY_MOVED] = "DEVICE_TRAY_MOVED",
     [QEVENT_SUSPEND] = "SUSPEND",
     [QEVENT_SUSPEND_DISK] = "SUSPEND_DISK",
diff --git a/monitor.h b/monitor.h
index b6e7d95..d1d2850 100644
--- a/monitor.h
+++ b/monitor.h
@@ -39,6 +39,7 @@  typedef enum MonitorEvent {
     QEVENT_BLOCK_JOB_COMPLETED,
     QEVENT_BLOCK_JOB_CANCELLED,
     QEVENT_BLOCK_JOB_ERROR,
+    QEVENT_BLOCK_JOB_READY,
     QEVENT_DEVICE_TRAY_MOVED,
     QEVENT_SUSPEND,
     QEVENT_SUSPEND_DISK,
diff --git a/qapi-schema.json b/qapi-schema.json
index 8211935..bc1b585 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2023,7 +2023,8 @@ 
 #
 # Manually trigger completion of an active background block operation.  This
 # is supported for drive mirroring, where it also switches the device to
-# write to the target path only.
+# write to the target path only.  The ability to complete is signaled with
+# a BLOCK_JOB_READY event.
 #
 # This command completes an active background block operation synchronously.
 # The ordering of this command's return with the BLOCK_JOB_COMPLETED event