cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
ae23c9
From 04abeb0ef2f62cf5eb252672afef623d9cc99545 Mon Sep 17 00:00:00 2001
ae23c9
From: Kevin Wolf <kwolf@redhat.com>
ae23c9
Date: Tue, 26 Jun 2018 09:48:03 +0200
ae23c9
Subject: [PATCH 095/268] job: Maintain a list of all jobs
ae23c9
ae23c9
RH-Author: Kevin Wolf <kwolf@redhat.com>
ae23c9
Message-id: <20180626094856.6924-21-kwolf@redhat.com>
ae23c9
Patchwork-id: 81105
ae23c9
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 20/73] job: Maintain a list of all jobs
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
This moves the job list from BlockJob to Job. Now we can check for
ae23c9
duplicate IDs in job_create().
ae23c9
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
Reviewed-by: Max Reitz <mreitz@redhat.com>
ae23c9
Reviewed-by: John Snow <jsnow@redhat.com>
ae23c9
(cherry picked from commit e7c1d78bbd5867804debeb7159b137fd9a6c44d3)
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
---
ae23c9
 blockjob.c               | 46 ++++++++++++++++++++++++----------------------
ae23c9
 include/block/blockjob.h |  3 ---
ae23c9
 include/qemu/job.h       | 19 +++++++++++++++++++
ae23c9
 job.c                    | 31 +++++++++++++++++++++++++++++++
ae23c9
 4 files changed, 74 insertions(+), 25 deletions(-)
ae23c9
ae23c9
diff --git a/blockjob.c b/blockjob.c
ae23c9
index 430a67b..c69b2e7 100644
ae23c9
--- a/blockjob.c
ae23c9
+++ b/blockjob.c
ae23c9
@@ -129,8 +129,6 @@ struct BlockJobTxn {
ae23c9
     int refcnt;
ae23c9
 };
ae23c9
 
ae23c9
-static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
ae23c9
-
ae23c9
 /*
ae23c9
  * The block job API is composed of two categories of functions.
ae23c9
  *
ae23c9
@@ -146,25 +144,34 @@ static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
ae23c9
  * blockjob_int.h.
ae23c9
  */
ae23c9
 
ae23c9
-BlockJob *block_job_next(BlockJob *job)
ae23c9
+static bool is_block_job(Job *job)
ae23c9
 {
ae23c9
-    if (!job) {
ae23c9
-        return QLIST_FIRST(&block_jobs);
ae23c9
-    }
ae23c9
-    return QLIST_NEXT(job, job_list);
ae23c9
+    return job_type(job) == JOB_TYPE_BACKUP ||
ae23c9
+           job_type(job) == JOB_TYPE_COMMIT ||
ae23c9
+           job_type(job) == JOB_TYPE_MIRROR ||
ae23c9
+           job_type(job) == JOB_TYPE_STREAM;
ae23c9
+}
ae23c9
+
ae23c9
+BlockJob *block_job_next(BlockJob *bjob)
ae23c9
+{
ae23c9
+    Job *job = bjob ? &bjob->job : NULL;
ae23c9
+
ae23c9
+    do {
ae23c9
+        job = job_next(job);
ae23c9
+    } while (job && !is_block_job(job));
ae23c9
+
ae23c9
+    return job ? container_of(job, BlockJob, job) : NULL;
ae23c9
 }
ae23c9
 
ae23c9
 BlockJob *block_job_get(const char *id)
