Blame SOURCES/kvm-job-Create-Job-JobDriver-and-job_create.patch

383d26
From 0223091bd8c515f4eab85de49c039f1275dd8a66 Mon Sep 17 00:00:00 2001
383d26
From: Kevin Wolf <kwolf@redhat.com>
383d26
Date: Tue, 26 Jun 2018 09:47:59 +0200
383d26
Subject: [PATCH 30/89] job: Create Job, JobDriver and job_create()
383d26
383d26
RH-Author: Kevin Wolf <kwolf@redhat.com>
383d26
Message-id: <20180626094856.6924-17-kwolf@redhat.com>
383d26
Patchwork-id: 81124
383d26
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 16/73] job: Create Job, JobDriver and job_create()
383d26
Bugzilla: 1513543
383d26
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
383d26
RH-Acked-by: Max Reitz <mreitz@redhat.com>
383d26
RH-Acked-by: Fam Zheng <famz@redhat.com>
383d26
383d26
This is the first step towards creating an infrastructure for generic
383d26
background jobs that aren't tied to a block device. For now, Job only
383d26
stores its ID and JobDriver, the rest stays in BlockJob.
383d26
383d26
The following patches will move over more parts of BlockJob to Job if
383d26
they are meaningful outside the context of a block job.
383d26
383d26
BlockJob.driver is now redundant, but this patch leaves it around to
383d26
avoid unnecessary churn. The next patches will get rid of almost all of
383d26
its uses anyway so that it can be removed later with much less churn.
383d26
383d26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
383d26
Reviewed-by: Max Reitz <mreitz@redhat.com>
383d26
Reviewed-by: John Snow <jsnow@redhat.com>
383d26
(cherry picked from commit 33e9e9bd62d9ae00880d9e12ad8a5b7d2c00e8a5)
383d26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 MAINTAINERS                  |  2 ++
383d26
 Makefile.objs                |  2 +-
383d26
 block/backup.c               |  4 ++-
383d26
 block/commit.c               |  4 ++-
383d26
 block/mirror.c               | 10 +++++---
383d26
 block/stream.c               |  4 ++-
383d26
 blockjob.c                   | 46 ++++++++++++++++-----------------
383d26
 include/block/blockjob.h     |  9 +++----
383d26
 include/block/blockjob_int.h |  4 +--
383d26
 include/qemu/job.h           | 60 ++++++++++++++++++++++++++++++++++++++++++++
383d26
 job.c                        | 48 +++++++++++++++++++++++++++++++++++
383d26
 tests/test-bdrv-drain.c      |  4 ++-
383d26
 tests/test-blockjob-txn.c    |  4 ++-
383d26
 tests/test-blockjob.c        | 12 ++++++---
383d26
 14 files changed, 169 insertions(+), 44 deletions(-)
383d26
 create mode 100644 include/qemu/job.h
383d26
 create mode 100644 job.c
383d26
383d26
diff --git a/MAINTAINERS b/MAINTAINERS
383d26
index ad5edc8..c5e3dfb 100644
383d26
--- a/MAINTAINERS
383d26
+++ b/MAINTAINERS
383d26
@@ -1371,6 +1371,8 @@ L: qemu-block@nongnu.org
383d26
 S: Supported
383d26
 F: blockjob.c
383d26
 F: include/block/blockjob.h
383d26
+F: job.c
383d26
+F: include/block/job.h
383d26
 F: block/backup.c
383d26
 F: block/commit.c
383d26
 F: block/stream.c
383d26
diff --git a/Makefile.objs b/Makefile.objs
383d26
index c6c9b8f..92b73fc 100644
383d26
--- a/Makefile.objs
383d26
+++ b/Makefile.objs
383d26
@@ -63,7 +63,7 @@ chardev-obj-y = chardev/
383d26
 # block-obj-y is code used by both qemu system emulation and qemu-img
383d26
 
383d26
 block-obj-y += nbd/
383d26
-block-obj-y += block.o blockjob.o
383d26
+block-obj-y += block.o blockjob.o job.o
383d26
 block-obj-y += block/ scsi/
383d26
 block-obj-y += qemu-io-cmds.o
383d26
 block-obj-$(CONFIG_REPLICATION) += replication.o
