qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, mreitz@redhat.com, jsnow@redhat.com,
	eblake@redhat.com, jcody@redhat.com, armbru@redhat.com,
	qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH v2 07/40] job: Maintain a list of all jobs
Date: Fri, 18 May 2018 15:20:41 +0200	[thread overview]
Message-ID: <20180518132114.4070-8-kwolf@redhat.com> (raw)
In-Reply-To: <20180518132114.4070-1-kwolf@redhat.com>

This moves the job list from BlockJob to Job. Now we can check for
duplicate IDs in job_create().

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
---
 include/block/blockjob.h |  3 ---
 include/qemu/job.h       | 19 +++++++++++++++++++
 blockjob.c               | 46 ++++++++++++++++++++++++----------------------
 job.c                    | 31 +++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 25 deletions(-)

diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 640e649034..10bd9f7059 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -105,9 +105,6 @@ typedef struct BlockJob {
      */
     bool deferred_to_main_loop;
 
-    /** Element of the list of block jobs */
-    QLIST_ENTRY(BlockJob) job_list;
-
     /** Status that is published by the query-block-jobs QMP API */
     BlockDeviceIoStatus iostatus;
 
diff --git a/include/qemu/job.h b/include/qemu/job.h
index 43dc2e4a7d..bae2b0920c 100644
--- a/include/qemu/job.h
+++ b/include/qemu/job.h
@@ -27,6 +27,7 @@
 #define JOB_H
 
 #include "qapi/qapi-types-block-core.h"
+#include "qemu/queue.h"
 
 typedef struct JobDriver JobDriver;
 
@@ -39,6 +40,9 @@ typedef struct Job {
 
     /** The type of this job. */
     const JobDriver *driver;
+
+    /** Element of the list of jobs */
+    QLIST_ENTRY(Job) job_list;
 } Job;
 
 /**
@@ -71,4 +75,19 @@ JobType job_type(const Job *job);
 /** Returns the enum string for the JobType of a given Job. */
 const char *job_type_str(const Job *job);
 
+/**
+ * Get the next element from the list of block jobs after @job, or the
+ * first one if @job is %NULL.
+ *
+ * Returns the requested job, or %NULL if there are no more jobs left.
+ */
+Job *job_next(Job *job);
+
+/**
+ * Get the job identified by @id (which must not be %NULL).
+ *
+ * Returns the requested job, or %NULL if it doesn't exist.
+ */
+Job *job_get(const char *id);
+
 #endif
diff --git a/blockjob.c b/blockjob.c
index 430a67ba63..c69b2e7cf5 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -129,8 +129,6 @@ struct BlockJobTxn {
     int refcnt;
 };
 
-static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
-
 /*
  * The block job API is composed of two categories of functions.
  *
@@ -146,25 +144,34 @@ static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
  * blockjob_int.h.
  */
 
-BlockJob *block_job_next(BlockJob *job)
+static bool is_block_job(Job *job)
 {
-    if (!job) {
-        return QLIST_FIRST(&block_jobs);
-    }
-    return QLIST_NEXT(job, job_list);
+    return job_type(job) == JOB_TYPE_BACKUP ||
+           job_type(job) == JOB_TYPE_COMMIT ||
+           job_type(job) == JOB_TYPE_MIRROR ||
+           job_type(job) == JOB_TYPE_STREAM;
+}
+
+BlockJob *block_job_next(BlockJob *bjob)
+{
+    Job *job = bjob ? &bjob->job : NULL;
+
+    do {
+        job = job_next(job);
+    } while (job && !is_block_job(job));
+
+    return job ? container_of(job, BlockJob, job) : NULL;
 }
 
 BlockJob *block_job_get(const char *id)
 {
-    BlockJob *job;
+    Job *job = job_get(id);
 
-    QLIST_FOREACH(job, &block_jobs, job_list) {
-        if (job->job.id && !strcmp(id, job->job.id)) {
-            return job;
-        }
+    if (job && is_block_job(job)) {
+        return container_of(job, BlockJob, job);
+    } else {
+        return NULL;
     }
-
-    return NULL;
 }
 
 BlockJobTxn *block_job_txn_new(void)
@@ -253,7 +260,6 @@ void block_job_unref(BlockJob *job)
         assert(job->status == BLOCK_JOB_STATUS_NULL);
         assert(!job->txn);
         BlockDriverState *bs = blk_bs(job->blk);
-        QLIST_REMOVE(job, job_list);
         bs->job = NULL;
         block_job_remove_all_bdrv(job);
         blk_remove_aio_context_notifier(job->blk,
@@ -812,7 +818,7 @@ void block_job_cancel_sync_all(void)
     BlockJob *job;
     AioContext *aio_context;
 
-    while ((job = QLIST_FIRST(&block_jobs))) {
+    while ((job = block_job_next(NULL))) {
         aio_context = blk_get_aio_context(job->blk);
         aio_context_acquire(aio_context);
         block_job_cancel_sync(job);
@@ -942,10 +948,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
             error_setg(errp, "Cannot specify job ID for internal block job");
             return NULL;
         }
-        if (block_job_get(job_id)) {
-            error_setg(errp, "Job ID '%s' already in use", job_id);
-            return NULL;
-        }
     }
 
     blk = blk_new(perm, shared_perm);
@@ -961,6 +963,8 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
         return NULL;
     }
 
+    assert(is_block_job(&job->job));
+
     job->driver        = driver;
     job->blk           = blk;
     job->cb            = cb;
@@ -983,8 +987,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
 
     bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
 
-    QLIST_INSERT_HEAD(&block_jobs, job, job_list);
-
     blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
                                  block_job_detach_aio_context, job);
 
diff --git a/job.c b/job.c
index cfdd008c52..e57303c6bb 100644
--- a/job.c
+++ b/job.c
@@ -29,6 +29,8 @@
 #include "qemu/job.h"
 #include "qemu/id.h"
 
+static QLIST_HEAD(, Job) jobs = QLIST_HEAD_INITIALIZER(jobs);
+
 JobType job_type(const Job *job)
 {
     return job->driver->job_type;
@@ -39,6 +41,27 @@ const char *job_type_str(const Job *job)
     return JobType_str(job_type(job));
 }
 
+Job *job_next(Job *job)
+{
+    if (!job) {
+        return QLIST_FIRST(&jobs);
+    }
+    return QLIST_NEXT(job, job_list);
+}
+
+Job *job_get(const char *id)
+{
+    Job *job;
+
+    QLIST_FOREACH(job, &jobs, job_list) {
+        if (job->id && !strcmp(id, job->id)) {
+            return job;
+        }
+    }
+
+    return NULL;
+}
+
 void *job_create(const char *job_id, const JobDriver *driver, Error **errp)
 {
     Job *job;
@@ -48,17 +71,25 @@ void *job_create(const char *job_id, const JobDriver *driver, Error **errp)
             error_setg(errp, "Invalid job ID '%s'", job_id);
             return NULL;
         }
+        if (job_get(job_id)) {
+            error_setg(errp, "Job ID '%s' already in use", job_id);
+            return NULL;
+        }
     }
 
     job = g_malloc0(driver->instance_size);
     job->driver        = driver;
     job->id            = g_strdup(job_id);
 