ae23c9
 {
ae23c9
-    BlockJob *job;
ae23c9
+    Job *job = job_get(id);
ae23c9
 
ae23c9
-    QLIST_FOREACH(job, &block_jobs, job_list) {
ae23c9
-        if (job->job.id && !strcmp(id, job->job.id)) {
ae23c9
-            return job;
ae23c9
-        }
ae23c9
+    if (job && is_block_job(job)) {
ae23c9
+        return container_of(job, BlockJob, job);
ae23c9
+    } else {
ae23c9
+        return NULL;
ae23c9
     }
ae23c9
-
ae23c9
-    return NULL;
ae23c9
 }
ae23c9
 
ae23c9
 BlockJobTxn *block_job_txn_new(void)
ae23c9
@@ -253,7 +260,6 @@ void block_job_unref(BlockJob *job)
ae23c9
         assert(job->status == BLOCK_JOB_STATUS_NULL);
ae23c9
         assert(!job->txn);
ae23c9
         BlockDriverState *bs = blk_bs(job->blk);
ae23c9
-        QLIST_REMOVE(job, job_list);
ae23c9
         bs->job = NULL;
ae23c9
         block_job_remove_all_bdrv(job);
ae23c9
         blk_remove_aio_context_notifier(job->blk,
ae23c9
@@ -812,7 +818,7 @@ void block_job_cancel_sync_all(void)
ae23c9
     BlockJob *job;
ae23c9
     AioContext *aio_context;
ae23c9
 
ae23c9
-    while ((job = QLIST_FIRST(&block_jobs))) {
ae23c9
+    while ((job = block_job_next(NULL))) {
ae23c9
         aio_context = blk_get_aio_context(job->blk);
ae23c9
         aio_context_acquire(aio_context);
ae23c9
         block_job_cancel_sync(job);
ae23c9
@@ -942,10 +948,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
ae23c9
             error_setg(errp, "Cannot specify job ID for internal block job");
ae23c9
             return NULL;
ae23c9
         }
ae23c9
-        if (block_job_get(job_id)) {
ae23c9
-            error_setg(errp, "Job ID '%s' already in use", job_id);
ae23c9
-            return NULL;
ae23c9
-        }
ae23c9
     }
ae23c9
 
ae23c9
     blk = blk_new(perm, shared_perm);
ae23c9
@@ -961,6 +963,8 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
ae23c9
         return NULL;
ae23c9
     }
ae23c9
 
ae23c9
+    assert(is_block_job(&job->job));
ae23c9
+
ae23c9
     job->driver        = driver;
ae23c9
     job->blk           = blk;
ae23c9
     job->cb            = cb;
ae23c9
@@ -983,8 +987,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
ae23c9
 
ae23c9
     bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
ae23c9
 
ae23c9
-    QLIST_INSERT_HEAD(&block_jobs, job, job_list);
ae23c9
-
ae23c9
     blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
ae23c9
                                  block_job_detach_aio_context, job);
ae23c9
 
