|
|
ae23c9 |
From 941f553a991d152f7691f5b1e3d8459b4843a51b Mon Sep 17 00:00:00 2001
|
|
|
ae23c9 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Date: Tue, 26 Jun 2018 09:48:15 +0200
|
|
|
ae23c9 |
Subject: [PATCH 107/268] job: Add job_event_*()
|
|
|
ae23c9 |
|
|
|
ae23c9 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Message-id: <20180626094856.6924-33-kwolf@redhat.com>
|
|
|
ae23c9 |
Patchwork-id: 81092
|
|
|
ae23c9 |
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 32/73] job: Add job_event_*()
|
|
|
ae23c9 |
Bugzilla: 1513543
|
|
|
ae23c9 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Go through the Job layer in order to send QMP events. For the moment,
|
|
|
ae23c9 |
these functions only call a notifier in the BlockJob layer that sends
|
|
|
ae23c9 |
the existing commands.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
This uses notifiers rather than JobDriver callbacks because internal
|
|
|
ae23c9 |
users of jobs won't receive QMP events, but might still be interested
|
|
|
ae23c9 |
in getting notified for the events.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
|
|
ae23c9 |
(cherry picked from commit 139a9f020d49e9f863e0d46fd3d0b440dfb3b9d7)
|
|
|
ae23c9 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
ae23c9 |
---
|
|
|
ae23c9 |
blockjob.c | 41 +++++++++++++++++++++++++++--------------
|
|
|
ae23c9 |
include/block/blockjob.h | 9 +++++++++
|
|
|
ae23c9 |
include/qemu/job.h | 18 ++++++++++++++++++
|
|
|
ae23c9 |
job.c | 19 +++++++++++++++++++
|
|
|
ae23c9 |
4 files changed, 73 insertions(+), 14 deletions(-)
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/blockjob.c b/blockjob.c
|
|
|
ae23c9 |
index b4334fb..05d7921 100644
|
|
|
ae23c9 |
--- a/blockjob.c
|
|
|
ae23c9 |
+++ b/blockjob.c
|
|
|
ae23c9 |
@@ -36,10 +36,6 @@
|
|
|
ae23c9 |
#include "qemu/coroutine.h"
|
|
|
ae23c9 |
#include "qemu/timer.h"
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-static void block_job_event_cancelled(BlockJob *job);
|
|
|
ae23c9 |
-static void block_job_event_completed(BlockJob *job, const char *msg);
|
|
|
ae23c9 |
-static void block_job_event_pending(BlockJob *job);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
/* Transactional group of block jobs */
|
|
|
ae23c9 |
struct BlockJobTxn {
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@@ -352,13 +348,9 @@ static int block_job_finalize_single(BlockJob *job)
|
|
|
ae23c9 |
/* Emit events only if we actually started */
|
|
|
ae23c9 |
if (job_started(&job->job)) {
|
|
|
ae23c9 |
if (job_is_cancelled(&job->job)) {
|
|
|
ae23c9 |
- block_job_event_cancelled(job);
|
|
|
ae23c9 |
+ job_event_cancelled(&job->job);
|
|
|
ae23c9 |
} else {
|
|
|
ae23c9 |
- const char *msg = NULL;
|
|
|
ae23c9 |
- if (job->ret < 0) {
|
|
|
ae23c9 |
- msg = strerror(-job->ret);
|
|
|
ae23c9 |
- }
|
|
|
ae23c9 |
- block_job_event_completed(job, msg);
|
|
|
ae23c9 |
+ job_event_completed(&job->job);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@@ -504,7 +496,7 @@ static int block_job_transition_to_pending(BlockJob *job)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
job_state_transition(&job->job, JOB_STATUS_PENDING);
|
|
|
ae23c9 |
if (!job->job.auto_finalize) {
|
|
|
ae23c9 |
- block_job_event_pending(job);
|
|
|
ae23c9 |
+ job_event_pending(&job->job);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
return 0;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -712,8 +704,10 @@ static void block_job_iostatus_set_err(BlockJob *job, int error)
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-static void block_job_event_cancelled(BlockJob *job)
|
|
|
ae23c9 |
+static void block_job_event_cancelled(Notifier *n, void *opaque)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
+ BlockJob *job = opaque;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
if (block_job_is_internal(job)) {
|
|
|
ae23c9 |
return;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -726,12 +720,19 @@ static void block_job_event_cancelled(BlockJob *job)
|
|
|
ae23c9 |
&error_abort);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-static void block_job_event_completed(BlockJob *job, const char *msg)
|
|
|
ae23c9 |
+static void block_job_event_completed(Notifier *n, void *opaque)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
+ BlockJob *job = opaque;
|
|
|
ae23c9 |
+ const char *msg = NULL;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
if (block_job_is_internal(job)) {
|
|
|
ae23c9 |
return;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+ if (job->ret < 0) {
|
|
|
ae23c9 |
+ msg = strerror(-job->ret);
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
qapi_event_send_block_job_completed(job_type(&job->job),
|
|
|
ae23c9 |
job->job.id,
|
|
|
ae23c9 |
job->len,
|
|
|
ae23c9 |
@@ -742,8 +743,10 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
|
|
|
ae23c9 |
&error_abort);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-static void block_job_event_pending(BlockJob *job)
|
|
|
ae23c9 |
+static void block_job_event_pending(Notifier *n, void *opaque)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
+ BlockJob *job = opaque;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
if (block_job_is_internal(job)) {
|
|
|
ae23c9 |
return;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -799,6 +802,16 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
|
|
ae23c9 |
job->cb = cb;
|
|
|
ae23c9 |
job->opaque = opaque;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+ job->finalize_cancelled_notifier.notify = block_job_event_cancelled;
|
|
|
ae23c9 |
+ job->finalize_completed_notifier.notify = block_job_event_completed;
|
|
|
ae23c9 |
+ job->pending_notifier.notify = block_job_event_pending;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ notifier_list_add(&job->job.on_finalize_cancelled,
|
|
|
ae23c9 |
+ &job->finalize_cancelled_notifier);
|
|
|
ae23c9 |
+ notifier_list_add(&job->job.on_finalize_completed,
|
|
|
ae23c9 |
+ &job->finalize_completed_notifier);
|
|
|
ae23c9 |
+ notifier_list_add(&job->job.on_pending, &job->pending_notifier);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
error_setg(&job->blocker, "block device is in use by block job: %s",
|
|
|
ae23c9 |
job_type_str(&job->job));
|
|
|
ae23c9 |
block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
|
|
|
ae23c9 |
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
|
|
|
ae23c9 |
index f9aaaaa..aef0629 100644
|
|
|
ae23c9 |
--- a/include/block/blockjob.h
|
|
|
ae23c9 |
+++ b/include/block/blockjob.h
|
|
|
ae23c9 |
@@ -82,6 +82,15 @@ typedef struct BlockJob {
|
|
|
ae23c9 |
/** Block other operations when block job is running */
|
|
|
ae23c9 |
Error *blocker;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+ /** Called when a cancelled job is finalised. */
|
|
|
ae23c9 |
+ Notifier finalize_cancelled_notifier;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ /** Called when a successfully completed job is finalised. */
|
|
|
ae23c9 |
+ Notifier finalize_completed_notifier;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ /** Called when the job transitions to PENDING */
|
|
|
ae23c9 |
+ Notifier pending_notifier;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
/** BlockDriverStates that are involved in this block job */
|
|
|
ae23c9 |
GSList *nodes;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/include/qemu/job.h b/include/qemu/job.h
|
|
|
ae23c9 |
index 9783e40..14d9377 100644
|
|
|
ae23c9 |
--- a/include/qemu/job.h
|
|
|
ae23c9 |
+++ b/include/qemu/job.h
|
|
|
ae23c9 |
@@ -105,6 +105,15 @@ typedef struct Job {
|
|
|
ae23c9 |
/** True if this job should automatically dismiss itself */
|
|
|
ae23c9 |
bool auto_dismiss;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+ /** Notifiers called when a cancelled job is finalised */
|
|
|
ae23c9 |
+ NotifierList on_finalize_cancelled;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ /** Notifiers called when a successfully completed job is finalised */
|
|
|
ae23c9 |
+ NotifierList on_finalize_completed;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ /** Notifiers called when the job transitions to PENDING */
|
|
|
ae23c9 |
+ NotifierList on_pending;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
/** Element of the list of jobs */
|
|
|
ae23c9 |
QLIST_ENTRY(Job) job_list;
|
|
|
ae23c9 |
} Job;
|
|
|
ae23c9 |
@@ -182,6 +191,15 @@ void job_ref(Job *job);
|
|
|
ae23c9 |
*/
|
|
|
ae23c9 |
void job_unref(Job *job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+/** To be called when a cancelled job is finalised. */
|
|
|
ae23c9 |
+void job_event_cancelled(Job *job);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/** To be called when a successfully completed job is finalised. */
|
|
|
ae23c9 |
+void job_event_completed(Job *job);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/** To be called when the job transitions to PENDING */
|
|
|
ae23c9 |
+void job_event_pending(Job *job);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
/**
|
|
|
ae23c9 |
* Conditionally enter the job coroutine if the job is ready to run, not
|
|
|
ae23c9 |
* already busy and fn() returns true. fn() is called while under the job_lock
|
|
|
ae23c9 |
diff --git a/job.c b/job.c
|
|
|
ae23c9 |
index dd46170..817c3b4 100644
|
|
|
ae23c9 |
--- a/job.c
|
|
|
ae23c9 |
+++ b/job.c
|
|
|
ae23c9 |
@@ -215,6 +215,10 @@ void *job_create(const char *job_id, const JobDriver *driver, AioContext *ctx,
|
|
|
ae23c9 |
job->auto_finalize = !(flags & JOB_MANUAL_FINALIZE);
|
|
|
ae23c9 |
job->auto_dismiss = !(flags & JOB_MANUAL_DISMISS);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+ notifier_list_init(&job->on_finalize_cancelled);
|
|
|
ae23c9 |
+ notifier_list_init(&job->on_finalize_completed);
|
|
|
ae23c9 |
+ notifier_list_init(&job->on_pending);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
job_state_transition(job, JOB_STATUS_CREATED);
|
|
|
ae23c9 |
aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
|
|
|
ae23c9 |
QEMU_CLOCK_REALTIME, SCALE_NS,
|
|
|
ae23c9 |
@@ -247,6 +251,21 @@ void job_unref(Job *job)
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+void job_event_cancelled(Job *job)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ notifier_list_notify(&job->on_finalize_cancelled, job);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+void job_event_completed(Job *job)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ notifier_list_notify(&job->on_finalize_completed, job);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+void job_event_pending(Job *job)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ notifier_list_notify(&job->on_pending, job);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
void job_enter_cond(Job *job, bool(*fn)(Job *job))
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
if (!job_started(job)) {
|
|
|
ae23c9 |
--
|
|
|
ae23c9 |
1.8.3.1
|
|
|
ae23c9 |
|