diff mbox series

[v5,29/31] jobs: introduce pre_run function in JobDriver

Message ID 20211124064418.3120601-30-eesposit@redhat.com
State New
Headers show
Series block layer: split block APIs in global state and I/O | expand

Commit Message

Emanuele Giuseppe Esposito Nov. 24, 2021, 6:44 a.m. UTC
.pre_run takes care of doing some initial job setup just before
the job is run inside the coroutine. Doing so can be useful
to invoke GS functions that require the BQL held.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 include/qemu/job.h |  9 +++++++++
 job.c              | 13 +++++++++++++
 2 files changed, 22 insertions(+)
diff mbox series

Patch

diff --git a/include/qemu/job.h b/include/qemu/job.h
index 4ea7a4a0cd..915ceff425 100644
--- a/include/qemu/job.h
+++ b/include/qemu/job.h
@@ -223,6 +223,15 @@  struct JobDriver {
      * the GS API.
      */
 
+    /**
+     * Called in the Main Loop context, before the job coroutine
+     * is started in the job aiocontext. Useful to perform operations
+     * that needs to be done under BQL (like permissions setup).
+     * On success, it returns 0. Otherwise the job failed to initialize
+     * and won't start.
+     */
+    int (*pre_run)(Job *job, Error **errp);
+
     /**
      * Called when the job is resumed by the user (i.e. user_paused becomes
      * false). .user_resume is called before .resume.
diff --git a/job.c b/job.c
index bb57ec6887..e048037099 100644
--- a/job.c
+++ b/job.c
@@ -967,11 +967,24 @@  static void coroutine_fn job_co_entry(void *opaque)
     aio_bh_schedule_oneshot(qemu_get_aio_context(), job_exit, job);
 }
 
+static int job_pre_run(Job *job)
+{
+    assert(qemu_in_main_thread());
+    if (job->driver->pre_run) {
+        return job->driver->pre_run(job, &job->err);
+    }
+
+    return 0;
+}
+
 void job_start(Job *job)
 {
     assert(job && !job_started(job) && job->paused &&
            job->driver && job->driver->run);
     job->co = qemu_coroutine_create(job_co_entry, job);
+    if (job_pre_run(job)) {
+        return;
+    }
     job->pause_count--;
     job->busy = true;
     job->paused = false;