ae23c9
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
ae23c9
index 640e649..10bd9f7 100644
ae23c9
--- a/include/block/blockjob.h
ae23c9
+++ b/include/block/blockjob.h
ae23c9
@@ -105,9 +105,6 @@ typedef struct BlockJob {
ae23c9
      */
ae23c9
     bool deferred_to_main_loop;
ae23c9
 
ae23c9
-    /** Element of the list of block jobs */
ae23c9
-    QLIST_ENTRY(BlockJob) job_list;
ae23c9
-
ae23c9
     /** Status that is published by the query-block-jobs QMP API */
ae23c9
     BlockDeviceIoStatus iostatus;
ae23c9
 
ae23c9
diff --git a/include/qemu/job.h b/include/qemu/job.h
ae23c9
index 43dc2e4..bae2b09 100644
ae23c9
--- a/include/qemu/job.h
ae23c9
+++ b/include/qemu/job.h
ae23c9
@@ -27,6 +27,7 @@
ae23c9
 #define JOB_H
ae23c9
 
ae23c9
 #include "qapi/qapi-types-block-core.h"
ae23c9
+#include "qemu/queue.h"
ae23c9
 
ae23c9
 typedef struct JobDriver JobDriver;
ae23c9
 
ae23c9
@@ -39,6 +40,9 @@ typedef struct Job {
ae23c9
 
ae23c9
     /** The type of this job. */
ae23c9
     const JobDriver *driver;
ae23c9
+
ae23c9
+    /** Element of the list of jobs */
ae23c9
+    QLIST_ENTRY(Job) job_list;
ae23c9
 } Job;
ae23c9
 
ae23c9
 /**
ae23c9
@@ -71,4 +75,19 @@ JobType job_type(const Job *job);
ae23c9
 /** Returns the enum string for the JobType of a given Job. */
ae23c9
 const char *job_type_str(const Job *job);
ae23c9
 
ae23c9
+/**
ae23c9
+ * Get the next element from the list of block jobs after @job, or the
ae23c9
+ * first one if @job is %NULL.
ae23c9
+ *
ae23c9
+ * Returns the requested job, or %NULL if there are no more jobs left.
ae23c9
+ */
ae23c9
+Job *job_next(Job *job);
ae23c9
+
ae23c9
+/**
ae23c9
+ * Get the job identified by @id (which must not be %NULL).
ae23c9
+ *
ae23c9
+ * Returns the requested job, or %NULL if it doesn't exist.
ae23c9
+ */
ae23c9
+Job *job_get(const char *id);
ae23c9
+
ae23c9
 #endif
ae23c9
diff --git a/job.c b/job.c
ae23c9
index cfdd008..e57303c 100644
ae23c9
--- a/job.c
ae23c9
+++ b/job.c
ae23c9
@@ -29,6 +29,8 @@
ae23c9
 #include "qemu/job.h"
ae23c9
 #include "qemu/id.h"
ae23c9
 
ae23c9
+static QLIST_HEAD(, Job) jobs = QLIST_HEAD_INITIALIZER(jobs);
ae23c9
+
ae23c9
 JobType job_type(const Job *job)
ae23c9
 {
ae23c9
     return job->driver->job_type;
ae23c9
@@ -39,6 +41,27 @@ const char *job_type_str(const Job *job)
ae23c9
     return JobType_str(job_type(job));
ae23c9
 }
ae23c9
 
ae23c9
+Job *job_next(Job *job)
ae23c9
+{
ae23c9
+    if (!job) {
ae23c9
+        return QLIST_FIRST(&jobs);
ae23c9
+    }
ae23c9
+    return QLIST_NEXT(job, job_list);
ae23c9
+}
ae23c9
+
ae23c9
+Job *job_get(const char *id)
ae23c9
+{
ae23c9
+    Job *job;
ae23c9
+
ae23c9
+    QLIST_FOREACH(job, &jobs, job_list) {
ae23c9
+        if (job->id && !strcmp(id, job->id)) {
ae23c9
+            return job;
ae23c9
+        }
ae23c9
+    }
ae23c9
+
ae23c9
+    return NULL;
ae23c9
+}
ae23c9
+
ae23c9
 void *job_create(const char *job_id, const JobDriver *driver, Error **errp)
ae23c9
 {
ae23c9
     Job *job;
ae23c9
@@ -48,17 +71,25 @@ void *job_create(const char *job_id, const JobDriver *driver, Error **errp)
ae23c9
             error_setg(errp, "Invalid job ID '%s'", job_id);
ae23c9
             return NULL;
ae23c9
         }
ae23c9
+        if (job_get(job_id)) {
ae23c9
+            error_setg(errp, "Job ID '%s' already in use", job_id);
ae23c9
+            return NULL;
ae23c9
+        }
ae23c9
     }
ae23c9
 
ae23c9
     job = g_malloc0(driver->instance_size);
ae23c9
     job->driver        = driver;
ae23c9
     job->id            = g_strdup(job_id);
ae23c9
 
ae23c9
+    QLIST_INSERT_HEAD(&jobs, job, job_list);
ae23c9
+
ae23c9
     return job;
ae23c9
 }
ae23c9
 
ae23c9
 void job_delete(Job *job)
ae23c9
 {
ae23c9
+    QLIST_REMOVE(job, job_list);
ae23c9
+
ae23c9
     g_free(job->id);
ae23c9
     g_free(job);
ae23c9
 }
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9