383d26
diff --git a/block/backup.c b/block/backup.c
383d26
index e14d995..9e672bb 100644
383d26
--- a/block/backup.c
383d26
+++ b/block/backup.c
383d26
@@ -523,7 +523,9 @@ static void coroutine_fn backup_run(void *opaque)
383d26
 }
383d26
 
383d26
 static const BlockJobDriver backup_job_driver = {
383d26
-    .instance_size          = sizeof(BackupBlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size          = sizeof(BackupBlockJob),
383d26
+    },
383d26
     .job_type               = BLOCK_JOB_TYPE_BACKUP,
383d26
     .start                  = backup_run,
383d26
     .commit                 = backup_commit,
383d26
diff --git a/block/commit.c b/block/commit.c
383d26
index ba5df6a..18cbb2f 100644
383d26
--- a/block/commit.c
383d26
+++ b/block/commit.c
383d26
@@ -215,7 +215,9 @@ out:
383d26
 }
383d26
 
383d26
 static const BlockJobDriver commit_job_driver = {
383d26
-    .instance_size = sizeof(CommitBlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size = sizeof(CommitBlockJob),
383d26
+    },
383d26
     .job_type      = BLOCK_JOB_TYPE_COMMIT,
383d26
     .start         = commit_run,
383d26
 };
383d26
diff --git a/block/mirror.c b/block/mirror.c
383d26
index a4197bb..aa1d6b7 100644
383d26
--- a/block/mirror.c
383d26
+++ b/block/mirror.c
383d26
@@ -913,7 +913,7 @@ static void mirror_complete(BlockJob *job, Error **errp)
383d26
 
383d26
     if (!s->synced) {
383d26
         error_setg(errp, "The active block job '%s' cannot be completed",
383d26
-                   job->id);
383d26
+                   job->job.id);
383d26
         return;
383d26
     }
383d26
 
383d26
@@ -986,7 +986,9 @@ static void mirror_drain(BlockJob *job)
383d26
 }
383d26
 
