26ba25
From dfed24e446a733eeadf0ee85f3ce8aec63b2b3bf Mon Sep 17 00:00:00 2001
26ba25
From: John Snow <jsnow@redhat.com>
26ba25
Date: Tue, 25 Sep 2018 22:34:08 +0100
26ba25
Subject: [PATCH 05/28] jobs: canonize Error object
26ba25
26ba25
RH-Author: John Snow <jsnow@redhat.com>
26ba25
Message-id: <20180925223431.24791-3-jsnow@redhat.com>
26ba25
Patchwork-id: 82262
26ba25
O-Subject: [RHEL8/rhel qemu-kvm PATCH 02/25] jobs: canonize Error object
26ba25
Bugzilla: 1632939
26ba25
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
26ba25
RH-Acked-by: Max Reitz <mreitz@redhat.com>
26ba25
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
26ba25
26ba25
Jobs presently use both an Error object in the case of the create job,
26ba25
and char strings in the case of generic errors elsewhere.
26ba25
26ba25
Unify the two paths as just j->err, and remove the extra argument from
26ba25
job_completed. The integer error code for job_completed is kept for now,
26ba25
to be removed shortly in a separate patch.
26ba25
26ba25
Signed-off-by: John Snow <jsnow@redhat.com>
26ba25
Message-id: 20180830015734.19765-3-jsnow@redhat.com
26ba25
[mreitz: Dropped a superfluous g_strdup()]
26ba25
Reviewed-by: Eric Blake <eblake@redhat.com>
26ba25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26ba25
(cherry picked from commit 3d1f8b07a4c241f81949eff507d9f3a8fd73b87b)
26ba25
Signed-off-by: John Snow <jsnow@redhat.com>
26ba25
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 block/backup.c            |  2 +-
26ba25
 block/commit.c            |  2 +-
26ba25
 block/create.c            |  5 ++---
26ba25
 block/mirror.c            |  2 +-
26ba25
 block/stream.c            |  2 +-
26ba25
 include/qemu/job.h        | 14 ++++++++------
26ba25
 job-qmp.c                 |  5 +++--
26ba25
 job.c                     | 18 ++++++------------
26ba25
 tests/test-bdrv-drain.c   |  2 +-
26ba25
 tests/test-blockjob-txn.c |  2 +-
26ba25
 tests/test-blockjob.c     |  2 +-
26ba25
 11 files changed, 26 insertions(+), 30 deletions(-)
26ba25
26ba25
diff --git a/block/backup.c b/block/backup.c
26ba25
index a142518..a5bf699 100644
26ba25
--- a/block/backup.c
26ba25
+++ b/block/backup.c
26ba25
@@ -388,7 +388,7 @@ static void backup_complete(Job *job, void *opaque)
26ba25
 {
26ba25
     BackupCompleteData *data = opaque;
26ba25
 
26ba25
-    job_completed(job, data->ret, NULL);
26ba25
+    job_completed(job, data->ret);
26ba25
     g_free(data);
26ba25
 }
26ba25
 
26ba25
diff --git a/block/commit.c b/block/commit.c
26ba25
index 905a1c5..af7579d 100644
26ba25
--- a/block/commit.c
26ba25
+++ b/block/commit.c
26ba25
@@ -117,7 +117,7 @@ static void commit_complete(Job *job, void *opaque)
26ba25
      * bdrv_set_backing_hd() to fail. */
26ba25
     block_job_remove_all_bdrv(bjob);
26ba25
 
26ba25
-    job_completed(job, ret, NULL);
26ba25
+    job_completed(job, ret);
26ba25
     g_free(data);
26ba25
 
