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