383d26
 static const BlockJobDriver mirror_job_driver = {
383d26
-    .instance_size          = sizeof(MirrorBlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size          = sizeof(MirrorBlockJob),
383d26
+    },
383d26
     .job_type               = BLOCK_JOB_TYPE_MIRROR,
383d26
     .start                  = mirror_run,
383d26
     .complete               = mirror_complete,
383d26
@@ -996,7 +998,9 @@ static const BlockJobDriver mirror_job_driver = {
383d26
 };
383d26
 
383d26
 static const BlockJobDriver commit_active_job_driver = {
383d26
-    .instance_size          = sizeof(MirrorBlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size          = sizeof(MirrorBlockJob),
383d26
+    },
383d26
     .job_type               = BLOCK_JOB_TYPE_COMMIT,
383d26
     .start                  = mirror_run,
383d26
     .complete               = mirror_complete,
383d26
diff --git a/block/stream.c b/block/stream.c
383d26
index df9660d..f88fc75 100644
383d26
--- a/block/stream.c
383d26
+++ b/block/stream.c
383d26
@@ -209,7 +209,9 @@ out:
383d26
 }
383d26
 
383d26
 static const BlockJobDriver stream_job_driver = {
383d26
-    .instance_size = sizeof(StreamBlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size = sizeof(StreamBlockJob),
383d26
+    },
383d26
     .job_type      = BLOCK_JOB_TYPE_STREAM,
383d26
     .start         = stream_run,
383d26
 };
383d26
diff --git a/blockjob.c b/blockjob.c
383d26
index 112672a..1464856 100644
383d26
--- a/blockjob.c
383d26
+++ b/blockjob.c
383d26
@@ -34,7 +34,6 @@
383d26
 #include "qapi/qapi-events-block-core.h"
383d26
 #include "qapi/qmp/qerror.h"
383d26
 #include "qemu/coroutine.h"
383d26
-#include "qemu/id.h"
383d26
 #include "qemu/timer.h"
383d26
 
383d26
 /* Right now, this mutex is only needed to synchronize accesses to job->busy
383d26
@@ -92,7 +91,8 @@ static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
383d26
         return 0;
383d26
     }
383d26
     error_setg(errp, "Job '%s' in state '%s' cannot accept command verb '%s'",
383d26
-               job->id, BlockJobStatus_str(job->status), BlockJobVerb_str(bv));
383d26
+               job->job.id, BlockJobStatus_str(job->status),
383d26
+               BlockJobVerb_str(bv));
383d26
     return -EPERM;
383d26
 }
383d26
 
383d26
@@ -159,7 +159,7 @@ BlockJob *block_job_get(const char *id)
383d26
     BlockJob *job;
383d26
 
383d26
     QLIST_FOREACH(job, &block_jobs, job_list) {
383d26
-        if (job->id && !strcmp(id, job->id)) {
383d26
+        if (job->job.id && !strcmp(id, job->job.id)) {
383d26
             return job;
383d26
         }
383d26
     }
383d26
@@ -261,7 +261,7 @@ void block_job_unref(BlockJob *job)
383d26
                                         block_job_detach_aio_context, job);
383d26
         blk_unref(job->blk);
383d26
         error_free(job->blocker);
383d26
-        g_free(job->id);
383d26
+        g_free(job->job.id);
383d26
         assert(!timer_pending(&job->sleep_timer));
383d26
         g_free(job);
383d26
     }
383d26
@@ -311,7 +311,7 @@ static char *child_job_get_parent_desc(BdrvChild *c)
383d26
     BlockJob *job = c->opaque;
383d26
     return g_strdup_printf("%s job '%s'",
383d26
                            BlockJobType_str(job->driver->job_type),
383d26
-                           job->id);
383d26
+                           job->job.id);
383d26
 }
383d26
 
383d26
 static void child_job_drained_begin(BdrvChild *c)
383d26
@@ -365,7 +365,7 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
383d26
 
383d26
 bool block_job_is_internal(BlockJob *job)
383d26
 {
383d26
-    return (job->id == NULL);
383d26
+    return (job->job.id == NULL);
383d26
 }
383d26
 
383d26
 static bool block_job_started(BlockJob *job)
383d26
@@ -705,13 +705,13 @@ int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
383d26
 void block_job_complete(BlockJob *job, Error **errp)
383d26
 {
383d26
     /* Should not be reachable via external interface for internal jobs */
383d26
-    assert(job->id);
383d26
+    assert(job->job.id);
383d26
     if (block_job_apply_verb(job, BLOCK_JOB_VERB_COMPLETE, errp)) {
383d26
         return;
383d26
     }
383d26
     if (job->pause_count || job->cancelled || !job->driver->complete) {
383d26
         error_setg(errp, "The active block job '%s' cannot be completed",
383d26
-                   job->id);
383d26
+                   job->job.id);
383d26
         return;
383d26
     }
383d26
 
383d26
@@ -720,7 +720,7 @@ void block_job_complete(BlockJob *job, Error **errp)
383d26
 
383d26
 void block_job_finalize(BlockJob *job, Error **errp)
383d26
 {
383d26
-    assert(job && job->id);
383d26
+    assert(job && job->job.id);
383d26
     if (block_job_apply_verb(job, BLOCK_JOB_VERB_FINALIZE, errp)) {
383d26
         return;
383d26
     }
383d26
@@ -731,7 +731,7 @@ void block_job_dismiss(BlockJob **jobptr, Error **errp)
383d26
 {
383d26
     BlockJob *job = *jobptr;
383d26
     /* similarly to _complete, this is QMP-interface only. */
383d26
-    assert(job->id);
383d26
+    assert(job->job.id);
383d26
     if (block_job_apply_verb(job, BLOCK_JOB_VERB_DISMISS, errp)) {
383d26
         return;
383d26
     }
383d26
@@ -848,7 +848,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
383d26
     }
383d26
     info = g_new0(BlockJobInfo, 1);
383d26
     info->type      = g_strdup(BlockJobType_str(job->driver->job_type));
383d26
-    info->device    = g_strdup(job->id);
383d26
+    info->device    = g_strdup(job->job.id);
383d26
     info->len       = job->len;
383d26
     info->busy      = atomic_read(&job->busy);
383d26
     info->paused    = job->pause_count > 0;
383d26
@@ -879,7 +879,7 @@ static void block_job_event_cancelled(BlockJob *job)
383d26
     }