26ba25
     /* If bdrv_drop_intermediate() didn't already do that, remove the commit
26ba25
diff --git a/block/create.c b/block/create.c
26ba25
index 04733c3..26a385c 100644
26ba25
--- a/block/create.c
26ba25
+++ b/block/create.c
26ba25
@@ -35,14 +35,13 @@ typedef struct BlockdevCreateJob {
26ba25
     BlockDriver *drv;
26ba25
     BlockdevCreateOptions *opts;
26ba25
     int ret;
26ba25
-    Error *err;
26ba25
 } BlockdevCreateJob;
26ba25
 
26ba25
 static void blockdev_create_complete(Job *job, void *opaque)
26ba25
 {
26ba25
     BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
26ba25
 
26ba25
-    job_completed(job, s->ret, s->err);
26ba25
+    job_completed(job, s->ret);
26ba25
 }
26ba25
 
26ba25
 static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
26ba25
@@ -50,7 +49,7 @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
26ba25
     BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
26ba25
 
26ba25
     job_progress_set_remaining(&s->common, 1);
26ba25
-    s->ret = s->drv->bdrv_co_create(s->opts, &s->err);
26ba25
+    s->ret = s->drv->bdrv_co_create(s->opts, errp);
26ba25
     job_progress_update(&s->common, 1);
26ba25
 
26ba25
     qapi_free_BlockdevCreateOptions(s->opts);
26ba25
diff --git a/block/mirror.c b/block/mirror.c
26ba25
index 89a92c2..3c330ee 100644
26ba25
--- a/block/mirror.c
26ba25
+++ b/block/mirror.c
26ba25
@@ -581,7 +581,7 @@ static void mirror_exit(Job *job, void *opaque)
26ba25
     blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
26ba25
     blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort);
26ba25
 
26ba25
-    job_completed(job, data->ret, NULL);
26ba25
+    job_completed(job, data->ret);
26ba25
 
26ba25
     g_free(data);
26ba25
     bdrv_drained_end(src);
26ba25
diff --git a/block/stream.c b/block/stream.c
26ba25
index b4b987d..26a7753 100644
26ba25
--- a/block/stream.c
26ba25
+++ b/block/stream.c
26ba25
@@ -93,7 +93,7 @@ out:
26ba25
     }
26ba25
 
26ba25
     g_free(s->backing_file_str);
26ba25
-    job_completed(job, data->ret, NULL);
26ba25
+    job_completed(job, data->ret);
26ba25
     g_free(data);
26ba25
 }
26ba25
 
26ba25
diff --git a/include/qemu/job.h b/include/qemu/job.h
26ba25
index e81cc34..905dfdd 100644
26ba25
--- a/include/qemu/job.h
26ba25
+++ b/include/qemu/job.h
26ba25
@@ -124,12 +124,16 @@ typedef struct Job {
26ba25
     /** Estimated progress_current value at the completion of the job */
26ba25
     int64_t progress_total;
26ba25
 
26ba25
-    /** Error string for a failed job (NULL if, and only if, job->ret == 0) */
26ba25
-    char *error;
26ba25
-
26ba25
     /** ret code passed to job_completed. */
26ba25
     int ret;
26ba25
 
26ba25
+    /**
26ba25
+     * Error object for a failed job.
26ba25
+     * If job->ret is nonzero and an error object was not set, it will be set
26ba25
+     * to strerror(-job->ret) during job_completed.
26ba25
+     */
26ba25
+    Error *err;
26ba25
+
26ba25
     /** The completion function that will be called when the job completes.  */
26ba25
     BlockCompletionFunc *cb;
26ba25
 
26ba25
@@ -469,15 +473,13 @@ void job_transition_to_ready(Job *job);
26ba25
 /**
26ba25
  * @job: The job being completed.
26ba25
  * @ret: The status code.
26ba25
- * @error: The error message for a failing job (only with @ret < 0). If @ret is
26ba25
- *         negative, but NULL is given for @error, strerror() is used.
26ba25
  *
26ba25
  * Marks @job as completed. If @ret is non-zero, the job transaction it is part
26ba25
  * of is aborted. If @ret is zero, the job moves into the WAITING state. If it
26ba25
  * is the last job to complete in its transaction, all jobs in the transaction
26ba25
  * move from WAITING to PENDING.
26ba25
  */
26ba25
-void job_completed(Job *job, int ret, Error *error);
26ba25
+void job_completed(Job *job, int ret);
26ba25
 
26ba25
 /** Asynchronously complete the specified @job. */
26ba25
 void job_complete(Job *job, Error **errp);
26ba25
diff --git a/job-qmp.c b/job-qmp.c
26ba25
index 410775d..a969b2b 100644
26ba25
--- a/job-qmp.c
26ba25
+++ b/job-qmp.c
26ba25
@@ -146,8 +146,9 @@ static JobInfo *job_query_single(Job *job, Error **errp)
26ba25
         .status             = job->status,
26ba25
         .current_progress   = job->progress_current,
26ba25
         .total_progress     = job->progress_total,
26ba25
-        .has_error          = !!job->error,
26ba25
-        .error              = g_strdup(job->error),
26ba25
+        .has_error          = !!job->err,
26ba25
+        .error              = job->err ? \
26ba25
+                              g_strdup(error_get_pretty(job->err)) : NULL,
26ba25
     };
26ba25
 
26ba25
     return info;