+    QLIST_INSERT_HEAD(&jobs, job, job_list);
+
     return job;
 }
 
 void job_delete(Job *job)
 {
+    QLIST_REMOVE(job, job_list);
+
     g_free(job->id);
     g_free(job);
 }
-- 
2.13.6

  parent reply	other threads:[~2018-05-18 13:21 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-18 13:20 [Qemu-devel] [PATCH v2 00/40] Generic background jobs Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 01/40] blockjob: Update block-job-pause/resume documentation Kevin Wolf
2018-05-18 14:20   ` Eric Blake
2018-05-18 17:12   ` John Snow
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 02/40] blockjob: Improve BlockJobInfo.offset/len documentation Kevin Wolf
2018-05-18 14:25   ` Eric Blake
2018-05-18 17:47   ` John Snow
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 03/40] job: Create Job, JobDriver and job_create() Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 04/40] job: Rename BlockJobType into JobType Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 05/40] job: Add JobDriver.job_type Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 06/40] job: Add job_delete() Kevin Wolf
2018-05-18 13:20 ` Kevin Wolf [this message]
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 08/40] job: Move state transitions to Job Kevin Wolf
2018-05-18 14:36   ` Eric Blake
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 09/40] job: Add reference counting Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 10/40] job: Move cancelled to Job Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 11/40] job: Add Job.aio_context Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 12/40] job: Move defer_to_main_loop to Job Kevin Wolf
2018-05-18 17:56   ` John Snow
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 13/40] job: Move coroutine and related code " Kevin Wolf
2018-05-18 18:43   ` John Snow
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 14/40] job: Add job_sleep_ns() Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 15/40] job: Move pause/resume functions to Job Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 16/40] job: Replace BlockJob.completed with job_is_completed() Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 17/40] job: Move BlockJobCreateFlags to Job Kevin Wolf
2018-05-23 22:24   ` John Snow
2018-05-24  8:17     ` Kevin Wolf
2018-05-24 17:46       ` John Snow
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 18/40] blockjob: Split block_job_event_pending() Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 19/40] job: Add job_event_*() Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 20/40] job: Move single job finalisation to Job Kevin Wolf
2018-05-18 18:00   ` Eric Blake
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 21/40] job: Convert block_job_cancel_async() " Kevin Wolf
2018-05-23 23:18   ` John Snow
2018-05-24  8:24     ` Kevin Wolf
2018-05-24 17:42       ` John Snow
2018-05-25  8:00         ` Kevin Wolf
2018-05-25 17:43           ` John Snow
2018-05-29 11:59           ` [Qemu-devel] [Qemu-block] " Kashyap Chamarthy
2018-05-29 12:30             ` Max Reitz
2018-05-29 13:10               ` Kashyap Chamarthy
2018-05-29 13:22                 ` Kashyap Chamarthy
2018-05-30 20:33               ` John Snow
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 22/40] job: Add job_drain() Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 23/40] job: Move .complete callback to Job Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 24/40] job: Move job_finish_sync() " Kevin Wolf
2018-05-18 13:20 ` [Qemu-devel] [PATCH v2 25/40] job: Switch transactions to JobTxn Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 26/40] job: Move transactions to Job Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 27/40] job: Move completion and cancellation " Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 28/40] block: Cancel job in bdrv_close_all() callers Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 29/40] job: Add job_yield() Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 30/40] job: Add job_dismiss() Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 31/40] job: Add job_is_ready() Kevin Wolf
2018-05-23 23:42   ` John Snow
2018-05-24  8:30     ` Kevin Wolf
2018-05-24 17:25       ` John Snow
2018-05-25  8:06         ` Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 32/40] job: Add job_transition_to_ready() Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 33/40] job: Move progress fields to Job Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 34/40] job: Introduce qapi/job.json Kevin Wolf
2018-05-18 15:59   ` Eric Blake
2018-05-31 21:21   ` Eric Blake
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 35/40] job: Add JOB_STATUS_CHANGE QMP event Kevin Wolf
2018-05-18 17:55   ` Eric Blake
2018-05-24  0:02   ` John Snow
2018-05-24  8:36     ` Kevin Wolf
2018-05-24 17:36       ` John Snow
2018-05-24 18:22         ` Eric Blake
2018-05-24 18:32           ` John Snow
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 36/40] job: Add lifecycle QMP commands Kevin Wolf
2018-05-18 18:12   ` Eric Blake
2018-05-22 10:40     ` Kevin Wolf
2018-05-23 23:56   ` John Snow
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 37/40] job: Add query-jobs QMP command Kevin Wolf
2018-05-18 18:14   ` Eric Blake
2018-05-18 18:22   ` Eric Blake
2018-05-22 10:44     ` Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 38/40] blockjob: Remove BlockJob.driver Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 39/40] iotests: Move qmp_to_opts() to VM Kevin Wolf
2018-05-18 13:21 ` [Qemu-devel] [PATCH v2 40/40] qemu-iotests: Test job-* with block jobs Kevin Wolf
2018-05-18 14:05 ` [Qemu-devel] [PATCH v2 00/40] Generic background jobs no-reply
2018-05-18 18:41 ` Dr. David Alan Gilbert
2018-05-22 11:01   ` Kevin Wolf
2018-05-22 17:15     ` Marc-André Lureau
2018-05-29 17:16       ` Dr. David Alan Gilbert
2018-05-23 12:31 ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180518132114.4070-8-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=jcody@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).