383d26
 
383d26
     qapi_event_send_block_job_cancelled(job->driver->job_type,
383d26
-                                        job->id,
383d26
+                                        job->job.id,
383d26
                                         job->len,
383d26
                                         job->offset,
383d26
                                         job->speed,
383d26
@@ -893,7 +893,7 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
383d26
     }
383d26
 
383d26
     qapi_event_send_block_job_completed(job->driver->job_type,
383d26
-                                        job->id,
383d26
+                                        job->job.id,
383d26
                                         job->len,
383d26
                                         job->offset,
383d26
                                         job->speed,
383d26
@@ -907,7 +907,7 @@ static int block_job_event_pending(BlockJob *job)
383d26
     block_job_state_transition(job, BLOCK_JOB_STATUS_PENDING);
383d26
     if (!job->auto_finalize && !block_job_is_internal(job)) {
383d26
         qapi_event_send_block_job_pending(job->driver->job_type,
383d26
-                                          job->id,
383d26
+                                          job->job.id,
383d26
                                           &error_abort);
383d26
     }
383d26
     return 0;
383d26
@@ -945,12 +945,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
383d26
             error_setg(errp, "Cannot specify job ID for internal block job");
383d26
             return NULL;
383d26
         }
383d26
-
383d26
-        if (!id_wellformed(job_id)) {
383d26
-            error_setg(errp, "Invalid job ID '%s'", job_id);
383d26
-            return NULL;
383d26
-        }
383d26
-
383d26
         if (block_job_get(job_id)) {
383d26
             error_setg(errp, "Job ID '%s' already in use", job_id);
383d26
             return NULL;
383d26
@@ -964,9 +958,13 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
383d26
         return NULL;
383d26
     }
383d26
 
383d26
-    job = g_malloc0(driver->instance_size);
383d26
+    job = job_create(job_id, &driver->job_driver, errp);
383d26
+    if (job == NULL) {
383d26
+        blk_unref(blk);
383d26
+        return NULL;
383d26
+    }
383d26
+
383d26
     job->driver        = driver;
383d26
-    job->id            = g_strdup(job_id);
383d26
     job->blk           = blk;
383d26
     job->cb            = cb;
383d26
     job->opaque        = opaque;
383d26
@@ -1187,7 +1185,7 @@ void block_job_event_ready(BlockJob *job)
383d26
     }
383d26
 
383d26
     qapi_event_send_block_job_ready(job->driver->job_type,
383d26
-                                    job->id,
383d26
+                                    job->job.id,
383d26
                                     job->len,
383d26
                                     job->offset,
383d26
                                     job->speed, &error_abort);
383d26
@@ -1217,7 +1215,7 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
383d26
         abort();
383d26
     }