26ba25
diff --git a/job.c b/job.c
26ba25
index d4e3041..17b4fad 100644
26ba25
--- a/job.c
26ba25
+++ b/job.c
26ba25
@@ -369,7 +369,7 @@ void job_unref(Job *job)
26ba25
 
26ba25
         QLIST_REMOVE(job, job_list);
26ba25
 
26ba25
-        g_free(job->error);
26ba25
+        error_free(job->err);
26ba25
         g_free(job->id);
26ba25
         g_free(job);
26ba25
     }
26ba25
@@ -541,7 +541,7 @@ static void coroutine_fn job_co_entry(void *opaque)
26ba25
 
26ba25
     assert(job && job->driver && job->driver->run);
26ba25
     job_pause_point(job);
26ba25
-    job->ret = job->driver->run(job, NULL);
26ba25
+    job->ret = job->driver->run(job, &job->err);
26ba25
 }
26ba25
 
26ba25
 
26ba25
@@ -661,8 +661,8 @@ static void job_update_rc(Job *job)
26ba25
         job->ret = -ECANCELED;
26ba25
     }
26ba25
     if (job->ret) {
26ba25
-        if (!job->error) {
26ba25
-            job->error = g_strdup(strerror(-job->ret));
26ba25
+        if (!job->err) {
26ba25
+            error_setg(&job->err, "%s", strerror(-job->ret));
26ba25
         }
26ba25
         job_state_transition(job, JOB_STATUS_ABORTING);
26ba25
     }
26ba25
@@ -860,17 +860,11 @@ static void job_completed_txn_success(Job *job)
26ba25
     }
26ba25
 }
26ba25
 
26ba25
-void job_completed(Job *job, int ret, Error *error)
26ba25
+void job_completed(Job *job, int ret)
26ba25
 {
26ba25
     assert(job && job->txn && !job_is_completed(job));
26ba25
 
26ba25
     job->ret = ret;
26ba25
-    if (error) {
26ba25
-        assert(job->ret < 0);
26ba25
-        job->error = g_strdup(error_get_pretty(error));
26ba25
-        error_free(error);
26ba25
-    }
26ba25
-
26ba25
     job_update_rc(job);
26ba25
     trace_job_completed(job, ret, job->ret);
26ba25
     if (job->ret) {
26ba25
@@ -888,7 +882,7 @@ void job_cancel(Job *job, bool force)
26ba25
     }
26ba25
     job_cancel_async(job, force);
26ba25
     if (!job_started(job)) {
26ba25
-        job_completed(job, -ECANCELED, NULL);
26ba25
+        job_completed(job, -ECANCELED);
26ba25
     } else if (job->deferred_to_main_loop) {
26ba25
         job_completed_txn_abort(job);
26ba25
     } else {
26ba25
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
26ba25
index 798445a..8937894 100644
26ba25
--- a/tests/test-bdrv-drain.c
26ba25
+++ b/tests/test-bdrv-drain.c
26ba25
@@ -498,7 +498,7 @@ typedef struct TestBlockJob {
26ba25
 
26ba25
 static void test_job_completed(Job *job, void *opaque)
26ba25
 {
26ba25
-    job_completed(job, 0, NULL);
26ba25
+    job_completed(job, 0);
26ba25
 }
26ba25
 
26ba25
 static int coroutine_fn test_job_run(Job *job, Error **errp)
26ba25
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
26ba25
index 3194924..82cedee 100644
26ba25
--- a/tests/test-blockjob-txn.c
26ba25
+++ b/tests/test-blockjob-txn.c
26ba25
@@ -34,7 +34,7 @@ static void test_block_job_complete(Job *job, void *opaque)
26ba25
         rc = -ECANCELED;
26ba25
     }
26ba25
 
26ba25
-    job_completed(job, rc, NULL);
26ba25
+    job_completed(job, rc);
26ba25
     bdrv_unref(bs);
26ba25
 }
26ba25
 
26ba25
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
26ba25
index b0462bf..408a226 100644
26ba25
--- a/tests/test-blockjob.c
26ba25
+++ b/tests/test-blockjob.c
26ba25
@@ -167,7 +167,7 @@ static void cancel_job_completed(Job *job, void *opaque)
26ba25
 {
26ba25
     CancelJob *s = opaque;
26ba25
     s->completed = true;
26ba25
-    job_completed(job, 0, NULL);
26ba25
+    job_completed(job, 0);
26ba25
 }
26ba25
 
26ba25
 static void cancel_job_complete(Job *job, Error **errp)
26ba25
-- 
26ba25
1.8.3.1
26ba25