383d26
     if (!block_job_is_internal(job)) {
383d26
-        qapi_event_send_block_job_error(job->id,
383d26
+        qapi_event_send_block_job_error(job->job.id,
383d26
                                         is_read ? IO_OPERATION_TYPE_READ :
383d26
                                         IO_OPERATION_TYPE_WRITE,
383d26
                                         action, &error_abort);
383d26
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
383d26
index 0f56f72..640e649 100644
383d26
--- a/include/block/blockjob.h
383d26
+++ b/include/block/blockjob.h
383d26
@@ -26,6 +26,7 @@
383d26
 #ifndef BLOCKJOB_H
383d26
 #define BLOCKJOB_H
383d26
 
383d26
+#include "qemu/job.h"
383d26
 #include "block/block.h"
383d26
 #include "qemu/ratelimit.h"
383d26
 
383d26
@@ -40,6 +41,9 @@ typedef struct BlockJobTxn BlockJobTxn;
383d26
  * Long-running operation on a BlockDriverState.
383d26
  */
383d26
 typedef struct BlockJob {
383d26
+    /** Data belonging to the generic Job infrastructure */
383d26
+    Job job;
383d26
+
383d26
     /** The job type, including the job vtable.  */
383d26
     const BlockJobDriver *driver;
383d26
 
383d26
@@ -47,11 +51,6 @@ typedef struct BlockJob {
383d26
     BlockBackend *blk;
383d26
 
383d26
     /**
383d26
-     * The ID of the block job. May be NULL for internal jobs.
383d26
-     */
383d26
-    char *id;
383d26
-
383d26
-    /**
383d26
      * The coroutine that executes the job.  If not NULL, it is
383d26
      * reentered when busy is false and the job is cancelled.
383d26
      */
383d26
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
383d26
index 62ec964..e8eca44 100644
383d26
--- a/include/block/blockjob_int.h
383d26
+++ b/include/block/blockjob_int.h
383d26
@@ -35,8 +35,8 @@
383d26
  * A class type for block job driver.
383d26
  */
383d26
 struct BlockJobDriver {
383d26
-    /** Derived BlockJob struct size */
383d26
-    size_t instance_size;
383d26
+    /** Generic JobDriver callbacks and settings */
383d26
+    JobDriver job_driver;
383d26
 
383d26
     /** String describing the operation, part of query-block-jobs QMP API */
383d26
     BlockJobType job_type;
383d26
diff --git a/include/qemu/job.h b/include/qemu/job.h
383d26
new file mode 100644
383d26
index 0000000..b4b49f1
383d26
--- /dev/null
383d26
+++ b/include/qemu/job.h
383d26
@@ -0,0 +1,60 @@
383d26
+/*
383d26
+ * Declarations for background jobs
383d26
+ *
383d26
+ * Copyright (c) 2011 IBM Corp.
383d26
+ * Copyright (c) 2012, 2018 Red Hat, Inc.
383d26
+ *
383d26
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
383d26
+ * of this software and associated documentation files (the "Software"), to deal
383d26
+ * in the Software without restriction, including without limitation the rights
383d26
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
383d26
+ * copies of the Software, and to permit persons to whom the Software is
383d26
+ * furnished to do so, subject to the following conditions:
383d26
+ *
383d26
+ * The above copyright notice and this permission notice shall be included in
383d26
+ * all copies or substantial portions of the Software.
383d26
+ *
383d26
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
383d26
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
383d26
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
383d26
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
383d26
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
383d26
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
383d26
+ * THE SOFTWARE.
383d26
+ */
383d26
+
383d26
+#ifndef JOB_H
383d26
+#define JOB_H
383d26
+
383d26
+typedef struct JobDriver JobDriver;
383d26
+
383d26
+/**
383d26
+ * Long-running operation.
383d26
+ */
383d26
+typedef struct Job {
383d26
+    /** The ID of the job. May be NULL for internal jobs. */
383d26
+    char *id;
383d26
+
383d26
+    /** The type of this job. */
383d26
+    const JobDriver *driver;
383d26
+} Job;
383d26
+
383d26
+/**
383d26
+ * Callbacks and other information about a Job driver.
383d26
+ */
383d26
+struct JobDriver {
383d26
+    /** Derived Job struct size */
383d26
+    size_t instance_size;
383d26
+};
383d26
+
383d26
+
383d26
+/**
383d26
+ * Create a new long-running job and return it.
383d26
+ *
383d26
+ * @job_id: The id of the newly-created job, or %NULL for internal jobs
383d26
+ * @driver: The class object for the newly-created job.
383d26
+ * @errp: Error object.
383d26
+ */
383d26
+void *job_create(const char *job_id, const JobDriver *driver, Error **errp);
383d26
+
383d26
+#endif
383d26
diff --git a/job.c b/job.c
383d26
new file mode 100644
383d26
index 0000000..87fd484
383d26
--- /dev/null
383d26
+++ b/job.c
383d26
@@ -0,0 +1,48 @@
383d26
+/*
383d26
+ * Background jobs (long-running operations)
383d26
+ *
383d26
+ * Copyright (c) 2011 IBM Corp.
383d26
+ * Copyright (c) 2012, 2018 Red Hat, Inc.
383d26
+ *
383d26
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
383d26
+ * of this software and associated documentation files (the "Software"), to deal
383d26
+ * in the Software without restriction, including without limitation the rights
383d26
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
383d26
+ * copies of the Software, and to permit persons to whom the Software is
383d26
+ * furnished to do so, subject to the following conditions:
383d26
+ *
383d26
+ * The above copyright notice and this permission notice shall be included in
383d26
+ * all copies or substantial portions of the Software.
383d26
+ *
383d26
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
383d26
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
383d26
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
383d26
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
383d26
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
383d26
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
383d26
+ * THE SOFTWARE.
383d26
+ */
383d26
+
383d26
+#include "qemu/osdep.h"
383d26
+#include "qemu-common.h"
383d26
+#include "qapi/error.h"
383d26
+#include "qemu/job.h"
383d26
+#include "qemu/id.h"
383d26
+
383d26
+void *job_create(const char *job_id, const JobDriver *driver, Error **errp)
383d26
+{
383d26
+    Job *job;
383d26
+
383d26
+    if (job_id) {
383d26
+        if (!id_wellformed(job_id)) {
383d26
+            error_setg(errp, "Invalid job ID '%s'", job_id);
383d26
+            return NULL;
383d26
+        }
383d26
+    }
383d26
+
383d26
+    job = g_malloc0(driver->instance_size);
383d26
+    job->driver        = driver;
383d26
+    job->id            = g_strdup(job_id);
383d26
+
383d26
+    return job;
383d26
+}
383d26
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
383d26
index 7673de1..fe9f412 100644
383d26
--- a/tests/test-bdrv-drain.c
383d26
+++ b/tests/test-bdrv-drain.c
383d26
@@ -520,7 +520,9 @@ static void test_job_complete(BlockJob *job, Error **errp)
383d26
 }
383d26
 
383d26
 BlockJobDriver test_job_driver = {
383d26
-    .instance_size  = sizeof(TestBlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size  = sizeof(TestBlockJob),
383d26
+    },
383d26
     .start          = test_job_start,
383d26
     .complete       = test_job_complete,
383d26
 };
383d26
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
383d26
index 5789893..48b12d1 100644
383d26
--- a/tests/test-blockjob-txn.c
383d26
+++ b/tests/test-blockjob-txn.c
383d26
@@ -74,7 +74,9 @@ static void test_block_job_cb(void *opaque, int ret)
383d26
 }
383d26
 
383d26
 static const BlockJobDriver test_block_job_driver = {
383d26
-    .instance_size = sizeof(TestBlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size = sizeof(TestBlockJob),
383d26
+    },
383d26
     .start = test_block_job_run,
383d26
 };
383d26
 
383d26
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
383d26
index 8946bfd..b820261 100644
383d26
--- a/tests/test-blockjob.c
383d26
+++ b/tests/test-blockjob.c
383d26
@@ -17,7 +17,9 @@
383d26
 #include "sysemu/block-backend.h"
383d26
 
383d26
 static const BlockJobDriver test_block_job_driver = {
383d26
-    .instance_size = sizeof(BlockJob),
383d26
+    .job_driver = {
383d26
+        .instance_size = sizeof(BlockJob),
383d26
+    },
383d26
 };
383d26
 
383d26
 static void block_job_cb(void *opaque, int ret)
383d26
@@ -38,9 +40,9 @@ static BlockJob *mk_job(BlockBackend *blk, const char *id,
383d26
         g_assert_null(errp);
383d26
         g_assert_nonnull(job);
383d26
         if (id) {
383d26
-            g_assert_cmpstr(job->id, ==, id);
383d26
+            g_assert_cmpstr(job->job.id, ==, id);
383d26
         } else {
383d26
-            g_assert_cmpstr(job->id, ==, blk_name(blk));
383d26
+            g_assert_cmpstr(job->job.id, ==, blk_name(blk));
383d26
         }
383d26
     } else {
383d26
         g_assert_nonnull(errp);
383d26
@@ -192,7 +194,9 @@ static void coroutine_fn cancel_job_start(void *opaque)
383d26
 }
383d26
 
383d26
 static const BlockJobDriver test_cancel_driver = {
383d26
-    .instance_size = sizeof(CancelJob),
383d26
+    .job_driver = {
383d26
+        .instance_size = sizeof(CancelJob),
383d26
+    },
383d26
     .start         = cancel_job_start,
383d26
     .complete      = cancel_job_complete,
383d26
 };
383d26
-- 
383d26
1.8.3.1
383d26