All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
@ 2018-02-23 23:51 John Snow
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick John Snow
                   ` (23 more replies)
  0 siblings, 24 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

This series seeks to address two distinct but closely related issues
concerning the job management API.

(1) For jobs that complete when a monitor is not attached and receiving
    events or notifications, there's no way to discern the job's final
    return code. Jobs must remain in the query list until dismissed
    for reliable management.

(2) Jobs that change the block graph structure at an indeterminate point
    after the job starts compete with the management layer that relies
    on that graph structure to issue meaningful commands.

    This structure should change only at the behest of the management
    API, and not asynchronously at unknown points in time. Before a job
    issues such changes, it must rely on explicit and synchronous
    confirmation from the management API.

This series is a rough sketch that solves these problems by adding three
new distinct job states, and two new job command verbs.

These changes are implemented by formalizing a State Transition Machine
for the BlockJob subsystem.

Job States:

UNDEFINED       Default state. Internal state only.
CREATED         Job has been created
RUNNING         Job has been started and is running
PAUSED          Job is not ready and has been paused
READY           Job is ready and is running
STANDBY         Job is ready and is paused

WAITING         Job is waiting on peers in transaction
PENDING         Job is waiting on ACK from QMP
ABORTING        Job is aborting or has been cancelled
CONCLUDED       Job has finished and has a retcode available
NULL            Job is being dismantled. Internal state only.

Job Verbs:

CANCEL          Instructs a running job to terminate with error,
                (Except when that job is READY, which produces no error.)
PAUSE           Request a job to pause.
RESUME          Request a job to resume from a pause.
SET-SPEED       Change the speed limiting parameter of a job.
COMPLETE        Ask a READY job to finish and exit.

FINALIZE        Ask a PENDING job to perform its graph finalization.
DISMISS         Finish cleaning up an empty job.

And here's my stab at a diagram:

                 +---------+
                 |UNDEFINED|
                 +--+------+
                    |
                 +--v----+
                 |CREATED+-----------------+
                 +--+----+                 |
                    |                      |
                 +--+----+     +------+    |
       +---------+RUNNING<----->PAUSED|    |
       |         +--+-+--+     +------+    |
       |            | |                    |
       |            | +------------------+ |
       |            |                    | |
       |         +--v--+       +-------+ | |
       +---------+READY<------->STANDBY| | |
       |         +--+--+       +-------+ | |
       |            |                    | |
       |         +--v----+               | |
       +---------+WAITING+---------------+ |
       |         +--+----+                 |
       |            |                      |
       |         +--v----+                 |
       +---------+PENDING|                 |
       |         +--+----+                 |
       |            |                      |
    +--v-----+   +--v------+               |
    |ABORTING+--->CONCLUDED|               |
    +--------+   +--+------+               |
                    |                      |
                 +--v-+                    |
                 |NULL+--------------------+
                 +----+

V4:
 - All jobs are now transactions.
 - All jobs now transition through states in a uniform way.
 - Verb permissions are now enforced.

V3:
 - Added WAITING and PENDING events
 - Added block_job_finalize verb
 - Added .pending() callback for jobs
 - Tweaked how .commit/.abort work

V2:
 - Added tests!
 - Changed property name (Jeff, Paolo)

RFC / Known problems:
- I need a lot more tests, still...

- STANDBY is a dumb name, and maybe not even really needed or wanted.
  However, a Paused job will return to either READY or RUNNING depending on
  the state it was in when it was PAUSED. We can keep that in an internal
  variable, or we can make it explicit in the STM.

- is "manual" descriptive as a property name?
  Kevin conceives of the new workflow as
  "No automatic transitions, please." (i.e. automatic-transitions: False)
  Whereas I think of it more like:
  "Enable manual workflow mode, please." (manual-transitions: True)

  I like the idea of the new property defaulting to false and have coded
  in a way mindful of that.

- Mirror needs to be refactored to use the commit/abort/pending/clean callbacks
  to fulfill the promise made by "no graph changes without user authorization"
  that PENDING is supposed to offer

________________________________________________________________________________

For convenience, this branch is available at:
https://github.com/jnsnow/qemu.git branch block-job-reap
https://github.com/jnsnow/qemu/tree/block-job-reap

This version is tagged block-job-reap-v4:
https://github.com/jnsnow/qemu/releases/tag/block-job-reap-v4

John Snow (21):
  blockjobs: fix set-speed kick
  blockjobs: model single jobs as transactions
  blockjobs: add manual property
  blockjobs: add status enum
  blockjobs: add state transition table
  iotests: add pause_wait
  blockjobs: add block_job_verb permission table
  blockjobs: add ABORTING state
  blockjobs: add CONCLUDED state
  blockjobs: add NULL state
  blockjobs: add block_job_dismiss
  blockjobs: ensure abort is called for cancelled jobs
  blockjobs: add commit, abort, clean helpers
  blockjobs: add block_job_txn_apply function
  blockjobs: add prepare callback
  blockjobs: add waiting status
  blockjobs: add PENDING status and event
  blockjobs: add block-job-finalize
  blockjobs: Expose manual property
  iotests: test manual job dismissal
  blockjobs: add manual_mgmt option to transactions

 block/backup.c                |   5 +-
 block/commit.c                |   2 +-
 block/mirror.c                |   2 +-
 block/stream.c                |   2 +-
 block/trace-events            |   7 +
 blockdev.c                    |  64 ++++++--
 blockjob.c                    | 355 +++++++++++++++++++++++++++++++++++++-----
 include/block/blockjob.h      |  57 ++++++-
 include/block/blockjob_int.h  |  17 +-
 qapi/block-core.json          | 193 ++++++++++++++++++++++-
 qapi/transaction.json         |   3 +-
 tests/qemu-iotests/030        |   6 +-
 tests/qemu-iotests/055        |  17 +-
 tests/qemu-iotests/056        | 195 +++++++++++++++++++++++
 tests/qemu-iotests/056.out    |   4 +-
 tests/qemu-iotests/109.out    |  24 +--
 tests/qemu-iotests/iotests.py |  12 +-
 tests/test-bdrv-drain.c       |   5 +-
 tests/test-blockjob-txn.c     |  25 ++-
 tests/test-blockjob.c         |   2 +-
 20 files changed, 877 insertions(+), 120 deletions(-)

-- 
2.14.3

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 16:32   ` Eric Blake
  2018-02-27 17:18   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions John Snow
                   ` (22 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

If speed is '0' it's not actually "less than" the previous speed.
Kick the job in this case too.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/blockjob.c b/blockjob.c
index 3f52f29f75..24833ef30f 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -499,7 +499,7 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
     }
 
     job->speed = speed;
-    if (speed <= old_speed) {
+    if (speed && speed <= old_speed) {
         return;
     }
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 16:36   ` Eric Blake
  2018-02-27 17:18   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property John Snow
                   ` (21 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

model all independent jobs as single job transactions.

It's one less case we have to worry about when we add more states to the
transition machine. This way, we can just treat all job lifetimes exactly
the same. This helps tighten assertions of the STM graph and removes some
conditionals that would have been needed in the coming commits adding a
more explicit job lifetime management API.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 block/backup.c               |  3 +--
 block/commit.c               |  2 +-
 block/mirror.c               |  2 +-
 block/stream.c               |  2 +-
 blockjob.c                   | 25 ++++++++++++++++---------
 include/block/blockjob_int.h |  3 ++-
 tests/test-bdrv-drain.c      |  4 ++--
 tests/test-blockjob-txn.c    | 19 +++++++------------
 tests/test-blockjob.c        |  2 +-
 9 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 4a16a37229..7e254dabff 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -621,7 +621,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
     }
 
     /* job->common.len is fixed, so we can't allow resize */
-    job = block_job_create(job_id, &backup_job_driver, bs,
+    job = block_job_create(job_id, &backup_job_driver, txn, bs,
                            BLK_PERM_CONSISTENT_READ,
                            BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
                            BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD,
@@ -677,7 +677,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
     block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
                        &error_abort);
     job->common.len = len;
-    block_job_txn_add_job(txn, &job->common);
 
     return &job->common;
 
diff --git a/block/commit.c b/block/commit.c
index bb6c904704..9682158ee7 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -289,7 +289,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
         return;
     }
 
-    s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,
+    s = block_job_create(job_id, &commit_job_driver, NULL, bs, 0, BLK_PERM_ALL,
                          speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
     if (!s) {
         return;
diff --git a/block/mirror.c b/block/mirror.c
index c9badc1203..6bab7cfdd8 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1166,7 +1166,7 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
     }
 
     /* Make sure that the source is not resized while the job is running */
-    s = block_job_create(job_id, driver, mirror_top_bs,
+    s = block_job_create(job_id, driver, NULL, mirror_top_bs,
                          BLK_PERM_CONSISTENT_READ,
                          BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
                          BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD, speed,
diff --git a/block/stream.c b/block/stream.c
index 499cdacdb0..f3b53f49e2 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -244,7 +244,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
     /* Prevent concurrent jobs trying to modify the graph structure here, we
      * already have our own plans. Also don't allow resize as the image size is
      * queried only at the job start and then cached. */
-    s = block_job_create(job_id, &stream_job_driver, bs,
+    s = block_job_create(job_id, &stream_job_driver, NULL, bs,
                          BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
                          BLK_PERM_GRAPH_MOD,
                          BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
diff --git a/blockjob.c b/blockjob.c
index 24833ef30f..7ba3683ee3 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -357,10 +357,8 @@ static void block_job_completed_single(BlockJob *job)
         }
     }
 
-    if (job->txn) {
-        QLIST_REMOVE(job, txn_list);
-        block_job_txn_unref(job->txn);
-    }
+    QLIST_REMOVE(job, txn_list);
+    block_job_txn_unref(job->txn);
     block_job_unref(job);
 }
 
@@ -647,7 +645,7 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
  */
 
 void *block_job_create(const char *job_id, const BlockJobDriver *driver,
-                       BlockDriverState *bs, uint64_t perm,
+                       BlockJobTxn *txn, BlockDriverState *bs, uint64_t perm,
                        uint64_t shared_perm, int64_t speed, int flags,
                        BlockCompletionFunc *cb, void *opaque, Error **errp)
 {
@@ -729,6 +727,17 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
             return NULL;
         }
     }
+
+    /* Single jobs are modeled as single-job transactions for sake of
+     * consolidating the job management logic */
+    if (!txn) {
+        txn = block_job_txn_new();
+        block_job_txn_add_job(txn, job);
+        block_job_txn_unref(txn);
+    } else {
+        block_job_txn_add_job(txn, job);
+    }
+
     return job;
 }
 
@@ -752,13 +761,11 @@ void block_job_early_fail(BlockJob *job)
 
 void block_job_completed(BlockJob *job, int ret)
 {
+    assert(job && job->txn && !job->completed);
     assert(blk_bs(job->blk)->job == job);
-    assert(!job->completed);
     job->completed = true;
     job->ret = ret;
-    if (!job->txn) {
-        block_job_completed_single(job);
-    } else if (ret < 0 || block_job_is_cancelled(job)) {
+    if (ret < 0 || block_job_is_cancelled(job)) {
         block_job_completed_txn_abort(job);
     } else {
         block_job_completed_txn_success(job);
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index c9b23b0cc9..becaae74c2 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -115,6 +115,7 @@ struct BlockJobDriver {
  * @job_id: The id of the newly-created job, or %NULL to have one
  * generated automatically.
  * @job_type: The class object for the newly-created job.
+ * @txn: The transaction this job belongs to, if any. %NULL otherwise.
  * @bs: The block
  * @perm, @shared_perm: Permissions to request for @bs
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
@@ -132,7 +133,7 @@ struct BlockJobDriver {
  * called from a wrapper that is specific to the job type.
  */
 void *block_job_create(const char *job_id, const BlockJobDriver *driver,
-                       BlockDriverState *bs, uint64_t perm,
+                       BlockJobTxn *txn, BlockDriverState *bs, uint64_t perm,
                        uint64_t shared_perm, int64_t speed, int flags,
                        BlockCompletionFunc *cb, void *opaque, Error **errp);
 
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
index d760e2b243..a7eecf1c1e 100644
--- a/tests/test-bdrv-drain.c
+++ b/tests/test-bdrv-drain.c
@@ -541,8 +541,8 @@ static void test_blockjob_common(enum drain_type drain_type)
     blk_target = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
     blk_insert_bs(blk_target, target, &error_abort);
 
-    job = block_job_create("job0", &test_job_driver, src, 0, BLK_PERM_ALL, 0,
-                           0, NULL, NULL, &error_abort);
+    job = block_job_create("job0", &test_job_driver, NULL, src, 0, BLK_PERM_ALL,
+                           0, 0, NULL, NULL, &error_abort);
     block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort);
     block_job_start(job);
 
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
index 3591c9617f..34f09ef8c1 100644
--- a/tests/test-blockjob-txn.c
+++ b/tests/test-blockjob-txn.c
@@ -87,7 +87,7 @@ static const BlockJobDriver test_block_job_driver = {
  */
 static BlockJob *test_block_job_start(unsigned int iterations,
                                       bool use_timer,
-                                      int rc, int *result)
+                                      int rc, int *result, BlockJobTxn *txn)
 {
     BlockDriverState *bs;
     TestBlockJob *s;
@@ -101,7 +101,7 @@ static BlockJob *test_block_job_start(unsigned int iterations,
     g_assert_nonnull(bs);
 
     snprintf(job_id, sizeof(job_id), "job%u", counter++);
-    s = block_job_create(job_id, &test_block_job_driver, bs,
+    s = block_job_create(job_id, &test_block_job_driver, txn, bs,
                          0, BLK_PERM_ALL, 0, BLOCK_JOB_DEFAULT,
                          test_block_job_cb, data, &error_abort);
     s->iterations = iterations;
@@ -120,8 +120,7 @@ static void test_single_job(int expected)
     int result = -EINPROGRESS;
 
     txn = block_job_txn_new();
-    job = test_block_job_start(1, true, expected, &result);
-    block_job_txn_add_job(txn, job);
+    job = test_block_job_start(1, true, expected, &result, txn);
     block_job_start(job);
 
     if (expected == -ECANCELED) {
@@ -160,10 +159,8 @@ static void test_pair_jobs(int expected1, int expected2)
     int result2 = -EINPROGRESS;
 
     txn = block_job_txn_new();
-    job1 = test_block_job_start(1, true, expected1, &result1);
-    block_job_txn_add_job(txn, job1);
-    job2 = test_block_job_start(2, true, expected2, &result2);
-    block_job_txn_add_job(txn, job2);
+    job1 = test_block_job_start(1, true, expected1, &result1, txn);
+    job2 = test_block_job_start(2, true, expected2, &result2, txn);
     block_job_start(job1);
     block_job_start(job2);
 
@@ -224,10 +221,8 @@ static void test_pair_jobs_fail_cancel_race(void)
     int result2 = -EINPROGRESS;
 
     txn = block_job_txn_new();
-    job1 = test_block_job_start(1, true, -ECANCELED, &result1);
-    block_job_txn_add_job(txn, job1);
-    job2 = test_block_job_start(2, false, 0, &result2);
-    block_job_txn_add_job(txn, job2);
+    job1 = test_block_job_start(1, true, -ECANCELED, &result1, txn);
+    job2 = test_block_job_start(2, false, 0, &result2, txn);
     block_job_start(job1);
     block_job_start(job2);
 
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
index 23bdf1a932..599e28d732 100644
--- a/tests/test-blockjob.c
+++ b/tests/test-blockjob.c
@@ -30,7 +30,7 @@ static BlockJob *do_test_id(BlockBackend *blk, const char *id,
     BlockJob *job;
     Error *errp = NULL;
 
-    job = block_job_create(id, &test_block_job_driver, blk_bs(blk),
+    job = block_job_create(id, &test_block_job_driver, NULL, blk_bs(blk),
                            0, BLK_PERM_ALL, 0, BLOCK_JOB_DEFAULT, block_job_cb,
                            NULL, &errp);
     if (should_succeed) {
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick John Snow
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 16:39   ` Eric Blake
  2018-02-27 17:18   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum John Snow
                   ` (20 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

This property will be used to opt-in to the new BlockJobs workflow
that allows a tighter, more explicit control over transitions from
one runstate to another.

While we're here, fix up the documentation for block_job_create
a little bit.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c                   |  1 +
 include/block/blockjob.h     | 10 ++++++++++
 include/block/blockjob_int.h |  4 +++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/blockjob.c b/blockjob.c
index 7ba3683ee3..47468331ec 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -700,6 +700,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
     job->paused        = true;
     job->pause_count   = 1;
     job->refcnt        = 1;
+    job->manual        = (flags & BLOCK_JOB_MANUAL);
     aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
                    QEMU_CLOCK_REALTIME, SCALE_NS,
                    block_job_sleep_timer_cb, job);
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 00403d9482..8ffabdcbc4 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -141,14 +141,24 @@ typedef struct BlockJob {
      */
     QEMUTimer sleep_timer;
 
+    /**
+     * Set to true when the management API has requested manual job
+     * management semantics.
+     */
+    bool manual;
+
     /** Non-NULL if this job is part of a transaction */
     BlockJobTxn *txn;
     QLIST_ENTRY(BlockJob) txn_list;
 } BlockJob;
 
 typedef enum BlockJobCreateFlags {
+    /* Default behavior */
     BLOCK_JOB_DEFAULT = 0x00,
+    /* BlockJob is not QMP-created and should not send QMP events */
     BLOCK_JOB_INTERNAL = 0x01,
+    /* BlockJob requests manual job management steps. */
+    BLOCK_JOB_MANUAL = 0x02,
 } BlockJobCreateFlags;
 
 /**
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index becaae74c2..259d49b32a 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -114,11 +114,13 @@ struct BlockJobDriver {
  * block_job_create:
  * @job_id: The id of the newly-created job, or %NULL to have one
  * generated automatically.
- * @job_type: The class object for the newly-created job.
+ * @driver: The class object for the newly-created job.
  * @txn: The transaction this job belongs to, if any. %NULL otherwise.
  * @bs: The block
  * @perm, @shared_perm: Permissions to request for @bs
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
+ * @flags: Creation flags for the Block Job.
+ *         See @BlockJobCreateFlags
  * @cb: Completion function for the job.
  * @opaque: Opaque pointer value passed to @cb.
  * @errp: Error object.
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (2 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 16:44   ` Eric Blake
  2018-02-27 17:19   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table John Snow
                   ` (19 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

We're about to add several new states, and booleans are becoming
unwieldly and difficult to reason about. It would help to have a
more explicit bookkeeping of the state of blockjobs. To this end,
add a new "status" field and add our existing states in a redundant
manner alongside the bools they are replacing:

UNDEFINED: Placeholder, default state. Not currently visible to QMP
           unless changes occur in the future to allow creating jobs
           without starting them via QMP.
CREATED:   replaces !!job->co && paused && !busy
RUNNING:   replaces effectively (!paused && busy)
PAUSED:    Nearly redundant with info->paused, which shows pause_count.
           This reports the actual status of the job, which almost always
           matches the paused request status. It differs in that it is
           strictly only true when the job has actually gone dormant.
READY:     replaces job->ready.
STANDBY:   Paused, but job->ready is true.

New state additions in coming commits will not be quite so redundant:

WAITING:   Waiting on transaction. This job has finished all the work
           it can until the transaction converges, fails, or is canceled.
PENDING:   Pending authorization from user. This job has finished all the
           work it can until the job or transaction is finalized via
           block_job_finalize. This implies the transaction has converged
           and left the WAITING phase.
ABORTING:  Job has encountered an error condition and is in the process
           of aborting.
CONCLUDED: Job has ceased all operations and has a return code available
           for query and may be dismissed via block_job_dismiss.
NULL:      Job has been dismissed and (should) be destroyed. Should never
           be visible to QMP.

Some of these states appear somewhat superfluous, but it helps define the
expected flow of a job; so some of the states wind up being synchronous
empty transitions. Importantly, jobs can be in only one of these states
at any given time, which helps code and external users alike reason about
the current condition of a job unambiguously.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c                 |  9 +++++++++
 include/block/blockjob.h   |  7 +++++--
 qapi/block-core.json       | 31 ++++++++++++++++++++++++++++++-
 tests/qemu-iotests/109.out | 24 ++++++++++++------------
 4 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 47468331ec..1be9c20cff 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -320,6 +320,7 @@ void block_job_start(BlockJob *job)
     job->pause_count--;
     job->busy = true;
     job->paused = false;
+    job->status = BLOCK_JOB_STATUS_RUNNING;
     bdrv_coroutine_enter(blk_bs(job->blk), job->co);
 }
 
@@ -598,6 +599,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
     info->speed     = job->speed;
     info->io_status = job->iostatus;
     info->ready     = job->ready;
+    info->status    = job->status;
     return info;
 }
 
@@ -701,6 +703,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
     job->pause_count   = 1;
     job->refcnt        = 1;
     job->manual        = (flags & BLOCK_JOB_MANUAL);
+    job->status        = BLOCK_JOB_STATUS_CREATED;
     aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
                    QEMU_CLOCK_REALTIME, SCALE_NS,
                    block_job_sleep_timer_cb, job);
@@ -814,9 +817,14 @@ void coroutine_fn block_job_pause_point(BlockJob *job)
     }
 
     if (block_job_should_pause(job) && !block_job_is_cancelled(job)) {
+        BlockJobStatus status = job->status;
+        job->status = status == BLOCK_JOB_STATUS_READY ? \
+                                BLOCK_JOB_STATUS_STANDBY : \
+                                BLOCK_JOB_STATUS_PAUSED;
         job->paused = true;
         block_job_do_yield(job, -1);
         job->paused = false;
+        job->status = status;
     }
 
     if (job->driver->resume) {
@@ -922,6 +930,7 @@ void block_job_iostatus_reset(BlockJob *job)
 
 void block_job_event_ready(BlockJob *job)
 {
+    job->status = BLOCK_JOB_STATUS_READY;
     job->ready = true;
 
     if (block_job_is_internal(job)) {
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 8ffabdcbc4..e254359d6b 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -143,10 +143,13 @@ typedef struct BlockJob {
 
     /**
      * Set to true when the management API has requested manual job
-     * management semantics.
+     * management semantics. See @BlockJobStatus for details.
      */
     bool manual;
 
+    /** Current state; See @BlockJobStatus for details. */
+    BlockJobStatus status;
+
     /** Non-NULL if this job is part of a transaction */
     BlockJobTxn *txn;
     QLIST_ENTRY(BlockJob) txn_list;
@@ -157,7 +160,7 @@ typedef enum BlockJobCreateFlags {
     BLOCK_JOB_DEFAULT = 0x00,
     /* BlockJob is not QMP-created and should not send QMP events */
     BLOCK_JOB_INTERNAL = 0x01,
-    /* BlockJob requests manual job management steps. */
+    /* BlockJob requests manual job management steps. See @BlockJobStatus. */
     BLOCK_JOB_MANUAL = 0x02,
 } BlockJobCreateFlags;
 
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 5c5921bfb7..deddee616a 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -955,6 +955,32 @@
 { 'enum': 'BlockJobType',
   'data': ['commit', 'stream', 'mirror', 'backup'] }
 
+##
+# @BlockJobStatus:
+#
+# Indicates the present state of a given blockjob in its lifetime.
+#
+# @undefined: Erroneous, default state. Should not ever be visible.
+#
+# @created: The job has been created, but not yet started.
+#
+# @running: The job is currently running.
+#
+# @paused: The job is running, but paused. The pause may be requested by
+#          either the QMP user or by internal processes.
+#
+# @ready: The job is running, but is ready for the user to signal completion.
+#         This is used for long-running jobs like mirror that are designed to
+#         run indefinitely.
+#
+# @standby: The job is ready, but paused. This is nearly identical to @paused.
+#           The job may return to @ready or otherwise be canceled.
+#
+# Since: 2.12
+##
+{ 'enum': 'BlockJobStatus',
+  'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby'] }
+
 ##
 # @BlockJobInfo:
 #
@@ -981,12 +1007,15 @@
 #
 # @ready: true if the job may be completed (since 2.2)
 #
+# @status: Current job state/status (since 2.12)
+#
 # Since: 1.1
 ##
 { 'struct': 'BlockJobInfo',
   'data': {'type': 'str', 'device': 'str', 'len': 'int',
            'offset': 'int', 'busy': 'bool', 'paused': 'bool', 'speed': 'int',
-           'io-status': 'BlockDeviceIoStatus', 'ready': 'bool'} }
+           'io-status': 'BlockDeviceIoStatus', 'ready': 'bool',
+           'status': 'BlockJobStatus' } }
 
 ##
 # @query-block-jobs:
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
index c189e2833d..d288f2eef6 100644
--- a/tests/qemu-iotests/109.out
+++ b/tests/qemu-iotests/109.out
@@ -19,7 +19,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
@@ -45,7 +45,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
@@ -71,7 +71,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
@@ -97,7 +97,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
@@ -123,7 +123,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
@@ -149,7 +149,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
@@ -174,7 +174,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
@@ -199,7 +199,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
@@ -224,7 +224,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
@@ -249,7 +249,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
@@ -265,7 +265,7 @@ Automatically detecting the format is dangerous for raw images, write operations
 Specify the 'raw' format explicitly to remove the restrictions.
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
@@ -274,7 +274,7 @@ Images are identical.
 {"return": {}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
-{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (3 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 16:27   ` Kevin Wolf
  2018-02-27 18:58   ` Eric Blake
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait John Snow
                   ` (18 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

The state transition table has mostly been implied. We're about to make
it a bit more complex, so let's make the STM explicit instead.

Perform state transitions with a function that for now just asserts the
transition is appropriate.

Transitions:
Undefined -> Created: During job initialization.
Created   -> Running: Once the job is started.
                      Jobs cannot transition from "Created" to "Paused"
                      directly, but will instead synchronously transition
                      to running to paused immediately.
Running   -> Paused:  Normal workflow for pauses.
Running   -> Ready:   Normal workflow for jobs reaching their sync point.
                      (e.g. mirror)
Ready     -> Standby: Normal workflow for pausing ready jobs.
Paused    -> Running: Normal resume.
Standby   -> Ready:   Resume of a Standby job.


+---------+
|UNDEFINED|
+--+------+
   |
+--v----+
|CREATED|
+--+----+
   |
+--v----+     +------+
|RUNNING<----->PAUSED|
+--+----+     +------+
   |
+--v--+       +-------+
|READY<------->STANDBY|
+-----+       +-------+


Notably, there is no state presently defined as of this commit that
deals with a job after the "running" or "ready" states, so this table
will be adjusted alongside the commits that introduce those states.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 block/trace-events |  3 +++
 blockjob.c         | 42 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/block/trace-events b/block/trace-events
index 02dd80ff0c..b75a0c8409 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -4,6 +4,9 @@
 bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags 0x%x format_name \"%s\""
 bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
 
+# blockjob.c
+block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
+
 # block/block-backend.c
 blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
 blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
diff --git a/blockjob.c b/blockjob.c
index 1be9c20cff..d745b3bb69 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -28,6 +28,7 @@
 #include "block/block.h"
 #include "block/blockjob_int.h"
 #include "block/block_int.h"
+#include "block/trace.h"
 #include "sysemu/block-backend.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
@@ -41,6 +42,34 @@
  * block_job_enter. */
 static QemuMutex block_job_mutex;
 
+/* BlockJob State Transition Table */
+bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
+                                          /* U, C, R, P, Y, S */
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
+};
+
+static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
+{
+    BlockJobStatus s0 = job->status;
+    if (s0 == s1) {
+        return;
+    }
+    assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
+    trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
+                                     "allowed" : "disallowed",
+                                     qapi_enum_lookup(&BlockJobStatus_lookup,
+                                                      s0),
+                                     qapi_enum_lookup(&BlockJobStatus_lookup,
+                                                      s1));
+    assert(BlockJobSTT[s0][s1]);
+    job->status = s1;
+}
+
 static void block_job_lock(void)
 {
     qemu_mutex_lock(&block_job_mutex);
@@ -320,7 +349,7 @@ void block_job_start(BlockJob *job)
     job->pause_count--;
     job->busy = true;
     job->paused = false;
-    job->status = BLOCK_JOB_STATUS_RUNNING;
+    block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
     bdrv_coroutine_enter(blk_bs(job->blk), job->co);
 }
 
@@ -704,6 +733,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
     job->refcnt        = 1;
     job->manual        = (flags & BLOCK_JOB_MANUAL);
     job->status        = BLOCK_JOB_STATUS_CREATED;
+    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
     aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
                    QEMU_CLOCK_REALTIME, SCALE_NS,
                    block_job_sleep_timer_cb, job);
@@ -818,13 +848,13 @@ void coroutine_fn block_job_pause_point(BlockJob *job)
 
     if (block_job_should_pause(job) && !block_job_is_cancelled(job)) {
         BlockJobStatus status = job->status;
-        job->status = status == BLOCK_JOB_STATUS_READY ? \
-                                BLOCK_JOB_STATUS_STANDBY : \
-                                BLOCK_JOB_STATUS_PAUSED;
+        block_job_state_transition(job, status == BLOCK_JOB_STATUS_READY ? \
+                                   BLOCK_JOB_STATUS_STANDBY :           \
+                                   BLOCK_JOB_STATUS_PAUSED);
         job->paused = true;
         block_job_do_yield(job, -1);
         job->paused = false;
-        job->status = status;
+        block_job_state_transition(job, status);
     }
 
     if (job->driver->resume) {
@@ -930,7 +960,7 @@ void block_job_iostatus_reset(BlockJob *job)
 
 void block_job_event_ready(BlockJob *job)
 {
-    job->status = BLOCK_JOB_STATUS_READY;
+    block_job_state_transition(job, BLOCK_JOB_STATUS_READY);
     job->ready = true;
 
     if (block_job_is_internal(job)) {
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (4 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 17:19   ` Kevin Wolf
  2018-02-27 19:01   ` Eric Blake
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table John Snow
                   ` (17 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Split out the pause command into the actual pause and the wait.
Not every usage presently needs to resubmit a pause request.

The intent with the next commit will be to explicitly disallow
redundant or meaningless pause/resume requests, so the tests
need to become more judicious to reflect that.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/qemu-iotests/030        |  6 ++----
 tests/qemu-iotests/055        | 17 ++++++-----------
 tests/qemu-iotests/iotests.py | 12 ++++++++----
 3 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index 457984b8e9..251883226c 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -86,11 +86,9 @@ class TestSingleDrive(iotests.QMPTestCase):
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
 
-        result = self.vm.qmp('block-job-pause', device='drive0')
-        self.assert_qmp(result, 'return', {})
-
+        self.pause_job('drive0', wait=False)
         self.vm.resume_drive('drive0')
-        self.pause_job('drive0')
+        self.pause_wait('drive0')
 
         result = self.vm.qmp('query-block-jobs')
         offset = self.dictpath(result, 'return[0]/offset')
diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
index 8a5d9fd269..3437c11507 100755
--- a/tests/qemu-iotests/055
+++ b/tests/qemu-iotests/055
@@ -86,11 +86,9 @@ class TestSingleDrive(iotests.QMPTestCase):
                              target=target, sync='full')
         self.assert_qmp(result, 'return', {})
 
-        result = self.vm.qmp('block-job-pause', device='drive0')
-        self.assert_qmp(result, 'return', {})
-
+        self.pause_job('drive0', wait=False)
         self.vm.resume_drive('drive0')
-        self.pause_job('drive0')
+        self.pause_wait('drive0')
 
         result = self.vm.qmp('query-block-jobs')
         offset = self.dictpath(result, 'return[0]/offset')
@@ -303,13 +301,12 @@ class TestSingleTransaction(iotests.QMPTestCase):
         ])
         self.assert_qmp(result, 'return', {})
 
-        result = self.vm.qmp('block-job-pause', device='drive0')
-        self.assert_qmp(result, 'return', {})
+        self.pause_job('drive0', wait=False)
 
         result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0)
         self.assert_qmp(result, 'return', {})
 
-        self.pause_job('drive0')
+        self.pause_wait('drive0')
 
         result = self.vm.qmp('query-block-jobs')
         offset = self.dictpath(result, 'return[0]/offset')
@@ -534,11 +531,9 @@ class TestDriveCompression(iotests.QMPTestCase):
         result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args)
         self.assert_qmp(result, 'return', {})
 
-        result = self.vm.qmp('block-job-pause', device='drive0')
-        self.assert_qmp(result, 'return', {})
-
+        self.pause_job('drive0', wait=False)
         self.vm.resume_drive('drive0')
-        self.pause_job('drive0')
+        self.pause_wait('drive0')
 
         result = self.vm.qmp('query-block-jobs')
         offset = self.dictpath(result, 'return[0]/offset')
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 1bcc9ca57d..5303bbc8e2 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -473,10 +473,7 @@ class QMPTestCase(unittest.TestCase):
         event = self.wait_until_completed(drive=drive)
         self.assert_qmp(event, 'data/type', 'mirror')
 
-    def pause_job(self, job_id='job0'):
-        result = self.vm.qmp('block-job-pause', device=job_id)
-        self.assert_qmp(result, 'return', {})
-
+    def pause_wait(self, job_id='job0'):
         with Timeout(1, "Timeout waiting for job to pause"):
             while True:
                 result = self.vm.qmp('query-block-jobs')
@@ -484,6 +481,13 @@ class QMPTestCase(unittest.TestCase):
                     if job['device'] == job_id and job['paused'] == True and job['busy'] == False:
                         return job
 
+    def pause_job(self, job_id='job0', wait=True):
+        result = self.vm.qmp('block-job-pause', device=job_id)
+        self.assert_qmp(result, 'return', {})
+        if wait:
+            return self.pause_wait(job_id)
+        return result
+
 
 def notrun(reason):
     '''Skip this test suite'''
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (5 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 17:19   ` Kevin Wolf
  2018-02-27 19:25   ` Eric Blake
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state John Snow
                   ` (16 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Which commands ("verbs") are appropriate for jobs in which state is
also somewhat burdensome to keep track of.

As of this commit, it looks rather useless, but begins to look more
interesting the more states we add to the STM table.

A recurring theme is that no verb will apply to an 'undefined' job.

Further, it's not presently possible to restrict the "pause" or "resume"
verbs any more than they are in this commit because of the asynchronous
nature of how jobs enter the PAUSED state; justifications for some
seemingly erroneous applications are given below.

=====
Verbs
=====

Cancel:    Any state except undefined.
Pause:     Any state except undefined;
           'created': Requests that the job pauses as it starts.
           'running': Normal usage. (PAUSED)
           'paused':  The job may be paused for internal reasons,
                      but the user may wish to force an indefinite
                      user-pause, so this is allowed.
           'ready':   Normal usage. (STANDBY)
           'standby': Same logic as above.
Resume:    Any state except undefined;
           'created': Will lift a user's pause-on-start request.
           'running': Will lift a pause request before it takes effect.
           'paused':  Normal usage.
           'ready':   Will lift a pause request before it takes effect.
           'standby': Normal usage.
Set-speed: Any state except undefined, though ready may not be meaningful.
Complete:  Only a 'ready' job may accept a complete request.


=======
Changes
=======

(1)

To facilitate "nice" error checking, all five major block-job verb
interfaces in blockjob.c now support an errp parameter:

- block_job_user_cancel is added as a new interface.
- block_job_user_pause gains an errp paramter
- block_job_user_resume gains an errp parameter
- block_job_set_speed already had an errp parameter.
- block_job_complete already had an errp parameter.

(2)

block-job-pause and block-job-resume will no longer no-op when trying
to pause an already paused job, or trying to resume a job that isn't
paused. These functions will now report that they did not perform the
action requested because it was not possible.

iotests have been adjusted to address this new behavior.

(3)

block-job-complete doesn't worry about checking !block_job_started,
because the permission table guards against this.

(4)

test-bdrv-drain's job implementation needs to announce that it is
'ready' now, in order to be completed.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 block/trace-events       |  1 +
 blockdev.c               | 10 +++----
 blockjob.c               | 71 ++++++++++++++++++++++++++++++++++++++++++------
 include/block/blockjob.h | 13 +++++++--
 qapi/block-core.json     | 20 ++++++++++++++
 tests/test-bdrv-drain.c  |  1 +
 6 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/block/trace-events b/block/trace-events
index b75a0c8409..3fe89f7ea6 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -6,6 +6,7 @@ bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
 
 # blockjob.c
 block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
+block_job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)"
 
 # block/block-backend.c
 blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
diff --git a/blockdev.c b/blockdev.c
index 3fb1ca803c..cba935a0a6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3805,7 +3805,7 @@ void qmp_block_job_cancel(const char *device,
     }
 
     trace_qmp_block_job_cancel(job);
-    block_job_cancel(job);
+    block_job_user_cancel(job, errp);
 out:
     aio_context_release(aio_context);
 }
@@ -3815,12 +3815,12 @@ void qmp_block_job_pause(const char *device, Error **errp)
     AioContext *aio_context;
     BlockJob *job = find_block_job(device, &aio_context, errp);
 
-    if (!job || block_job_user_paused(job)) {
+    if (!job) {
         return;
     }
 
     trace_qmp_block_job_pause(job);
-    block_job_user_pause(job);
+    block_job_user_pause(job, errp);
     aio_context_release(aio_context);
 }
 
@@ -3829,12 +3829,12 @@ void qmp_block_job_resume(const char *device, Error **errp)
     AioContext *aio_context;
     BlockJob *job = find_block_job(device, &aio_context, errp);
 
-    if (!job || !block_job_user_paused(job)) {
+    if (!job) {
         return;
     }
 
     trace_qmp_block_job_resume(job);
-    block_job_user_resume(job);
+    block_job_user_resume(job, errp);
     aio_context_release(aio_context);
 }
 
diff --git a/blockjob.c b/blockjob.c
index d745b3bb69..4e424fef72 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -53,6 +53,15 @@ bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
     /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
 };
 
+bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
+                                          /* U, C, R, P, Y, S */
+    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1},
+    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1},
+    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1},
+    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1},
+    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0},
+};
+
 static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
 {
     BlockJobStatus s0 = job->status;
@@ -70,6 +79,23 @@ static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
     job->status = s1;
 }
 
+static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
+{
+    assert(bv >= 0 && bv <= BLOCK_JOB_VERB__MAX);
+    trace_block_job_apply_verb(job, qapi_enum_lookup(&BlockJobStatus_lookup,
+                                                     job->status),
+                               qapi_enum_lookup(&BlockJobVerb_lookup, bv),
+                               BlockJobVerbTable[bv][job->status] ?
+                               "allowed" : "prohibited");
+    if (BlockJobVerbTable[bv][job->status]) {
+        return 0;
+    }
+    error_setg(errp, "Job '%s' in state '%s' cannot accept command verb '%s'",
+               job->id, qapi_enum_lookup(&BlockJobStatus_lookup, job->status),
+               qapi_enum_lookup(&BlockJobVerb_lookup, bv));
+    return -EPERM;
+}
+
 static void block_job_lock(void)
 {
     qemu_mutex_lock(&block_job_mutex);
@@ -520,6 +546,9 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
         error_setg(errp, QERR_UNSUPPORTED);
         return;
     }
+    if (block_job_apply_verb(job, BLOCK_JOB_VERB_SET_SPEED, errp)) {
+        return;
+    }
     job->driver->set_speed(job, speed, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -539,8 +568,10 @@ void block_job_complete(BlockJob *job, Error **errp)
 {
     /* Should not be reachable via external interface for internal jobs */
     assert(job->id);
-    if (job->pause_count || job->cancelled ||
-        !block_job_started(job) || !job->driver->complete) {
+    if (block_job_apply_verb(job, BLOCK_JOB_VERB_COMPLETE, errp)) {
+        return;
+    }
+    if (job->pause_count || job->cancelled || !job->driver->complete) {
         error_setg(errp, "The active block job '%s' cannot be completed",
                    job->id);
         return;
@@ -549,8 +580,15 @@ void block_job_complete(BlockJob *job, Error **errp)
     job->driver->complete(job, errp);
 }
 
-void block_job_user_pause(BlockJob *job)
+void block_job_user_pause(BlockJob *job, Error **errp)
 {
+    if (block_job_apply_verb(job, BLOCK_JOB_VERB_PAUSE, errp)) {
+        return;
+    }
+    if (job->user_paused) {
+        error_setg(errp, "Job is already paused");
+        return;
+    }
     job->user_paused = true;
     block_job_pause(job);
 }
@@ -560,13 +598,19 @@ bool block_job_user_paused(BlockJob *job)
     return job->user_paused;
 }
 
-void block_job_user_resume(BlockJob *job)
+void block_job_user_resume(BlockJob *job, Error **errp)
 {
-    if (job && job->user_paused && job->pause_count > 0) {
-        block_job_iostatus_reset(job);
-        job->user_paused = false;
-        block_job_resume(job);
+    assert(job);
+    if (!job->user_paused || job->pause_count <= 0) {
+        error_setg(errp, "Can't resume a job that was not paused");
+        return;
     }
+    if (block_job_apply_verb(job, BLOCK_JOB_VERB_RESUME, errp)) {
+        return;
+    }
+    block_job_iostatus_reset(job);
+    job->user_paused = false;
+    block_job_resume(job);
 }
 
 void block_job_cancel(BlockJob *job)
@@ -579,6 +623,14 @@ void block_job_cancel(BlockJob *job)
     }
 }
 
+void block_job_user_cancel(BlockJob *job, Error **errp)
+{
+    if (block_job_apply_verb(job, BLOCK_JOB_VERB_CANCEL, errp)) {
+        return;
+    }
+    block_job_cancel(job);
+}
+
 /* A wrapper around block_job_cancel() taking an Error ** parameter so it may be
  * used with block_job_finish_sync() without the need for (rather nasty)
  * function pointer casts there. */
@@ -1004,8 +1056,9 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
                                         action, &error_abort);
     }
     if (action == BLOCK_ERROR_ACTION_STOP) {
+        block_job_pause(job);
         /* make the pause user visible, which will be resumed from QMP. */
-        block_job_user_pause(job);
+        job->user_paused = true;
         block_job_iostatus_set_err(job, error);
     }
     return action;
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index e254359d6b..403a168073 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -260,7 +260,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp);
  * Asynchronously pause the specified job.
  * Do not allow a resume until a matching call to block_job_user_resume.
  */
-void block_job_user_pause(BlockJob *job);
+void block_job_user_pause(BlockJob *job, Error **errp);
 
 /**
  * block_job_paused:
@@ -277,7 +277,16 @@ bool block_job_user_paused(BlockJob *job);
  * Resume the specified job.
  * Must be paired with a preceding block_job_user_pause.
  */
-void block_job_user_resume(BlockJob *job);
+void block_job_user_resume(BlockJob *job, Error **errp);
+
+/**
+ * block_job_user_cancel:
+ * @job: The job to be cancelled.
+ *
+ * Cancels the specified job, but may refuse to do so if the
+ * operation isn't currently meaningful.
+ */
+void block_job_user_cancel(BlockJob *job, Error **errp);
 
 /**
  * block_job_cancel_sync:
diff --git a/qapi/block-core.json b/qapi/block-core.json
index deddee616a..11659496c5 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -955,6 +955,26 @@
 { 'enum': 'BlockJobType',
   'data': ['commit', 'stream', 'mirror', 'backup'] }
 
+##
+# @BlockJobVerb:
+#
+# Represents command verbs that can be applied to a blockjob.
+#
+# @cancel: see @block-job-cancel
+#
+# @pause: see @block-job-pause
+#
+# @resume: see @block-job-resume
+#
+# @set-speed: see @block-job-set-speed
+#
+# @complete: see @block-job-complete
+#
+# Since: 2.12
+##
+{ 'enum': 'BlockJobVerb',
+  'data': ['cancel', 'pause', 'resume', 'set-speed', 'complete' ] }
+
 ##
 # @BlockJobStatus:
 #
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
index a7eecf1c1e..7673de1062 100644
--- a/tests/test-bdrv-drain.c
+++ b/tests/test-bdrv-drain.c
@@ -505,6 +505,7 @@ static void coroutine_fn test_job_start(void *opaque)
 {
     TestBlockJob *s = opaque;
 
+    block_job_event_ready(&s->common);
     while (!s->should_complete) {
         block_job_sleep_ns(&s->common, 100000);
     }
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (6 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:34   ` Eric Blake
  2018-02-28 14:54   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state John Snow
                   ` (15 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Add a new state ABORTING.

This makes transitions from normative states to error states explicit
in the STM, and serves as a disambiguation for which states may complete
normally when normal end-states (CONCLUDED) are added in future commits.

Notably, Paused/Standby jobs do not transition directly to aborting,
as they must wake up first and cooperate in their cancellation.

Transitions:
Running -> Aborting: can be cancelled or encounter an error
Ready   -> Aborting: can be cancelled or encounter an error

Verbs:
None. The job must finish cleaning itself up and report its final status.

             +---------+
             |UNDEFINED|
             +--+------+
                |
             +--v----+
             |CREATED|
             +--+----+
                |
             +--v----+     +------+
   +---------+RUNNING<----->PAUSED|
   |         +--+----+     +------+
   |            |
   |         +--v--+       +-------+
   +---------+READY<------->STANDBY|
   |         +-----+       +-------+
   |
+--v-----+
|ABORTING|
+--------+

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c           | 31 ++++++++++++++++++-------------
 qapi/block-core.json |  7 ++++++-
 2 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 4e424fef72..4c3fcda46c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -44,22 +44,23 @@ static QemuMutex block_job_mutex;
 
 /* BlockJob State Transition Table */
 bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S */
-    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},
-    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},
-    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},
-    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},
-    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},
-    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
+                                          /* U, C, R, P, Y, S, X */
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0},
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0},
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1},
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0},
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1},
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0},
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0},
 };
 
 bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S */
-    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1},
-    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1},
-    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1},
-    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1},
-    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0},
+                                          /* U, C, R, P, Y, S, X */
+    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 0},
+    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0},
+    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0},
+    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0},
+    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0},
 };
 
 static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
@@ -383,6 +384,10 @@ static void block_job_completed_single(BlockJob *job)
 {
     assert(job->completed);
 
+    if (job->ret || block_job_is_cancelled(job)) {
+        block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
+    }
+
     if (!job->ret) {
         if (job->driver->commit) {
             job->driver->commit(job);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 11659496c5..3f7d559fc0 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -996,10 +996,15 @@
 # @standby: The job is ready, but paused. This is nearly identical to @paused.
 #           The job may return to @ready or otherwise be canceled.
 #
+# @aborting: The job is in the process of being aborted, and will finish with
+#            an error. The job will afterwards report that it is @concluded.
+#            This status may not be visible to the management process.
+#
 # Since: 2.12
 ##
 { 'enum': 'BlockJobStatus',
-  'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby'] }
+  'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby',
+           'aborting' ] }
 
 ##
 # @BlockJobInfo:
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (7 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:38   ` Eric Blake
  2018-02-28 15:37   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state John Snow
                   ` (14 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

add a new state "CONCLUDED" that identifies a job that has ceased all
operations. The wording was chosen to avoid any phrasing that might
imply success, error, or cancellation. The task has simply ceased all
operation and can never again perform any work.

("finished", "done", and "completed" might all imply success.)

Transitions:
Running  -> Concluded: normal completion
Ready    -> Concluded: normal completion
Aborting -> Concluded: error and cancellations

Verbs:
None as of this commit. (a future commit adds 'dismiss')

             +---------+
             |UNDEFINED|
             +--+------+
                |
             +--v----+
             |CREATED|
             +--+----+
                |
             +--v----+     +------+
   +---------+RUNNING<----->PAUSED|
   |         +--+-+--+     +------+
   |            | |
   |            | +------------------+
   |            |                    |
   |         +--v--+       +-------+ |
   +---------+READY<------->STANDBY| |
   |         +--+--+       +-------+ |
   |            |                    |
+--v-----+   +--v------+             |
|ABORTING+--->CONCLUDED<-------------+
+--------+   +---------+

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c           | 43 ++++++++++++++++++++++++++++---------------
 qapi/block-core.json |  5 ++++-
 2 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 4c3fcda46c..93b0a36306 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -44,23 +44,24 @@ static QemuMutex block_job_mutex;
 
 /* BlockJob State Transition Table */
 bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, X */
-    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0},
-    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0},
-    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1},
-    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0},
-    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1},
-    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0},
-    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0},
+                                          /* U, C, R, P, Y, S, X, E */
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0},
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0},
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1},
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0},
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1},
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0},
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1},
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0},
 };
 
 bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, X */
-    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 0},
-    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0},
-    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0},
-    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0},
-    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0},
+                                          /* U, C, R, P, Y, S, X, E */
+    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 0, 0},
+    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0, 0},
+    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0},
+    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0},
+    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0},
 };
 
 static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
@@ -114,6 +115,7 @@ static void __attribute__((__constructor__)) block_job_init(void)
 
 static void block_job_event_cancelled(BlockJob *job);
 static void block_job_event_completed(BlockJob *job, const char *msg);
+static void block_job_event_concluded(BlockJob *job);
 static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job));
 
 /* Transactional group of block jobs */
@@ -420,6 +422,7 @@ static void block_job_completed_single(BlockJob *job)
 
     QLIST_REMOVE(job, txn_list);
     block_job_txn_unref(job->txn);
+    block_job_event_concluded(job);
     block_job_unref(job);
 }
 
@@ -620,7 +623,9 @@ void block_job_user_resume(BlockJob *job, Error **errp)
 
 void block_job_cancel(BlockJob *job)
 {
-    if (block_job_started(job)) {
+    if (job->status == BLOCK_JOB_STATUS_CONCLUDED) {
+        return;
+    } else if (block_job_started(job)) {
         block_job_cancel_async(job);
         block_job_enter(job);
     } else {
@@ -727,6 +732,14 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
                                         &error_abort);
 }
 
+static void block_job_event_concluded(BlockJob *job)
+{
+    if (block_job_is_internal(job) || !job->manual) {
+        return;
+    }
+    block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
+}
+
 /*
  * API for block job drivers and the block layer.  These functions are
  * declared in blockjob_int.h.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3f7d559fc0..aeb9b1937b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1000,11 +1000,14 @@
 #            an error. The job will afterwards report that it is @concluded.
 #            This status may not be visible to the management process.
 #
+# @concluded: The job has finished all work. If manual was set to true, the job
+#             will remain in the query list until it is dismissed.
+#
 # Since: 2.12
 ##
 { 'enum': 'BlockJobStatus',
   'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby',
-           'aborting' ] }
+           'aborting', 'concluded' ] }
 
 ##
 # @BlockJobInfo:
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (8 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:41   ` Eric Blake
  2018-02-28 15:42   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss John Snow
                   ` (13 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Add a new state that specifically demarcates when we begin to permanently
demolish a job after it has performed all work. This makes the transition
explicit in the STM table and highlights conditions under which a job may
be demolished.


Transitions:
Created   -> Null: Early failure event before the job is started
Concluded -> Null: Standard transition.

Verbs:
None. This should not ever be visible to the monitor.

             +---------+
             |UNDEFINED|
             +--+------+
                |
             +--v----+
             |CREATED+------------------+
             +--+----+                  |
                |                       |
             +--v----+     +------+     |
   +---------+RUNNING<----->PAUSED|     |
   |         +--+-+--+     +------+     |
   |            | |                     |
   |            | +------------------+  |
   |            |                    |  |
   |         +--v--+       +-------+ |  |
   +---------+READY<------->STANDBY| |  |
   |         +--+--+       +-------+ |  |
   |            |                    |  |
+--v-----+   +--v------+             |  |
|ABORTING+--->CONCLUDED<-------------+  |
+--------+   +--+------+                |
                |                       |
             +--v-+                     |
             |NULL<---------------------+
             +----+

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c           | 35 +++++++++++++++++------------------
 qapi/block-core.json |  5 ++++-
 2 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 93b0a36306..7b5c4063cf 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -44,24 +44,25 @@ static QemuMutex block_job_mutex;
 
 /* BlockJob State Transition Table */
 bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, X, E */
-    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0},
-    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0},
-    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1},
-    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0},
-    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1},
-    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0},
-    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1},
-    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0},
+                                          /* U, C, R, P, Y, S, X, E, N */
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0},
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 1},
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0},
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0},
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0},
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0},
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1, 0},
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 1},
+    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0},
 };
 
 bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, X, E */
-    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 0, 0},
-    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0, 0},
-    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0},
-    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0},
-    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0},
+                                          /* U, C, R, P, Y, S, X, E, N */
+    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 0, 0, 0},
+    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0, 0, 0},
+    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0},
+    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0},
+    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0},
 };
 
 static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
@@ -423,6 +424,7 @@ static void block_job_completed_single(BlockJob *job)
     QLIST_REMOVE(job, txn_list);
     block_job_txn_unref(job->txn);
     block_job_event_concluded(job);
+    block_job_state_transition(job, BLOCK_JOB_STATUS_NULL);
     block_job_unref(job);
 }
 
@@ -734,9 +736,6 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
 
 static void block_job_event_concluded(BlockJob *job)
 {
-    if (block_job_is_internal(job) || !job->manual) {
-        return;
-    }
     block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
 }
 
diff --git a/qapi/block-core.json b/qapi/block-core.json
index aeb9b1937b..578c0c91ca 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1003,11 +1003,14 @@
 # @concluded: The job has finished all work. If manual was set to true, the job
 #             will remain in the query list until it is dismissed.
 #
+# @null: The job is in the process of being dismantled. This state should not
+#        ever be visible externally.
+#
 # Since: 2.12
 ##
 { 'enum': 'BlockJobStatus',
   'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby',
-           'aborting', 'concluded' ] }
+           'aborting', 'concluded', 'null' ] }
 
 ##
 # @BlockJobInfo:
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (9 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:44   ` Eric Blake
  2018-02-28 15:53   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs John Snow
                   ` (12 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

For jobs that have reached their CONCLUDED state, prior to having their
last reference put down (meaning jobs that have completed successfully,
unsuccessfully, or have been canceled), allow the user to dismiss the
job's lingering status report via block-job-dismiss.

This gives management APIs the chance to conclusively determine if a job
failed or succeeded, even if the event broadcast was missed.

Note that jobs do not yet linger in any such state, they are freed
immediately upon reaching this previously-unnamed state. such a state is
added immediately in the next commit.

Verbs:
Dismiss: operates on CONCLUDED jobs only.
Signed-off-by: John Snow <jsnow@redhat.com>
---
 block/trace-events       |  1 +
 blockdev.c               | 14 ++++++++++++++
 blockjob.c               | 34 ++++++++++++++++++++++++++++++++--
 include/block/blockjob.h |  9 +++++++++
 qapi/block-core.json     | 24 +++++++++++++++++++++++-
 5 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/block/trace-events b/block/trace-events
index 3fe89f7ea6..266afd9e99 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -50,6 +50,7 @@ qmp_block_job_cancel(void *job) "job %p"
 qmp_block_job_pause(void *job) "job %p"
 qmp_block_job_resume(void *job) "job %p"
 qmp_block_job_complete(void *job) "job %p"
+qmp_block_job_dismiss(void *job) "job %p"
 qmp_block_stream(void *bs, void *job) "bs %p job %p"
 
 # block/file-win32.c
diff --git a/blockdev.c b/blockdev.c
index cba935a0a6..3180130782 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3852,6 +3852,20 @@ void qmp_block_job_complete(const char *device, Error **errp)
     aio_context_release(aio_context);
 }
 
+void qmp_block_job_dismiss(const char *id, Error **errp)
+{
+    AioContext *aio_context;
+    BlockJob *job = find_block_job(id, &aio_context, errp);
+
+    if (!job) {
+        return;
+    }
+
+    trace_qmp_block_job_dismiss(job);
+    block_job_dismiss(&job, errp);
+    aio_context_release(aio_context);
+}
+
 void qmp_change_backing_file(const char *device,
                              const char *image_node_name,
                              const char *backing_file,
diff --git a/blockjob.c b/blockjob.c
index 7b5c4063cf..4d29391673 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -63,6 +63,7 @@ bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
     [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0},
     [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0},
     [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_DISMISS]              = {0, 0, 0, 0, 0, 0, 0, 1, 0},
 };
 
 static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
@@ -424,7 +425,6 @@ static void block_job_completed_single(BlockJob *job)
     QLIST_REMOVE(job, txn_list);
     block_job_txn_unref(job->txn);
     block_job_event_concluded(job);
-    block_job_state_transition(job, BLOCK_JOB_STATUS_NULL);
     block_job_unref(job);
 }
 
@@ -441,6 +441,13 @@ static void block_job_cancel_async(BlockJob *job)
     job->cancelled = true;
 }
 
+static void block_job_do_dismiss(BlockJob *job)
+{
+    assert(job);
+    block_job_state_transition(job, BLOCK_JOB_STATUS_NULL);
+    block_job_unref(job);
+}
+
 static int block_job_finish_sync(BlockJob *job,
                                  void (*finish)(BlockJob *, Error **errp),
                                  Error **errp)
@@ -590,6 +597,19 @@ void block_job_complete(BlockJob *job, Error **errp)
     job->driver->complete(job, errp);
 }
 
+void block_job_dismiss(BlockJob **jobptr, Error **errp)
+{
+    BlockJob *job = *jobptr;
+    /* similarly to _complete, this is QMP-interface only. */
+    assert(job->id);
+    if (block_job_apply_verb(job, BLOCK_JOB_VERB_DISMISS, errp)) {
+        return;
+    }
+
+    block_job_do_dismiss(job);
+    *jobptr = NULL;
+}
+
 void block_job_user_pause(BlockJob *job, Error **errp)
 {
     if (block_job_apply_verb(job, BLOCK_JOB_VERB_PAUSE, errp)) {
@@ -626,7 +646,7 @@ void block_job_user_resume(BlockJob *job, Error **errp)
 void block_job_cancel(BlockJob *job)
 {
     if (job->status == BLOCK_JOB_STATUS_CONCLUDED) {
-        return;
+        block_job_do_dismiss(job);
     } else if (block_job_started(job)) {
         block_job_cancel_async(job);
         block_job_enter(job);
@@ -737,6 +757,10 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
 static void block_job_event_concluded(BlockJob *job)
 {
     block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
+    /* for pre-2.12 style jobs, automatically destroy */
+    if (!job->manual) {
+        block_job_do_dismiss(job);
+    }
 }
 
 /*
@@ -841,6 +865,9 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
         block_job_txn_add_job(txn, job);
     }
 
+    /* For the expanded job control STM, grab an extra
+     * reference for finalize() to put down */
+    block_job_ref(job);
     return job;
 }
 
@@ -859,6 +886,9 @@ void block_job_pause_all(void)
 
 void block_job_early_fail(BlockJob *job)
 {
+    /* One for creation, one for finalize() */
+    assert(job->status == BLOCK_JOB_STATUS_CREATED);
+    block_job_unref(job);
     block_job_unref(job);
 }
 
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 403a168073..9bb0be1b13 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -245,6 +245,15 @@ void block_job_cancel(BlockJob *job);
  */
 void block_job_complete(BlockJob *job, Error **errp);
 
+/**
+ * block_job_dismiss:
+ * @job: The job to be dismissed.
+ * @errp: Error object.
+ *
+ * Remove a concluded job from the query list.
+ */
+void block_job_dismiss(BlockJob **job, Error **errp);
+
 /**
  * block_job_query:
  * @job: The job to get information about.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 578c0c91ca..b42796a6a0 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -970,10 +970,12 @@
 #
 # @complete: see @block-job-complete
 #
+# @dismiss: see @block-job-dismiss
+#
 # Since: 2.12
 ##
 { 'enum': 'BlockJobVerb',
-  'data': ['cancel', 'pause', 'resume', 'set-speed', 'complete' ] }
+  'data': ['cancel', 'pause', 'resume', 'set-speed', 'complete', 'dismiss' ] }
 
 ##
 # @BlockJobStatus:
@@ -2243,6 +2245,26 @@
 ##
 { 'command': 'block-job-complete', 'data': { 'device': 'str' } }
 
+##
+# @block-job-dismiss:
+#
+# For jobs that have already concluded, remove them from the block-job-query
+# list. This command only needs to be run for jobs which were started with
+# QEMU 2.12+ job lifetime management semantics.
+#
+# This command will refuse to operate on any job that has not yet reached
+# its terminal state, BLOCK_JOB_STATUS_CONCLUDED. For jobs that make use of
+# BLOCK_JOB_READY event, block-job-cancel or block-job-complete will still need
+# to be used as appropriate.
+#
+# @id: The job identifier.
+#
+# Returns: Nothing on success
+#
+# Since: 2.12
+##
+{ 'command': 'block-job-dismiss', 'data': { 'id': 'str' } }
+
 ##
 # @BlockdevDiscardOptions:
 #
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (10 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:49   ` Eric Blake
  2018-02-28 16:05   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers John Snow
                   ` (11 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Presently, even if a job is canceled post-completion as a result of
a failing peer in a transaction, it will still call .commit because
nothing has updated or changed its return code.

The reason why this does not cause problems currently is because
backup's implementation of .commit checks for cancellation itself.

I'd like to simplify this contract:

(1) Abort is called if the job/transaction fails
(2) Commit is called if the job/transaction succeeds

To this end: A job's return code, if 0, will be forcibly set as
-ECANCELED if that job has already concluded. Remove the now
redundant check in the backup job implementation.

We need to check for cancellation in both block_job_completed
AND block_job_completed_single, because jobs may be cancelled between
those two calls; for instance in transactions.

The check in block_job_completed could be removed, but there's no
point in starting to attempt to succeed a transaction that we know
in advance will fail.

This does NOT affect mirror jobs that are "canceled" during their
synchronous phase. The mirror job itself forcibly sets the canceled
property to false prior to ceding control, so such cases will invoke
the "commit" callback.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 block/backup.c     |  2 +-
 block/trace-events |  1 +
 blockjob.c         | 19 +++++++++++++++----
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 7e254dabff..453cd62c24 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -206,7 +206,7 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
     BdrvDirtyBitmap *bm;
     BlockDriverState *bs = blk_bs(job->common.blk);
 
-    if (ret < 0 || block_job_is_cancelled(&job->common)) {
+    if (ret < 0) {
         /* Merge the successor back into the parent, delete nothing. */
         bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
         assert(bm);
diff --git a/block/trace-events b/block/trace-events
index 266afd9e99..5e531e0310 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -5,6 +5,7 @@ bdrv_open_common(void *bs, const char *filename, int flags, const char *format_n
 bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
 
 # blockjob.c
+block_job_completed(void *job, int ret, int jret) "job %p ret %d corrected ret %d"
 block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
 block_job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)"
 
diff --git a/blockjob.c b/blockjob.c
index 4d29391673..ef17dea004 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -384,13 +384,22 @@ void block_job_start(BlockJob *job)
     bdrv_coroutine_enter(blk_bs(job->blk), job->co);
 }
 
+static void block_job_update_rc(BlockJob *job)
+{
+    if (!job->ret && block_job_is_cancelled(job)) {
+        job->ret = -ECANCELED;
+    }
+    if (job->ret) {
+        block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
+    }
+}
+
 static void block_job_completed_single(BlockJob *job)
 {
     assert(job->completed);
 
-    if (job->ret || block_job_is_cancelled(job)) {
-        block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
-    }
+    /* Ensure abort is called for late-transactional failures */
+    block_job_update_rc(job);
 
     if (!job->ret) {
         if (job->driver->commit) {
@@ -898,7 +907,9 @@ void block_job_completed(BlockJob *job, int ret)
     assert(blk_bs(job->blk)->job == job);
     job->completed = true;
     job->ret = ret;
-    if (ret < 0 || block_job_is_cancelled(job)) {
+    block_job_update_rc(job);
+    trace_block_job_completed(job, ret, job->ret);
+    if (job->ret) {
         block_job_completed_txn_abort(job);
     } else {
         block_job_completed_txn_success(job);
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (11 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:50   ` Eric Blake
  2018-02-28 16:07   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function John Snow
                   ` (10 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

The completed_single function is getting a little mucked up with
checking to see which callbacks exist, so let's factor them out.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c | 35 ++++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index ef17dea004..431ce9c220 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -394,6 +394,29 @@ static void block_job_update_rc(BlockJob *job)
     }
 }
 
+static void block_job_commit(BlockJob *job)
+{
+    assert(!job->ret);
+    if (job->driver->commit) {
+        job->driver->commit(job);
+    }
+}
+
+static void block_job_abort(BlockJob *job)
+{
+    assert(job->ret);
+    if (job->driver->abort) {
+        job->driver->abort(job);
+    }
+}
+
+static void block_job_clean(BlockJob *job)
+{
+    if (job->driver->clean) {
+        job->driver->clean(job);
+    }
+}
+
 static void block_job_completed_single(BlockJob *job)
 {
     assert(job->completed);
@@ -402,17 +425,11 @@ static void block_job_completed_single(BlockJob *job)
     block_job_update_rc(job);
 
     if (!job->ret) {
-        if (job->driver->commit) {
-            job->driver->commit(job);
-        }
+        block_job_commit(job);
     } else {
-        if (job->driver->abort) {
-            job->driver->abort(job);
-        }
-    }
-    if (job->driver->clean) {
-        job->driver->clean(job);
+        block_job_abort(job);
     }
+    block_job_clean(job);
 
     if (job->cb) {
         job->cb(job->opaque, job->ret);
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (12 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:52   ` Eric Blake
  2018-02-28 16:32   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback John Snow
                   ` (9 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Simply apply a function transaction-wide.
A few more uses of this in forthcoming patches.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 431ce9c220..8f02c03880 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -467,6 +467,19 @@ static void block_job_cancel_async(BlockJob *job)
     job->cancelled = true;
 }
 
+static void block_job_txn_apply(BlockJobTxn *txn, void fn(BlockJob *))
+{
+    AioContext *ctx;
+    BlockJob *job, *next;
+
+    QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
+        ctx = blk_get_aio_context(job->blk);
+        aio_context_acquire(ctx);
+        fn(job);
+        aio_context_release(ctx);
+    }
+}
+
 static void block_job_do_dismiss(BlockJob *job)
 {
     assert(job);
@@ -552,9 +565,8 @@ static void block_job_completed_txn_abort(BlockJob *job)
 
 static void block_job_completed_txn_success(BlockJob *job)
 {
-    AioContext *ctx;
     BlockJobTxn *txn = job->txn;
-    BlockJob *other_job, *next;
+    BlockJob *other_job;
     /*
      * Successful completion, see if there are other running jobs in this
      * txn.
@@ -565,13 +577,7 @@ static void block_job_completed_txn_success(BlockJob *job)
         }
     }
     /* We are the last completed job, commit the transaction. */
-    QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
-        ctx = blk_get_aio_context(other_job->blk);
-        aio_context_acquire(ctx);
-        assert(other_job->ret == 0);
-        block_job_completed_single(other_job);
-        aio_context_release(ctx);
-    }
+    block_job_txn_apply(txn, block_job_completed_single);
 }
 
 /* Assumes the block_job_mutex is held */
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (13 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 19:56   ` Eric Blake
  2018-02-28 17:04   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status John Snow
                   ` (8 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Some jobs upon finalization may need to perform some work that can
still fail. If these jobs are part of a transaction, it's important
that these callbacks fail the entire transaction.

We allow for a new callback in addition to commit/abort/clean that
allows us the opportunity to have fairly late-breaking failures
in the transactional process.

The expected flow is:

- All jobs in a transaction converge to the WAITING state
  (added in a forthcoming commit)
- All jobs prepare to call either commit/abort
- If any job fails, is canceled, or fails preparation, all jobs
  call their .abort callback.
- All jobs enter the PENDING state, awaiting manual intervention
  (also added in a forthcoming commit)
- block-job-finalize is issued by the user/management layer
- All jobs call their commit callbacks.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c                   | 34 +++++++++++++++++++++++++++++++---
 include/block/blockjob_int.h | 10 ++++++++++
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 8f02c03880..1c010ec100 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -394,6 +394,18 @@ static void block_job_update_rc(BlockJob *job)
     }
 }
 
+static int block_job_prepare(BlockJob *job)
+{
+    if (job->ret) {
+        goto out;
+    }
+    if (job->driver->prepare) {
+        job->ret = job->driver->prepare(job);
+    }
+ out:
+    return job->ret;
+}
+
 static void block_job_commit(BlockJob *job)
 {
     assert(!job->ret);
@@ -417,7 +429,7 @@ static void block_job_clean(BlockJob *job)
     }
 }
 
-static void block_job_completed_single(BlockJob *job)
+static int block_job_completed_single(BlockJob *job)
 {
     assert(job->completed);
 
@@ -452,6 +464,7 @@ static void block_job_completed_single(BlockJob *job)
     block_job_txn_unref(job->txn);
     block_job_event_concluded(job);
     block_job_unref(job);
+    return 0;
 }
 
 static void block_job_cancel_async(BlockJob *job)
@@ -467,17 +480,22 @@ static void block_job_cancel_async(BlockJob *job)
     job->cancelled = true;
 }
 
-static void block_job_txn_apply(BlockJobTxn *txn, void fn(BlockJob *))
+static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *))
 {
     AioContext *ctx;
     BlockJob *job, *next;
+    int rc;
 
     QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
         ctx = blk_get_aio_context(job->blk);
         aio_context_acquire(ctx);
-        fn(job);
+        rc = fn(job);
         aio_context_release(ctx);
+        if (rc) {
+            break;
+        }
     }
+    return rc;
 }
 
 static void block_job_do_dismiss(BlockJob *job)
@@ -567,6 +585,8 @@ static void block_job_completed_txn_success(BlockJob *job)
 {
     BlockJobTxn *txn = job->txn;
     BlockJob *other_job;
+    int rc = 0;
+
     /*
      * Successful completion, see if there are other running jobs in this
      * txn.
@@ -576,6 +596,14 @@ static void block_job_completed_txn_success(BlockJob *job)
             return;
         }
     }
+
+    /* Jobs may require some prep-work to complete without failure */
+    rc = block_job_txn_apply(txn, block_job_prepare);
+    if (rc) {
+        block_job_completed_txn_abort(job);
+        return;
+    }
+
     /* We are the last completed job, commit the transaction. */
     block_job_txn_apply(txn, block_job_completed_single);
 }
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index 259d49b32a..642adce68b 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -53,6 +53,16 @@ struct BlockJobDriver {
      */
     void (*complete)(BlockJob *job, Error **errp);
 
+    /**
+     * If the callback is not NULL, prepare will be invoked when all the jobs
+     * belonging to the same transaction complete; or upon this job's completion
+     * if it is not in a transaction.
+     *
+     * This callback will not be invoked if the job has already failed.
+     * If it fails, abort and then clean will be called.
+     */
+    int (*prepare)(BlockJob *job);
+
     /**
      * If the callback is not NULL, it will be invoked when all the jobs
      * belonging to the same transaction complete; or upon this job's
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (14 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 20:00   ` Eric Blake
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event John Snow
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

For jobs that are stuck waiting on others in a transaction, it would
be nice to know that they are no longer "running" in that sense, but
instead are waiting on other jobs in the transaction.

Jobs that are "waiting" in this sense cannot be meaningfully altered
any longer as they have left their running loop. The only meaningful
user verb for jobs in this state is "cancel," which will cancel the
whole transaction, too.

Transitions:
Running -> Waiting:   Normal transition.
Ready   -> Waiting:   Normal transition.
Waiting -> Aborting:  Transactional cancellation.
Waiting -> Concluded: Normal transition.

Removed Transitions:
Running -> Concluded: Jobs must go to WAITING first.
Ready   -> Concluded: Jobs must go to WAITING fisrt.

Verbs:
Cancel: Can be applied to WAITING jobs.

             +---------+
             |UNDEFINED|
             +--+------+
                |
             +--v----+
             |CREATED+-----------------+
             +--+----+                 |
                |                      |
             +--v----+     +------+    |
   +---------+RUNNING<----->PAUSED|    |
   |         +--+-+--+     +------+    |
   |            | |                    |
   |            | +------------------+ |
   |            |                    | |
   |         +--v--+       +-------+ | |
   +---------+READY<------->STANDBY| | |
   |         +--+--+       +-------+ | |
   |            |                    | |
   |         +--v----+               | |
   +---------+WAITING<---------------+ |
   |         +--+----+                 |
   |            |                      |
+--+-----+   +--v------+               |
|ABORTING+--->CONCLUDED|               |
+--------+   +--+------+               |
                |                      |
             +--v-+                    |
             |NULL<--------------------+
             +----+

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c           | 37 ++++++++++++++++++++-----------------
 qapi/block-core.json | 29 ++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 1c010ec100..4aed86fc6b 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -44,26 +44,27 @@ static QemuMutex block_job_mutex;
 
 /* BlockJob State Transition Table */
 bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, X, E, N */
-    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0},
-    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 1},
-    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0},
-    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0},
-    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0},
-    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0},
-    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1, 0},
-    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 1},
-    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0},
+                                          /* U, C, R, P, Y, S, W, X, E, N */
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0, 0},
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
+    /* W: */ [BLOCK_JOB_STATUS_WAITING]   = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 };
 
 bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, X, E, N */
-    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 0, 0, 0},
-    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0, 0, 0},
-    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0},
-    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0},
-    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0},
-    [BLOCK_JOB_VERB_DISMISS]              = {0, 0, 0, 0, 0, 0, 0, 1, 0},
+                                          /* U, C, R, P, Y, S, W, X, E, N */
+    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 1, 0, 0, 0},
+    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_DISMISS]              = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
 };
 
 static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
@@ -587,6 +588,8 @@ static void block_job_completed_txn_success(BlockJob *job)
     BlockJob *other_job;
     int rc = 0;
 
+    block_job_state_transition(job, BLOCK_JOB_STATUS_WAITING);
+
     /*
      * Successful completion, see if there are other running jobs in this
      * txn.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index b42796a6a0..3005aac7e2 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -998,6 +998,10 @@
 # @standby: The job is ready, but paused. This is nearly identical to @paused.
 #           The job may return to @ready or otherwise be canceled.
 #
+# @waiting: The job is waiting for other jobs in the transaction to converge
+#           to the waiting state. This status will likely not be visible for
+#           the last job in a transaction.
+#
 # @aborting: The job is in the process of being aborted, and will finish with
 #            an error. The job will afterwards report that it is @concluded.
 #            This status may not be visible to the management process.
@@ -1012,7 +1016,7 @@
 ##
 { 'enum': 'BlockJobStatus',
   'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby',
-           'aborting', 'concluded', 'null' ] }
+           'waiting', 'aborting', 'concluded', 'null' ] }
 
 ##
 # @BlockJobInfo:
@@ -3934,6 +3938,29 @@
             'offset': 'int',
             'speed' : 'int' } }
 
+##
+# @BLOCK_JOB_WAITING:
+#
+# Emitted when a block job that is part of a transction has stopped work and is
+# waiting for other jobs in the transaction to reach the same state.
+#
+# @type: job type
+#
+# @id: The job identifier.
+#
+# Since: 2.12
+#
+# Example:
+#
+# <- { "event": "BLOCK_JOB_WAITING",
+#      "data": { "id": "drive0", "type": "mirror" },
+#      "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
+##
+{ 'event': 'BLOCK_JOB_WAITING',
+  'data': { 'type'  : 'BlockJobType',
+            'id'    : 'str' } }
+
 ##
 # @PreallocMode:
 #
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (15 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 20:05   ` Eric Blake
  2018-02-28 17:55   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize John Snow
                   ` (6 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

For jobs utilizing the new manual workflow, we intend to prohibit
them from modifying the block graph until the management layer provides
an explicit ACK via block-job-finalize to move the process forward.

To distinguish this runstate from "ready" or "waiting," we add a new
"pending" event.

For now, the transition from PENDING to CONCLUDED/ABORTING is automatic,
but a future commit will add the explicit block-job-finalize step.

Transitions:
Waiting -> Pending:   Normal transition.
Pending -> Concluded: Normal transition.
Pending -> Aborting:  Late transactional failures and cancellations.

Removed Transitions:
Waiting -> Concluded: Jobs must go to PENDING first.

Verbs:
Cancel: Can be applied to a pending job.

             +---------+
             |UNDEFINED|
             +--+------+
                |
             +--v----+
             |CREATED+-----------------+
             +--+----+                 |
                |                      |
             +--+----+     +------+    |
   +---------+RUNNING<----->PAUSED|    |
   |         +--+-+--+     +------+    |
   |            | |                    |
   |            | +------------------+ |
   |            |                    | |
   |         +--v--+       +-------+ | |
   +---------+READY<------->STANDBY| | |
   |         +--+--+       +-------+ | |
   |            |                    | |
   |         +--v----+               | |
   +---------+WAITING+---------------+ |
   |         +--+----+                 |
   |            |                      |
   |         +--v----+                 |
   +---------+PENDING|                 |
   |         +--+----+                 |
   |            |                      |
+--v-----+   +--v------+               |
|ABORTING+--->CONCLUDED|               |
+--------+   +--+------+               |
                |                      |
             +--v-+                    |
             |NULL+--------------------+
             +----+

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockjob.c           | 66 +++++++++++++++++++++++++++++++++-------------------
 qapi/block-core.json | 31 +++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 25 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 4aed86fc6b..23b4b99fd4 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -44,27 +44,28 @@ static QemuMutex block_job_mutex;
 
 /* BlockJob State Transition Table */
 bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, W, X, E, N */
-    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
-    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
-    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0, 0},
-    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
-    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
-    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
-    /* W: */ [BLOCK_JOB_STATUS_WAITING]   = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
-    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
-    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
-    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+                                          /* U, C, R, P, Y, S, W, D, X, E, N */
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0},
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0},
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+    /* W: */ [BLOCK_JOB_STATUS_WAITING]   = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+    /* D: */ [BLOCK_JOB_STATUS_PENDING]   = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 };
 
 bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
-                                          /* U, C, R, P, Y, S, W, X, E, N */
-    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 1, 0, 0, 0},
-    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
-    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
-    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
-    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
-    [BLOCK_JOB_VERB_DISMISS]              = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
+                                          /* U, C, R, P, Y, S, W, D, X, E, N */
+    [BLOCK_JOB_VERB_CANCEL]               = {0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0},
+    [BLOCK_JOB_VERB_PAUSE]                = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_DISMISS]              = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
 };
 
 static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
@@ -119,6 +120,7 @@ static void __attribute__((__constructor__)) block_job_init(void)
 static void block_job_event_cancelled(BlockJob *job);
 static void block_job_event_completed(BlockJob *job, const char *msg);
 static void block_job_event_concluded(BlockJob *job);
+static int block_job_event_pending(BlockJob *job);
 static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job));
 
 /* Transactional group of block jobs */
@@ -481,17 +483,21 @@ static void block_job_cancel_async(BlockJob *job)
     job->cancelled = true;
 }
 
-static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *))
+static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *), bool lock)
 {
     AioContext *ctx;
     BlockJob *job, *next;
     int rc;
 
     QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
-        ctx = blk_get_aio_context(job->blk);
-        aio_context_acquire(ctx);
+        if (lock) {
+            ctx = blk_get_aio_context(job->blk);
+            aio_context_acquire(ctx);
+        }
         rc = fn(job);
-        aio_context_release(ctx);
+        if (lock) {
+            aio_context_release(ctx);
+        }
         if (rc) {
             break;
         }
@@ -601,14 +607,15 @@ static void block_job_completed_txn_success(BlockJob *job)
     }
 
     /* Jobs may require some prep-work to complete without failure */
-    rc = block_job_txn_apply(txn, block_job_prepare);
+    rc = block_job_txn_apply(txn, block_job_prepare, true);
     if (rc) {
         block_job_completed_txn_abort(job);
         return;
     }
 
     /* We are the last completed job, commit the transaction. */
-    block_job_txn_apply(txn, block_job_completed_single);
+    block_job_txn_apply(txn, block_job_event_pending, false);
+    block_job_txn_apply(txn, block_job_completed_single, true);
 }
 
 /* Assumes the block_job_mutex is held */
@@ -817,6 +824,17 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
                                         &error_abort);
 }
 
+static int block_job_event_pending(BlockJob *job)
+{
+    block_job_state_transition(job, BLOCK_JOB_STATUS_PENDING);
+    if (job->manual && !block_job_is_internal(job)) {
+        qapi_event_send_block_job_pending(job->driver->job_type,
+                                          job->id,
+                                          &error_abort);
+    }
+    return 0;
+}
+
 static void block_job_event_concluded(BlockJob *job)
 {
     block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3005aac7e2..acf9e56876 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1002,6 +1002,11 @@
 #           to the waiting state. This status will likely not be visible for
 #           the last job in a transaction.
 #
+# @pending: The job has finished its work, but has finalization steps that it
+#           needs to make prior to completing. These changes may require
+#           manual intervention by the management process if manual was set
+#           to true.
+#
 # @aborting: The job is in the process of being aborted, and will finish with
 #            an error. The job will afterwards report that it is @concluded.
 #            This status may not be visible to the management process.
@@ -1016,7 +1021,7 @@
 ##
 { 'enum': 'BlockJobStatus',
   'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby',
-           'waiting', 'aborting', 'concluded', 'null' ] }
+           'waiting', 'pending', 'aborting', 'concluded', 'null' ] }
 
 ##
 # @BlockJobInfo:
@@ -3961,6 +3966,30 @@
   'data': { 'type'  : 'BlockJobType',
             'id'    : 'str' } }
 
+##
+# @BLOCK_JOB_PENDING:
+#
+# Emitted when a block job is awaiting explicit authorization to finalize graph
+# changes via @block-job-finalize. If this job is part of a transaction, it will
+# not emit this event until the transaction has converged first.
+#
+# @type: job type
+#
+# @id: The job identifier.
+#
+# Since: 2.12
+#
+# Example:
+#
+# <- { "event": "BLOCK_JOB_WAITING",
+#      "data": { "device": "drive0", "type": "mirror" },
+#      "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
+##
+{ 'event': 'BLOCK_JOB_PENDING',
+  'data': { 'type'  : 'BlockJobType',
+            'id'    : 'str' } }
+
 ##
 # @PreallocMode:
 #
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (16 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 20:13   ` Eric Blake
  2018-02-28 18:15   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property John Snow
                   ` (5 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Instead of automatically transitioning from PENDING to CONCLUDED, gate
the .prepare() and .commit() phases behind an explicit acknowledgement
provided by the QMP monitor if manual completion mode has been requested.

This allows us to perform graph changes in prepare and/or commit so that
graph changes do not occur autonomously without knowledge of the
controlling management layer.

Transactions that have reached the "PENDING" state together can all be
moved to invoke their finalization methods by issuing block_job_finalize
to any one job in the transaction.

Jobs in a transaction with mixed job->manual settings will remain stuck
in the "WAITING" state until block_job_finalize is authored on the job(s)
that have reached the "PENDING" state.

These jobs are not allowed to progress because other jobs in the
transaction may still fail during their preparation phase during
finalization, so these jobs must remain in the WAITING phase until
success is guaranteed. These jobs will then automatically dismiss
themselves, but jobs that had the manual property set will remain
at CONCLUDED as normal.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 block/trace-events       |  1 +
 blockdev.c               | 14 ++++++++++
 blockjob.c               | 69 +++++++++++++++++++++++++++++++++++++-----------
 include/block/blockjob.h | 17 ++++++++++++
 qapi/block-core.json     | 23 +++++++++++++++-
 5 files changed, 108 insertions(+), 16 deletions(-)

diff --git a/block/trace-events b/block/trace-events
index 5e531e0310..a81b66ff36 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -51,6 +51,7 @@ qmp_block_job_cancel(void *job) "job %p"
 qmp_block_job_pause(void *job) "job %p"
 qmp_block_job_resume(void *job) "job %p"
 qmp_block_job_complete(void *job) "job %p"
+qmp_block_job_finalize(void *job) "job %p"
 qmp_block_job_dismiss(void *job) "job %p"
 qmp_block_stream(void *bs, void *job) "bs %p job %p"
 
diff --git a/blockdev.c b/blockdev.c
index 3180130782..05fd421cdc 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3852,6 +3852,20 @@ void qmp_block_job_complete(const char *device, Error **errp)
     aio_context_release(aio_context);
 }
 
+void qmp_block_job_finalize(const char *id, Error **errp)
+{
+    AioContext *aio_context;
+    BlockJob *job = find_block_job(id, &aio_context, errp);
+
+    if (!job) {
+        return;
+    }
+
+    trace_qmp_block_job_finalize(job);
+    block_job_finalize(job, errp);
+    aio_context_release(aio_context);
+}
+
 void qmp_block_job_dismiss(const char *id, Error **errp)
 {
     AioContext *aio_context;
diff --git a/blockjob.c b/blockjob.c
index 23b4b99fd4..f9e8a64261 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -65,14 +65,15 @@ bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
     [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
     [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
     [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+    [BLOCK_JOB_VERB_FINALIZE]             = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
     [BLOCK_JOB_VERB_DISMISS]              = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
 };
 
-static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
+static bool block_job_state_transition(BlockJob *job, BlockJobStatus s1)
 {
     BlockJobStatus s0 = job->status;
     if (s0 == s1) {
-        return;
+        return false;
     }
     assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
     trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
@@ -83,6 +84,7 @@ static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
                                                       s1));
     assert(BlockJobSTT[s0][s1]);
     job->status = s1;
+    return true;
 }
 
 static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
@@ -432,7 +434,7 @@ static void block_job_clean(BlockJob *job)
     }
 }
 
-static int block_job_completed_single(BlockJob *job)
+static int block_job_finalize_single(BlockJob *job)
 {
     assert(job->completed);
 
@@ -581,18 +583,44 @@ static void block_job_completed_txn_abort(BlockJob *job)
             assert(other_job->cancelled);
             block_job_finish_sync(other_job, NULL, NULL);
         }
-        block_job_completed_single(other_job);
+        block_job_finalize_single(other_job);
         aio_context_release(ctx);
     }
 
     block_job_txn_unref(txn);
 }
 
+static int block_job_is_manual(BlockJob *job)
+{
+    return job->manual;
+}
+
+static void block_job_do_finalize(BlockJob *job)
+{
+    int rc;
+    assert(job && job->txn);
+
+    /* For jobs set !job->manual, transition to pending synchronously now */
+    block_job_txn_apply(job->txn, block_job_event_pending, false);
+
+    /* prepare the transaction to complete */
+    rc = block_job_txn_apply(job->txn, block_job_prepare, true);
+    if (rc) {
+        block_job_completed_txn_abort(job);
+    } else {
+        block_job_txn_apply(job->txn, block_job_finalize_single, true);
+    }
+}
+
+static int block_job_pending_conditional(BlockJob *job)
+{
+    return job->manual ? block_job_event_pending(job) : 0;
+}
+
 static void block_job_completed_txn_success(BlockJob *job)
 {
     BlockJobTxn *txn = job->txn;
     BlockJob *other_job;
-    int rc = 0;
 
     block_job_state_transition(job, BLOCK_JOB_STATUS_WAITING);
 
@@ -606,16 +634,15 @@ static void block_job_completed_txn_success(BlockJob *job)
         }
     }
 
-    /* Jobs may require some prep-work to complete without failure */
-    rc = block_job_txn_apply(txn, block_job_prepare, true);
-    if (rc) {
-        block_job_completed_txn_abort(job);
-        return;
-    }
+    /* For jobs with (job->manual), transition to the PENDING state.
+     * jobs with !job->manual are left WAITING (on their pending comrades). */
+    block_job_txn_apply(txn, block_job_pending_conditional, false);
 
-    /* We are the last completed job, commit the transaction. */
-    block_job_txn_apply(txn, block_job_event_pending, false);
-    block_job_txn_apply(txn, block_job_completed_single, true);
+    /* Transactions with any manual jobs must await finalization.
+     * do_finalize will handle lingering WAITING->PENDING transitions. */
+    if (!block_job_txn_apply(txn, block_job_is_manual, false)) {
+        block_job_do_finalize(job);
+    }
 }
 
 /* Assumes the block_job_mutex is held */
@@ -667,6 +694,15 @@ void block_job_complete(BlockJob *job, Error **errp)
     job->driver->complete(job, errp);
 }
 
+void block_job_finalize(BlockJob *job, Error **errp)
+{
+    assert(job && job->id && job->txn);
+    if (block_job_apply_verb(job, BLOCK_JOB_VERB_FINALIZE, errp)) {
+        return;
+    }
+    block_job_do_finalize(job);
+}
+
 void block_job_dismiss(BlockJob **jobptr, Error **errp)
 {
     BlockJob *job = *jobptr;
@@ -826,7 +862,10 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
 
 static int block_job_event_pending(BlockJob *job)
 {
-    block_job_state_transition(job, BLOCK_JOB_STATUS_PENDING);
+    /* If we're already pending, don't re-announce */
+    if (!block_job_state_transition(job, BLOCK_JOB_STATUS_PENDING)) {
+        return 0;
+    }
     if (job->manual && !block_job_is_internal(job)) {
         qapi_event_send_block_job_pending(job->driver->job_type,
                                           job->id,
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 9bb0be1b13..e09064c342 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -245,6 +245,23 @@ void block_job_cancel(BlockJob *job);
  */
 void block_job_complete(BlockJob *job, Error **errp);
 
+
+/**
+ * block_job_finalize:
+ * @job: The job to fully commit and finish.
+ * @errp: Error object.
+ *
+ * For jobs that have finished their work and are pending
+ * awaiting explicit acknowledgement to commit their work,
+ * This will commit that work.
+ *
+ * FIXME: Make the below statement universally true:
+ * For jobs that support the manual workflow mode, all graph
+ * changes that occur as a result will occur after this command
+ * and before a successful reply.
+ */
+void block_job_finalize(BlockJob *job, Error **errp);
+
 /**
  * block_job_dismiss:
  * @job: The job to be dismissed.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index acf9e56876..549c6c02d8 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -972,10 +972,13 @@
 #
 # @dismiss: see @block-job-dismiss
 #
+# @finalize: see @block-job-finalize
+#
 # Since: 2.12
 ##
 { 'enum': 'BlockJobVerb',
-  'data': ['cancel', 'pause', 'resume', 'set-speed', 'complete', 'dismiss' ] }
+  'data': ['cancel', 'pause', 'resume', 'set-speed', 'complete', 'dismiss',
+           'finalize' ] }
 
 ##
 # @BlockJobStatus:
@@ -2274,6 +2277,24 @@
 ##
 { 'command': 'block-job-dismiss', 'data': { 'id': 'str' } }
 
+##
+# @block-job-finalize:
+#
+# Once a job that has manual=true reaches the pending state, it can be
+# instructed to finalize any graph changes and do any necessary cleanup
+# via this command.
+# For jobs in a transaction, instructing one job to finalize will force
+# ALL jobs in the transaction to finalize, so it is only necessary to instruct
+# a single member job to finalize.
+#
+# @id: The job identifier.
+#
+# Returns: Nothing on success
+#
+# Since: 2.12
+##
+{ 'command': 'block-job-finalize', 'data': { 'id': 'str' } }
+
 ##
 # @BlockdevDiscardOptions:
 #
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (17 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 20:16   ` Eric Blake
  2018-02-28 18:25   ` Kevin Wolf
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 20/21] iotests: test manual job dismissal John Snow
                   ` (4 subsequent siblings)
  23 siblings, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Expose the "manual" property via QAPI for the backup-related jobs.
As of this commit, this allows the management API to request the
"concluded" and "dismiss" semantics for backup jobs.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockdev.c           | 19 ++++++++++++++++---
 qapi/block-core.json | 32 ++++++++++++++++++++++++++------
 2 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 05fd421cdc..2eddb0e726 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3260,7 +3260,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
     AioContext *aio_context;
     QDict *options = NULL;
     Error *local_err = NULL;
-    int flags;
+    int flags, job_flags = BLOCK_JOB_DEFAULT;
     int64_t size;
     bool set_backing_hd = false;
 
@@ -3279,6 +3279,9 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
     if (!backup->has_job_id) {
         backup->job_id = NULL;
     }
+    if (!backup->has_manual) {
+        backup->manual = false;
+    }
     if (!backup->has_compress) {
         backup->compress = false;
     }
@@ -3370,11 +3373,14 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
             goto out;
         }
     }
+    if (backup->manual) {
+        job_flags |= BLOCK_JOB_MANUAL;
+    }
 
     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
                             backup->sync, bmap, backup->compress,
                             backup->on_source_error, backup->on_target_error,
-                            BLOCK_JOB_DEFAULT, NULL, NULL, txn, &local_err);
+                            job_flags, NULL, NULL, txn, &local_err);
     bdrv_unref(target_bs);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
@@ -3409,6 +3415,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
     Error *local_err = NULL;
     AioContext *aio_context;
     BlockJob *job = NULL;
+    int job_flags = BLOCK_JOB_DEFAULT;
 
     if (!backup->has_speed) {
         backup->speed = 0;
@@ -3422,6 +3429,9 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
     if (!backup->has_job_id) {
         backup->job_id = NULL;
     }
+    if (!backup->has_manual) {
+        backup->manual = false;
+    }
     if (!backup->has_compress) {
         backup->compress = false;
     }
@@ -3450,10 +3460,13 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
             goto out;
         }
     }
+    if (backup->manual) {
+        job_flags |= BLOCK_JOB_MANUAL;
+    }
     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
                             backup->sync, NULL, backup->compress,
                             backup->on_source_error, backup->on_target_error,
-                            BLOCK_JOB_DEFAULT, NULL, NULL, txn, &local_err);
+                            job_flags, NULL, NULL, txn, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
     }
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 549c6c02d8..7b3af93682 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1177,6 +1177,16 @@
 # @job-id: identifier for the newly-created block job. If
 #          omitted, the device name will be used. (Since 2.7)
 #
+# @manual: True to use an expanded, more explicit job control flow.
+#          Jobs may transition from a running state to a pending state,
+#          where they must be instructed to complete manually via
+#          block-job-finalize.
+#          Jobs belonging to a transaction must either all or all not use this
+#          setting. Once a transaction reaches a pending state, issuing the
+#          finalize command to any one job in the transaction is sufficient
+#          to finalize the entire transaction.
+#          (Since 2.12)
+#
 # @device: the device name or node-name of a root node which should be copied.
 #
 # @target: the target of the new image. If the file exists, or if it
@@ -1217,9 +1227,10 @@
 # Since: 1.6
 ##
 { 'struct': 'DriveBackup',
-  'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
-            '*format': 'str', 'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
-            '*speed': 'int', '*bitmap': 'str', '*compress': 'bool',
+  'data': { '*job-id': 'str', '*manual': 'bool', 'device': 'str',
+            'target': 'str', '*format': 'str', 'sync': 'MirrorSyncMode',
+            '*mode': 'NewImageMode', '*speed': 'int',
+            '*bitmap': 'str', '*compress': 'bool',
             '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError' } }
 
@@ -1229,6 +1240,16 @@
 # @job-id: identifier for the newly-created block job. If
 #          omitted, the device name will be used. (Since 2.7)
 #
+# @manual: True to use an expanded, more explicit job control flow.
+#          Jobs may transition from a running state to a pending state,
+#          where they must be instructed to complete manually via
+#          block-job-finalize.
+#          Jobs belonging to a transaction must either all or all not use this
+#          setting. Once a transaction reaches a pending state, issuing the
+#          finalize command to any one job in the transaction is sufficient
+#          to finalize the entire transaction.
+#          (Since 2.12)
+#
 # @device: the device name or node-name of a root node which should be copied.
 #
 # @target: the device name or node-name of the backup target node.
@@ -1258,9 +1279,8 @@
 # Since: 2.3
 ##
 { 'struct': 'BlockdevBackup',
-  'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
-            'sync': 'MirrorSyncMode',
-            '*speed': 'int',
+  'data': { '*job-id': 'str', '*manual': 'bool', 'device': 'str',
+            'target': 'str', 'sync': 'MirrorSyncMode', '*speed': 'int',
             '*compress': 'bool',
             '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError' } }
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 20/21] iotests: test manual job dismissal
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (18 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 20:21   ` Eric Blake
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions John Snow
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/qemu-iotests/056     | 195 +++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/056.out |   4 +-
 2 files changed, 197 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
index 04f2c3c841..bc21ba9af8 100755
--- a/tests/qemu-iotests/056
+++ b/tests/qemu-iotests/056
@@ -29,6 +29,26 @@ backing_img = os.path.join(iotests.test_dir, 'backing.img')
 test_img = os.path.join(iotests.test_dir, 'test.img')
 target_img = os.path.join(iotests.test_dir, 'target.img')
 
+def img_create(img, fmt=iotests.imgfmt, size='64M', **kwargs):
+    fullname = os.path.join(iotests.test_dir, '%s.%s' % (img, fmt))
+    optargs = []
+    for k,v in kwargs.iteritems():
+        optargs = optargs + ['-o', '%s=%s' % (k,v)]
+    args = ['create', '-f', fmt] + optargs + [fullname, size]
+    iotests.qemu_img(*args)
+    return fullname
+
+def try_remove(img):
+    try:
+        os.remove(img)
+    except OSError:
+        pass
+
+def io_write_patterns(img, patterns):
+    for pattern in patterns:
+        iotests.qemu_io('-c', 'write -P%s %s %s' % pattern, img)
+
+
 class TestSyncModesNoneAndTop(iotests.QMPTestCase):
     image_len = 64 * 1024 * 1024 # MB
 
@@ -108,5 +128,180 @@ class TestBeforeWriteNotifier(iotests.QMPTestCase):
         event = self.cancel_and_wait()
         self.assert_qmp(event, 'data/type', 'backup')
 
+class BackupTest(iotests.QMPTestCase):
+    def setUp(self):
+        self.vm = iotests.VM()
+        self.test_img = img_create('test')
+        self.dest_img = img_create('dest')
+        self.vm.add_drive(self.test_img)
+        self.vm.launch()
+
+    def tearDown(self):
+        self.vm.shutdown()
+        try_remove(self.test_img)
+        try_remove(self.dest_img)
+
+    def hmp_io_writes(self, drive, patterns):
+        for pattern in patterns:
+            self.vm.hmp_qemu_io(drive, 'write -P%s %s %s' % pattern)
+        self.vm.hmp_qemu_io(drive, 'flush')
+
+    def qmp_job_pending_wait(self, device):
+        event = self.vm.event_wait(name="BLOCK_JOB_PENDING",
+                                   match={'data': {'id': device}})
+        self.assertNotEqual(event, None)
+        res = self.vm.qmp("block-job-finalize", id=device)
+        self.assert_qmp(res, 'return', {})
+
+    def qmp_backup_and_wait(self, cmd='drive-backup', serror=None,
+                            aerror=None, **kwargs):
+        if not self.qmp_backup(cmd, serror, **kwargs):
+            return False
+        if 'manual' in kwargs and kwargs['manual']:
+                self.qmp_job_pending_wait(kwargs['device'])
+        return self.qmp_backup_wait(kwargs['device'], aerror)
+
+    def qmp_backup(self, cmd='drive-backup',
+                   error=None, **kwargs):
+        self.assertTrue('device' in kwargs)
+        res = self.vm.qmp(cmd, **kwargs)
+        if error:
+            self.assert_qmp(res, 'error/desc', error)
+            return False
+        self.assert_qmp(res, 'return', {})
+        return True
+
+    def qmp_backup_wait(self, device, error=None):
+        event = self.vm.event_wait(name="BLOCK_JOB_COMPLETED",
+                                   match={'data': {'device': device}})
+        self.assertNotEqual(event, None)
+        try:
+            failure = self.dictpath(event, 'data/error')
+        except AssertionError:
+            # Backup succeeded.
+            self.assert_qmp(event, 'data/offset', event['data']['len'])
+            return True
+        else:
+            # Failure.
+            self.assert_qmp(event, 'data/error', qerror)
+            return False
+
+    def test_dismiss_false(self):
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+        self.qmp_backup_and_wait(device='drive0', format=iotests.imgfmt,
+                                 sync='full', target=self.dest_img, manual=False)
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+
+    def test_dismiss_true(self):
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+        self.qmp_backup_and_wait(device='drive0', format=iotests.imgfmt,
+                                 sync='full', target=self.dest_img, manual=True)
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return[0]/status', 'concluded')
+        res = self.vm.qmp('block-job-dismiss', id='drive0')
+        self.assert_qmp(res, 'return', {})
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+
+    def test_dismiss_bad_id(self):
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+        res = self.vm.qmp('block-job-dismiss', id='foobar')
+        self.assert_qmp(res, 'error/class', 'DeviceNotActive')
+
+    def test_dismiss_collision(self):
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+        self.qmp_backup_and_wait(device='drive0', format=iotests.imgfmt,
+                                 sync='full', target=self.dest_img, manual=True)
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return[0]/status', 'concluded')
+        # Leave zombie job un-dismissed, observe a failure:
+        res = self.qmp_backup_and_wait(serror='Need a root block node',
+                                       device='drive0', format=iotests.imgfmt,
+                                       sync='full', target=self.dest_img,
+                                       manual=True)
+        self.assertEqual(res, False)
+        # OK, dismiss the zombie.
+        res = self.vm.qmp('block-job-dismiss', id='drive0')
+        self.assert_qmp(res, 'return', {})
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+        # Ensure it's really gone.
+        self.qmp_backup_and_wait(device='drive0', format=iotests.imgfmt,
+                                 sync='full', target=self.dest_img, manual=True)
+
+    def dismissal_failure(self, manual_opt):
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return', [])
+        # Give blkdebug something to chew on
+        self.hmp_io_writes('drive0',
+                           (('0x9a', 0, 512),
+                           ('0x55', '8M', '352k'),
+                           ('0x78', '15872k', '1M')))
+        # Add destination node via blkdebug
+        res = self.vm.qmp('blockdev-add',
+                          node_name='target0',
+                          driver=iotests.imgfmt,
+                          file={
+                              'driver': 'blkdebug',
+                              'image': {
+                                  'driver': 'file',
+                                  'filename': self.dest_img
+                              },
+                              'inject-error': [{
+                                  'event': 'write_aio',
+                                  'errno': 5,
+                                  'immediately': False,
+                                  'once': True
+                              }],
+                          })
+        self.assert_qmp(res, 'return', {})
+
+        res = self.qmp_backup(cmd='blockdev-backup',
+                              device='drive0', target='target0',
+                              on_target_error='stop',
+                              sync='full',
+                              manual=manual_opt)
+        self.assertTrue(res)
+        event = self.vm.event_wait(name="BLOCK_JOB_ERROR",
+                                   match={'data': {'device': 'drive0'}})
+        self.assertNotEqual(event, None)
+        # OK, job should be wedged
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return[0]/status', 'paused')
+        res = self.vm.qmp('block-job-dismiss', id='drive0')
+        self.assert_qmp(res, 'error/desc',
+                        "Job 'drive0' in state 'paused' cannot accept"
+                        " command verb 'dismiss'")
+        res = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(res, 'return[0]/status', 'paused')
+        # OK, unstick job and move forward.
+        res = self.vm.qmp('block-job-resume', device='drive0')
+        self.assert_qmp(res, 'return', {})
+        if manual_opt:
+            # Job is now PENDING. Wait and finalize it.
+            self.qmp_job_pending_wait('drive0')
+        # And now we need to wait for it to conclude;
+        res = self.qmp_backup_wait(device='drive0')
+        self.assertTrue(res)
+        if manual_opt:
+            # Job should now be languishing:
+            res = self.vm.qmp('query-block-jobs')
+            self.assert_qmp(res, 'return[0]/status', 'concluded')
+            res = self.vm.qmp('block-job-dismiss', id='drive0')
+            self.assert_qmp(res, 'return', {})
+            res = self.vm.qmp('query-block-jobs')
+            self.assert_qmp(res, 'return', [])
+
+    def test_dismiss_premature(self):
+        self.dismissal_failure(True)
+
+    def test_dismiss_erroneous(self):
+        self.dismissal_failure(False)
+
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2', 'qed'])
diff --git a/tests/qemu-iotests/056.out b/tests/qemu-iotests/056.out
index 8d7e996700..dae404e278 100644
--- a/tests/qemu-iotests/056.out
+++ b/tests/qemu-iotests/056.out
@@ -1,5 +1,5 @@
-...
+.........
 ----------------------------------------------------------------------
-Ran 3 tests
+Ran 9 tests
 
 OK
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (19 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 20/21] iotests: test manual job dismissal John Snow
@ 2018-02-23 23:51 ` John Snow
  2018-02-27 20:24   ` Eric Blake
  2018-02-24  0:30 ` [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management no-reply
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-23 23:51 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel, John Snow

This allows us to easily force the option for all jobs belonging
to a transaction to ensure consistency with how all those jobs
will be handled.

This is purely a convenience.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockdev.c                |  7 ++++++-
 blockjob.c                | 10 +++++++---
 include/block/blockjob.h  |  5 ++++-
 qapi/transaction.json     |  3 ++-
 tests/test-blockjob-txn.c |  6 +++---
 5 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 2eddb0e726..34181c41c2 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2225,6 +2225,11 @@ static TransactionProperties *get_transaction_properties(
         props->completion_mode = ACTION_COMPLETION_MODE_INDIVIDUAL;
     }
 
+    if (!props->has_manual_mgmt) {
+        props->has_manual_mgmt = true;
+        props->manual_mgmt = false;
+    }
+
     return props;
 }
 
@@ -2250,7 +2255,7 @@ void qmp_transaction(TransactionActionList *dev_list,
      */
     props = get_transaction_properties(props);
     if (props->completion_mode != ACTION_COMPLETION_MODE_INDIVIDUAL) {
-        block_job_txn = block_job_txn_new();
+        block_job_txn = block_job_txn_new(props->manual_mgmt);
     }
 
     /* drain all i/o before any operations */
diff --git a/blockjob.c b/blockjob.c
index f9e8a64261..eaaa2aea65 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -136,6 +136,9 @@ struct BlockJobTxn {
 
     /* Reference count */
     int refcnt;
+
+    /* Participating jobs must use manual completion */
+    bool manual;
 };
 
 static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
@@ -176,11 +179,12 @@ BlockJob *block_job_get(const char *id)
     return NULL;
 }
 
-BlockJobTxn *block_job_txn_new(void)
+BlockJobTxn *block_job_txn_new(bool manual_mgmt)
 {
     BlockJobTxn *txn = g_new0(BlockJobTxn, 1);
     QLIST_INIT(&txn->jobs);
     txn->refcnt = 1;
+    txn->manual = manual_mgmt;
     return txn;
 }
 
@@ -944,7 +948,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
     job->paused        = true;
     job->pause_count   = 1;
     job->refcnt        = 1;
-    job->manual        = (flags & BLOCK_JOB_MANUAL);
+    job->manual        = (flags & BLOCK_JOB_MANUAL) || (txn && txn->manual);
     job->status        = BLOCK_JOB_STATUS_CREATED;
     block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
     aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
@@ -978,7 +982,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
     /* Single jobs are modeled as single-job transactions for sake of
      * consolidating the job management logic */
     if (!txn) {
-        txn = block_job_txn_new();
+        txn = block_job_txn_new(false);
         block_job_txn_add_job(txn, job);
         block_job_txn_unref(txn);
     } else {
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index e09064c342..f3d026f13d 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -371,8 +371,11 @@ void block_job_iostatus_reset(BlockJob *job);
  * All jobs in the transaction either complete successfully or fail/cancel as a
  * group.  Jobs wait for each other before completing.  Cancelling one job
  * cancels all jobs in the transaction.
+ *
+ * @manual_mgmt: whether or not jobs that belong to this transaction will be
+ *               forced to use 2.12+ job management semantics
  */
-BlockJobTxn *block_job_txn_new(void);
+BlockJobTxn *block_job_txn_new(bool manual_mgmt);
 
 /**
  * block_job_ref:
diff --git a/qapi/transaction.json b/qapi/transaction.json
index bd312792da..9611758cb6 100644
--- a/qapi/transaction.json
+++ b/qapi/transaction.json
@@ -79,7 +79,8 @@
 ##
 { 'struct': 'TransactionProperties',
   'data': {
-       '*completion-mode': 'ActionCompletionMode'
+       '*completion-mode': 'ActionCompletionMode',
+       '*manual-mgmt': 'bool'
   }
 }
 
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
index 34f09ef8c1..2d84f9a41e 100644
--- a/tests/test-blockjob-txn.c
+++ b/tests/test-blockjob-txn.c
@@ -119,7 +119,7 @@ static void test_single_job(int expected)
     BlockJobTxn *txn;
     int result = -EINPROGRESS;
 
-    txn = block_job_txn_new();
+    txn = block_job_txn_new(false);
     job = test_block_job_start(1, true, expected, &result, txn);
     block_job_start(job);
 
@@ -158,7 +158,7 @@ static void test_pair_jobs(int expected1, int expected2)
     int result1 = -EINPROGRESS;
     int result2 = -EINPROGRESS;
 
-    txn = block_job_txn_new();
+    txn = block_job_txn_new(false);
     job1 = test_block_job_start(1, true, expected1, &result1, txn);
     job2 = test_block_job_start(2, true, expected2, &result2, txn);
     block_job_start(job1);
@@ -220,7 +220,7 @@ static void test_pair_jobs_fail_cancel_race(void)
     int result1 = -EINPROGRESS;
     int result2 = -EINPROGRESS;
 
-    txn = block_job_txn_new();
+    txn = block_job_txn_new(false);
     job1 = test_block_job_start(1, true, -ECANCELED, &result1, txn);
     job2 = test_block_job_start(2, false, 0, &result2, txn);
     block_job_start(job1);
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (20 preceding siblings ...)
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions John Snow
@ 2018-02-24  0:30 ` no-reply
  2018-02-24 14:31 ` no-reply
  2018-02-25 23:25 ` no-reply
  23 siblings, 0 replies; 98+ messages in thread
From: no-reply @ 2018-02-24  0:30 UTC (permalink / raw)
  To: jsnow; +Cc: famz, qemu-block, kwolf, pkrempa, jtc, qemu-devel

Hi,

This series failed build test on ppcbe host. Please find the details below.

Type: series
Message-id: 20180223235142.21501-1-jsnow@redhat.com
Subject: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management

=== TEST SCRIPT BEGIN ===
#!/bin/bash
# Testing script will be invoked under the git checkout with
# HEAD pointing to a commit that has the patches applied on top of "base"
# branch
set -e
echo "=== ENV ==="
env
echo "=== PACKAGES ==="
rpm -qa
echo "=== TEST BEGIN ==="
INSTALL=$PWD/install
BUILD=$PWD/build
mkdir -p $BUILD $INSTALL
SRC=$PWD
cd $BUILD
$SRC/configure --prefix=$INSTALL
make -j100
# XXX: we need reliable clean up
# make check -j100 V=1
make install
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/20180223153636.29809-1-alex.bennee@linaro.org -> patchew/20180223153636.29809-1-alex.bennee@linaro.org
 * [new tag]         patchew/20180223235142.21501-1-jsnow@redhat.com -> patchew/20180223235142.21501-1-jsnow@redhat.com
Submodule 'capstone' (git://git.qemu.org/capstone.git) registered for path 'capstone'
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (git://git.qemu.org/QemuMacDrivers.git) registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (git://git.qemu-project.org/SLOF.git) registered for path 'roms/SLOF'
Submodule 'roms/ipxe' (git://git.qemu-project.org/ipxe.git) registered for path 'roms/ipxe'
Submodule 'roms/openbios' (git://git.qemu-project.org/openbios.git) registered for path 'roms/openbios'
Submodule 'roms/openhackware' (git://git.qemu-project.org/openhackware.git) registered for path 'roms/openhackware'
Submodule 'roms/qemu-palcode' (git://github.com/rth7680/qemu-palcode.git) registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (git://git.qemu-project.org/seabios.git/) registered for path 'roms/seabios'
Submodule 'roms/seabios-hppa' (git://github.com/hdeller/seabios-hppa.git) registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (git://git.qemu-project.org/sgabios.git) registered for path 'roms/sgabios'
Submodule 'roms/skiboot' (git://git.qemu.org/skiboot.git) registered for path 'roms/skiboot'
Submodule 'roms/u-boot' (git://git.qemu-project.org/u-boot.git) registered for path 'roms/u-boot'
Submodule 'roms/vgabios' (git://git.qemu-project.org/vgabios.git/) registered for path 'roms/vgabios'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out '22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 'd4e7d7ac663fcb55f1b93575445fcbca372f17a7'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 'fa981320a1e0968d6fc1b8de319723ff8212b337'
Cloning into 'roms/ipxe'...
Submodule path 'roms/ipxe': checked out '0600d3ae94f93efd10fc6b3c7420a9557a3a1670'
Cloning into 'roms/openbios'...
Submodule path 'roms/openbios': checked out '54d959d97fb331708767b2fd4a878efd2bbc41bb'
Cloning into 'roms/openhackware'...
Submodule path 'roms/openhackware': checked out 'c559da7c8eec5e45ef1f67978827af6f0b9546f5'
Cloning into 'roms/qemu-palcode'...
Submodule path 'roms/qemu-palcode': checked out 'f3c7e44c70254975df2a00af39701eafbac4d471'
Cloning into 'roms/seabios'...
Submodule path 'roms/seabios': checked out '63451fca13c75870e1703eb3e20584d91179aebc'
Cloning into 'roms/seabios-hppa'...
Submodule path 'roms/seabios-hppa': checked out '649e6202b8d65d46c69f542b1380f840fbe8ab13'
Cloning into 'roms/sgabios'...
Submodule path 'roms/sgabios': checked out 'cbaee52287e5f32373181cff50a00b6c4ac9015a'
Cloning into 'roms/skiboot'...
Submodule path 'roms/skiboot': checked out 'e0ee24c27a172bcf482f6f2bc905e6211c134bcc'
Cloning into 'roms/u-boot'...
Submodule path 'roms/u-boot': checked out 'd85ca029f257b53a96da6c2fb421e78a003a9943'
Cloning into 'roms/vgabios'...
Submodule path 'roms/vgabios': checked out '19ea12c230ded95928ecaef0db47a82231c2e485'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out '6b3d716e2b6472eb7189d3220552280ef3d832ce'
Switched to a new branch 'test'
230e578 blockjobs: add manual_mgmt option to transactions
f278a51 iotests: test manual job dismissal
8e473ab blockjobs: Expose manual property
7ad2d01 blockjobs: add block-job-finalize
3857c91 blockjobs: add PENDING status and event
18eb8a4 blockjobs: add waiting status
daf9613 blockjobs: add prepare callback
78be501 blockjobs: add block_job_txn_apply function
4b659ab blockjobs: add commit, abort, clean helpers
4023046 blockjobs: ensure abort is called for cancelled jobs
e9300b1 blockjobs: add block_job_dismiss
4fc045e blockjobs: add NULL state
e6aa454 blockjobs: add CONCLUDED state
78efa2f blockjobs: add ABORTING state
057ad24 blockjobs: add block_job_verb permission table
c62c5b7 iotests: add pause_wait
4aadb9c blockjobs: add state transition table
afc594c blockjobs: add status enum
434d381 blockjobs: add manual property
fc3e3ee blockjobs: model single jobs as transactions
8d32662 blockjobs: fix set-speed kick

=== OUTPUT BEGIN ===
=== ENV ===
XDG_SESSION_ID=29961
SHELL=/bin/sh
USER=patchew
PATCHEW=./patchew-cli -s https://patchew.org
PATH=/usr/bin:/bin
PWD=/var/tmp/patchew-tester-tmp-84g4a1ey/src
LANG=en_US.UTF-8
HOME=/home/patchew
SHLVL=2
LOGNAME=patchew
XDG_RUNTIME_DIR=/run/user/1000
_=/usr/bin/env
=== PACKAGES ===
telepathy-filesystem-0.0.2-6.el7.noarch
ipa-common-4.5.0-20.el7.centos.noarch
ipa-client-common-4.5.0-20.el7.centos.noarch
nhn-nanum-fonts-common-3.020-9.el7.noarch
perl-srpm-macros-1-8.el7.noarch
glibc-common-2.17-196.el7.ppc64
zlib-1.2.7-17.el7.ppc64
nss-util-3.28.4-3.el7.ppc64
libSM-1.2.2-2.el7.ppc64
avahi-libs-0.6.31-17.el7.ppc64
libogg-1.3.0-7.el7.ppc64
libtevent-0.9.31-1.el7.ppc64
libicu-50.1.2-15.el7.ppc64
libXext-1.3.3-3.el7.ppc64
libXinerama-1.1.3-2.1.el7.ppc64
boost-system-1.53.0-27.el7.ppc64
xz-5.2.2-1.el7.ppc64
apr-1.4.8-3.el7.ppc64
pixman-0.34.0-1.el7.ppc64
libplist-1.12-3.el7.ppc64
boost-thread-1.53.0-27.el7.ppc64
libraw1394-2.1.0-2.el7.ppc64
newt-0.52.15-4.el7.ppc64
unixODBC-2.3.1-11.el7.ppc64
groff-base-1.22.2-8.el7.ppc64
psmisc-22.20-15.el7.ppc64
libpfm-4.7.0-4.el7.ppc64
perl-parent-0.225-244.el7.noarch
perl-libs-5.16.3-292.el7.ppc64
perl-Scalar-List-Utils-1.27-248.el7.ppc64
perl-Pod-Simple-3.28-4.el7.noarch
perl-Module-Load-0.24-3.el7.noarch
perl-Module-Pluggable-4.8-3.el7.noarch
perl-CPAN-Meta-2.120921-5.el7.noarch
perl-Object-Accessor-0.42-292.el7.noarch
perl-Module-Loaded-0.08-292.el7.noarch
boost-locale-1.53.0-27.el7.ppc64
fuse-2.9.2-8.el7.ppc64
xml-common-0.6.3-39.el7.noarch
libunistring-0.9.3-9.el7.ppc64
boost-math-1.53.0-27.el7.ppc64
yajl-2.0.4-4.el7.ppc64
libthai-0.1.14-9.el7.ppc64
libvisual-0.4.0-16.el7.ppc64
iptables-1.4.21-18.0.1.el7.centos.ppc64
teamd-1.25-5.el7.ppc64
perl-YAML-0.84-5.el7.noarch
perl-DBD-SQLite-1.39-3.el7.ppc64
perl-Pod-Coverage-0.23-3.el7.noarch
perl-HTML-Parser-3.71-4.el7.ppc64
perl-YAML-Tiny-1.51-6.el7.noarch
perl-FCGI-0.74-8.el7.ppc64
device-mapper-persistent-data-0.7.0-0.1.rc6.el7.ppc64
lzop-1.03-10.el7.ppc64
tcp_wrappers-devel-7.6-77.el7.ppc64
vim-minimal-7.4.160-2.el7.ppc64
dyninst-9.3.1-1.el7.ppc64
check-0.9.9-5.el7.ppc64
lsof-4.87-4.el7.ppc64
redhat-menus-12.0.2-8.el7.noarch
fontconfig-2.10.95-11.el7.ppc64
libXft-2.3.2-2.el7.ppc64
json-glib-1.2.6-1.el7.ppc64
zlib-devel-1.2.7-17.el7.ppc64
imsettings-libs-1.6.3-9.el7.ppc64
glibmm24-2.50.0-1.el7.ppc64
gnome-icon-theme-3.12.0-1.el7.noarch
python-enum34-1.0.4-1.el7.noarch
pam-1.1.8-18.el7.ppc64
procps-ng-3.3.10-16.el7.ppc64
gettext-libs-0.19.8.1-2.el7.ppc64
libXext-devel-1.3.3-3.el7.ppc64
libXinerama-devel-1.1.3-2.1.el7.ppc64
xz-devel-5.2.2-1.el7.ppc64
libpinyin-0.9.93-4.el7.ppc64
e2fsprogs-1.42.9-10.el7.ppc64
pyparsing-1.5.6-9.el7.noarch
fipscheck-lib-1.4.1-6.el7.ppc64
systemtap-sdt-devel-3.1-3.el7.ppc64
perl-Module-Build-0.40.05-2.el7.noarch
elfutils-devel-0.168-8.el7.ppc64
python-pwquality-1.2.3-4.el7.ppc64
xdg-user-dirs-0.15-4.el7.ppc64
xorg-x11-xbitmaps-1.1.1-6.el7.noarch
p11-kit-devel-0.23.5-3.el7.ppc64
nettle-devel-2.7.1-8.el7.ppc64
python-qrcode-core-5.0.1-1.el7.noarch
python-inotify-0.9.4-4.el7.noarch
python-backports-ssl_match_hostname-3.4.0.2-4.el7.noarch
python-schedutils-0.4-6.el7.ppc64
python-beaker-1.5.4-10.el7.noarch
python-sss-murmur-1.15.2-50.el7.ppc64
blktrace-1.0.5-8.el7.ppc64
bind-libs-9.9.4-50.el7.ppc64
perl-HTML-Format-2.10-7.el7.noarch
freerdp-libs-1.0.2-10.el7.ppc64
nss-3.28.4-8.el7.ppc64
rpm-4.11.3-25.el7.ppc64
libuser-0.60-7.el7_1.ppc64
mailx-12.5-16.el7.ppc64
color-filesystem-1-13.el7.noarch
pcp-libs-3.11.8-7.el7.ppc64
libproxy-0.4.11-10.el7.ppc64
libreport-rhel-anaconda-bugzilla-2.1.11-38.el7.centos.ppc64
pcsc-lite-libs-1.8.8-6.el7.ppc64
libao-1.1.0-8.el7.ppc64
pth-2.0.7-23.el7.ppc64
yum-plugin-fastestmirror-1.1.31-42.el7.noarch
sgpio-1.2.0.10-13.el7.ppc64
libfastjson-0.99.4-2.el7.ppc64
lsscsi-0.27-6.el7.ppc64
util-linux-2.23.2-43.el7.ppc64
systemd-219-42.el7.ppc64
mesa-libGL-17.0.1-6.20170307.el7.ppc64
NetworkManager-glib-1.8.0-9.el7.ppc64
gstreamer-plugins-base-0.10.36-10.el7.ppc64
samba-common-4.6.2-8.el7.noarch
cairomm-1.12.0-1.el7.ppc64
crontabs-1.11-6.20121102git.el7.noarch
libstoragemgmt-python-1.4.0-3.el7.noarch
pciutils-3.5.1-2.el7.ppc64
speech-dispatcher-0.7.1-15.el7.ppc64
bluez-5.44-2.el7.ppc64
systemd-python-219-42.el7.ppc64
openssh-7.4p1-11.el7.ppc64
at-spi2-core-devel-2.22.0-1.el7.ppc64
NetworkManager-team-1.8.0-9.el7.ppc64
dracut-network-033-502.el7.ppc64
openldap-devel-2.4.44-5.el7.ppc64
abrt-addon-ccpp-2.1.11-48.el7.centos.ppc64
xorg-x11-drv-ati-7.7.1-3.20160928git3fc839ff.el7.ppc64
autofs-5.0.7-69.el7.ppc64
pango-devel-1.40.4-1.el7.ppc64
cups-pk-helper-0.2.6-2.el7.ppc64
firewalld-0.4.4.4-6.el7.noarch
hplip-common-3.15.9-3.el7.ppc64
usb_modeswitch-data-20160612-2.el7.noarch
usbmuxd-1.1.0-1.el7.ppc64
gupnp-1.0.1-1.el7.ppc64
dleyna-server-0.5.0-1.el7.ppc64
device-mapper-multipath-0.4.9-111.el7.ppc64
openlmi-providers-0.5.0-4.el7.ppc64
rubygem-psych-2.0.0-30.el7.ppc64
rubygem-thor-0.19.1-1.el7.noarch
cogl-1.22.2-1.el7.ppc64
imsettings-gsettings-1.6.3-9.el7.ppc64
poppler-glib-0.26.5-16.el7.ppc64
phonon-backend-gstreamer-4.6.3-3.el7.ppc64
qdox-1.12.1-10.el7.noarch
gutenprint-5.2.9-18.el7.ppc64
libfprint-0.5.0-4.el7.ppc64
cups-filesystem-1.6.3-29.el7.noarch
sssd-ad-1.15.2-50.el7.ppc64
skkdic-20130104-6.T1435.el7.noarch
ibus-gtk2-1.5.3-13.el7.ppc64
webkitgtk4-2.14.7-2.el7.ppc64
python2-caribou-0.4.21-1.el7.noarch
libpeas-gtk-1.20.0-1.el7.ppc64
folks-0.11.3-1.el7.ppc64
abrt-gui-2.1.11-48.el7.centos.ppc64
gnome-keyring-3.20.0-3.el7.ppc64
gucharmap-libs-3.18.2-1.el7.ppc64
file-roller-3.22.3-1.el7.ppc64
gnome-themes-standard-3.22.2-1.el7.ppc64
libwacom-data-0.24-1.el7.noarch
vim-common-7.4.160-2.el7.ppc64
mesa-filesystem-17.0.1-6.20170307.el7.ppc64
gnome-shell-extension-alternate-tab-3.22.2-10.el7.noarch
kbd-legacy-1.15.5-13.el7.noarch
intltool-0.50.2-7.el7.noarch
ipa-client-4.5.0-20.el7.centos.ppc64
gnome-contacts-3.22.1-1.el7.ppc64
gnome-dictionary-3.20.0-1.el7.ppc64
abrt-desktop-2.1.11-48.el7.centos.ppc64
gvfs-goa-1.30.4-3.el7.ppc64
ibus-hangul-1.4.2-10.el7.ppc64
seahorse-3.20.0-1.el7.ppc64
xdg-desktop-portal-gtk-0.5-1.el7.ppc64
ppc64-diag-2.7.3-3.el7.ppc64
librsvg2-devel-2.40.16-1.el7.ppc64
selinux-policy-targeted-3.13.1-166.el7.noarch
SDL-devel-1.2.15-14.el7.ppc64
plymouth-system-theme-0.8.9-0.28.20140113.el7.centos.ppc64
wvdial-1.61-9.el7.ppc64
python-smbc-1.0.13-7.el7.ppc64
PackageKit-gstreamer-plugin-1.1.5-1.el7.centos.ppc64
irqbalance-1.0.7-10.el7.ppc64
dracut-config-rescue-033-502.el7.ppc64
rpm-sign-4.11.3-25.el7.ppc64
crash-trace-command-2.0-12.el7.ppc64
hmaccalc-0.9.13-4.el7.ppc64
libblkid-devel-2.23.2-43.el7.ppc64
boost-devel-1.53.0-27.el7.ppc64
gnome-icon-theme-extras-3.12.0-1.el7.noarch
c-ares-devel-1.10.0-3.el7.ppc64
mtr-0.85-7.el7.ppc64
wget-1.14-15.el7.ppc64
hunspell-en-0.20121024-6.el7.noarch
perl-XML-Dumper-0.81-17.el7.noarch
flex-2.5.37-3.el7.ppc64
ltrace-0.7.91-14.el7.ppc64
wqy-zenhei-fonts-0.9.46-11.el7.noarch
madan-fonts-2.000-11.el7.noarch
lohit-assamese-fonts-2.5.3-2.el7.noarch
sil-abyssinica-fonts-1.200-6.el7.noarch
wqy-microhei-fonts-0.2.0-0.12.beta.el7.noarch
sil-padauk-fonts-2.8-5.el7.noarch
rdate-1.4-25.el7.ppc64
iwl7260-firmware-22.0.7.0-56.el7.noarch
iwl135-firmware-18.168.6.1-56.el7.noarch
iwl3945-firmware-15.32.2.9-56.el7.noarch
gpg-pubkey-f4a80eb5-53a7ff4b
libgcc-4.8.5-16.el7.ppc64
liberation-fonts-common-1.07.2-15.el7.noarch
mailcap-2.1.41-2.el7.noarch
poppler-data-0.4.6-3.el7.noarch
smc-fonts-common-6.0-7.el7.noarch
pcp-conf-3.11.8-7.el7.ppc64
glibc-2.17-196.el7.ppc64
dbus-libs-1.6.12-17.el7.ppc64
popt-1.13-16.el7.ppc64
sed-4.2.2-5.el7.ppc64
libgpg-error-1.12-3.el7.ppc64
gawk-4.0.2-4.el7_3.1.ppc64
gmp-6.0.0-15.el7.ppc64
json-c-0.11-4.el7_0.ppc64
libXi-1.7.9-1.el7.ppc64
libXcursor-1.1.14-8.el7.ppc64
tcp_wrappers-libs-7.6-77.el7.ppc64
findutils-4.5.11-5.el7.ppc64
diffutils-3.3-4.el7.ppc64
apr-util-1.5.2-6.el7.ppc64
libmng-1.0.10-14.el7.ppc64
giflib-4.1.6-9.el7.ppc64
libdvdread-5.0.3-3.el7.ppc64
lm_sensors-libs-3.4.0-4.20160601gitf9185e5.el7.ppc64
boost-filesystem-1.53.0-27.el7.ppc64
unzip-6.0-16.el7.ppc64
libedit-3.0-12.20121213cvs.el7.ppc64
numactl-libs-2.0.9-6.el7_2.ppc64
perl-HTTP-Tiny-0.033-3.el7.noarch
perl-macros-5.16.3-292.el7.ppc64
perl-threads-shared-1.43-6.el7.ppc64
perl-Getopt-Long-2.40-2.el7.noarch
perl-XML-Parser-2.41-10.el7.ppc64
perl-Digest-SHA-5.85-4.el7.ppc64
perl-Parse-CPAN-Meta-1.4404-5.el7.noarch
perl-Log-Message-0.08-3.el7.noarch
perl-HTML-Tagset-3.20-15.el7.noarch
libiec61883-1.2.0-10.el7.ppc64
copy-jdk-configs-2.2-3.el7.noarch
boost-iostreams-1.53.0-27.el7.ppc64
libss-1.42.9-10.el7.ppc64
boost-test-1.53.0-27.el7.ppc64
boost-atomic-1.53.0-27.el7.ppc64
libevdev-1.5.6-1.el7.ppc64
libdv-1.0.0-17.el7.ppc64
libnetfilter_conntrack-1.0.6-1.el7_3.ppc64
libteam-1.25-5.el7.ppc64
perl-Version-Requirements-0.101022-244.el7.noarch
perl-DBI-1.627-4.el7.ppc64
perl-Devel-Symdump-2.10-2.el7.noarch
perl-HTTP-Message-6.06-6.el7.noarch
perl-Text-Soundex-3.04-4.el7.ppc64
perl-TermReadKey-2.30-20.el7.ppc64
libsamplerate-0.1.8-6.el7.ppc64
cpp-4.8.5-16.el7.ppc64
hesiod-3.2.1-3.el7.ppc64
gdisk-0.8.6-5.el7.ppc64
libdwarf-20130207-4.el7.ppc64
popt-devel-1.13-16.el7.ppc64
qpdf-libs-5.0.1-3.el7.ppc64
gcc-4.8.5-16.el7.ppc64
krb5-libs-1.15.1-8.el7.ppc64
libblkid-2.23.2-43.el7.ppc64
pkgconfig-0.27.1-4.el7.ppc64
harfbuzz-1.3.2-1.el7.ppc64
libxml2-python-2.9.1-6.el7_2.3.ppc64
libxklavier-5.4-7.el7.ppc64
xdg-utils-1.1.0-0.17.20120809git.el7.noarch
python2-pyasn1-0.1.9-7.el7.noarch
libpwquality-1.2.3-4.el7.ppc64
plymouth-graphics-libs-0.8.9-0.28.20140113.el7.centos.ppc64
gettext-0.19.8.1-2.el7.ppc64
libXfixes-devel-5.0.3-1.el7.ppc64
libXmu-devel-1.1.2-2.el7.ppc64
libxml2-devel-2.9.1-6.el7_2.3.ppc64
libipa_hbac-1.15.2-50.el7.ppc64
python-augeas-0.5.0-2.el7.noarch
python-chardet-2.2.1-1.el7_1.noarch
fipscheck-1.4.1-6.el7.ppc64
perl-ExtUtils-ParseXS-3.18-3.el7.noarch
perl-File-Fetch-0.42-2.el7.noarch
libXv-devel-1.0.11-1.el7.ppc64
python2-pyasn1-modules-0.1.9-7.el7.noarch
sos-3.4-6.el7.centos.noarch
motif-2.3.4-8.1.el7_3.ppc64
graphite2-devel-1.3.6-1.el7_2.ppc64
meanwhile-1.1.0-12.el7.ppc64
tk-8.5.13-6.el7.ppc64
python-perf-3.10.0-693.el7.ppc64
python-setuptools-0.9.8-7.el7.noarch
newt-python-0.52.15-4.el7.ppc64
python-mako-0.8.1-2.el7.noarch
python-idna-2.4-1.el7.noarch
python-ply-3.4-11.el7.noarch
bind-utils-9.9.4-50.el7.ppc64
perl-HTML-Tree-5.03-2.el7.noarch
cyrus-sasl-scram-2.1.26-21.el7.ppc64
nss-pem-1.0.3-4.el7.ppc64
rpm-libs-4.11.3-25.el7.ppc64
postgresql-libs-9.2.21-1.el7.ppc64
python-nss-0.16.0-3.el7.ppc64
redhat-rpm-config-9.1.0-76.el7.centos.noarch
pykickstart-1.99.66.12-1.el7.noarch
libmodman-2.0.1-8.el7.ppc64
libreport-anaconda-2.1.11-38.el7.centos.ppc64
libsysfs-2.1.0-16.el7.ppc64
festival-speechtools-libs-1.2.96-28.el7.ppc64
espeak-1.47.11-4.el7.ppc64
pygpgme-0.3-9.el7.ppc64
ncompress-4.2.4.4-3.el7.ppc64
mtdev-1.1.5-5.el7.ppc64
checkpolicy-2.5-4.el7.ppc64
libutempter-1.1.6-4.el7.ppc64
kmod-20-15.el7.ppc64
mesa-libEGL-17.0.1-6.20170307.el7.ppc64
PackageKit-glib-1.1.5-1.el7.centos.ppc64
java-1.8.0-openjdk-1.8.0.131-11.b12.el7.ppc64
httpd-2.4.6-67.el7.centos.ppc64
PackageKit-1.1.5-1.el7.centos.ppc64
libcgroup-0.41-13.el7.ppc64
authconfig-6.2.8-30.el7.ppc64
device-mapper-event-1.02.140-8.el7.ppc64
rpcbind-0.2.0-42.el7.ppc64
mesa-libGL-devel-17.0.1-6.20170307.el7.ppc64
mdadm-4.0-5.el7.ppc64
usermode-1.111-5.el7.ppc64
grub2-ppc64-2.02-0.64.el7.centos.ppc64
NetworkManager-wifi-1.8.0-9.el7.ppc64
kexec-tools-2.0.14-17.el7.ppc64
apr-util-devel-1.5.2-6.el7.ppc64
abrt-cli-2.1.11-48.el7.centos.ppc64
xorg-x11-drv-v4l-0.2.0-47.el7.ppc64
oddjob-0.31.5-4.el7.ppc64
mesa-libGLU-9.0.0-4.el7.ppc64
rtkit-0.11-10.el7.ppc64
unbound-libs-1.4.20-34.el7.ppc64
brltty-4.5-15.el7.ppc64
trousers-0.3.14-2.el7.ppc64
glib-networking-2.50.0-1.el7.ppc64
gupnp-igd-0.2.4-1.el7.ppc64
telepathy-gabble-0.18.1-4.el7.ppc64
python-blivet-0.61.15.65-1.el7.noarch
libsemanage-python-2.5-8.el7.ppc64
rubygem-bigdecimal-1.2.0-30.el7.ppc64
rubygem-net-http-persistent-2.8-5.el7.noarch
librsvg2-2.40.16-1.el7.ppc64
imsettings-1.6.3-9.el7.ppc64
farstream02-0.2.3-3.el7.ppc64
phonon-4.6.0-10.el7.ppc64
hamcrest-1.3-6.el7.noarch
sane-backends-drivers-cameras-1.0.24-9.el7.ppc64
fprintd-0.5.0-4.0.el7_0.ppc64
cups-filters-1.0.35-22.el7.ppc64
sssd-ipa-1.15.2-50.el7.ppc64
libkkc-0.3.1-9.el7.ppc64
ibus-gtk3-1.5.3-13.el7.ppc64
gnome-online-accounts-3.22.5-1.el7.ppc64
zenity-3.22.0-1.el7.ppc64
vte291-0.46.2-1.el7.ppc64
clutter-gst2-2.0.18-1.el7.ppc64
libwnck3-3.20.1-1.el7.ppc64
ibus-table-1.5.0-5.el7.noarch
libtimezonemap-0.4.4-1.el7.ppc64
librsvg2-tools-2.40.16-1.el7.ppc64
webkitgtk3-2.4.11-2.el7.ppc64
evince-3.22.1-5.el7.ppc64
vim-filesystem-7.4.160-2.el7.ppc64
lldpad-1.0.1-3.git036e314.el7.ppc64
gnome-shell-extension-user-theme-3.22.2-10.el7.noarch
gettext-devel-0.19.8.1-2.el7.ppc64
pm-utils-1.4.1-27.el7.ppc64
firefox-52.2.0-2.el7.centos.ppc64
cheese-3.22.1-1.el7.ppc64
vinagre-3.22.0-8.el7.ppc64
gnome-terminal-nautilus-3.22.1-2.el7.ppc64
gnome-weather-3.20.2-1.el7.noarch
gvfs-smb-1.30.4-3.el7.ppc64
ibus-qt-1.3.2-4.el7.ppc64
PackageKit-gtk3-module-1.1.5-1.el7.centos.ppc64
PyQt4-devel-4.10.1-13.el7.ppc64
libnotify-devel-0.7.7-1.el7.ppc64
tuned-2.8.0-5.el7.noarch
freeglut-devel-2.8.1-3.el7.ppc64
httpd-devel-2.4.6-67.el7.centos.ppc64
setuptool-1.19.11-8.el7.ppc64
mlocate-0.26-6.el7.ppc64
PackageKit-command-not-found-1.1.5-1.el7.centos.ppc64
rng-tools-5-11.el7.ppc64
kpatch-0.4.0-1.el7.noarch
perl-App-cpanminus-1.6922-2.el7.noarch
gcc-c++-4.8.5-16.el7.ppc64
crypto-utils-2.4.1-42.el7.ppc64
readline-devel-6.2-10.el7.ppc64
dvd+rw-tools-7.1-15.el7.ppc64
gnome-icon-theme-symbolic-3.12.0-2.el7.noarch
iptables-devel-1.4.21-18.0.1.el7.centos.ppc64
latencytop-tui-0.5-13.el7.ppc64
wodim-1.1.11-23.el7.ppc64
papi-devel-5.2.0-23.el7.ppc64
patchutils-0.3.3-4.el7.ppc64
unixODBC-devel-2.3.1-11.el7.ppc64
bzip2-devel-1.0.6-13.el7.ppc64
vlgothic-fonts-20130607-2.el7.noarch
paratype-pt-sans-fonts-20101909-3.el7.noarch
lklug-fonts-0.6-10.20090803cvs.el7.noarch
sil-nuosu-fonts-2.1.1-5.el7.noarch
lohit-malayalam-fonts-2.5.3-2.el7.noarch
gnu-free-sans-fonts-20120503-8.el7.noarch
rfkill-0.4-9.el7.ppc64
iwl3160-firmware-22.0.7.0-56.el7.noarch
iwl1000-firmware-39.31.5.1-56.el7.noarch
iwl4965-firmware-228.61.2.24-56.el7.noarch
gpg-pubkey-f533f4fa-56585169
fontpackages-filesystem-1.44-8.el7.noarch
control-center-filesystem-3.22.2-5.el7.ppc64
libreport-filesystem-2.1.11-38.el7.centos.ppc64
latencytop-common-0.5-13.el7.ppc64
khmeros-fonts-common-5.0-17.el7.noarch
libX11-common-1.6.5-1.el7.noarch
libstdc++-4.8.5-16.el7.ppc64
freetype-2.4.11-15.el7.ppc64
chkconfig-1.7.4-1.el7.ppc64
expat-2.1.0-10.el7_3.ppc64
libgcrypt-1.5.3-14.el7.ppc64
libtdb-1.3.12-2.el7.ppc64
libvorbis-1.3.3-8.el7.ppc64
libnl3-3.2.28-4.el7.ppc64
libXfixes-5.0.3-1.el7.ppc64
libXt-1.1.5-3.el7.ppc64
libexif-0.6.21-6.el7.ppc64
jansson-2.10-1.el7.ppc64
hunspell-en-US-0.20121024-6.el7.noarch
boost-chrono-1.53.0-27.el7.ppc64
libv4l-0.9.5-4.el7.ppc64
libxkbfile-1.0.9-3.el7.ppc64
libmnl-1.0.3-7.el7.ppc64
pcre2-10.23-2.el7.ppc64
libXp-1.0.2-2.1.el7.ppc64
bzip2-1.0.6-13.el7.ppc64
libpcap-1.5.3-9.el7.ppc64
opus-1.0.2-6.el7.ppc64
perl-podlators-2.5.1-3.el7.noarch
perl-Time-HiRes-1.9725-3.el7.ppc64
perl-Time-Local-1.2300-2.el7.noarch
perl-5.16.3-292.el7.ppc64
perl-ExtUtils-Manifest-1.61-244.el7.noarch
perl-Digest-1.17-245.el7.noarch
perl-JSON-PP-2.27202-2.el7.noarch
perl-Module-Load-Conditional-0.54-3.el7.noarch
perl-IO-Zlib-1.10-292.el7.noarch
libavc1394-0.5.3-14.el7.ppc64
libnl3-cli-3.2.28-4.el7.ppc64
libdb-devel-5.3.21-20.el7.ppc64
mozjs17-17.0.0-19.el7.ppc64
boost-program-options-1.53.0-27.el7.ppc64
boost-random-1.53.0-27.el7.ppc64
libdaemon-0.14-7.el7.ppc64
hostname-3.13-3.el7.ppc64
theora-tools-1.1.1-8.el7.ppc64
libcdio-paranoia-10.2+0.90-11.el7.ppc64
perl-Archive-Zip-1.30-11.el7.noarch
perl-PlRPC-0.2020-14.el7.noarch
perl-Text-Diff-1.41-5.el7.noarch
perl-HTTP-Date-6.02-8.el7.noarch
perl-Text-Unidecode-0.04-20.el7.noarch
perl-Digest-SHA1-2.13-9.el7.ppc64
libXaw-1.0.13-4.el7.ppc64
xorg-x11-server-common-1.19.3-11.el7.ppc64
xorg-x11-xauth-1.0.9-1.el7.ppc64
startup-notification-0.12-8.el7.ppc64
libgcrypt-devel-1.5.3-14.el7.ppc64
isomd5sum-1.0.10-5.el7.ppc64
mesa-private-llvm-3.9.1-3.el7.ppc64
glibc-devel-2.17-196.el7.ppc64
openssl-libs-1.0.2k-8.el7.ppc64
ruby-libs-2.0.0.648-30.el7.ppc64
atk-2.22.0-3.el7.ppc64
avahi-glib-0.6.31-17.el7.ppc64
libpeas-1.20.0-1.el7.ppc64
freetype-devel-2.4.11-15.el7.ppc64
mariadb-libs-5.5.56-2.el7.ppc64
libudisks2-2.1.2-6.el7.ppc64
python-gssapi-1.2.0-3.el7.ppc64
plymouth-core-libs-0.8.9-0.28.20140113.el7.centos.ppc64
libSM-devel-1.2.2-2.el7.ppc64
libxcb-devel-1.12-1.el7.ppc64
libXi-devel-1.7.9-1.el7.ppc64
atk-devel-2.22.0-3.el7.ppc64
libffi-devel-3.0.13-18.el7.ppc64
libgtop2-2.34.2-1.el7.ppc64
python-dns-1.12.0-4.20150617git465785f.el7.noarch
boost-python-1.53.0-27.el7.ppc64
boost-1.53.0-27.el7.ppc64
perl-Archive-Extract-0.68-3.el7.noarch
python-yubico-1.2.3-1.el7.noarch
libusbx-devel-1.0.20-1.el7.ppc64
python-firewall-0.4.4.4-6.el7.noarch
libicu-devel-50.1.2-15.el7.ppc64
openssl-devel-1.0.2k-8.el7.ppc64
gstreamer1-devel-1.10.4-2.el7.ppc64
libgcab1-0.7-3.el7.ppc64
cups-client-1.6.3-29.el7.ppc64
python-ipaddress-1.0.16-2.el7.noarch
python-urwid-1.1.1-3.el7.ppc64
python-tempita-0.5.1-6.el7.noarch
cmpi-bindings-pywbem-0.9.5-6.el7.ppc64
python-ntplib-0.3.2-1.el7.noarch
gd-2.0.35-26.el7.ppc64
perl-Net-HTTP-6.06-2.el7.noarch
cyrus-sasl-md5-2.1.26-21.el7.ppc64
NetworkManager-libnm-1.8.0-9.el7.ppc64
satyr-0.13-14.el7.ppc64
liboauth-0.9.7-4.el7.ppc64
dhcp-common-4.2.5-58.el7.centos.ppc64
sip-devel-4.14.6-4.el7.ppc64
marisa-0.2.4-4.el7.ppc64
libreport-plugin-mantisbt-2.1.11-38.el7.centos.ppc64
dotconf-1.3-8.el7.ppc64
autogen-libopts-5.18-5.el7.ppc64
festival-lib-1.96-28.el7.ppc64
rpm-build-libs-4.11.3-25.el7.ppc64
createrepo-0.9.9-28.el7.noarch
libiptcdata-1.0.4-11.el7.ppc64
gavl-1.4.0-4.el7.ppc64
ustr-1.0.4-16.el7.ppc64
kpartx-0.4.9-111.el7.ppc64
libdrm-2.4.74-1.el7.ppc64
pango-1.40.4-1.el7.ppc64
dbus-x11-1.6.12-17.el7.ppc64
device-mapper-event-libs-1.02.140-8.el7.ppc64
samba-client-libs-4.6.2-8.el7.ppc64
accountsservice-libs-0.6.45-2.el7.ppc64
cronie-1.4.11-17.el7.ppc64
libstoragemgmt-python-clibs-1.4.0-3.el7.ppc64
libibverbs-13-7.el7.ppc64
python-gobject-3.22.0-1.el7.ppc64
ppp-2.4.5-33.el7.ppc64
lockdev-1.0.4-0.13.20111007git.el7.ppc64
python-meh-0.25.2-1.el7.noarch
mesa-libEGL-devel-17.0.1-6.20170307.el7.ppc64
librdmacm-13-7.el7.ppc64
abrt-addon-vmcore-2.1.11-48.el7.centos.ppc64
pcp-selinux-3.11.8-7.el7.ppc64
samba-common-libs-4.6.2-8.el7.ppc64
xorg-x11-drv-synaptics-1.9.0-1.el7.ppc64
oddjob-mkhomedir-0.31.5-4.el7.ppc64
mesa-libGLU-devel-9.0.0-4.el7.ppc64
pulseaudio-10.0-3.el7.ppc64
fxload-2002_04_11-16.el7.ppc64
brlapi-0.6.0-15.el7.ppc64
gnutls-3.3.26-9.el7.ppc64
libsoup-2.56.0-3.el7.ppc64
libnice-0.1.3-4.el7.ppc64
telepathy-salut-0.8.1-6.el7.ppc64
selinux-policy-3.13.1-166.el7.noarch
policycoreutils-python-2.5-17.1.el7.ppc64
ruby-irb-2.0.0.648-30.el7.noarch
libestr-0.1.9-2.el7.ppc64
sane-backends-libs-1.0.24-9.el7.ppc64
gtk-update-icon-cache-3.22.10-4.el7.ppc64
system-config-printer-libs-1.4.1-19.el7.noarch
PyQt4-4.10.1-13.el7.ppc64
junit-4.11-8.el7.noarch
sane-backends-drivers-scanners-1.0.24-9.el7.ppc64
libgsf-1.14.26-7.el7.ppc64
cups-1.6.3-29.el7.ppc64
sssd-krb5-1.15.2-50.el7.ppc64
adwaita-cursor-theme-3.22.0-1.el7.noarch
ibus-1.5.3-13.el7.ppc64
nautilus-extensions-3.22.3-3.el7.ppc64
libreport-gtk-2.1.11-38.el7.centos.ppc64
gjs-1.46.0-1.el7.ppc64
libcanberra-gtk2-0.30-5.el7.ppc64
gtk3-devel-3.22.10-4.el7.ppc64
gvfs-fuse-1.30.4-3.el7.ppc64
gtkspell3-3.0.3-4.el7.ppc64
keybinder3-0.3.0-1.el7.ppc64
im-chooser-1.6.4-4.el7.ppc64
mutter-3.22.3-11.el7.ppc64
gnome-user-docs-3.22.0-1.el7.noarch
kernel-3.10.0-693.el7.ppc64
gnome-shell-extension-common-3.22.2-10.el7.noarch
gettext-common-devel-0.19.8.1-2.el7.noarch
initial-setup-gui-0.3.9.40-1.el7.centos.ppc64
fcoe-utils-1.0.32-1.el7.ppc64
empathy-3.12.12-4.el7.ppc64
gnome-system-monitor-3.22.2-2.el7.ppc64
ibus-table-chinese-1.4.6-3.el7.noarch
gnome-calculator-3.22.3-1.el7.ppc64
gvfs-archive-1.30.4-3.el7.ppc64
ibus-libpinyin-1.6.91-4.el7.ppc64
baobab-3.22.1-1.el7.ppc64
fprintd-pam-0.5.0-4.0.el7_0.ppc64
gtk2-immodule-xim-2.24.31-1.el7.ppc64
systemtap-3.1-3.el7.ppc64
pulseaudio-module-x11-10.0-3.el7.ppc64
cgdcbxd-1.0.2-7.el7.ppc64
openssh-server-7.4p1-11.el7.ppc64
avahi-0.6.31-17.el7.ppc64
usbutils-007-5.el7.ppc64
at-3.1.13-22.el7.ppc64
aic94xx-firmware-30-6.el7.noarch
yum-langpacks-0.4.2-7.el7.noarch
tbb-devel-4.1-9.20130314.el7.ppc64
libcurl-devel-7.29.0-42.el7.ppc64
perl-XML-Twig-3.44-2.el7.noarch
perl-core-5.16.3-292.el7.ppc64
startup-notification-devel-0.12-8.el7.ppc64
sqlite-devel-3.7.17-8.el7.ppc64
libcap-devel-2.22-9.el7.ppc64
ps_mem-3.1-7.el7.noarch
libacl-devel-2.2.51-12.el7.ppc64
mpfr-devel-3.1.1-4.el7.ppc64
hyphen-en-2.8.6-5.el7.noarch
nfs4-acl-tools-0.3.3-15.el7.ppc64
swig-2.0.10-5.el7.ppc64
khmeros-base-fonts-5.0-17.el7.noarch
stix-fonts-1.1.0-5.el7.noarch
lohit-kannada-fonts-2.5.3-3.el7.noarch
smc-meera-fonts-6.0-7.el7.noarch
ucs-miscfixed-fonts-0.3-11.el7.noarch
ctags-5.8-13.el7.ppc64
iwl105-firmware-18.168.6.1-56.el7.noarch
iwl6050-firmware-41.28.5.1-56.el7.noarch
iwl5000-firmware-8.83.5.1_1-56.el7.noarch
libgcc-4.8.5-16.el7.ppc
python34-libs-3.4.5-5.el7.ppc64
grub2-common-2.02-0.64.el7.centos.noarch
xkeyboard-config-2.20-1.el7.noarch
basesystem-10.0-7.el7.centos.noarch
langtable-0.0.31-3.el7.noarch
thai-scalable-fonts-common-0.5.0-7.el7.noarch
vte-profile-0.46.2-1.el7.ppc64
ncurses-libs-5.9-13.20130511.el7.ppc64
info-5.1-4.el7.ppc64
xz-libs-5.2.2-1.el7.ppc64
libdb-5.3.21-20.el7.ppc64
libtalloc-2.1.9-1.el7.ppc64
libattr-2.4.46-12.el7.ppc64
augeas-libs-1.4.0-2.el7.ppc64
binutils-2.25.1-31.base.el7.ppc64
libXdamage-1.1.4-4.1.el7.ppc64
libbasicobjects-0.1.1-27.el7.ppc64
libidn-1.28-4.el7.ppc64
libtool-ltdl-2.4.2-22.el7_3.ppc64
hunspell-1.3.2-15.el7.ppc64
libXxf86vm-1.1.4-1.el7.ppc64
libgomp-4.8.5-16.el7.ppc64
xorg-x11-xkb-utils-7.7-12.el7.ppc64
libseccomp-2.3.1-3.el7.ppc64
libaio-0.3.109-13.el7.ppc64
libXpm-3.5.12-1.el7.ppc64
zip-3.0-11.el7.ppc64
libXdmcp-1.1.2-6.el7.ppc64
wavpack-4.60.1-9.el7.ppc64
perl-Pod-Perldoc-3.20-4.el7.noarch
perl-Storable-2.45-3.el7.ppc64
perl-constant-1.27-2.el7.noarch
perl-Data-Dumper-2.145-3.el7.ppc64
perl-Pod-Parser-1.61-2.el7.noarch
perl-Perl-OSType-1.003-3.el7.noarch
autoconf-2.69-11.el7.noarch
perl-Params-Check-0.38-2.el7.noarch
perl-IO-Compress-2.061-2.el7.noarch
libdvdnav-5.0.3-1.el7.ppc64
xorg-x11-server-utils-7.7-20.el7.ppc64
bc-1.06.95-13.el7.ppc64
mozjs24-24.2.0-7.el7.ppc64
graphite2-1.3.6-1.el7_2.ppc64
boost-signals-1.53.0-27.el7.ppc64
libusal-1.1.11-23.el7.ppc64
SDL-1.2.15-14.el7.ppc64
sysvinit-tools-2.88-14.dsf.el7.ppc64
crash-7.1.9-2.el7.ppc64
perl-Pod-LaTeX-0.61-2.el7.noarch
perl-Net-Daemon-0.48-5.el7.noarch
perl-Algorithm-Diff-1.1902-17.el7.noarch
perl-TimeDate-2.30-2.el7.noarch
perl-Font-AFM-1.20-13.el7.noarch
perl-Time-Piece-1.20.1-292.el7.ppc64
libXfont-1.5.2-1.el7.ppc64
ipset-6.29-1.el7.ppc64
hunspell-en-GB-0.20121024-6.el7.noarch
xcb-util-0.4.0-2.el7.ppc64
libgpg-error-devel-1.12-3.el7.ppc64
libbluray-0.2.3-5.el7.ppc64
ttmkfdir-3.0.9-42.el7.ppc64
glibc-headers-2.17-196.el7.ppc64
coreutils-8.22-18.el7.ppc64
libarchive-3.1.2-10.el7_2.ppc64
shared-mime-info-1.8-3.el7.ppc64
gvfs-client-1.30.4-3.el7.ppc64
libcroco-0.6.11-1.el7.ppc64
libgee-0.18.1-1.el7.ppc64
hicolor-icon-theme-0.12-7.el7.noarch
cracklib-2.9.0-11.el7.ppc64
cracklib-dicts-2.9.0-11.el7.ppc64
python-pyudev-0.15-9.el7.noarch
atkmm-2.24.2-1.el7.ppc64
libX11-devel-1.6.5-1.el7.ppc64
libXdamage-devel-1.1.4-4.1.el7.ppc64
libcom_err-devel-1.42.9-10.el7.ppc64
libpinyin-data-0.9.93-4.el7.ppc64
xfsprogs-4.5.0-12.el7.ppc64
python-sssdconfig-1.15.2-50.el7.noarch
libkadm5-1.15.1-8.el7.ppc64
python-kitchen-1.1.1-5.el7.noarch
perl-ExtUtils-CBuilder-0.28.2.6-292.el7.noarch
python-libipa_hbac-1.15.2-50.el7.ppc64
libatasmart-0.19-6.el7.ppc64
pinentry-qt-0.8.1-17.el7.ppc64
alsa-lib-devel-1.1.3-3.el7.ppc64
ncurses-devel-5.9-13.20130511.el7.ppc64
libuuid-devel-2.23.2-43.el7.ppc64
kernel-bootwrapper-3.10.0-693.el7.ppc64
python-markupsafe-0.11-10.el7.ppc64
python-backports-1.0-8.el7.ppc64
python-configshell-1.1.fb23-3.el7.noarch
python-paste-1.7.5.1-9.20111221hg1498.el7.noarch
openlmi-python-base-0.5.0-4.el7.noarch
python-iniparse-0.4-9.el7.noarch
bind-libs-lite-9.9.4-50.el7.ppc64
perl-libwww-perl-6.05-2.el7.noarch
libssh2-1.4.3-10.el7_2.1.ppc64
nss-sysinit-3.28.4-8.el7.ppc64
openldap-2.4.44-5.el7.ppc64
libnfsidmap-0.25-17.el7.ppc64
python-deltarpm-3.6-3.el7.ppc64
sip-macros-4.14.6-4.el7.ppc64
trace-cmd-2.6.0-8.el7.ppc64
libreport-web-2.1.11-38.el7.centos.ppc64
libreport-plugin-ureport-2.1.11-38.el7.centos.ppc64
libhangul-0.1.0-8.el7.ppc64
sox-14.4.1-6.el7.ppc64
gnupg2-2.0.22-4.el7.ppc64
yum-3.4.3-154.el7.centos.noarch
hardlink-1.0-19.el7.ppc64
libgdither-0.6-8.el7.ppc64
pakchois-0.4-10.el7.ppc64
policycoreutils-2.5-17.1.el7.ppc64
dbus-1.6.12-17.el7.ppc64
cairo-1.14.8-2.el7.ppc64
GConf2-3.2.6-8.el7.ppc64
hwdata-0.252-8.6.el7.ppc64
libwbclient-4.6.2-8.el7.ppc64
accountsservice-0.6.45-2.el7.ppc64
cronie-anacron-1.4.11-17.el7.ppc64
libstoragemgmt-1.4.0-3.el7.ppc64
rdma-core-13-7.el7.ppc64
pycairo-1.8.10-8.el7.ppc64
dbus-devel-1.6.12-17.el7.ppc64
abrt-addon-python-2.1.11-48.el7.centos.ppc64
openssh-clients-7.4p1-11.el7.ppc64
at-spi2-atk-devel-2.22.0-2.el7.ppc64
ibacm-13-7.el7.ppc64
plymouth-plugin-label-0.8.9-0.28.20140113.el7.centos.ppc64
pcp-3.11.8-7.el7.ppc64
xorg-x11-drv-wacom-0.34.2-2.el7.ppc64
xorg-x11-drv-fbdev-0.4.3-25.el7.ppc64
realmd-0.16.1-9.el7.ppc64
glx-utils-8.2.0-3.el7.ppc64
xdg-desktop-portal-0.5-2.el7.ppc64
alsa-firmware-1.0.28-2.el7.noarch
python-brlapi-0.6.0-15.el7.ppc64
libimobiledevice-1.2.0-1.el7.ppc64
geocode-glib-3.20.1-1.el7.ppc64
rest-0.8.0-1.el7.ppc64
gnutls-c++-3.3.26-9.el7.ppc64
virt-what-1.13-10.el7.ppc64
setroubleshoot-plugins-3.0.65-1.el7.noarch
ruby-2.0.0.648-30.el7.ppc64
libpipeline-1.2.3-3.el7.ppc64
qt-x11-4.8.5-13.el7.ppc64
gtk2-2.24.31-1.el7.ppc64
hplip-libs-3.15.9-3.el7.ppc64
telepathy-farstream-0.6.0-5.el7.ppc64
libglade2-2.6.4-11.el7.ppc64
qt-devel-4.8.5-13.el7.ppc64
tracker-1.10.5-4.el7.ppc64
ghostscript-cups-9.07-28.el7.ppc64
sssd-ldap-1.15.2-50.el7.ppc64
adwaita-icon-theme-3.22.0-1.el7.noarch
ibus-setup-1.5.3-13.el7.noarch
libgweather-3.20.4-1.el7.ppc64
libgdata-0.17.8-1.el7.ppc64
grilo-0.3.3-1.el7.ppc64
metacity-2.34.13-7.el7.ppc64
gnome-abrt-0.3.4-8.el7.ppc64
yelp-libs-3.22.0-1.el7.ppc64
gnome-packagekit-updater-3.22.1-2.el7.ppc64
vino-3.22.0-3.el7.ppc64
im-chooser-common-1.6.4-4.el7.ppc64
totem-3.22.1-1.el7.ppc64
yelp-3.22.0-1.el7.ppc64
linux-firmware-20170606-56.gitc990aae.el7.noarch
pulseaudio-gdm-hooks-10.0-3.el7.ppc64
tigervnc-server-minimal-1.8.0-1.el7.ppc64
initial-setup-0.3.9.40-1.el7.centos.ppc64
gnome-session-xsession-3.22.3-4.el7.ppc64
totem-nautilus-3.22.1-1.el7.ppc64
imsettings-qt-1.6.3-9.el7.ppc64
gucharmap-3.18.2-1.el7.ppc64
sushi-3.21.91-1.el7.ppc64
gvfs-mtp-1.30.4-3.el7.ppc64
ibus-sayura-1.3.2-3.el7.ppc64
gtk3-immodule-xim-3.22.10-4.el7.ppc64
sane-backends-devel-1.0.24-9.el7.ppc64
latencytop-0.5-13.el7.ppc64
openlmi-providers-devel-0.5.0-4.el7.ppc64
alsa-plugins-pulseaudio-1.1.1-1.el7.ppc64
abrt-console-notification-2.1.11-48.el7.centos.ppc64
grub2-2.02-0.64.el7.centos.ppc64
NetworkManager-adsl-1.8.0-9.el7.ppc64
spice-vdagent-0.14.0-14.el7.ppc64
qemu-guest-agent-2.8.0-2.el7.ppc64
powertop-2.3-12.el7.ppc64
net-snmp-devel-5.7.2-28.el7.ppc64
libproxy-mozjs-0.4.11-10.el7.ppc64
sudo-1.8.19p2-10.el7.ppc64
tk-devel-8.5.13-6.el7.ppc64
perl-homedir-1.008010-4.el7.noarch
pinfo-0.6.10-9.el7.ppc64
libnl-devel-1.1.4-3.el7.ppc64
bash-completion-2.1-6.el7.noarch
perl-Crypt-SSLeay-0.64-5.el7.ppc64
xorg-x11-utils-7.5-22.el7.ppc64
perl-Test-Pod-1.48-3.el7.noarch
bison-3.0.4-1.el7.ppc64
m17n-contrib-1.1.14-3.el7.noarch
lohit-gujarati-fonts-2.5.3-2.el7.noarch
lohit-devanagari-fonts-2.5.3-4.el7.noarch
liberation-serif-fonts-1.07.2-15.el7.noarch
nhn-nanum-gothic-fonts-3.020-9.el7.noarch
google-crosextra-caladea-fonts-1.002-0.4.20130214.el7.noarch
jomolhari-fonts-0.003-17.el7.noarch
diffstat-1.57-4.el7.ppc64
iwl6000g2b-firmware-17.168.5.2-56.el7.noarch
rootfiles-8.1-11.el7.noarch
ivtv-firmware-20080701-26.el7.noarch
strace32-4.12-4.el7.ppc
python34-3.4.5-5.el7.ppc64
kernel-headers-3.10.0-693.el7.ppc64
tzdata-2017b-1.el7.noarch
m17n-db-1.6.4-3.el7.noarch
langtable-data-0.0.31-3.el7.noarch
libkkc-common-0.3.1-9.el7.noarch
firewalld-filesystem-0.4.4.4-6.el7.noarch
bash-4.2.46-28.el7.ppc64
libcom_err-1.42.9-10.el7.ppc64
libxml2-2.9.1-6.el7_2.3.ppc64
readline-6.2-10.el7.ppc64
cyrus-sasl-lib-2.1.26-21.el7.ppc64
libcap-2.22-9.el7.ppc64
which-2.20-7.el7.ppc64
libcollection-0.6.2-27.el7.ppc64
libXcomposite-0.4.4-4.1.el7.ppc64
libref_array-0.1.5-27.el7.ppc64
cpio-2.11-24.el7.ppc64
orc-0.4.26-1.el7.ppc64
libsigc++20-2.10.0-1.el7.ppc64
libXv-1.0.11-1.el7.ppc64
lzo-2.06-8.el7.ppc64
kmod-libs-20-15.el7.ppc64
libxshmfence-1.2-1.el7.ppc64
speex-1.2-0.19.rc1.el7.ppc64
boost-regex-1.53.0-27.el7.ppc64
m4-1.4.16-10.el7.ppc64
libnl-1.1.4-3.el7.ppc64
pciutils-libs-3.5.1-2.el7.ppc64
perl-Pod-Escapes-1.04-292.el7.noarch
perl-Carp-1.26-244.el7.noarch
perl-Socket-2.010-4.el7.ppc64
perl-version-0.99.07-2.el7.ppc64
perl-Thread-Queue-3.02-2.el7.noarch
perl-CPAN-Meta-Requirements-2.122-7.el7.noarch
perl-Locale-Maketext-Simple-0.21-292.el7.noarch
perl-Compress-Raw-Bzip2-2.061-3.el7.ppc64
libshout-2.2.2-11.el7.ppc64
libXxf86misc-1.0.3-7.1.el7.ppc64
libassuan-2.1.0-3.el7.ppc64
jasper-libs-1.900.1-31.el7.ppc64
lksctp-tools-1.0.17-2.el7.ppc64
libconfig-1.4.9-5.el7.ppc64
cdparanoia-libs-10.2-17.el7.ppc64
libsss_autofs-1.15.2-50.el7.ppc64
libmpcdec-1.2.6-12.el7.ppc64
libxkbcommon-x11-0.7.1-1.el7.ppc64
perl-Pod-Checker-1.60-2.el7.noarch
perl-IO-HTML-1.00-2.el7.noarch
perl-Locale-Codes-3.26-2.el7.noarch
perl-WWW-RobotRules-6.02-5.el7.noarch
perl-File-Listing-6.04-7.el7.noarch
perl-File-CheckTree-4.42-3.el7.noarch
iw-4.3-1.el7.ppc64
ipset-libs-6.29-1.el7.ppc64
gdbm-devel-1.10-8.el7.ppc64
libXxf86dga-1.1.4-2.1.el7.ppc64
cyrus-sasl-plain-2.1.26-21.el7.ppc64
exiv2-libs-0.23-6.el7.ppc64
libchewing-0.3.4-6.el7.ppc64
elfutils-0.168-8.el7.ppc64
ncurses-5.9-13.20130511.el7.ppc64
alsa-lib-1.1.3-3.el7.ppc64
glib2-2.50.3-3.el7.ppc64
gobject-introspection-1.50.0-1.el7.ppc64
dbus-python-1.1.1-9.el7.ppc64
enchant-1.6.0-8.el7.ppc64
xorg-x11-xinit-1.3.4-1.el7.ppc64
python-decorator-3.4.0-3.el7.noarch
xorg-x11-font-utils-7.5-20.el7.ppc64
cyrus-sasl-gssapi-2.1.26-21.el7.ppc64
libusbx-1.0.20-1.el7.ppc64
colord-libs-1.3.4-1.el7.ppc64
telepathy-logger-0.8.0-5.el7.ppc64
libXt-devel-1.1.5-3.el7.ppc64
pcre-devel-8.32-17.el7.ppc64
libXft-devel-2.3.2-2.el7.ppc64
libgnome-keyring-3.12.0-1.el7.ppc64
python-ethtool-0.8-5.el7.ppc64
pyOpenSSL-0.13.1-3.el7.ppc64
libtool-2.4.2-22.el7_3.ppc64
perl-devel-5.16.3-292.el7.ppc64
perl-CPANPLUS-Dist-Build-0.70-3.el7.noarch
libqmi-utils-1.16.0-1.el7.ppc64
python-slip-0.4.0-2.el7.noarch
libsepol-devel-2.5-6.el7.ppc64
libverto-devel-0.2.5-4.el7.ppc64
python-devel-2.7.5-58.el7.ppc64
gupnp-av-0.12.10-1.el7.ppc64
flite-1.3-22.el7.ppc64
python-javapackages-3.4.1-11.el7.noarch
python-requests-2.6.0-1.el7_1.noarch
fros-1.0-2.el7.noarch
m2crypto-0.21.1-17.el7.ppc64
pytz-2016.10-2.el7.noarch
python2-cryptography-1.7.2-1.el7.ppc64
perl-Net-SSLeay-1.55-6.el7.ppc64
openslp-2.0.0-6.el7.ppc64
nss-tools-3.28.4-8.el7.ppc64
libreport-2.1.11-38.el7.centos.ppc64
dhcp-libs-4.2.5-58.el7.centos.ppc64
passwd-0.79-4.el7.ppc64
net-snmp-agent-libs-5.7.2-28.el7.ppc64
konkretcmpi-python-0.9.1-5.el7.ppc64
libreport-plugin-bugzilla-2.1.11-38.el7.centos.ppc64
libgfortran-4.8.5-16.el7.ppc64
libasyncns-0.8-7.el7.ppc64
festival-1.96-28.el7.ppc64
gpgme-1.3.2-5.el7.ppc64
rpm-devel-4.11.3-25.el7.ppc64
libini_config-1.3.0-27.el7.ppc64
gnome-video-effects-0.4.3-1.el7.noarch
shadow-utils-4.1.5.1-24.el7.ppc64
device-mapper-libs-1.02.140-8.el7.ppc64
polkit-pkla-compat-0.1-4.el7.ppc64
gstreamer1-plugins-base-1.10.4-1.el7.ppc64
java-1.7.0-openjdk-headless-1.7.0.141-2.6.10.5.el7.ppc64
xorg-x11-server-Xorg-1.19.3-11.el7.ppc64
parted-3.1-28.el7.ppc64
abrt-2.1.11-48.el7.centos.ppc64
initscripts-9.49.39-1.el7.ppc64
abrt-addon-pstoreoops-2.1.11-48.el7.centos.ppc64
telepathy-mission-control-5.16.3-3.el7.ppc64
colord-1.3.4-1.el7.ppc64
os-prober-1.58-9.el7.ppc64
cryptsetup-1.7.4-3.el7.ppc64
git-1.8.3.1-11.el7.ppc64
cairo-gobject-devel-1.14.8-2.el7.ppc64
qt-settings-19-23.5.el7.centos.noarch
dmraid-1.0.0.rc16-28.el7.ppc64
plymouth-plugin-two-step-0.8.9-0.28.20140113.el7.centos.ppc64
sysstat-10.1.5-12.el7.ppc64
xorg-x11-drv-dummy-0.3.7-1.el7.ppc64
xorg-x11-drv-qxl-0.1.5-3.el7.ppc64
audit-2.7.6-3.el7.ppc64
freeglut-2.8.1-3.el7.ppc64
certmonger-0.78.4-3.el7.ppc64
alsa-tools-firmware-1.1.0-1.el7.ppc64
python-rtslib-2.1.fb63-2.el7.noarch
upower-0.99.4-2.el7.ppc64
totem-pl-parser-3.10.7-1.el7.ppc64
dleyna-core-0.5.0-1.el7.ppc64
gnutls-dane-3.3.26-9.el7.ppc64
systemtap-runtime-3.1-3.el7.ppc64
setroubleshoot-server-3.2.28-3.el7.ppc64
rubygem-io-console-0.4.2-30.el7.ppc64
jbigkit-libs-2.0-11.el7.ppc64
sane-backends-1.0.24-9.el7.ppc64
java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.ppc64
gstreamer-plugins-good-0.10.31-13.el7.ppc64
poppler-utils-0.26.5-16.el7.ppc64
pygtk2-libglade-2.24.0-9.el7.ppc64
gstreamer-plugins-bad-free-0.10.23-23.el7.ppc64
libappstream-glib-0.6.10-1.el7.ppc64
libsss_sudo-1.15.2-50.el7.ppc64
sssd-proxy-1.15.2-50.el7.ppc64
gtk3-3.22.10-4.el7.ppc64
gvfs-1.30.4-3.el7.ppc64
clutter-gst3-3.0.22-1.el7.ppc64
evolution-data-server-3.22.7-6.el7.ppc64
gtksourceview3-3.22.2-1.el7.ppc64
abrt-gui-libs-2.1.11-48.el7.centos.ppc64
python-meh-gui-0.25.2-1.el7.noarch
gnome-packagekit-common-3.22.1-2.el7.ppc64
unique3-3.0.2-8.el7.ppc64
gtkmm30-3.22.0-1.el7.ppc64
nautilus-3.22.3-3.el7.ppc64
yelp-xsl-3.20.1-1.el7.noarch
centos-indexhtml-7-9.el7.centos.noarch
gdm-3.22.3-11.el7.ppc64
gnome-shell-extension-launch-new-instance-3.22.2-10.el7.noarch
anaconda-gui-21.48.22.121-1.el7.centos.ppc64
system-config-printer-1.4.1-19.el7.ppc64
evince-nautilus-3.22.1-5.el7.ppc64
gnome-font-viewer-3.22.0-1.el7.ppc64
unique3-devel-3.0.2-8.el7.ppc64
NetworkManager-libreswan-gnome-1.2.4-2.el7.ppc64
gvfs-afc-1.30.4-3.el7.ppc64
ibus-rawcode-1.3.2-3.el7.ppc64
mousetweaks-3.12.0-1.el7.ppc64
hpijs-3.15.9-3.el7.ppc64
java-1.7.0-openjdk-devel-1.7.0.141-2.6.10.5.el7.ppc64
rubygem-abrt-0.3.0-1.el7.noarch
targetcli-2.1.fb46-1.el7.noarch
samba-client-4.6.2-8.el7.ppc64
rdma-core-devel-13-7.el7.ppc64
NetworkManager-tui-1.8.0-9.el7.ppc64
mod_ssl-2.4.6-67.el7.centos.ppc64
systemd-devel-219-42.el7.ppc64
smartmontools-6.2-8.el7.ppc64
iprutils-2.4.14.1-1.el7.ppc64
gcc-gfortran-4.8.5-16.el7.ppc64
adcli-0.8.1-3.el7.ppc64
motif-devel-2.3.4-8.1.el7_3.ppc64
e2fsprogs-devel-1.42.9-10.el7.ppc64
binutils-devel-2.25.1-31.base.el7.ppc64
audit-libs-devel-2.7.6-3.el7.ppc64
perf-3.10.0-693.el7.ppc64
libitm-devel-4.8.5-16.el7.ppc64
crash-gcore-command-1.3.1-0.el7.ppc64
numactl-devel-2.0.9-6.el7_2.ppc64
xvattr-1.3-27.el7.ppc64
ed-1.9-4.el7.ppc64
dejavu-serif-fonts-2.33-6.el7.noarch
dejavu-sans-fonts-2.33-6.el7.noarch
lohit-telugu-fonts-2.5.3-3.el7.noarch
scl-utils-20130529-17.el7_1.ppc64
open-sans-fonts-1.10-1.el7.noarch
strace-4.12-4.el7.ppc64
setserial-2.17-33.el7.ppc64
iwl100-firmware-39.31.5.1-56.el7.noarch
iwl6000g2a-firmware-17.168.5.3-56.el7.noarch
glibc-2.17-196.el7.ppc
centos-release-7-4.1708.el7.centos.ppc64
dejavu-fonts-common-2.33-6.el7.noarch
mobile-broadband-provider-info-1.20170310-1.el7.noarch
bind-license-9.9.4-50.el7.noarch
appstream-data-7-20170301.el7.noarch
libkkc-data-0.3.1-9.el7.ppc64
pcre-8.32-17.el7.ppc64
nspr-4.13.1-1.0.el7_3.ppc64
bzip2-libs-1.0.6-13.el7.ppc64
sqlite-3.7.17-8.el7.ppc64
keyutils-libs-1.5.8-3.el7.ppc64
libacl-2.2.51-12.el7.ppc64
lcms2-2.6-3.el7.ppc64
libXau-1.0.8-2.1.el7.ppc64
libXrender-0.9.10-1.el7.ppc64
libldb-1.1.29-1.el7.ppc64
file-libs-5.11-33.el7.ppc64
libXmu-1.1.2-2.el7.ppc64
gdbm-1.10-8.el7.ppc64
tar-1.26-32.el7.ppc64
libepoxy-1.3.1-1.el7.ppc64
e2fsprogs-libs-1.42.9-10.el7.ppc64
libverto-0.2.5-4.el7.ppc64
gsm-1.0.13-11.el7.ppc64
keyutils-1.5.8-3.el7.ppc64
taglib-1.8-7.20130218git.el7.ppc64
libwebp-0.3.0-7.el7.ppc64
openjpeg-libs-1.5.1-17.el7.ppc64
perl-Text-ParseWords-3.29-4.el7.noarch
perl-Filter-1.49-3.el7.ppc64
perl-File-Path-2.09-2.el7.noarch
perl-Compress-Raw-Zlib-2.061-4.el7.ppc64
perl-Package-Constants-0.02-292.el7.noarch
perl-Digest-MD5-2.52-3.el7.ppc64
perl-Locale-Maketext-1.23-3.el7.noarch
perl-local-lib-1.008010-4.el7.noarch
boost-wave-1.53.0-27.el7.ppc64
ca-certificates-2017.2.14-71.el7.noarch
patch-2.7.1-8.el7.ppc64
libjpeg-turbo-devel-1.2.90-5.el7.ppc64
abattis-cantarell-fonts-0.0.25-1.el7.noarch
soundtouch-1.4.0-9.el7.ppc64
lsvpd-1.7.8-1.el7.ppc64
c-ares-1.10.0-3.el7.ppc64
libvpx-1.3.0-5.el7_0.ppc64
m17n-lib-1.6.4-14.el7.ppc64
perl-libxml-perl-0.08-19.el7.noarch
perl-Net-LibIDN-0.12-15.el7.ppc64
perl-Newt-1.08-36.el7.ppc64
perl-URI-1.60-9.el7.noarch
perl-HTTP-Negotiate-6.01-5.el7.noarch
perl-Env-1.04-2.el7.noarch
papi-5.2.0-23.el7.ppc64
libverto-tevent-0.2.5-4.el7.ppc64
libusbmuxd-1.0.10-5.el7.ppc64
libdmx-1.1.3-3.el7.ppc64
keyutils-libs-devel-1.5.8-3.el7.ppc64
libdb-utils-5.3.21-20.el7.ppc64
libitm-4.8.5-16.el7.ppc64
elfutils-libs-0.168-8.el7.ppc64
liberation-sans-fonts-1.07.2-15.el7.noarch
cups-libs-1.6.3-29.el7.ppc64
libmount-2.23.2-43.el7.ppc64
libsecret-0.18.5-2.el7.ppc64
telepathy-glib-0.24.0-1.el7.ppc64
openssl-1.0.2k-8.el7.ppc64
harfbuzz-icu-1.3.2-1.el7.ppc64
libselinux-python-2.5-11.el7.ppc64
ModemManager-glib-1.6.0-2.el7.ppc64
libevent-2.0.21-4.el7.ppc64
libmbim-1.14.0-2.el7.ppc64
xorg-x11-fonts-Type1-7.5-9.el7.noarch
libXau-devel-1.0.8-2.1.el7.ppc64
libXcursor-devel-1.1.14-8.el7.ppc64
glib2-devel-2.50.3-3.el7.ppc64
apr-devel-1.4.8-3.el7.ppc64
yum-metadata-parser-1.1.4-10.el7.ppc64
langtable-python-0.0.31-3.el7.noarch
pyliblzma-0.5.3-11.el7.ppc64
krb5-workstation-1.15.1-8.el7.ppc64
perl-IPC-Cmd-0.80-4.el7.noarch
perl-ExtUtils-Embed-1.30-292.el7.noarch
libmbim-utils-1.14.0-2.el7.ppc64
python-slip-dbus-0.4.0-2.el7.noarch
libselinux-devel-2.5-11.el7.ppc64
krb5-devel-1.15.1-8.el7.ppc64
check-devel-0.9.9-5.el7.ppc64
compat-libcolord1-1.0.4-1.el7.ppc64
python-cups-1.9.63-6.el7.ppc64
javapackages-tools-3.4.1-11.el7.noarch
python-configobj-4.7.2-7.el7.noarch
python-linux-procfs-0.4.9-3.el7.noarch
pywbem-0.7.0-25.20130827svn625.el7.noarch
pyxattr-0.5.1-5.el7.ppc64
python-jwcrypto-0.2.1-1.el7.noarch
perl-IO-Socket-SSL-1.94-6.el7.noarch
ldns-1.6.16-10.el7.ppc64
libsss_certmap-1.15.2-50.el7.ppc64
libreport-python-2.1.11-38.el7.centos.ppc64
libreport-cli-2.1.11-38.el7.centos.ppc64
libuser-python-0.60-7.el7_1.ppc64
systemtap-devel-3.1-3.el7.ppc64
konkretcmpi-0.9.1-5.el7.ppc64
libreport-centos-2.1.11-38.el7.centos.ppc64
libsrtp-1.4.4-10.20101004cvs.el7.ppc64
libndp-1.2-7.el7.ppc64
festvox-slt-arctic-hts-0.20061229-28.el7.noarch
rpm-python-4.11.3-25.el7.ppc64
yum-utils-1.1.31-42.el7.noarch
libpath_utils-0.2.1-27.el7.ppc64
frei0r-plugins-1.3-13.el7.ppc64
libsemanage-2.5-8.el7.ppc64
device-mapper-1.02.140-8.el7.ppc64
polkit-0.112-12.el7_3.ppc64
cairo-gobject-1.14.8-2.el7.ppc64
dconf-0.26.0-2.el7.ppc64
libpciaccess-0.13.4-3.el7_3.ppc64
libsmbclient-4.6.2-8.el7.ppc64
abrt-python-2.1.11-48.el7.centos.ppc64
iputils-20160308-10.el7.ppc64
dhclient-4.2.5-58.el7.centos.ppc64
libibumad-13-7.el7.ppc64
pyatspi-2.20.3-1.el7.noarch
rsync-3.0.9-18.el7.ppc64
libgphoto2-2.5.2-5.el7.ppc64
perl-Git-1.8.3.1-11.el7.noarch
cairo-devel-1.14.8-2.el7.ppc64
libibcm-13-7.el7.ppc64
python-pyblock-0.53-6.el7.ppc64
plymouth-theme-charge-0.8.9-0.28.20140113.el7.centos.ppc64
libcgroup-tools-0.41-13.el7.ppc64
xorg-x11-drv-evdev-2.10.5-2.1.el7.ppc64
osinfo-db-20170423-2.el7.noarch
gupnp-dlna-0.10.5-1.el7.ppc64
gsound-1.0.2-2.el7.ppc64
ntpdate-4.2.6p5-25.el7.centos.2.ppc64
gssproxy-0.7.0-4.el7.ppc64
libreswan-3.20-3.el7.ppc64
neon-0.30.0-3.el7.ppc64
geoclue2-2.4.5-1.el7.ppc64
flatpak-0.8.7-1.el7.ppc64
libmtp-1.1.6-5.el7.ppc64
systemtap-client-3.1-3.el7.ppc64
sbc-1.0-5.el7.ppc64
rubygem-json-1.7.7-30.el7.ppc64
libtiff-4.0.3-27.el7_3.ppc64
gdk-pixbuf2-devel-2.36.5-1.el7.ppc64
pygtk2-2.24.0-9.el7.ppc64
gvnc-0.7.0-2.el7.ppc64
powerpc-utils-python-1.2.1-9.el7.noarch
adwaita-gtk2-theme-3.22.2-1.el7.ppc64
farstream-0.1.2-8.el7.ppc64
libdmapsharing-2.9.37-1.el7.ppc64
sssd-common-1.15.2-50.el7.ppc64
sssd-1.15.2-50.el7.ppc64
libcanberra-gtk3-0.30-5.el7.ppc64
clutter-gtk-1.8.2-1.el7.ppc64
caribou-gtk3-module-0.4.21-1.el7.ppc64
libchamplain-0.12.15-1.el7.ppc64
evince-libs-3.22.1-5.el7.ppc64
colord-gtk-0.1.25-4.el7.ppc64
libchamplain-gtk-0.12.15-1.el7.ppc64
gnome-packagekit-3.22.1-2.el7.ppc64
avahi-ui-gtk3-0.6.31-17.el7.ppc64
gtk-vnc2-0.7.0-2.el7.ppc64
cheese-libs-3.22.1-1.el7.ppc64
control-center-3.22.2-5.el7.ppc64
nfs-utils-1.3.0-0.48.el7.ppc64
gnome-shell-3.22.3-17.el7.ppc64
gnome-shell-extension-apps-menu-3.22.2-10.el7.noarch
anaconda-core-21.48.22.121-1.el7.centos.ppc64
gnome-initial-setup-3.22.1-4.el7.ppc64
orca-3.6.3-4.el7.ppc64
gnome-software-3.22.7-1.el7.ppc64
iowatcher-1.0-6.el7.ppc64
firstboot-19.12-1.el7.ppc64
gvfs-afp-1.30.4-3.el7.ppc64
ibus-kkc-1.5.18-7.el7.ppc64
gnome-system-log-3.9.90-3.el7.ppc64
gutenprint-cups-5.2.9-18.el7.ppc64
system-config-printer-udev-1.4.1-19.el7.ppc64
rubygem-bundler-1.7.8-3.el7.noarch
subversion-1.7.14-10.el7.ppc64
xorg-x11-drivers-7.7-6.el7.ppc64
qt-mysql-4.8.5-13.el7.ppc64
pygobject3-devel-3.22.0-1.el7.ppc64
httpd-manual-2.4.6-67.el7.centos.noarch
gstreamer1-plugins-base-devel-1.10.4-1.el7.ppc64
net-tools-2.0-0.22.20131004git.el7.ppc64
oprofile-0.9.9-22.el7.ppc64
kernel-tools-3.10.0-693.el7.ppc64
qt3-PostgreSQL-3.3.8b-51.el7.ppc64
libXaw-devel-1.0.13-4.el7.ppc64
libgudev1-devel-219-42.el7.ppc64
gvfs-devel-1.30.4-3.el7.ppc64
hunspell-devel-1.3.2-15.el7.ppc64
iotop-0.6-2.el7.noarch
libatomic-static-4.8.5-16.el7.ppc64
ledmon-0.80-2.el7.ppc64
libpfm-devel-4.7.0-4.el7.ppc64
rcs-5.9.0-5.el7.ppc64
time-1.7-45.el7.ppc64
lohit-bengali-fonts-2.5.3-4.el7.noarch
paktype-naskh-basic-fonts-4.1-3.el7.noarch
lohit-nepali-fonts-2.5.3-2.el7.noarch
pnm2ppa-1.04-28.el7.ppc64
cscope-15.8-10.el7.ppc64
doxygen-1.8.5-3.el7.ppc64
bridge-utils-1.5-9.el7.ppc64
words-3.0-22.el7.noarch
iwl6000-firmware-9.221.4.1-56.el7.noarch
nss-softokn-freebl-3.28.3-6.el7.ppc
setup-2.8.71-7.el7.noarch
gnu-free-fonts-common-20120503-8.el7.noarch
emacs-filesystem-24.3-19.el7_3.noarch
mozilla-filesystem-1.9-11.el7.ppc64
cim-schema-2.33.0-6.el7.noarch
ncurses-base-5.9-13.20130511.el7.noarch
libsepol-2.5-6.el7.ppc64
libjpeg-turbo-1.2.90-5.el7.ppc64
libuuid-2.23.2-43.el7.ppc64
elfutils-libelf-0.168-8.el7.ppc64
libffi-3.0.13-18.el7.ppc64
libcap-ng-0.7.5-4.el7.ppc64
lua-5.1.4-15.el7.ppc64
libxcb-1.12-1.el7.ppc64
libXrandr-1.5.1-2.el7.ppc64
libxslt-1.1.28-5.el7.ppc64
libdhash-0.4.3-27.el7.ppc64
nettle-2.7.1-8.el7.ppc64
libtasn1-4.10-1.el7.ppc64
flac-libs-1.3.0-5.el7_1.ppc64
libmpc-1.0.1-3.el7.ppc64
mesa-libglapi-17.0.1-6.20170307.el7.ppc64
libieee1284-0.2.11-15.el7.ppc64
libsndfile-1.0.25-10.el7.ppc64
libvpd-2.2.5-1.el7.ppc64
libfontenc-1.1.3-3.el7.ppc64
hyphen-2.8.6-5.el7.ppc64
libical-1.0.1-1.el7.ppc64
perl-Encode-2.51-7.el7.ppc64
perl-Exporter-5.68-3.el7.noarch
perl-File-Temp-0.23.01-3.el7.noarch
perl-Test-Harness-3.28-3.el7.noarch
perl-Module-Metadata-1.000018-2.el7.noarch
perl-CPAN-Meta-YAML-0.008-14.el7.noarch
perl-Encode-Locale-1.03-5.el7.noarch
perl-Term-UI-0.36-2.el7.noarch
boost-graph-1.53.0-27.el7.ppc64
p11-kit-trust-0.23.5-3.el7.ppc64
acl-2.2.51-12.el7.ppc64
pinentry-0.8.1-17.el7.ppc64
libcdio-0.92-1.el7.ppc64
snappy-1.1.0-3.el7.ppc64
sg3_utils-libs-1.37-12.el7.ppc64
libnfnetlink-1.0.1-4.el7.ppc64
ethtool-4.8-1.el7.ppc64
tcl-devel-8.5.13-8.el7.ppc64
perl-B-Lint-1.17-3.el7.noarch
perl-Sys-Syslog-0.33-3.el7.ppc64
kernel-devel-3.10.0-693.el7.ppc64
perl-Business-ISBN-2.06-2.el7.noarch
perl-HTTP-Cookies-6.01-5.el7.noarch
perl-IO-stringy-2.110-22.el7.noarch
perl-autodie-2.16-2.el7.noarch
libieee1284-devel-0.2.11-15.el7.ppc64
libofa-0.9.3-24.el7.ppc64
libXres-1.0.7-2.1.el7.ppc64
attr-2.4.46-12.el7.ppc64
setools-libs-3.3.8-1.1.el7.ppc64
libatomic-4.8.5-16.el7.ppc64
elfutils-default-yama-scope-0.168-8.el7.noarch
libhugetlbfs-2.16-12.el7.ppc64
python-2.7.5-58.el7.ppc64
gzip-1.5-9.el7.ppc64
dbus-glib-0.100-7.el7.ppc64
xorg-x11-proto-devel-7.7-20.el7.noarch
python-gobject-base-3.22.0-1.el7.ppc64
net-snmp-libs-5.7.2-28.el7.ppc64
pygobject2-2.28.6-11.el7.ppc64
libpng-devel-1.5.13-7.el7_2.ppc64
gdb-7.6.1-100.el7.ppc64
systemd-libs-219-42.el7.ppc64
libqmi-1.16.0-1.el7.ppc64
elfutils-libelf-devel-0.168-8.el7.ppc64
libXrender-devel-0.9.10-1.el7.ppc64
libXcomposite-devel-0.4.4-4.1.el7.ppc64
expat-devel-2.1.0-10.el7_3.ppc64
libgee06-0.6.8-3.el7.ppc64
audit-libs-python-2.7.6-3.el7.ppc64
sip-4.14.6-4.el7.ppc64
automake-1.13.4-3.el7.noarch
perl-ExtUtils-MakeMaker-6.68-3.el7.noarch
perl-CPANPLUS-0.91.38-4.el7.noarch
libXp-devel-1.0.2-2.1.el7.ppc64
urw-fonts-2.4-16.el7.noarch
python-dmidecode-3.12.2-1.el7.ppc64
libtasn1-devel-4.10-1.el7.ppc64
gstreamer-tools-0.10.36-7.el7.ppc64
osinfo-db-tools-1.1.0-1.el7.ppc64
grubby-8.28-23.el7.ppc64
python-netaddr-0.7.5-7.el7.noarch
python-coverage-3.6-0.5.b3.el7.ppc64
python-netifaces-0.10.4-3.el7.ppc64
gobject-introspection-devel-1.50.0-1.el7.ppc64
python-dateutil-1.5-7.el7.noarch
python-pycparser-2.14-1.el7.noarch
libwvstreams-4.6.1-11.el7.ppc64
logrotate-3.8.6-14.el7.ppc64
curl-7.29.0-42.el7.ppc64
xmlrpc-c-client-1.32.5-1905.svn2451.el7.ppc64
deltarpm-3.6-3.el7.ppc64
kde-filesystem-4-47.el7.ppc64
python-urlgrabber-3.10-8.el7.noarch
tbb-4.1-9.20130314.el7.ppc64
libreport-plugin-rhtsupport-2.1.11-38.el7.centos.ppc64
kernel-tools-libs-3.10.0-693.el7.ppc64
pulseaudio-libs-glib2-10.0-3.el7.ppc64
pulseaudio-utils-10.0-3.el7.ppc64
perl-Module-Signature-0.73-2.el7.noarch
python2-ipaclient-4.5.0-20.el7.centos.noarch
sssd-client-1.15.2-50.el7.ppc64
http-parser-2.7.1-1.el7.ppc64
servicelog-1.1.14-3.el7.ppc64
dracut-033-502.el7.ppc64
mesa-libgbm-17.0.1-6.20170307.el7.ppc64
ibus-libs-1.5.3-13.el7.ppc64
java-1.8.0-openjdk-devel-1.8.0.131-11.b12.el7.ppc64
at-spi2-atk-2.22.0-2.el7.ppc64
PackageKit-yum-1.1.5-1.el7.centos.ppc64
abrt-addon-kerneloops-2.1.11-48.el7.centos.ppc64
plymouth-0.8.9-0.28.20140113.el7.centos.ppc64
pangomm-2.40.1-1.el7.ppc64
NetworkManager-1.8.0-9.el7.ppc64
libdrm-devel-2.4.74-1.el7.ppc64
iscsi-initiator-utils-6.2.0.874-4.el7.ppc64
grub2-tools-minimal-2.02-0.64.el7.centos.ppc64
grub2-tools-2.02-0.64.el7.centos.ppc64
speech-dispatcher-python-0.7.1-15.el7.ppc64
dmraid-events-1.0.0.rc16-28.el7.ppc64
lvm2-libs-2.02.171-8.el7.ppc64
cyrus-sasl-2.1.26-21.el7.ppc64
abrt-tui-2.1.11-48.el7.centos.ppc64
xorg-x11-drv-void-1.4.1-2.el7.ppc64
libosinfo-1.0.0-1.el7.ppc64
paps-libs-0.6.8-28.el7.1.ppc64
polkit-docs-0.112-12.el7_3.noarch
ntp-4.2.6p5-25.el7.centos.2.ppc64
alsa-utils-1.1.3-2.el7.ppc64
NetworkManager-libreswan-1.2.4-2.el7.ppc64
libmusicbrainz5-5.0.1-9.el7.ppc64
geoclue2-libs-2.4.5-1.el7.ppc64
flatpak-libs-0.8.7-1.el7.ppc64
cryptsetup-python-1.7.4-3.el7.ppc64
tog-pegasus-libs-2.14.1-5.el7.ppc64
pulseaudio-module-bluetooth-10.0-3.el7.ppc64
rubygems-2.0.14.1-30.el7.noarch
gdk-pixbuf2-2.36.5-1.el7.ppc64
ghostscript-9.07-28.el7.ppc64
gstreamer1-plugins-good-1.10.4-2.el7.ppc64
libmediaart-1.9.1-1.el7.ppc64
powerpc-utils-1.3.3-4.el7.ppc64
gtk2-devel-2.24.31-1.el7.ppc64
libpurple-2.10.11-5.el7.ppc64
libtiff-devel-4.0.3-27.el7_3.ppc64
sssd-krb5-common-1.15.2-50.el7.ppc64
gpm-libs-1.20.7-5.el7.ppc64
gcr-3.20.0-1.el7.ppc64
webkitgtk4-jsc-2.14.7-2.el7.ppc64
caribou-gtk2-module-0.4.21-1.el7.ppc64
libnma-1.8.0-3.el7.ppc64
libnm-gtk-1.8.0-3.el7.ppc64
gnome-bluetooth-3.20.1-1.el7.ppc64
gnome-terminal-3.22.1-2.el7.ppc64
gnome-packagekit-installer-3.22.1-2.el7.ppc64
anaconda-widgets-21.48.22.121-1.el7.centos.ppc64
gnome-dictionary-libs-3.20.0-1.el7.ppc64
compat-cheese314-3.14.2-1.el7.ppc64
gnome-settings-daemon-3.22.2-5.el7.ppc64
quota-4.01-14.el7.ppc64
gnome-session-3.22.3-4.el7.ppc64
gnome-shell-extension-window-list-3.22.2-10.el7.noarch
anaconda-tui-21.48.22.121-1.el7.centos.ppc64
gnome-tweak-tool-3.22.0-1.el7.noarch
gnome-getting-started-docs-3.22.0-1.el7.noarch
gnome-clocks-3.22.1-1.el7.ppc64
file-roller-nautilus-3.22.3-1.el7.ppc64
gnome-color-manager-3.22.2-1.el7.ppc64
gvfs-gphoto2-1.30.4-3.el7.ppc64
ibus-chewing-1.4.4-14.el7.ppc64
gnome-disk-utility-3.22.1-1.el7.ppc64
firewall-config-0.4.4.4-6.el7.noarch
libsane-hpaio-3.15.9-3.el7.ppc64
rsyslog-8.24.0-12.el7.ppc64
libsoup-devel-2.56.0-3.el7.ppc64
java-1.6.0-openjdk-devel-1.6.0.41-1.13.13.1.el7_3.ppc64
qt-postgresql-4.8.5-13.el7.ppc64
dbus-glib-devel-0.100-7.el7.ppc64
mod_fcgid-2.3.9-4.el7.ppc64
psacct-6.6.1-13.el7.ppc64
ModemManager-1.6.0-2.el7.ppc64
tcpdump-4.9.0-5.el7.ppc64
pulseaudio-libs-devel-10.0-3.el7.ppc64
libreport-plugin-mailx-2.1.11-38.el7.centos.ppc64
mariadb-devel-5.5.56-2.el7.ppc64
xfsdump-3.1.4-1.el7.ppc64
qt3-MySQL-3.3.8b-51.el7.ppc64
fuse-devel-2.9.2-8.el7.ppc64
nautilus-sendto-3.8.4-1.el7.ppc64
tcsh-6.18.01-15.el7.ppc64
perl-Test-Pod-Coverage-1.08-21.el7.noarch
valgrind-3.12.0-8.el7.ppc64
libaio-devel-0.3.109-13.el7.ppc64
nano-2.3.1-10.el7.ppc64
lohit-oriya-fonts-2.5.4.1-3.el7.noarch
thai-scalable-waree-fonts-0.5.0-7.el7.noarch
lohit-marathi-fonts-2.5.3-2.el7.noarch
cjkuni-uming-fonts-0.2.20080216.1-53.el7.noarch
traceroute-2.0.22-2.el7.ppc64
gnu-free-serif-fonts-20120503-8.el7.noarch
byacc-1.9.20130304-3.el7.ppc64
iwl5150-firmware-8.24.2.2-56.el7.noarch
man-pages-3.53-5.el7.noarch
iwl2000-firmware-18.168.6.1-56.el7.noarch
epel-release-7-9.noarch
filesystem-3.2-21.el7.ppc64
tzdata-java-2017b-1.el7.noarch
gl-manpages-1.1-7.20130122.el7.noarch
grub2-ppc64-modules-2.02-0.64.el7.centos.noarch
tigervnc-license-1.8.0-1.el7.noarch
nss-softokn-freebl-3.28.3-6.el7.ppc64
libselinux-2.5-11.el7.ppc64
libpng-1.5.13-7.el7_2.ppc64
libICE-1.0.9-9.el7.ppc64
grep-2.20-3.el7.ppc64
p11-kit-0.23.5-3.el7.ppc64
audit-libs-2.7.6-3.el7.ppc64
libtar-1.2.11-29.el7.ppc64
libX11-1.6.5-1.el7.ppc64
libXtst-1.2.3-1.el7.ppc64
xmlrpc-c-1.32.5-1905.svn2451.el7.ppc64
mpfr-3.1.1-4.el7.ppc64
libtheora-1.1.1-8.el7.ppc64
libsss_idmap-1.15.2-50.el7.ppc64
nss-softokn-3.28.3-6.el7.ppc64
file-5.11-33.el7.ppc64
boost-date-time-1.53.0-27.el7.ppc64
slang-2.2.4-11.el7.ppc64
librtas-2.0.1-1.el7.ppc64
exempi-2.2.0-8.el7.ppc64
GeoIP-1.5.0-11.el7.ppc64
fuse-libs-2.9.2-8.el7.ppc64
libXfont2-2.0.1-2.el7.ppc64
perl-Pod-Usage-1.63-3.el7.noarch
perl-threads-1.87-4.el7.ppc64
perl-PathTools-3.40-5.el7.ppc64
perl-Module-CoreList-2.76.02-292.el7.noarch
perl-Test-Simple-0.98-243.el7.noarch
perl-LWP-MediaTypes-6.02-2.el7.noarch
perl-Error-0.17020-2.el7.noarch
perl-Log-Message-Simple-0.10-2.el7.noarch
less-458-9.el7.ppc64
boost-timer-1.53.0-27.el7.ppc64
gmp-devel-6.0.0-15.el7.ppc64
iso-codes-3.46-2.el7.noarch
make-3.82-23.el7.ppc64
boost-serialization-1.53.0-27.el7.ppc64
libxkbcommon-0.7.1-1.el7.ppc64
tcl-8.5.13-8.el7.ppc64
dosfstools-3.0.20-9.el7.ppc64
iproute-3.10.0-87.el7.ppc64
perl-Archive-Tar-1.92-2.el7.noarch
perl-DB_File-1.830-6.el7.ppc64
perl-DBIx-Simple-1.35-7.el7.noarch
perl-Business-ISBN-Data-20120719.001-2.el7.noarch
perl-HTTP-Daemon-6.01-5.el7.noarch
perl-IO-Socket-IP-0.21-4.el7.noarch
perl-CGI-3.63-4.el7.noarch
lm_sensors-devel-3.4.0-4.20160601gitf9185e5.el7.ppc64
fftw-libs-double-3.3.3-8.el7.ppc64
tcp_wrappers-7.6-77.el7.ppc64
libattr-devel-2.4.46-12.el7.ppc64
dwz-0.11-3.el7.ppc64
liblouis-2.5.2-10.el7.ppc64
libselinux-utils-2.5-11.el7.ppc64
liberation-mono-fonts-1.07.2-15.el7.noarch
python-libs-2.7.5-58.el7.ppc64
python-six-1.9.0-2.el7.noarch
gstreamer1-1.10.4-2.el7.ppc64
gsettings-desktop-schemas-3.22.0-1.el7.ppc64
desktop-file-utils-0.23-1.el7.ppc64
centos-logos-70.0.6-3.el7.centos.noarch
qt3-3.3.8b-51.el7.ppc64
libICE-devel-1.0.9-9.el7.ppc64
libtirpc-0.2.4-0.10.el7.ppc64
libgudev1-219-42.el7.ppc64
libgusb-0.2.9-1.el7.ppc64
avahi-gobject-0.6.31-17.el7.ppc64
libXrandr-devel-1.5.1-2.el7.ppc64
libXxf86vm-devel-1.1.4-1.el7.ppc64
fontconfig-devel-2.10.95-11.el7.ppc64
gnome-menus-3.13.3-3.el7.ppc64
pyusb-1.0.0-0.11.b1.el7.noarch
python-IPy-0.75-6.el7.noarch
genisoimage-1.1.11-23.el7.ppc64
perl-ExtUtils-Install-1.58-292.el7.noarch
perl-CPAN-1.9800-292.el7.noarch
libXpm-devel-3.5.12-1.el7.ppc64
ghostscript-fonts-5.50-32.el7.noarch
libepoxy-devel-1.3.1-1.el7.ppc64
pixman-devel-0.34.0-1.el7.ppc64
gstreamer-0.10.36-7.el7.ppc64
gom-0.3.2-1.el7.ppc64
btrfs-progs-4.9.1-1.el7.ppc64
python-lxml-3.2.1-4.el7.ppc64
python-urllib3-1.10.2-3.el7.noarch
liblouis-python-2.5.2-10.el7.noarch
python-di-0.3-2.el7.noarch
python-kmod-0.9-4.el7.ppc64
python-cffi-1.6.0-5.el7.ppc64
httpd-tools-2.4.6-67.el7.centos.ppc64
sound-theme-freedesktop-0.8-3.el7.noarch
libcurl-7.29.0-42.el7.ppc64
abrt-libs-2.1.11-48.el7.centos.ppc64
python-ldap-2.4.15-2.el7.ppc64
postgresql-9.2.21-1.el7.ppc64
python-pycurl-7.19.0-19.el7.ppc64
libstdc++-devel-4.8.5-16.el7.ppc64
libreport-plugin-reportuploader-2.1.11-38.el7.centos.ppc64
opencc-0.4.3-3.el7.ppc64
pulseaudio-libs-10.0-3.el7.ppc64
festival-freebsoft-utils-0.10-7.el7.noarch
perl-PAR-Dist-0.49-2.el7.noarch
python2-ipalib-4.5.0-20.el7.centos.noarch
libsss_nss_idmap-1.15.2-50.el7.ppc64
qrencode-libs-3.4.1-3.el7.ppc64
libservicelog-1.1.17-2.el7.ppc64
cryptsetup-libs-1.7.4-3.el7.ppc64
libcanberra-0.30-5.el7.ppc64
systemd-sysv-219-42.el7.ppc64
java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.ppc64
at-spi2-core-2.22.0-1.el7.ppc64
pyparted-3.9-13.el7.ppc64
abrt-dbus-2.1.11-48.el7.centos.ppc64
plymouth-scripts-0.8.9-0.28.20140113.el7.centos.ppc64
abrt-addon-xorg-2.1.11-48.el7.centos.ppc64
wpa_supplicant-2.6-5.el7.ppc64
mesa-libGLES-17.0.1-6.20170307.el7.ppc64
iscsi-initiator-utils-iscsiuio-6.2.0.874-4.el7.ppc64
udisks2-2.1.2-6.el7.ppc64
grub2-tools-extra-2.02-0.64.el7.centos.ppc64
libpeas-loader-python-1.20.0-1.el7.ppc64
qt-4.8.5-13.el7.ppc64
lvm2-2.02.171-8.el7.ppc64
cyrus-sasl-devel-2.1.26-21.el7.ppc64
abrt-retrace-client-2.1.11-48.el7.centos.ppc64
xorg-x11-drv-nouveau-1.0.13-3.el7.ppc64
java-1.6.0-openjdk-1.6.0.41-1.13.13.1.el7_3.ppc64
harfbuzz-devel-1.3.2-1.el7.ppc64
polkit-devel-0.112-12.el7_3.ppc64
ebtables-2.0.10-15.el7.ppc64
chrony-3.1-2.el7.centos.ppc64
usb_modeswitch-2.4.0-5.el7.ppc64
subversion-libs-1.7.14-10.el7.ppc64
gssdp-1.0.1-1.el7.ppc64
dleyna-connector-dbus-0.2.0-2.el7.ppc64
device-mapper-multipath-libs-0.4.9-111.el7.ppc64
tog-pegasus-2.14.1-5.el7.ppc64
libyaml-0.1.4-11.el7_0.ppc64
rubygem-rdoc-4.0.0-30.el7.noarch
libnotify-0.7.7-1.el7.ppc64
gstreamer1-plugins-bad-free-1.10.4-2.el7.ppc64
poppler-0.26.5-16.el7.ppc64
libgxps-0.2.5-1.el7.ppc64
easymock2-2.5.2-12.el7.noarch
libspectre-0.2.8-1.el7.ppc64
telepathy-haze-0.8.0-1.el7.ppc64
cups-filters-libs-1.0.35-22.el7.ppc64
sssd-common-pac-1.15.2-50.el7.ppc64
kbd-misc-1.15.5-13.el7.noarch
clutter-1.26.0-1.el7.ppc64
webkitgtk4-plugin-process-gtk2-2.14.7-2.el7.ppc64
caribou-0.4.21-1.el7.ppc64
libgnomekbd-3.22.0.1-1.el7.ppc64
nm-connection-editor-1.8.0-3.el7.ppc64
gnome-bluetooth-libs-3.20.1-1.el7.ppc64
grilo-plugins-0.3.4-1.el7.ppc64
gnome-keyring-pam-3.20.0-3.el7.ppc64
glade-libs-3.20.0-1.el7.ppc64
gspell-1.2.3-1.el7.ppc64
gnome-desktop3-3.22.2-2.el7.ppc64
libwacom-0.24-1.el7.ppc64
quota-nls-4.01-14.el7.noarch
mesa-dri-drivers-17.0.1-6.20170307.el7.ppc64
gnome-shell-extension-places-menu-3.22.2-10.el7.noarch
kbd-1.15.5-13.el7.ppc64
gnome-classic-session-3.22.2-10.el7.noarch
vim-enhanced-7.4.160-2.el7.ppc64
eog-3.20.5-2.el7.ppc64
gedit-3.22.0-3.el7.ppc64
libcanberra-devel-0.30-5.el7.ppc64
setroubleshoot-3.2.28-3.el7.ppc64
ibus-m17n-1.3.4-13.el7.ppc64
gnome-screenshot-3.22.0-1.el7.ppc64
xdg-user-dirs-gtk-0.10-4.el7.ppc64
ppc64-utils-0.14-16.el7.ppc64
man-db-2.6.3-9.el7.ppc64
gnutls-devel-3.3.26-9.el7.ppc64
paps-0.6.8-28.el7.1.ppc64
qt-odbc-4.8.5-13.el7.ppc64
NetworkManager-ppp-1.8.0-9.el7.ppc64
cifs-utils-6.2-10.el7.ppc64
postfix-2.10.1-6.el7.ppc64
crda-3.13_2016.02.08-1.el7.ppc64
memstomp-0.1.4-11.el7.ppc64
rpm-build-4.11.3-25.el7.ppc64
postgresql-devel-9.2.21-1.el7.ppc64
cups-devel-1.6.3-29.el7.ppc64
libxslt-devel-1.1.28-5.el7.ppc64
qt3-ODBC-3.3.8b-51.el7.ppc64
libcap-ng-devel-0.7.5-4.el7.ppc64
dstat-0.7.2-12.el7.noarch
libhugetlbfs-devel-2.16-12.el7.ppc64
perl-XML-Grove-0.46alpha-52.el7.noarch
enscript-1.6.6-6.el7.ppc64
ntsysv-1.7.4-1.el7.ppc64
indent-2.2.11-13.el7.ppc64
dejavu-sans-mono-fonts-2.33-6.el7.noarch
overpass-fonts-2.1-1.el7.noarch
gnu-free-mono-fonts-20120503-8.el7.noarch
lohit-tamil-fonts-2.5.3-2.el7.noarch
lohit-punjabi-fonts-2.5.3-2.el7.noarch
google-crosextra-carlito-fonts-1.103-0.2.20130920.el7.noarch
lrzsz-0.12.20-36.el7.ppc64
iwl2030-firmware-18.168.6.1-56.el7.noarch
iwl7265-firmware-22.0.7.0-56.el7.noarch
man-pages-overrides-7.4.3-1.el7.ppc64
gpg-pubkey-352c64e5-52ae6884
=== TEST BEGIN ===
Install prefix    /var/tmp/patchew-tester-tmp-84g4a1ey/src/install
BIOS directory    /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/share/qemu
firmware path     /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/share/qemu-firmware
binary directory  /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/bin
library directory /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/lib
module directory  /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/lib/qemu
libexec directory /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/libexec
include directory /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/include
config directory  /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/etc
local state directory   /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/var
Manual directory  /var/tmp/patchew-tester-tmp-84g4a1ey/src/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /var/tmp/patchew-tester-tmp-84g4a1ey/src
GIT binary        git
GIT submodules    ui/keycodemapdb dtc capstone
C compiler        cc
Host C compiler   cc
C++ compiler      c++
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS       -I/usr/include/pixman-1   -I$(SRC_PATH)/dtc/libfdt -Werror -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -DNCURSES_WIDECHAR   -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-strong -Wno-missing-braces -I/usr/include/p11-kit-1       -I/usr/include/libpng15   -I$(SRC_PATH)/capstone/include
LDFLAGS           -Wl,--warn-common -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          ppc64
host big endian   yes
target list       aarch64-softmmu alpha-softmmu arm-softmmu cris-softmmu hppa-softmmu i386-softmmu lm32-softmmu m68k-softmmu microblazeel-softmmu microblaze-softmmu mips64el-softmmu mips64-softmmu mipsel-softmmu mips-softmmu moxie-softmmu nios2-softmmu or1k-softmmu ppc64-softmmu ppcemb-softmmu ppc-softmmu s390x-softmmu sh4eb-softmmu sh4-softmmu sparc64-softmmu sparc-softmmu tricore-softmmu unicore32-softmmu x86_64-softmmu xtensaeb-softmmu xtensa-softmmu aarch64_be-linux-user aarch64-linux-user alpha-linux-user armeb-linux-user arm-linux-user cris-linux-user hppa-linux-user i386-linux-user m68k-linux-user microblazeel-linux-user microblaze-linux-user mips64el-linux-user mips64-linux-user mipsel-linux-user mips-linux-user mipsn32el-linux-user mipsn32-linux-user nios2-linux-user or1k-linux-user ppc64abi32-linux-user ppc64le-linux-user ppc64-linux-user ppc-linux-user s390x-linux-user sh4eb-linux-user sh4-linux-user sparc32plus-linux-user sparc64-linux-user sparc-linux-user tilegx-linux-user x86_64-linux-user
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
SDL support       yes (1.2.15)
GTK support       yes (3.22.10)
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    yes
GNUTLS rnd        yes
libgcrypt         no
libgcrypt kdf     no
nettle            yes (2.7.1)
nettle kdf        yes
libtasn1          yes
curses support    yes
virgl support     no
curl support      yes
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    yes
Multipath support no
VNC support       yes
VNC SASL support  yes
VNC JPEG support  yes
VNC PNG support   yes
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               no
vde support       no
netmap support    no
Linux AIO support yes
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
HAX support       no
HVF support       no
WHPX support      no
TCG support       yes
TCG debug enabled no
TCG interpreter   no
malloc trim support yes
RDMA support      yes
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
posix_memalign    yes
libcap-ng support yes
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
vhost-user support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            yes
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
debug stack usage no
crypto afalg      no
GlusterFS support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   no
TPM emulator      yes
QOM debugging     yes
Live block migration yes
lzo support       no
snappy support    no
bzip2 support     yes
NUMA host support yes
libxml2           yes
tcmalloc support  no
jemalloc support  no
avx2 optimization no
replication support yes
VxHS block device no
capstone          git

WARNING: Use of SDL 1.2 is deprecated and will be removed in
WARNING: future releases. Please switch to using SDL 2.0
  GEN     aarch64-softmmu/config-devices.mak.tmp
  GEN     alpha-softmmu/config-devices.mak.tmp
  GEN     cris-softmmu/config-devices.mak.tmp
  GEN     arm-softmmu/config-devices.mak.tmp
  GEN     hppa-softmmu/config-devices.mak.tmp
  GEN     lm32-softmmu/config-devices.mak.tmp
  GEN     i386-softmmu/config-devices.mak.tmp
  GEN     microblaze-softmmu/config-devices.mak.tmp
  GEN     microblazeel-softmmu/config-devices.mak.tmp
  GEN     m68k-softmmu/config-devices.mak.tmp
  GEN     mips64el-softmmu/config-devices.mak.tmp
  GEN     alpha-softmmu/config-devices.mak
  GEN     mips64-softmmu/config-devices.mak.tmp
  GEN     mips-softmmu/config-devices.mak.tmp
  GEN     mipsel-softmmu/config-devices.mak.tmp
  GEN     moxie-softmmu/config-devices.mak.tmp
  GEN     lm32-softmmu/config-devices.mak
  GEN     arm-softmmu/config-devices.mak
  GEN     cris-softmmu/config-devices.mak
  GEN     nios2-softmmu/config-devices.mak.tmp
  GEN     or1k-softmmu/config-devices.mak.tmp
  GEN     ppcemb-softmmu/config-devices.mak.tmp
  GEN     hppa-softmmu/config-devices.mak
  GEN     ppc-softmmu/config-devices.mak.tmp
  GEN     aarch64-softmmu/config-devices.mak
  GEN     ppc64-softmmu/config-devices.mak.tmp
  GEN     microblaze-softmmu/config-devices.mak
  GEN     sh4eb-softmmu/config-devices.mak.tmp
  GEN     s390x-softmmu/config-devices.mak.tmp
  GEN     moxie-softmmu/config-devices.mak
  GEN     i386-softmmu/config-devices.mak
  GEN     sh4-softmmu/config-devices.mak.tmp
  GEN     microblazeel-softmmu/config-devices.mak
  GEN     m68k-softmmu/config-devices.mak
  GEN     sparc64-softmmu/config-devices.mak.tmp
  GEN     tricore-softmmu/config-devices.mak.tmp
  GEN     unicore32-softmmu/config-devices.mak.tmp
  GEN     sparc-softmmu/config-devices.mak.tmp
  GEN     i386-linux-user/config-devices.mak.tmp
  GEN     x86_64-softmmu/config-devices.mak.tmp
  GEN     alpha-linux-user/config-devices.mak.tmp
  GEN     hppa-linux-user/config-devices.mak.tmp
  GEN     microblaze-linux-user/config-devices.mak.tmp
  GEN     m68k-linux-user/config-devices.mak.tmp
  GEN     arm-linux-user/config-devices.mak.tmp
  GEN     nios2-softmmu/config-devices.mak
  GEN     cris-linux-user/config-devices.mak.tmp
  GEN     aarch64_be-linux-user/config-devices.mak.tmp
  GEN     xtensaeb-softmmu/config-devices.mak.tmp
  GEN     microblazeel-linux-user/config-devices.mak.tmp
  GEN     mipsel-linux-user/config-devices.mak.tmp
  GEN     armeb-linux-user/config-devices.mak.tmp
  GEN     mips-linux-user/config-devices.mak.tmp
  GEN     aarch64-linux-user/config-devices.mak.tmp
  GEN     mips64el-linux-user/config-devices.mak.tmp
  GEN     mips64-linux-user/config-devices.mak.tmp
  GEN     xtensa-softmmu/config-devices.mak.tmp
  GEN     mipsn32-linux-user/config-devices.mak.tmp
  GEN     nios2-linux-user/config-devices.mak.tmp
  GEN     or1k-linux-user/config-devices.mak.tmp
  GEN     ppc64abi32-linux-user/config-devices.mak.tmp
  GEN     s390x-linux-user/config-devices.mak.tmp
  GEN     ppc64-linux-user/config-devices.mak.tmp
  GEN     sh4eb-linux-user/config-devices.mak.tmp
  GEN     sparc32plus-linux-user/config-devices.mak.tmp
  GEN     sparc64-linux-user/config-devices.mak.tmp
  GEN     sparc-linux-user/config-devices.mak.tmp
  GEN     tilegx-linux-user/config-devices.mak.tmp
  GEN     x86_64-linux-user/config-devices.mak.tmp
  GEN     config-host.h
  GIT     ui/keycodemapdb dtc capstone
  GEN     qemu-options.def
  GEN     sh4-linux-user/config-devices.mak.tmp
  GEN     or1k-softmmu/config-devices.mak
  GEN     or1k-linux-user/config-devices.mak
  GEN     s390x-linux-user/config-devices.mak
  GEN     sparc64-linux-user/config-devices.mak
  GEN     aarch64_be-linux-user/config-devices.mak
  GEN     mipsel-softmmu/config-devices.mak
  GEN     ppcemb-softmmu/config-devices.mak
  GEN     sparc-linux-user/config-devices.mak
  GEN     mips64el-linux-user/config-devices.mak
  GEN     s390x-softmmu/config-devices.mak
  GEN     qapi-types.h
  GEN     qapi-event.h
  GEN     tilegx-linux-user/config-devices.mak
  GEN     qmp-marshal.c
  GEN     qapi-visit.h
  GEN     qapi-types.c
  GEN     trace/generated-tcg-tracers.h
  GEN     sh4-linux-user/config-devices.mak
  GEN     mips64-softmmu/config-devices.mak
  GEN     trace/generated-helpers-wrappers.h
  GEN     ppc-linux-user/config-devices.mak.tmp
  GEN     qmp-introspect.c
  GEN     qapi-visit.c
  GEN     trace/generated-helpers.h
  GEN     trace/generated-helpers.c
  GEN     module_block.h
  GEN     qmp-introspect.h
  GEN     qmp-commands.h
  GEN     qapi-event.c
  GEN     ppc64le-linux-user/config-devices.mak.tmp
  GEN     ppc-softmmu/config-devices.mak
  GEN     sh4eb-softmmu/config-devices.mak
  GEN     sparc64-softmmu/config-devices.mak
  GEN     unicore32-softmmu/config-devices.mak
  GEN     arm-linux-user/config-devices.mak
  GEN     alpha-linux-user/config-devices.mak
  GEN     sh4-softmmu/config-devices.mak
  GEN     i386-linux-user/config-devices.mak
  GEN     m68k-linux-user/config-devices.mak
  GEN     cris-linux-user/config-devices.mak
  GEN     mipsn32el-linux-user/config-devices.mak.tmp
  GEN     mips-linux-user/config-devices.mak
  GEN     ppc64-softmmu/config-devices.mak
  GEN     microblaze-linux-user/config-devices.mak
  GEN     nios2-linux-user/config-devices.mak
  GEN     mips-softmmu/config-devices.mak
  GEN     ppc64-linux-user/config-devices.mak
  GEN     ppc-linux-user/config-devices.mak
  GEN     mips64el-softmmu/config-devices.mak
  GEN     sh4eb-linux-user/config-devices.mak
  GEN     xtensa-softmmu/config-devices.mak
  GEN     x86_64-softmmu/config-devices.mak
  GEN     ppc64abi32-linux-user/config-devices.mak
  GEN     mipsn32-linux-user/config-devices.mak
  GEN     hppa-linux-user/config-devices.mak
  GEN     x86_64-linux-user/config-devices.mak
  GEN     aarch64-linux-user/config-devices.mak
  GEN     sparc32plus-linux-user/config-devices.mak
  GEN     microblazeel-linux-user/config-devices.mak
  GEN     tricore-softmmu/config-devices.mak
  GEN     armeb-linux-user/config-devices.mak
  GEN     tests/test-qapi-types.h
  GEN     mips64-linux-user/config-devices.mak
  GEN     tests/test-qapi-visit.h
  GEN     mipsel-linux-user/config-devices.mak
  GEN     tests/test-qmp-commands.h
  GEN     sparc-softmmu/config-devices.mak
  GEN     ppc64le-linux-user/config-devices.mak
  GEN     mipsn32el-linux-user/config-devices.mak
  GEN     tests/test-qapi-event.h
  GEN     tests/test-qmp-introspect.h
  GEN     trace-root.h
  GEN     xtensaeb-softmmu/config-devices.mak
  GEN     util/trace.h
  GEN     crypto/trace.h
  GEN     io/trace.h
  GEN     migration/trace.h
  GEN     block/trace.h
  GEN     chardev/trace.h
  GEN     hw/block/trace.h
  GEN     hw/block/dataplane/trace.h
  GEN     hw/char/trace.h
  GEN     hw/intc/trace.h
  GEN     hw/net/trace.h
  GEN     hw/rdma/trace.h
  GEN     hw/rdma/vmw/trace.h
  GEN     hw/virtio/trace.h
  GEN     hw/audio/trace.h
  GEN     hw/misc/trace.h
  GEN     hw/misc/macio/trace.h
  GEN     hw/usb/trace.h
  GEN     hw/scsi/trace.h
  GEN     hw/nvram/trace.h
  GEN     hw/display/trace.h
  GEN     hw/input/trace.h
  GEN     hw/timer/trace.h
  GEN     hw/dma/trace.h
  GEN     hw/sparc/trace.h
  GEN     hw/sparc64/trace.h
  GEN     hw/sd/trace.h
  GEN     hw/isa/trace.h
  GEN     hw/mem/trace.h
  GEN     hw/i386/trace.h
  GEN     hw/i386/xen/trace.h
  GEN     hw/9pfs/trace.h
  GEN     hw/ppc/trace.h
  GEN     hw/pci/trace.h
  GEN     hw/pci-host/trace.h
  GEN     hw/s390x/trace.h
  GEN     hw/vfio/trace.h
  GEN     hw/acpi/trace.h
  GEN     hw/arm/trace.h
  GEN     hw/alpha/trace.h
  GEN     hw/hppa/trace.h
  GEN     hw/xen/trace.h
  GEN     hw/ide/trace.h
  GEN     ui/trace.h
  GEN     audio/trace.h
  GEN     net/trace.h
  GEN     target/arm/trace.h
  GEN     target/i386/trace.h
  GEN     target/mips/trace.h
  GEN     target/sparc/trace.h
  GEN     target/s390x/trace.h
  GEN     target/ppc/trace.h
  GEN     qom/trace.h
  GEN     linux-user/trace.h
  GEN     qapi/trace.h
  GEN     accel/tcg/trace.h
  GEN     accel/kvm/trace.h
  GEN     nbd/trace.h
  GEN     scsi/trace.h
  GEN     trace-root.c
  GEN     util/trace.c
  GEN     crypto/trace.c
  GEN     io/trace.c
  GEN     migration/trace.c
  GEN     block/trace.c
  GEN     chardev/trace.c
  GEN     hw/block/trace.c
  GEN     hw/block/dataplane/trace.c
  GEN     hw/char/trace.c
  GEN     hw/intc/trace.c
  GEN     hw/net/trace.c
  GEN     hw/rdma/trace.c
  GEN     hw/rdma/vmw/trace.c
  GEN     hw/virtio/trace.c
  GEN     hw/audio/trace.c
  GEN     hw/misc/trace.c
  GEN     hw/misc/macio/trace.c
  GEN     hw/usb/trace.c
  GEN     hw/scsi/trace.c
  GEN     hw/nvram/trace.c
  GEN     hw/display/trace.c
  GEN     hw/input/trace.c
  GEN     hw/timer/trace.c
  GEN     hw/dma/trace.c
  GEN     hw/sparc/trace.c
  GEN     hw/sparc64/trace.c
  GEN     hw/sd/trace.c
  GEN     hw/isa/trace.c
  GEN     hw/mem/trace.c
  GEN     hw/i386/trace.c
  GEN     hw/i386/xen/trace.c
  GEN     hw/9pfs/trace.c
  GEN     hw/ppc/trace.c
  GEN     hw/pci/trace.c
  GEN     hw/pci-host/trace.c
  GEN     hw/s390x/trace.c
  GEN     hw/vfio/trace.c
  GEN     hw/acpi/trace.c
  GEN     hw/arm/trace.c
  GEN     hw/alpha/trace.c
  GEN     hw/hppa/trace.c
  GEN     hw/xen/trace.c
  GEN     hw/ide/trace.c
  GEN     ui/trace.c
  GEN     audio/trace.c
  GEN     net/trace.c
  GEN     target/arm/trace.c
  GEN     target/i386/trace.c
  GEN     target/mips/trace.c
  GEN     target/sparc/trace.c
  GEN     target/s390x/trace.c
  GEN     target/ppc/trace.c
  GEN     qom/trace.c
  GEN     linux-user/trace.c
  GEN     qapi/trace.c
  GEN     accel/tcg/trace.c
  GEN     accel/kvm/trace.c
  GEN     nbd/trace.c
  GEN     scsi/trace.c
  GEN     config-all-devices.mak
mkdir -p dtc/libfdt
mkdir -p dtc/tests
  GEN     ui/input-keymap-atset1-to-qcode.c
  GEN     ui/input-keymap-linux-to-qcode.c
  GEN     ui/input-keymap-qcode-to-atset1.c
  GEN     ui/input-keymap-qcode-to-atset2.c
  GEN     ui/input-keymap-qcode-to-atset3.c
  GEN     ui/input-keymap-qcode-to-linux.c
  GEN     ui/input-keymap-qcode-to-qnum.c
  GEN     ui/input-keymap-qcode-to-sun.c
  GEN     ui/input-keymap-qnum-to-qcode.c
  GEN     ui/input-keymap-win32-to-qcode.c
  GEN     ui/input-keymap-usb-to-qcode.c
  GEN     ui/input-keymap-x11-to-qcode.c
  GEN     ui/input-keymap-xorgevdev-to-qcode.c
  GEN     ui/input-keymap-xorgkbd-to-qcode.c
  GEN     ui/input-keymap-xorgxquartz-to-qcode.c
  GEN     ui/input-keymap-xorgxwin-to-qcode.c
  CC      cs.o
  CC      utils.o
  CC      SStream.o
  CC      MCRegisterInfo.o
  CC      arch/ARM/ARMMapping.o
  CC      arch/AArch64/AArch64BaseInfo.o
  CC      arch/ARM/ARMModule.o
  CC      arch/ARM/ARMInstPrinter.o
  CC      arch/ARM/ARMDisassembler.o
  CC      MCInstrDesc.o
  CC      arch/AArch64/AArch64Disassembler.o
  CC      arch/AArch64/AArch64InstPrinter.o
  CC      arch/AArch64/AArch64Mapping.o
  CC      arch/Mips/MipsInstPrinter.o
  CC      arch/Mips/MipsDisassembler.o
  CC      arch/AArch64/AArch64Module.o
  CC      arch/Mips/MipsMapping.o
  CC      arch/Mips/MipsModule.o
  CC      arch/PowerPC/PPCDisassembler.o
  CC      arch/PowerPC/PPCMapping.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/trees.S
  CC      arch/PowerPC/PPCInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/dumptrees.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/value-labels.c
  CC      arch/PowerPC/PPCModule.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/testutils.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/asm_tree_dump.c
  CC      arch/Sparc/SparcInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/check_path.c
  CC      arch/Sparc/SparcMapping.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/overlay.c
  CC      arch/Sparc/SparcModule.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/truncated_property.c
  CC      arch/Sparc/SparcDisassembler.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/overlay_bad_fixup.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/integer-expressions.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/path_offset_aliases.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/subnode_iterate.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/add_subnode_with_nops.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/dtbs_equal_unordered.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/utilfdt_test.c
  CC      arch/SystemZ/SystemZDisassembler.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/property_iterate.c
  CC      arch/SystemZ/SystemZMapping.o
  CC      arch/SystemZ/SystemZInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/dtb_reverse.c
  CC      arch/SystemZ/SystemZModule.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/dtbs_equal_ordered.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/extra-terminating-null.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/incbin.c
  CC      arch/X86/X86DisassemblerDecoder.o
  CC      arch/SystemZ/SystemZMCTargetDesc.o
  CC      arch/X86/X86Disassembler.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/boot-cpuid.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/phandle_format.c
  CC      arch/X86/X86IntelInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/references.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/path-references.c
  CC      arch/X86/X86ATTInstPrinter.o
  CC      arch/X86/X86Mapping.o
  CC      arch/XCore/XCoreDisassembler.o
  CC      arch/XCore/XCoreInstPrinter.o
  CC      arch/XCore/XCoreMapping.o
  CC      arch/X86/X86Module.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/string_escapes.c
  CC      arch/XCore/XCoreModule.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/propname_escapes.c
  CC      MCInst.o
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/appendprop2.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/appendprop1.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/del_property.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/setprop.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/del_node.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/set_name.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/rw_tree1.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/open_pack.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/nopulate.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/mangle-layout.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/move_and_save.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/sw_tree1.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/nop_node.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/nop_property.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/setprop_inplace.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/stringlist.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/addr_size_cells.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/notfound.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/sized_cells.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/char_literal.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/get_alias.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/node_offset_by_compatible.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/node_check_compatible.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/node_offset_by_phandle.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/node_offset_by_prop_value.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/parent_offset.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/supernode_atdepth_offset.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/get_path.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/get_phandle.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/getprop.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/get_name.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/path_offset.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/subnode_offset.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/find_property.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/root_node.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/tests/get_mem_rsv.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_overlay.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_addresses.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_empty_tree.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_strerror.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_rw.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_sw.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_wip.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt_ro.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/libfdt/fdt.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/fdtoverlay.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/util.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/fdtput.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/fdtget.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/fdtdump.c
	 LEX convert-dtsv0-lexer.lex.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/srcpos.c
	 BISON dtc-parser.tab.c
	 LEX dtc-lexer.lex.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/treesource.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/livetree.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/fstree.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/flattree.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/data.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/checks.c
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/dtc.c
	 DEP convert-dtsv0-lexer.lex.c
	 DEP dtc-parser.tab.c
	 DEP dtc-lexer.lex.c
	CHK version_gen.h
	UPD version_gen.h
	 DEP /var/tmp/patchew-tester-tmp-84g4a1ey/src/dtc/util.c
	 CC libfdt/fdt.o
	 CC libfdt/fdt_ro.o
	 CC libfdt/fdt_wip.o
	 CC libfdt/fdt_sw.o
	 CC libfdt/fdt_rw.o
	 CC libfdt/fdt_strerror.o
	 CC libfdt/fdt_empty_tree.o
	 CC libfdt/fdt_addresses.o
	 CC libfdt/fdt_overlay.o
	 AR libfdt/libfdt.a
ar: creating libfdt/libfdt.a
a - libfdt/fdt.o
a - libfdt/fdt_ro.o
a - libfdt/fdt_wip.o
a - libfdt/fdt_sw.o
a - libfdt/fdt_rw.o
a - libfdt/fdt_strerror.o
a - libfdt/fdt_empty_tree.o
a - libfdt/fdt_addresses.o
a - libfdt/fdt_overlay.o
  AR      libcapstone.a
ar: creating /var/tmp/patchew-tester-tmp-84g4a1ey/src/build/capstone/libcapstone.a
mkdir -p dtc/libfdt
mkdir -p dtc/tests
  CC      tests/qemu-iotests/socket_scm_helper.o
  GEN     qga/qapi-generated/qga-qapi-types.h
  GEN     qga/qapi-generated/qga-qapi-visit.h
  GEN     qga/qapi-generated/qga-qmp-commands.h
  GEN     qga/qapi-generated/qga-qapi-types.c
  GEN     qga/qapi-generated/qga-qapi-visit.c
  GEN     qga/qapi-generated/qga-qmp-marshal.c
  CC      qmp-introspect.o
  CC      qapi-types.o
  CC      qapi-event.o
  CC      qapi-visit.o
  CC      qapi/qapi-visit-core.o
  CC      qapi/qobject-output-visitor.o
  CC      qapi/qobject-input-visitor.o
  CC      qapi/qmp-registry.o
  CC      qapi/string-input-visitor.o
  CC      qapi/opts-visitor.o
  CC      qapi/qapi-clone-visitor.o
  CC      qapi/qmp-dispatch.o
  CC      qapi/qapi-dealloc-visitor.o
  CC      qapi/qapi-util.o
  CC      qobject/qnull.o
  CC      qapi/qmp-event.o
  CC      qapi/string-output-visitor.o
  CC      qobject/qnum.o
  CC      qobject/qdict.o
  CC      qobject/qstring.o
  CC      qobject/qlist.o
  CC      qobject/qlit.o
  CC      qobject/qbool.o
  CC      qobject/qjson.o
  CC      qobject/qobject.o
  CC      qobject/json-lexer.o
  CC      qobject/json-streamer.o
  CC      qobject/json-parser.o
  CC      trace/control.o
  CC      trace/qmp.o
  CC      util/osdep.o
  CC      util/cutils.o
  CC      util/unicode.o
  CC      util/qemu-timer-common.o
  CC      util/bufferiszero.o
  CC      util/lockcnt.o
  CC      util/aiocb.o
  CC      util/thread-pool.o
  CC      util/async.o
  CC      util/qemu-timer.o
  CC      util/main-loop.o
  CC      util/compatfd.o
  CC      util/event_notifier-posix.o
  CC      util/iohandler.o
  CC      util/qemu-thread-posix.o
  CC      util/oslib-posix.o
  CC      util/qemu-openpty.o
  CC      util/envlist.o
  CC      util/aio-posix.o
  CC      util/path.o
  CC      util/module.o
  CC      util/mmap-alloc.o
  CC      util/bitops.o
  CC      util/bitmap.o
  CC      util/fifo8.o
  CC      util/acl.o
  CC      util/error.o
  CC      util/id.o
  CC      util/host-utils.o
  CC      util/iov.o
  CC      util/uri.o
  CC      util/qemu-sockets.o
  CC      util/notify.o
  CC      util/memfd.o
  CC      util/hbitmap.o
  CC      util/qemu-error.o
  CC      util/qemu-config.o
  CC      util/cacheinfo.o
  CC      util/hexdump.o
  CC      util/qemu-progress.o
  CC      util/keyval.o
  CC      util/qemu-option.o
  CC      util/crc32c.o
  CC      util/throttle.o
  CC      util/uuid.o
  CC      util/getauxval.o
  CC      util/readline.o
  CC      util/qemu-coroutine.o
  CC      util/rcu.o
  CC      util/qemu-coroutine-lock.o
  CC      util/qemu-coroutine-io.o
  CC      util/qemu-coroutine-sleep.o
  CC      util/coroutine-ucontext.o
  CC      util/timed-average.o
  CC      util/base64.o
  CC      util/buffer.o
  CC      util/log.o
  CC      util/pagesize.o
  CC      util/qdist.o
  CC      util/qht.o
  CC      util/range.o
  CC      util/stats64.o
  CC      util/systemd.o
  CC      util/vfio-helpers.o
  CC      trace-root.o
  CC      util/trace.o
  CC      crypto/trace.o
  CC      io/trace.o
  CC      migration/trace.o
  CC      block/trace.o
  CC      chardev/trace.o
  CC      hw/block/trace.o
  CC      hw/block/dataplane/trace.o
  CC      hw/char/trace.o
  CC      hw/intc/trace.o
  CC      hw/net/trace.o
  CC      hw/rdma/trace.o
  CC      hw/virtio/trace.o
  CC      hw/rdma/vmw/trace.o
  CC      hw/audio/trace.o
  CC      hw/misc/trace.o
  CC      hw/misc/macio/trace.o
  CC      hw/usb/trace.o
  CC      hw/scsi/trace.o
  CC      hw/nvram/trace.o
  CC      hw/display/trace.o
  CC      hw/input/trace.o
  CC      hw/timer/trace.o
  CC      hw/dma/trace.o
  CC      hw/sparc/trace.o
  CC      hw/sparc64/trace.o
  CC      hw/sd/trace.o
  CC      hw/isa/trace.o
  CC      hw/i386/trace.o
  CC      hw/mem/trace.o
  CC      hw/i386/xen/trace.o
  CC      hw/9pfs/trace.o
  CC      hw/ppc/trace.o
  CC      hw/pci/trace.o
  CC      hw/pci-host/trace.o
  CC      hw/s390x/trace.o
  CC      hw/vfio/trace.o
  CC      hw/acpi/trace.o
  CC      hw/arm/trace.o
  CC      hw/alpha/trace.o
  CC      hw/hppa/trace.o
  CC      hw/xen/trace.o
  CC      hw/ide/trace.o
  CC      ui/trace.o
  CC      audio/trace.o
  CC      net/trace.o
  CC      target/arm/trace.o
  CC      target/i386/trace.o
  CC      target/mips/trace.o
  CC      target/sparc/trace.o
  CC      target/s390x/trace.o
  CC      qom/trace.o
  CC      qapi/trace.o
  CC      accel/tcg/trace.o
  CC      target/ppc/trace.o
  CC      linux-user/trace.o
  CC      accel/kvm/trace.o
  CC      nbd/trace.o
  CC      scsi/trace.o
  CC      crypto/pbkdf-stub.o
  CC      stubs/arch-query-cpu-def.o
  CC      stubs/arch-query-cpu-model-expansion.o
  CC      stubs/arch-query-cpu-model-comparison.o
  CC      stubs/arch-query-cpu-model-baseline.o
  CC      stubs/bdrv-next-monitor-owned.o
  CC      stubs/blk-commit-all.o
  CC      stubs/blockdev-close-all-bdrv-states.o
  CC      stubs/clock-warp.o
  CC      stubs/cpu-get-clock.o
  CC      stubs/cpu-get-icount.o
  CC      stubs/dump.o
  CC      stubs/error-printf.o
  CC      stubs/fdset.o
  CC      stubs/get-vm-name.o
  CC      stubs/gdbstub.o
  CC      stubs/iothread.o
  CC      stubs/iothread-lock.o
  CC      stubs/is-daemonized.o
  CC      stubs/linux-aio.o
  CC      stubs/machine-init-done.o
  CC      stubs/migr-blocker.o
  CC      stubs/change-state-handler.o
  CC      stubs/monitor.o
  CC      stubs/notify-event.o
  CC      stubs/qtest.o
  CC      stubs/replay.o
  CC      stubs/runstate-check.o
  CC      stubs/set-fd-handler.o
  CC      stubs/slirp.o
  CC      stubs/sysbus.o
  CC      stubs/tpm.o
  CC      stubs/trace-control.o
  CC      stubs/uuid.o
  CC      stubs/vm-stop.o
  CC      stubs/vmstate.o
  CC      stubs/qmp_pc_dimm.o
  CC      stubs/target-monitor-defs.o
  CC      stubs/target-get-monitor-def.o
  CC      stubs/pc_madt_cpu_entry.o
  CC      stubs/vmgenid.o
  CC      stubs/xen-common.o
  CC      stubs/xen-hvm.o
  CC      stubs/pci-host-piix.o
  CC      stubs/ram-block.o
  CC      contrib/ivshmem-client/ivshmem-client.o
  CC      contrib/ivshmem-client/main.o
  CC      contrib/ivshmem-server/ivshmem-server.o
  CC      contrib/ivshmem-server/main.o
  CC      qemu-nbd.o
  CC      block.o
  CC      blockjob.o
  CC      qemu-io-cmds.o
  CC      replication.o
  CC      block/raw-format.o
  CC      block/qcow.o
  CC      block/vdi.o
  CC      block/vmdk.o
  CC      block/cloop.o
  CC      block/bochs.o
  CC      block/vpc.o
  CC      block/vvfat.o
  CC      block/dmg.o
  CC      block/qcow2.o
  CC      block/qcow2-refcount.o
  CC      block/qcow2-cluster.o
  CC      block/qcow2-snapshot.o
  CC      block/qcow2-cache.o
  CC      block/qcow2-bitmap.o
  CC      block/qed.o
  CC      block/qed-l2-cache.o
  CC      block/qed-table.o
  CC      block/qed-cluster.o
  CC      block/vhdx.o
  CC      block/vhdx-endian.o
  CC      block/qed-check.o
  CC      block/vhdx-log.o
  CC      block/parallels.o
  CC      block/quorum.o
  CC      block/blkverify.o
  CC      block/blkdebug.o
  CC      block/block-backend.o
  CC      block/blkreplay.o
  CC      block/snapshot.o
  CC      block/file-posix.o
  CC      block/qapi.o
  CC      block/linux-aio.o
  CC      block/null.o
  CC      block/mirror.o
  CC      block/commit.o
  CC      block/io.o
  CC      block/throttle-groups.o
  CC      block/nbd.o
  CC      block/nvme.o
  CC      block/nbd-client.o
  CC      block/sheepdog.o
  CC      block/accounting.o
  CC      block/dirty-bitmap.o
  CC      block/backup.o
  CC      block/write-threshold.o
  CC      block/replication.o
  CC      block/crypto.o
  CC      block/throttle.o
  CC      nbd/server.o
  CC      nbd/common.o
  CC      nbd/client.o
  CC      scsi/utils.o
  CC      scsi/pr-manager.o
  CC      scsi/pr-manager-helper.o
  CC      block/curl.o
  CC      block/dmg-bz2.o
  CC      crypto/init.o
  CC      crypto/hash.o
  CC      crypto/hash-nettle.o
  CC      crypto/hmac.o
  CC      crypto/hmac-nettle.o
  CC      crypto/aes.o
  CC      crypto/cipher.o
  CC      crypto/tlscreds.o
  CC      crypto/desrfb.o
  CC      crypto/tlscredsanon.o
  CC      crypto/tlscredsx509.o
  CC      crypto/tlssession.o
  CC      crypto/secret.o
  CC      crypto/random-gnutls.o
  CC      crypto/pbkdf.o
  CC      crypto/pbkdf-nettle.o
  CC      crypto/ivgen.o
  CC      crypto/ivgen-essiv.o
  CC      crypto/ivgen-plain.o
  CC      crypto/ivgen-plain64.o
  CC      crypto/afsplit.o
  CC      crypto/xts.o
  CC      crypto/block.o
  CC      crypto/block-qcow.o
  CC      crypto/block-luks.o
  CC      io/channel.o
  CC      io/channel-buffer.o
  CC      io/channel-command.o
  CC      io/channel-file.o
  CC      io/channel-socket.o
  CC      io/channel-tls.o
  CC      io/channel-watch.o
/var/tmp/patchew-tester-tmp-84g4a1ey/src/blockjob.c: In function ‘block_job_txn_apply.isra.8’:
/var/tmp/patchew-tester-tmp-84g4a1ey/src/blockjob.c:511:5: error: ‘rc’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
     return rc;
     ^
  CC      io/channel-websock.o
  CC      io/channel-util.o
  CC      io/dns-resolver.o
  CC      io/net-listener.o
  CC      io/task.o
cc1: all warnings being treated as errors
make: *** [blockjob.o] Error 1
make: *** Waiting for unfinished jobs....
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (21 preceding siblings ...)
  2018-02-24  0:30 ` [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management no-reply
@ 2018-02-24 14:31 ` no-reply
  2018-02-27 21:01   ` John Snow
  2018-02-25 23:25 ` no-reply
  23 siblings, 1 reply; 98+ messages in thread
From: no-reply @ 2018-02-24 14:31 UTC (permalink / raw)
  To: jsnow; +Cc: famz, qemu-block, kwolf, pkrempa, jtc, qemu-devel

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20180223235142.21501-1-jsnow@redhat.com
Subject: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
230e578fa2 blockjobs: add manual_mgmt option to transactions
f278a5155a iotests: test manual job dismissal
8e473ab4a8 blockjobs: Expose manual property
7ad2d0164f blockjobs: add block-job-finalize
3857c91315 blockjobs: add PENDING status and event
18eb8a4130 blockjobs: add waiting status
daf9613432 blockjobs: add prepare callback
78be501212 blockjobs: add block_job_txn_apply function
4b659abe69 blockjobs: add commit, abort, clean helpers
4023046d76 blockjobs: ensure abort is called for cancelled jobs
e9300b122e blockjobs: add block_job_dismiss
4fc045eae4 blockjobs: add NULL state
e6aa454753 blockjobs: add CONCLUDED state
78efa2f937 blockjobs: add ABORTING state
057ad2472f blockjobs: add block_job_verb permission table
c62c5b75a3 iotests: add pause_wait
4aadb9c38c blockjobs: add state transition table
afc594c4b0 blockjobs: add status enum
434d3811fa blockjobs: add manual property
fc3e3eebc9 blockjobs: model single jobs as transactions
8d32662676 blockjobs: fix set-speed kick

=== OUTPUT BEGIN ===
Checking PATCH 1/21: blockjobs: fix set-speed kick...
Checking PATCH 2/21: blockjobs: model single jobs as transactions...
Checking PATCH 3/21: blockjobs: add manual property...
Checking PATCH 4/21: blockjobs: add status enum...
Checking PATCH 5/21: blockjobs: add state transition table...
ERROR: space prohibited before open square bracket '['
#81: FILE: blockjob.c:48:
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#82: FILE: blockjob.c:49:
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#83: FILE: blockjob.c:50:
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},

ERROR: space prohibited before open square bracket '['
#84: FILE: blockjob.c:51:
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#85: FILE: blockjob.c:52:
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#86: FILE: blockjob.c:53:
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},

total: 6 errors, 0 warnings, 90 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 6/21: iotests: add pause_wait...
Checking PATCH 7/21: blockjobs: add block_job_verb permission table...
Checking PATCH 8/21: blockjobs: add ABORTING state...
ERROR: space prohibited before open square bracket '['
#61: FILE: blockjob.c:48:
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#62: FILE: blockjob.c:49:
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#63: FILE: blockjob.c:50:
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1},

ERROR: space prohibited before open square bracket '['
#64: FILE: blockjob.c:51:
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#65: FILE: blockjob.c:52:
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1},

ERROR: space prohibited before open square bracket '['
#66: FILE: blockjob.c:53:
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0},

ERROR: space prohibited before open square bracket '['
#67: FILE: blockjob.c:54:
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0},

total: 7 errors, 0 warnings, 62 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 9/21: blockjobs: add CONCLUDED state...
ERROR: space prohibited before open square bracket '['
#63: FILE: blockjob.c:48:
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#64: FILE: blockjob.c:49:
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#65: FILE: blockjob.c:50:
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1},

ERROR: space prohibited before open square bracket '['
#66: FILE: blockjob.c:51:
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#67: FILE: blockjob.c:52:
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1},

ERROR: space prohibited before open square bracket '['
#68: FILE: blockjob.c:53:
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#69: FILE: blockjob.c:54:
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#70: FILE: blockjob.c:55:
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0},

total: 8 errors, 0 warnings, 91 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 10/21: blockjobs: add NULL state...
ERROR: space prohibited before open square bracket '['
#65: FILE: blockjob.c:48:
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#66: FILE: blockjob.c:49:
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#67: FILE: blockjob.c:50:
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0},

ERROR: space prohibited before open square bracket '['
#68: FILE: blockjob.c:51:
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#69: FILE: blockjob.c:52:
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0},

ERROR: space prohibited before open square bracket '['
#70: FILE: blockjob.c:53:
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#71: FILE: blockjob.c:54:
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1, 0},

ERROR: space prohibited before open square bracket '['
#72: FILE: blockjob.c:55:
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#73: FILE: blockjob.c:56:
+    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0},

total: 9 errors, 0 warnings, 71 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 11/21: blockjobs: add block_job_dismiss...
Checking PATCH 12/21: blockjobs: ensure abort is called for cancelled jobs...
Checking PATCH 13/21: blockjobs: add commit, abort, clean helpers...
Checking PATCH 14/21: blockjobs: add block_job_txn_apply function...
Checking PATCH 15/21: blockjobs: add prepare callback...
Checking PATCH 16/21: blockjobs: add waiting status...
ERROR: space prohibited before open square bracket '['
#80: FILE: blockjob.c:48:
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#81: FILE: blockjob.c:49:
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#82: FILE: blockjob.c:50:
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0, 0},

ERROR: space prohibited before open square bracket '['
#83: FILE: blockjob.c:51:
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#84: FILE: blockjob.c:52:
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0, 0},

ERROR: space prohibited before open square bracket '['
#85: FILE: blockjob.c:53:
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#86: FILE: blockjob.c:54:
+    /* W: */ [BLOCK_JOB_STATUS_WAITING]   = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},

ERROR: space prohibited before open square bracket '['
#87: FILE: blockjob.c:55:
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},

ERROR: space prohibited before open square bracket '['
#88: FILE: blockjob.c:56:
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#89: FILE: blockjob.c:57:
+    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

total: 10 errors, 0 warnings, 99 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 17/21: blockjobs: add PENDING status and event...
ERROR: space prohibited before open square bracket '['
#84: FILE: blockjob.c:48:
+    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#85: FILE: blockjob.c:49:
+    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#86: FILE: blockjob.c:50:
+    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0},

ERROR: space prohibited before open square bracket '['
#87: FILE: blockjob.c:51:
+    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#88: FILE: blockjob.c:52:
+    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0},

ERROR: space prohibited before open square bracket '['
#89: FILE: blockjob.c:53:
+    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},

ERROR: space prohibited before open square bracket '['
#90: FILE: blockjob.c:54:
+    /* W: */ [BLOCK_JOB_STATUS_WAITING]   = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},

ERROR: space prohibited before open square bracket '['
#91: FILE: blockjob.c:55:
+    /* D: */ [BLOCK_JOB_STATUS_PENDING]   = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},

ERROR: space prohibited before open square bracket '['
#92: FILE: blockjob.c:56:
+    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},

ERROR: space prohibited before open square bracket '['
#93: FILE: blockjob.c:57:
+    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},

ERROR: space prohibited before open square bracket '['
#94: FILE: blockjob.c:58:
+    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

total: 11 errors, 0 warnings, 161 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 18/21: blockjobs: add block-job-finalize...
Checking PATCH 19/21: blockjobs: Expose manual property...
Checking PATCH 20/21: iotests: test manual job dismissal...
Checking PATCH 21/21: blockjobs: add manual_mgmt option to transactions...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
  2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
                   ` (22 preceding siblings ...)
  2018-02-24 14:31 ` no-reply
@ 2018-02-25 23:25 ` no-reply
  2018-02-27 20:58   ` John Snow
  23 siblings, 1 reply; 98+ messages in thread
From: no-reply @ 2018-02-25 23:25 UTC (permalink / raw)
  To: jsnow; +Cc: famz, qemu-block, kwolf, pkrempa, jtc, qemu-devel

Hi,

This series failed build test on ppcle host. Please find the details below.

Message-id: 20180223235142.21501-1-jsnow@redhat.com
Subject: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
# Testing script will be invoked under the git checkout with
# HEAD pointing to a commit that has the patches applied on top of "base"
# branch
set -e
echo "=== ENV ==="
env
echo "=== PACKAGES ==="
rpm -qa
echo "=== TEST BEGIN ==="
INSTALL=$PWD/install
BUILD=$PWD/build
mkdir -p $BUILD $INSTALL
SRC=$PWD
cd $BUILD
$SRC/configure --prefix=$INSTALL
make -j100
# XXX: we need reliable clean up
# make check -j100 V=1
make install
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Submodule 'capstone' (git://git.qemu.org/capstone.git) registered for path 'capstone'
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (git://git.qemu.org/QemuMacDrivers.git) registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (git://git.qemu-project.org/SLOF.git) registered for path 'roms/SLOF'
Submodule 'roms/ipxe' (git://git.qemu-project.org/ipxe.git) registered for path 'roms/ipxe'
Submodule 'roms/openbios' (git://git.qemu-project.org/openbios.git) registered for path 'roms/openbios'
Submodule 'roms/openhackware' (git://git.qemu-project.org/openhackware.git) registered for path 'roms/openhackware'
Submodule 'roms/qemu-palcode' (git://github.com/rth7680/qemu-palcode.git) registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (git://git.qemu-project.org/seabios.git/) registered for path 'roms/seabios'
Submodule 'roms/seabios-hppa' (git://github.com/hdeller/seabios-hppa.git) registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (git://git.qemu-project.org/sgabios.git) registered for path 'roms/sgabios'
Submodule 'roms/skiboot' (git://git.qemu.org/skiboot.git) registered for path 'roms/skiboot'
Submodule 'roms/u-boot' (git://git.qemu-project.org/u-boot.git) registered for path 'roms/u-boot'
Submodule 'roms/vgabios' (git://git.qemu-project.org/vgabios.git/) registered for path 'roms/vgabios'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out '22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 'd4e7d7ac663fcb55f1b93575445fcbca372f17a7'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 'fa981320a1e0968d6fc1b8de319723ff8212b337'
Cloning into 'roms/ipxe'...
Submodule path 'roms/ipxe': checked out '0600d3ae94f93efd10fc6b3c7420a9557a3a1670'
Cloning into 'roms/openbios'...
Submodule path 'roms/openbios': checked out '54d959d97fb331708767b2fd4a878efd2bbc41bb'
Cloning into 'roms/openhackware'...
Submodule path 'roms/openhackware': checked out 'c559da7c8eec5e45ef1f67978827af6f0b9546f5'
Cloning into 'roms/qemu-palcode'...
Submodule path 'roms/qemu-palcode': checked out 'f3c7e44c70254975df2a00af39701eafbac4d471'
Cloning into 'roms/seabios'...
Submodule path 'roms/seabios': checked out '63451fca13c75870e1703eb3e20584d91179aebc'
Cloning into 'roms/seabios-hppa'...
Submodule path 'roms/seabios-hppa': checked out '649e6202b8d65d46c69f542b1380f840fbe8ab13'
Cloning into 'roms/sgabios'...
Submodule path 'roms/sgabios': checked out 'cbaee52287e5f32373181cff50a00b6c4ac9015a'
Cloning into 'roms/skiboot'...
Submodule path 'roms/skiboot': checked out 'e0ee24c27a172bcf482f6f2bc905e6211c134bcc'
Cloning into 'roms/u-boot'...
Submodule path 'roms/u-boot': checked out 'd85ca029f257b53a96da6c2fb421e78a003a9943'
Cloning into 'roms/vgabios'...
Submodule path 'roms/vgabios': checked out '19ea12c230ded95928ecaef0db47a82231c2e485'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out '6b3d716e2b6472eb7189d3220552280ef3d832ce'
Switched to a new branch 'test'
230e578 blockjobs: add manual_mgmt option to transactions
f278a51 iotests: test manual job dismissal
8e473ab blockjobs: Expose manual property
7ad2d01 blockjobs: add block-job-finalize
3857c91 blockjobs: add PENDING status and event
18eb8a4 blockjobs: add waiting status
daf9613 blockjobs: add prepare callback
78be501 blockjobs: add block_job_txn_apply function
4b659ab blockjobs: add commit, abort, clean helpers
4023046 blockjobs: ensure abort is called for cancelled jobs
e9300b1 blockjobs: add block_job_dismiss
4fc045e blockjobs: add NULL state
e6aa454 blockjobs: add CONCLUDED state
78efa2f blockjobs: add ABORTING state
057ad24 blockjobs: add block_job_verb permission table
c62c5b7 iotests: add pause_wait
4aadb9c blockjobs: add state transition table
afc594c blockjobs: add status enum
434d381 blockjobs: add manual property
fc3e3ee blockjobs: model single jobs as transactions
8d32662 blockjobs: fix set-speed kick

=== OUTPUT BEGIN ===
=== ENV ===
XDG_SESSION_ID=209502
SHELL=/bin/sh
USER=patchew
PATCHEW=/home/patchew/patchew/patchew-cli -s http://patchew.org --nodebug
PATH=/usr/bin:/bin
PWD=/var/tmp/patchew-tester-tmp-9ukz0kme/src
LANG=en_US.UTF-8
HOME=/home/patchew
SHLVL=2
LOGNAME=patchew
XDG_RUNTIME_DIR=/run/user/1000
_=/usr/bin/env
=== PACKAGES ===
plymouth-core-libs-0.8.9-0.28.20140113.el7.centos.ppc64le
vim-common-7.4.160-2.el7.ppc64le
perl-Test-Simple-0.98-243.el7.noarch
hplip-common-3.15.9-3.el7.ppc64le
valgrind-3.12.0-8.el7.ppc64le
gamin-0.1.10-16.el7.ppc64le
libpeas-loader-python-1.20.0-1.el7.ppc64le
telepathy-filesystem-0.0.2-6.el7.noarch
colord-libs-1.3.4-1.el7.ppc64le
kbd-legacy-1.15.5-13.el7.noarch
perl-CPAN-Meta-YAML-0.008-14.el7.noarch
libvirt-daemon-driver-nwfilter-3.2.0-14.el7.ppc64le
ntsysv-1.7.4-1.el7.ppc64le
kernel-bootwrapper-3.10.0-693.el7.ppc64le
telepathy-farstream-0.6.0-5.el7.ppc64le
kdenetwork-common-4.10.5-8.el7_0.noarch
elfutils-devel-0.168-8.el7.ppc64le
pm-utils-1.4.1-27.el7.ppc64le
perl-Error-0.17020-2.el7.noarch
usbmuxd-1.1.0-1.el7.ppc64le
bzip2-devel-1.0.6-13.el7.ppc64le
blktrace-1.0.5-8.el7.ppc64le
gnome-keyring-pam-3.20.0-3.el7.ppc64le
tzdata-java-2017b-1.el7.noarch
perl-devel-5.16.3-292.el7.ppc64le
gnome-getting-started-docs-3.22.0-1.el7.noarch
perl-Log-Message-Simple-0.10-2.el7.noarch
totem-pl-parser-3.10.7-1.el7.ppc64le
lohit-oriya-fonts-2.5.4.1-3.el7.noarch
python-coverage-3.6-0.5.b3.el7.ppc64le
java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.ppc64le
mailcap-2.1.41-2.el7.noarch
perl-CPANPLUS-0.91.38-4.el7.noarch
fprintd-pam-0.5.0-4.0.el7_0.ppc64le
less-458-9.el7.ppc64le
gupnp-igd-0.2.4-1.el7.ppc64le
thai-scalable-waree-fonts-0.5.0-7.el7.noarch
python-di-0.3-2.el7.noarch
yelp-libs-3.22.0-1.el7.ppc64le
vte-profile-0.46.2-1.el7.ppc64le
gpm-libs-1.20.7-5.el7.ppc64le
gnome-clocks-3.22.1-1.el7.ppc64le
p11-kit-trust-0.23.5-3.el7.ppc64le
gssproxy-0.7.0-4.el7.ppc64le
gnu-free-mono-fonts-20120503-8.el7.noarch
python-dateutil-1.5-7.el7.noarch
gucharmap-libs-3.18.2-1.el7.ppc64le
glibc-common-2.17-196.el7.ppc64le
libreport-plugin-mantisbt-2.1.11-38.el7.centos.ppc64le
motif-devel-2.3.4-8.1.el7_3.ppc64le
celt051-0.5.1.3-8.el7.ppc64le
radvd-1.9.2-9.el7.ppc64le
lohit-tamil-fonts-2.5.3-2.el7.noarch
python-ipaddress-1.0.16-2.el7.noarch
anaconda-widgets-21.48.22.121-1.el7.centos.ppc64le
zlib-1.2.7-17.el7.ppc64le
system-config-printer-1.4.1-19.el7.ppc64le
mozjs24-24.2.0-7.el7.ppc64le
device-mapper-multipath-libs-0.4.9-111.el7.ppc64le
wqy-microhei-fonts-0.2.0-0.12.beta.el7.noarch
python-schedutils-0.4-6.el7.ppc64le
gnome-bluetooth-3.20.1-1.el7.ppc64le
nss-util-3.28.4-3.el7.ppc64le
dotconf-1.3-8.el7.ppc64le
ibus-rawcode-1.3.2-3.el7.ppc64le
abattis-cantarell-fonts-0.0.25-1.el7.noarch
sssd-common-1.15.2-50.el7.ppc64le
sil-padauk-fonts-2.8-5.el7.noarch
bind-utils-9.9.4-50.el7.ppc64le
sox-14.4.1-6.el7.ppc64le
libSM-1.2.2-2.el7.ppc64le
libtiff-devel-4.0.3-27.el7_3.ppc64le
plymouth-system-theme-0.8.9-0.28.20140113.el7.centos.ppc64le
python-libs-2.7.5-58.el7.ppc64le
sssd-1.15.2-50.el7.ppc64le
rfkill-0.4-9.el7.ppc64le
cyrus-sasl-md5-2.1.26-21.el7.ppc64le
libXtst-devel-1.2.3-1.el7.ppc64le
avahi-libs-0.6.31-17.el7.ppc64le
ruby-2.0.0.648-30.el7.ppc64le
seahorse-3.20.0-1.el7.ppc64le
python-six-1.9.0-2.el7.noarch
gpgme-1.3.2-5.el7.ppc64le
iwl7260-firmware-22.0.7.0-56.el7.noarch
libsss_certmap-1.15.2-50.el7.ppc64le
xorg-x11-drv-wacom-0.34.2-2.el7.ppc64le
libXau-1.0.8-2.1.el7.ppc64le
shadow-utils-4.1.5.1-24.el7.ppc64le
evolution-ews-3.22.6-6.el7.ppc64le
libsecret-0.18.5-2.el7.ppc64le
perl-Module-Signature-0.73-2.el7.noarch
rootfiles-8.1-11.el7.noarch
trace-cmd-2.6.0-8.el7.ppc64le
hamcrest-1.3-6.el7.noarch
gawk-4.0.2-4.el7_3.1.ppc64le
usermode-1.111-5.el7.ppc64le
gnome-terminal-nautilus-3.22.1-2.el7.ppc64le
gvfs-client-1.30.4-3.el7.ppc64le
yum-utils-1.1.31-42.el7.noarch
iwl3945-firmware-15.32.2.9-56.el7.noarch
perl-Archive-Zip-1.30-11.el7.noarch
spice-glib-0.33-6.el7.ppc64le
augeas-libs-1.4.0-2.el7.ppc64le
openlmi-providers-0.5.0-4.el7.ppc64le
gnome-color-manager-3.22.2-1.el7.ppc64le
imsettings-libs-1.6.3-9.el7.ppc64le
nss-softokn-devel-3.28.3-6.el7.ppc64le
python34-3.4.5-4.el7.ppc64le
perl-DBI-1.627-4.el7.ppc64le
plymouth-plugin-label-0.8.9-0.28.20140113.el7.centos.ppc64le
binutils-2.25.1-31.base.el7.ppc64le
libsss_nss_idmap-1.15.2-50.el7.ppc64le
gvfs-smb-1.30.4-3.el7.ppc64le
freetype-devel-2.4.11-15.el7.ppc64le
libXi-1.7.9-1.el7.ppc64le
libitm-4.8.5-16.el7_4.1.ppc64le
perl-Text-Diff-1.41-5.el7.noarch
gcr-devel-3.20.0-1.el7.ppc64le
numactl-libs-2.0.9-6.el7_2.ppc64le
hardlink-1.0-19.el7.ppc64le
gnome-disk-utility-3.22.1-1.el7.ppc64le
mariadb-libs-5.5.56-2.el7.ppc64le
libnotify-0.7.7-1.el7.ppc64le
perl-TimeDate-2.30-2.el7.noarch
soprano-devel-2.9.2-3.el7.ppc64le
pixman-0.34.0-1.el7.ppc64le
kmod-20-15.el7.ppc64le
qt3-PostgreSQL-3.3.8b-51.el7.ppc64le
python2-pyasn1-0.1.9-7.el7.noarch
libXt-1.1.5-3.el7.ppc64le
perl-Font-AFM-1.20-13.el7.noarch
ibus-1.5.3-13.el7.ppc64le
findutils-4.5.11-5.el7.ppc64le
ibus-libs-1.5.3-13.el7.ppc64le
iprutils-2.4.14.1-1.el7.ppc64le
libpwquality-1.2.3-4.el7.ppc64le
libXrender-devel-0.9.10-1.el7.ppc64le
perl-IO-stringy-2.110-22.el7.noarch
kdelibs-4.14.8-6.el7_3.ppc64le
flac-libs-1.3.0-5.el7_1.ppc64le
device-mapper-event-libs-1.02.140-8.el7.ppc64le
gnutls-devel-3.3.26-9.el7.ppc64le
libXau-devel-1.0.8-2.1.el7.ppc64le
gstreamer1-plugins-base-1.10.4-1.el7.ppc64le
perl-HTML-Tree-5.03-2.el7.noarch
kdenetwork-kopete-4.10.5-8.el7_0.ppc64le
libepoxy-1.3.1-1.el7.ppc64le
mesa-libGLES-17.0.1-6.20170307.el7.ppc64le
qt-postgresql-4.8.5-13.el7.ppc64le
fontconfig-devel-2.10.95-11.el7.ppc64le
java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.ppc64le
libXfont-1.5.2-1.el7.ppc64le
libkexiv2-4.10.5-3.el7.ppc64le
openjpeg-libs-1.5.1-17.el7.ppc64le
iscsi-initiator-utils-6.2.0.874-4.el7.ppc64le
NetworkManager-adsl-1.8.0-9.el7.ppc64le
libgtop2-2.34.2-1.el7.ppc64le
libXdamage-devel-1.1.4-4.1.el7.ppc64le
ipset-libs-6.29-1.el7.ppc64le
kde-runtime-drkonqi-4.10.5-8.el7.ppc64le
e2fsprogs-libs-1.42.9-10.el7.ppc64le
dhclient-4.2.5-58.el7.centos.ppc64le
usbutils-007-5.el7.ppc64le
python-ethtool-0.8-5.el7.ppc64le
gstreamer1-plugins-bad-free-1.10.4-2.el7.ppc64le
fftw-libs-double-3.3.3-8.el7.ppc64le
kdenetwork-krdc-4.10.5-8.el7_0.ppc64le
fuse-libs-2.9.2-8.el7.ppc64le
pciutils-3.5.1-2.el7.ppc64le
at-3.1.13-22.el7.ppc64le
python-IPy-0.75-6.el7.noarch
libXp-1.0.2-2.1.el7.ppc64le
vim-minimal-7.4.160-2.el7.ppc64le
kdesdk-kmtrace-4.10.5-6.el7.ppc64le
libraw1394-2.1.0-2.el7.ppc64le
libdrm-devel-2.4.74-1.el7.ppc64le
irqbalance-1.0.7-10.el7.ppc64le
fipscheck-lib-1.4.1-6.el7.ppc64le
gvfs-1.30.4-3.el7.ppc64le
libiscsi-1.9.0-7.el7.ppc64le
motif-2.3.4-8.1.el7_3.ppc64le
keyutils-1.5.8-3.el7.ppc64le
NetworkManager-ppp-1.8.0-9.el7.ppc64le
systemtap-3.1-3.el7.ppc64le
boost-serialization-1.53.0-27.el7.ppc64le
grilo-0.3.3-1.el7.ppc64le
rpm-4.11.3-25.el7.ppc64le
kdegraphics-libs-4.10.5-3.el7.noarch
libfontenc-1.1.3-3.el7.ppc64le
perl-Git-1.8.3.1-11.el7.noarch
rubygem-abrt-0.3.0-1.el7.noarch
tcl-8.5.13-8.el7.ppc64le
gtksourceview3-3.22.2-1.el7.ppc64le
cmake-2.8.12.2-2.el7.ppc64le
pulseaudio-utils-10.0-3.el7.ppc64le
libusal-1.1.11-23.el7.ppc64le
grub2-ppc64le-2.02-0.64.el7.centos.ppc64le
libreport-plugin-mailx-2.1.11-38.el7.centos.ppc64le
libvisual-0.4.0-16.el7.ppc64le
metacity-2.34.13-7.el7.ppc64le
redland-virtuoso-1.0.16-6.el7.ppc64le
nautilus-3.22.3-3.el7.ppc64le
pciutils-libs-3.5.1-2.el7.ppc64le
soprano-2.9.2-3.el7.ppc64le
mariadb-devel-5.5.56-2.el7.ppc64le
libxkbcommon-x11-0.7.1-1.el7.ppc64le
farstream02-0.2.3-3.el7.ppc64le
redhat-rpm-config-9.1.0-76.el7.centos.noarch
skkdic-20130104-6.T1435.el7.noarch
perl-HTTP-Tiny-0.033-3.el7.noarch
lvm2-libs-2.02.171-8.el7.ppc64le
perl-XML-Grove-0.46alpha-52.el7.noarch
boost-devel-1.53.0-27.el7.ppc64le
pycairo-1.8.10-8.el7.ppc64le
popt-devel-1.13-16.el7.ppc64le
gnome-settings-daemon-3.22.2-5.el7.ppc64le
perl-Socket-2.010-4.el7.ppc64le
numad-0.5-17.20150602git.el7.ppc64le
e2fsprogs-devel-1.42.9-10.el7.ppc64le
libsecret-devel-0.18.5-2.el7.ppc64le
libXv-devel-1.0.11-1.el7.ppc64le
libchewing-0.3.4-6.el7.ppc64le
gnome-shell-extension-places-menu-3.22.2-10.el7.noarch
perl-Time-HiRes-1.9725-3.el7.ppc64le
openchange-2.3-2.el7.ppc64le
audit-libs-devel-2.7.6-3.el7.ppc64le
python-dmidecode-3.12.2-1.el7.ppc64le
libmediaart-1.9.1-1.el7.ppc64le
elfutils-default-yama-scope-0.168-8.el7.noarch
quota-4.01-14.el7.ppc64le
perl-threads-1.87-4.el7.ppc64le
realmd-0.16.1-9.el7.ppc64le
nautilus-sendto-3.8.4-1.el7.ppc64le
gstreamer-0.10.36-7.el7.ppc64le
cairo-gobject-devel-1.14.8-2.el7.ppc64le
abrt-libs-2.1.11-48.el7.centos.ppc64le
libvirt-daemon-driver-storage-iscsi-3.2.0-14.el7.ppc64le
perl-Pod-Parser-1.61-2.el7.noarch
python-devel-2.7.5-58.el7.ppc64le
mpfr-devel-3.1.1-4.el7.ppc64le
kernel-headers-3.10.0-693.el7.ppc64le
powerpc-utils-python-1.2.1-9.el7.noarch
linux-firmware-20170606-56.gitc990aae.el7.noarch
libqmi-1.16.0-1.el7.ppc64le
libvirt-libs-3.2.0-14.el7.ppc64le
perl-Digest-1.17-245.el7.noarch
libgcab1-0.7-3.el7.ppc64le
flex-2.5.37-3.el7.ppc64le
tzdata-2017b-1.el7.noarch
phonon-4.6.0-10.el7.ppc64le
anaconda-tui-21.48.22.121-1.el7.centos.ppc64le
libmbim-utils-1.14.0-2.el7.ppc64le
gnutls-utils-3.3.26-9.el7.ppc64le
perl-Parse-CPAN-Meta-1.4404-5.el7.noarch
flite-1.3-22.el7.ppc64le
nfs4-acl-tools-0.3.3-15.el7.ppc64le
poppler-data-0.4.6-3.el7.noarch
gvfs-fuse-1.30.4-3.el7.ppc64le
gnome-software-3.22.7-1.el7.ppc64le
perl-ExtUtils-ParseXS-3.18-3.el7.noarch
libvirt-python-3.2.0-3.el7.ppc64le
perl-Module-Load-Conditional-0.54-3.el7.noarch
python-netifaces-0.10.4-3.el7.ppc64le
swig-2.0.10-5.el7.ppc64le
ipa-client-common-4.5.0-20.el7.centos.noarch
cheese-libs-3.22.1-1.el7.ppc64le
gnome-tweak-tool-3.22.0-1.el7.noarch
perl-ExtUtils-CBuilder-0.28.2.6-292.el7.noarch
libsoup-devel-2.56.0-3.el7.ppc64le
perl-IO-Zlib-1.10-292.el7.noarch
fros-1.0-2.el7.noarch
lohit-devanagari-fonts-2.5.3-4.el7.noarch
grub2-ppc64le-modules-2.02-0.64.el7.centos.noarch
libgdata-0.17.8-1.el7.ppc64le
evince-nautilus-3.22.1-5.el7.ppc64le
perl-ExtUtils-Embed-1.30-292.el7.noarch
dleyna-connector-dbus-0.2.0-2.el7.ppc64le
libiec61883-1.2.0-10.el7.ppc64le
python-lxml-3.2.1-4.el7.ppc64le
liberation-serif-fonts-1.07.2-15.el7.noarch
tigervnc-license-1.8.0-1.el7.noarch
gnome-packagekit-3.22.1-2.el7.ppc64le
hpijs-3.15.9-3.el7.ppc64le
libmodman-2.0.1-8.el7.ppc64le
ntp-4.2.6p5-25.el7.centos.2.ppc64le
gmp-devel-6.0.0-15.el7.ppc64le
pyxattr-0.5.1-5.el7.ppc64le
sil-abyssinica-fonts-1.200-6.el7.noarch
ncurses-libs-5.9-13.20130511.el7.ppc64le
gnome-dictionary-libs-3.20.0-1.el7.ppc64le
kdesdk-devel-4.10.5-6.el7.ppc64le
libreport-rhel-anaconda-bugzilla-2.1.11-38.el7.centos.ppc64le
libvirt-daemon-config-network-3.2.0-14.el7.ppc64le
boost-iostreams-1.53.0-27.el7.ppc64le
python-ply-3.4-11.el7.noarch
ucs-miscfixed-fonts-0.3-11.el7.noarch
info-5.1-4.el7.ppc64le
libXxf86misc-devel-1.0.3-7.1.el7.ppc64le
ibus-qt-1.3.2-4.el7.ppc64le
gnome-video-effects-0.4.3-1.el7.noarch
bridge-utils-1.5-9.el7.ppc64le
make-3.82-23.el7.ppc64le
pywbem-0.7.0-25.20130827svn625.el7.noarch
pnm2ppa-1.04-28.el7.ppc64le
chkconfig-1.7.4-1.el7.ppc64le
at-spi2-atk-devel-2.22.0-2.el7.ppc64le
freeglut-devel-2.8.1-3.el7.ppc64le
jbigkit-libs-2.0-11.el7.ppc64le
sssd-ipa-1.15.2-50.el7.ppc64le
openssl-libs-1.0.2k-8.el7.ppc64le
ldns-1.6.16-10.el7.ppc64le
rdate-1.4-25.el7.ppc64le
libdb-5.3.21-20.el7.ppc64le
evince-libs-3.22.1-5.el7.ppc64le
empathy-3.12.12-4.el7.ppc64le
rubygem-json-1.7.7-30.el7.ppc64le
dmraid-1.0.0.rc16-28.el7.ppc64le
libblkid-2.23.2-43.el7.ppc64le
logrotate-3.8.6-14.el7.ppc64le
iwl105-firmware-18.168.6.1-56.el7.noarch
grep-2.20-3.el7.ppc64le
xorg-x11-drv-synaptics-1.9.0-1.el7.ppc64le
iowatcher-1.0-6.el7.ppc64le
rubygem-net-http-persistent-2.8-5.el7.noarch
setroubleshoot-plugins-3.0.65-1.el7.noarch
atk-2.22.0-3.el7.ppc64le
libcacard-2.5.2-2.el7.ppc64le
iwl6050-firmware-41.28.5.1-56.el7.noarch
lcms2-2.6-3.el7.ppc64le
tigervnc-server-minimal-1.8.0-1.el7.ppc64le
gvfs-goa-1.30.4-3.el7.ppc64le
authconfig-6.2.8-30.el7.ppc64le
yum-plugin-fastestmirror-1.1.31-42.el7.noarch
dbus-python-1.1.1-9.el7.ppc64le
perl-Archive-Tar-1.92-2.el7.noarch
iwl5000-firmware-8.83.5.1_1-56.el7.noarch
libacl-2.2.51-12.el7.ppc64le
farstream-0.1.2-8.el7.ppc64le
ppc64-utils-0.14-16.el7.ppc64le
servicelog-1.1.14-3.el7.ppc64le
python2-ipaclient-4.5.0-20.el7.centos.noarch
libpeas-1.20.0-1.el7.ppc64le
perl-TermReadKey-2.30-20.el7.ppc64le
hdparm-9.43-5.el7.ppc64le
libicu-50.1.2-15.el7.ppc64le
polkit-qt-0.103.0-10.el7_0.ppc64le
gnome-weather-3.20.2-1.el7.noarch
libmspack-0.5-0.5.alpha.el7.ppc64le
libkkc-data-0.3.1-9.el7.ppc64le
hicolor-icon-theme-0.12-7.el7.noarch
perl-Newt-1.08-36.el7.ppc64le
libstdc++-devel-4.8.5-16.el7_4.1.ppc64le
libexif-0.6.21-6.el7.ppc64le
gtk3-devel-3.22.10-4.el7.ppc64le
gvfs-mtp-1.30.4-3.el7.ppc64le
ncompress-4.2.4.4-3.el7.ppc64le
libXcomposite-0.4.4-4.1.el7.ppc64le
python-decorator-3.4.0-3.el7.noarch
perl-Business-ISBN-Data-20120719.001-2.el7.noarch
gcc-gfortran-4.8.5-16.el7_4.1.ppc64le
cpio-2.11-24.el7.ppc64le
mesa-libGLU-9.0.0-4.el7.ppc64le
baobab-3.22.1-1.el7.ppc64le
device-mapper-libs-1.02.140-8.el7.ppc64le
libXtst-1.2.3-1.el7.ppc64le
ModemManager-glib-1.6.0-2.el7.ppc64le
perl-HTML-Parser-3.71-4.el7.ppc64le
libical-1.0.1-1.el7.ppc64le
xorg-x11-xinit-1.3.4-1.el7.ppc64le
gstreamer1-plugins-base-devel-1.10.4-1.el7.ppc64le
libdrm-2.4.74-1.el7.ppc64le
libXfixes-devel-5.0.3-1.el7.ppc64le
python-gssapi-1.2.0-3.el7.ppc64le
perl-Text-Unidecode-0.04-20.el7.noarch
hunspell-1.3.2-15.el7.ppc64le
kde-settings-19-23.5.el7.centos.noarch
perl-App-cpanminus-1.6922-2.el7.noarch
parted-3.1-28.el7.ppc64le
mesa-libGL-17.0.1-6.20170307.el7.ppc64le
elfutils-libelf-devel-0.168-8.el7.ppc64le
perl-Net-LibIDN-0.12-15.el7.ppc64le
apr-1.4.8-3.el7.ppc64le
kdepimlibs-4.10.5-4.el7.ppc64le
virt-top-1.0.8-23.el7.ppc64le
samba-client-libs-4.6.2-8.el7.ppc64le
gstreamer-plugins-base-0.10.36-10.el7.ppc64le
json-glib-devel-1.2.6-1.el7.ppc64le
perl-autodie-2.16-2.el7.noarch
tar-1.26-32.el7.ppc64le
ksysguard-libs-4.11.19-8.el7.ppc64le
rdma-core-devel-13-7.el7.ppc64le
accountsservice-0.6.45-2.el7.ppc64le
libxklavier-5.4-7.el7.ppc64le
libxml2-devel-2.9.1-6.el7_2.3.ppc64le
ghostscript-fonts-5.50-32.el7.noarch
libassuan-2.1.0-3.el7.ppc64le
libkipi-devel-4.10.5-3.el7.ppc64le
python-smbc-1.0.13-7.el7.ppc64le
initscripts-9.49.39-1.el7.ppc64le
qt3-3.3.8b-51.el7.ppc64le
yum-metadata-parser-1.1.4-10.el7.ppc64le
device-mapper-persistent-data-0.7.0-0.1.rc6.el7.ppc64le
adwaita-icon-theme-3.22.0-1.el7.noarch
kdepim-4.10.5-6.el7.ppc64le
postfix-2.10.1-6.el7.ppc64le
abrt-addon-pstoreoops-2.1.11-48.el7.centos.ppc64le
freerdp-libs-1.0.2-10.el7.ppc64le
langtable-python-0.0.31-3.el7.noarch
tcp_wrappers-7.6-77.el7.ppc64le
lm_sensors-libs-3.4.0-4.20160601gitf9185e5.el7.ppc64le
kde-style-oxygen-4.11.19-8.el7.ppc64le
powertop-2.3-12.el7.ppc64le
wpa_supplicant-2.6-5.el7.ppc64le
gtk3-3.22.10-4.el7.ppc64le
boost-python-1.53.0-27.el7.ppc64le
keyutils-libs-devel-1.5.8-3.el7.ppc64le
libdvdread-5.0.3-3.el7.ppc64le
im-chooser-common-1.6.4-4.el7.ppc64le
aic94xx-firmware-30-6.el7.noarch
media-player-info-17-4.el7.noarch
compat-gnome-desktop314-3.14.2-1.el7.ppc64le
harfbuzz-1.3.2-1.el7.ppc64le
libgcrypt-devel-1.5.3-14.el7.ppc64le
groff-base-1.22.2-8.el7.ppc64le
sane-backends-1.0.24-9.el7.ppc64le
setuptool-1.19.11-8.el7.ppc64le
ebtables-2.0.10-15.el7.ppc64le
libchamplain-0.12.15-1.el7.ppc64le
boost-math-1.53.0-27.el7.ppc64le
libuser-0.60-7.el7_1.ppc64le
boost-date-time-1.53.0-27.el7.ppc64le
espeak-1.47.11-4.el7.ppc64le
tbb-devel-4.1-9.20130314.el7.ppc64le
grub2-tools-minimal-2.02-0.64.el7.centos.ppc64le
gjs-1.46.0-1.el7.ppc64le
libsss_autofs-1.15.2-50.el7.ppc64le
deltarpm-3.6-3.el7.ppc64le
libnl-1.1.4-3.el7.ppc64le
libgpod-0.8.2-12.el7.ppc64le
postgresql-devel-9.2.21-1.el7.ppc64le
libibcm-13-7.el7.ppc64le
abrt-gui-libs-2.1.11-48.el7.centos.ppc64le
libxkbcommon-0.7.1-1.el7.ppc64le
passwd-0.79-4.el7.ppc64le
lsvpd-1.7.8-1.el7.ppc64le
fprintd-0.5.0-4.0.el7_0.ppc64le
hunspell-en-0.20121024-6.el7.noarch
qca-ossl-2.0.0-0.19.beta3.el7.ppc64le
libdmapsharing-2.9.37-1.el7.ppc64le
ortp-0.20.0-10.el7.ppc64le
python-pycurl-7.19.0-19.el7.ppc64le
perl-Pod-Escapes-1.04-292.el7.noarch
pcp-3.11.8-7.el7.ppc64le
libblkid-devel-2.23.2-43.el7.ppc64le
dracut-network-033-502.el7.ppc64le
pyatspi-2.20.3-1.el7.noarch
systemtap-sdt-devel-3.1-3.el7.ppc64le
check-0.9.9-5.el7.ppc64le
perl-threads-shared-1.43-6.el7.ppc64le
gnome-shell-extension-common-3.22.2-10.el7.noarch
gnome-icon-theme-symbolic-3.12.0-2.el7.noarch
abrt-cli-2.1.11-48.el7.centos.ppc64le
festival-speechtools-libs-1.2.96-28.el7.ppc64le
python-slip-dbus-0.4.0-2.el7.noarch
mesa-private-llvm-3.9.1-3.el7.ppc64le
perl-Time-Local-1.2300-2.el7.noarch
yelp-3.22.0-1.el7.ppc64le
fuse-devel-2.9.2-8.el7.ppc64le
dnsmasq-2.76-2.el7.ppc64le
festvox-slt-arctic-hts-0.20061229-28.el7.noarch
libtasn1-devel-4.10-1.el7.ppc64le
libgudev1-219-42.el7.ppc64le
perl-version-0.99.07-2.el7.ppc64le
libvirt-daemon-driver-qemu-3.2.0-14.el7.ppc64le
ps_mem-3.1-7.el7.noarch
rtkit-0.11-10.el7.ppc64le
abrt-gui-2.1.11-48.el7.centos.ppc64le
nettle-devel-2.7.1-8.el7.ppc64le
perl-ExtUtils-Manifest-1.61-244.el7.noarch
libreswan-3.20-3.el7.ppc64le
python-pyudev-0.15-9.el7.noarch
appstream-data-7-20170301.el7.noarch
powerpc-utils-1.3.3-4.el7.ppc64le
setup-2.8.71-7.el7.noarch
enscript-1.6.6-6.el7.ppc64le
libgexiv2-0.10.4-2.el7.ppc64le
perl-Digest-SHA-5.85-4.el7.ppc64le
upower-0.99.4-2.el7.ppc64le
dhcp-libs-4.2.5-58.el7.centos.ppc64le
kbd-1.15.5-13.el7.ppc64le
phonon-backend-gstreamer-4.6.3-3.el7.ppc64le
dejavu-fonts-common-2.33-6.el7.noarch
libaio-devel-0.3.109-13.el7.ppc64le
grubby-8.28-23.el7.ppc64le
perl-CPAN-Meta-2.120921-5.el7.noarch
libmusicbrainz5-5.0.1-9.el7.ppc64le
liberation-mono-fonts-1.07.2-15.el7.noarch
fcoe-utils-1.0.32-1.el7.ppc64le
gvfs-afc-1.30.4-3.el7.ppc64le
m17n-db-1.6.4-3.el7.noarch
time-1.7-45.el7.ppc64le
python-configobj-4.7.2-7.el7.noarch
perl-Log-Message-0.08-3.el7.noarch
glib-networking-2.50.0-1.el7.ppc64le
gnome-classic-session-3.22.2-10.el7.noarch
libglade2-2.6.4-11.el7.ppc64le
langtable-data-0.0.31-3.el7.noarch
dejavu-serif-fonts-2.33-6.el7.noarch
python-requests-2.6.0-1.el7_1.noarch
perl-HTML-Tagset-3.20-15.el7.noarch
gssdp-1.0.1-1.el7.ppc64le
perl-CPANPLUS-Dist-Build-0.70-3.el7.noarch
brasero-nautilus-3.12.1-2.el7.ppc64le
evolution-data-server-3.22.7-6.el7.ppc64le
khmeros-fonts-common-5.0-17.el7.noarch
dejavu-sans-fonts-2.33-6.el7.noarch
python-kmod-0.9-4.el7.ppc64le
lzop-1.03-10.el7.ppc64le
telepathy-salut-0.8.1-6.el7.ppc64le
tbb-4.1-9.20130314.el7.ppc64le
kdegraphics-devel-4.10.5-3.el7.noarch
libcryptui-3.12.2-1.el7.ppc64le
ncurses-base-5.9-13.20130511.el7.noarch
lohit-nepali-fonts-2.5.3-2.el7.noarch
python-configshell-1.1.fb23-3.el7.noarch
acl-2.2.51-12.el7.ppc64le
python-rtslib-2.1.fb63-2.el7.noarch
libreport-plugin-rhtsupport-2.1.11-38.el7.centos.ppc64le
imsettings-qt-1.6.3-9.el7.ppc64le
webkitgtk3-2.4.11-2.el7.ppc64le
libsepol-2.5-6.el7.ppc64le
smc-meera-fonts-6.0-7.el7.noarch
python-mako-0.8.1-2.el7.noarch
pinentry-0.8.1-17.el7.ppc64le
alsa-tools-firmware-1.1.0-1.el7.ppc64le
libgdither-0.6-8.el7.ppc64le
ibus-libpinyin-1.6.91-4.el7.ppc64le
libXp-devel-1.0.2-2.1.el7.ppc64le
nspr-4.13.1-1.0.el7_3.ppc64le
cscope-15.8-10.el7.ppc64le
m2crypto-0.21.1-17.el7.ppc64le
libatomic-4.8.5-16.el7.ppc64le
opencc-0.4.3-3.el7.ppc64le
sbc-1.0-5.el7.ppc64le
SDL-devel-1.2.15-14.el7.ppc64le
vorbis-tools-1.4.0-12.el7.ppc64le
bzip2-libs-1.0.6-13.el7.ppc64le
google-crosextra-carlito-fonts-1.103-0.2.20130920.el7.noarch
nmap-ncat-6.40-7.el7.ppc64le
krb5-libs-1.15.1-8.el7.ppc64le
sssd-krb5-1.15.2-50.el7.ppc64le
cups-filters-libs-1.0.35-22.el7.ppc64le
virt-manager-1.4.1-7.el7.noarch
evince-3.22.1-5.el7.ppc64le
readline-6.2-10.el7.ppc64le
ctags-5.8-13.el7.ppc64le
sound-theme-freedesktop-0.8-3.el7.noarch
ruby-libs-2.0.0.648-30.el7.ppc64le
pth-2.0.7-23.el7.ppc64le
rubygems-2.0.14.1-30.el7.noarch
gnome-dictionary-3.20.0-1.el7.ppc64le
xorg-x11-drv-evdev-2.10.5-2.1.el7.ppc64le
audit-libs-2.7.6-3.el7.ppc64le
iwl135-firmware-18.168.6.1-56.el7.noarch
python-nss-0.16.0-3.el7.ppc64le
json-glib-1.2.6-1.el7.ppc64le
flatpak-libs-0.8.7-1.el7.ppc64le
libutempter-1.1.6-4.el7.ppc64le
ekiga-4.0.1-7.el7.ppc64le
easymock2-2.5.2-12.el7.noarch
keyutils-libs-1.5.8-3.el7.ppc64le
iwl1000-firmware-39.31.5.1-56.el7.noarch
teamd-1.25-5.el7.ppc64le
telepathy-glib-0.24.0-1.el7.ppc64le
PackageKit-yum-1.1.5-1.el7.centos.ppc64le
virt-what-1.13-10.el7.ppc64le
ppc64-diag-2.7.3-3.el7.ppc64le
libpurple-2.10.11-5.el7.ppc64le
libffi-3.0.13-18.el7.ppc64le
iwl2000-firmware-18.168.6.1-56.el7.noarch
perl-YAML-0.84-5.el7.noarch
libxml2-python-2.9.1-6.el7_2.3.ppc64le
lsscsi-0.27-6.el7.ppc64le
systemtap-client-3.1-3.el7.ppc64le
virt-viewer-5.0-7.el7.ppc64le
dbusmenu-qt-0.9.2-7.el7.ppc64le
libtar-1.2.11-29.el7.ppc64le
ccache-3.3.4-1.el7.ppc64le
perl-DBD-SQLite-1.39-3.el7.ppc64le
gnome-icon-theme-3.12.0-1.el7.noarch
gdk-pixbuf2-2.36.5-1.el7.ppc64le
libpath_utils-0.2.1-27.el7.ppc64le
gvfs-archive-1.30.4-3.el7.ppc64le
gnome-online-accounts-devel-3.22.5-1.el7.ppc64le
yajl-2.0.4-4.el7.ppc64le
gcc-4.8.5-16.el7_4.1.ppc64le
perl-Pod-Coverage-0.23-3.el7.noarch
libselinux-python-2.5-11.el7.ppc64le
libX11-devel-1.6.5-1.el7.ppc64le
qrencode-libs-3.4.1-3.el7.ppc64le
gnome-system-log-3.9.90-3.el7.ppc64le
mesa-libGLU-devel-9.0.0-4.el7.ppc64le
boost-system-1.53.0-27.el7.ppc64le
perl-HTTP-Message-6.06-6.el7.noarch
cracklib-2.9.0-11.el7.ppc64le
libXcursor-1.1.14-8.el7.ppc64le
dbus-1.6.12-17.el7.ppc64le
libnotify-devel-0.7.7-1.el7.ppc64le
ibus-gtk3-1.5.3-13.el7.ppc64le
libv4l-0.9.5-4.el7.ppc64le
perl-Time-Piece-1.20.1-292.el7.ppc64le
cracklib-dicts-2.9.0-11.el7.ppc64le
startup-notification-0.12-8.el7.ppc64le
dconf-0.26.0-2.el7.ppc64le
net-snmp-devel-5.7.2-28.el7.ppc64le
kate-part-4.10.5-4.el7.ppc64le
orc-0.4.26-1.el7.ppc64le
kernel-devel-3.10.0-693.el7.ppc64le
avahi-gobject-0.6.31-17.el7.ppc64le
cairo-gobject-1.14.8-2.el7.ppc64le
httpd-2.4.6-67.el7.centos.ppc64le
subversion-1.7.14-10.el7.ppc64le
kdepimlibs-akonadi-4.10.5-4.el7.ppc64le
gdbm-1.10-8.el7.ppc64le
perl-File-CheckTree-4.42-3.el7.noarch
atk-devel-2.22.0-3.el7.ppc64le
java-1.8.0-openjdk-devel-1.8.0.131-11.b12.el7.ppc64le
abrt-dbus-2.1.11-48.el7.centos.ppc64le
qt-mysql-4.8.5-13.el7.ppc64le
libkdcraw-4.10.5-4.el7.ppc64le
libaio-0.3.109-13.el7.ppc64le
urw-fonts-2.4-16.el7.noarch
libgee06-0.6.8-3.el7.ppc64le
libXrandr-devel-1.5.1-2.el7.ppc64le
cronie-anacron-1.4.11-17.el7.ppc64le
mlocate-0.26-6.el7.ppc64le
kdesdk-okteta-devel-4.10.5-6.el7.ppc64le
iso-codes-3.46-2.el7.noarch
e2fsprogs-1.42.9-10.el7.ppc64le
at-spi2-atk-2.22.0-2.el7.ppc64le
libstoragemgmt-python-clibs-1.4.0-3.el7.ppc64le
PackageKit-command-not-found-1.1.5-1.el7.centos.ppc64le
kdenetwork-kopete-devel-4.10.5-8.el7_0.ppc64le
libmnl-1.0.3-7.el7.ppc64le
tcp_wrappers-devel-7.6-77.el7.ppc64le
python-dns-1.12.0-4.20150617git465785f.el7.noarch
libXinerama-devel-1.1.3-2.1.el7.ppc64le
libibverbs-13-7.el7.ppc64le
net-tools-2.0-0.22.20131004git.el7.ppc64le
kde-workspace-libs-4.11.19-8.el7.ppc64le
libwebp-0.3.0-7.el7.ppc64le
libattr-devel-2.4.46-12.el7.ppc64le
libkadm5-1.15.1-8.el7.ppc64le
gcr-3.20.0-1.el7.ppc64le
colord-1.3.4-1.el7.ppc64le
rsyslog-8.24.0-12.el7.ppc64le
im-chooser-1.6.4-4.el7.ppc64le
boost-filesystem-1.53.0-27.el7.ppc64le
libgpg-error-devel-1.12-3.el7.ppc64le
harfbuzz-icu-1.3.2-1.el7.ppc64le
libpeas-gtk-1.20.0-1.el7.ppc64le
abrt-addon-python-2.1.11-48.el7.centos.ppc64le
selinux-policy-targeted-3.13.1-166.el7.noarch
libksane-4.10.5-4.el7.ppc64le
m4-1.4.16-10.el7.ppc64le
xmlrpc-c-client-1.32.5-1905.svn2451.el7.ppc64le
sysvinit-tools-2.88-14.dsf.el7.ppc64le
libnma-1.8.0-3.el7.ppc64le
os-prober-1.58-9.el7.ppc64le
libproxy-mozjs-0.4.11-10.el7.ppc64le
speech-dispatcher-0.7.1-15.el7.ppc64le
boost-signals-1.53.0-27.el7.ppc64le
python-ldap-2.4.15-2.el7.ppc64le
libvpx-1.3.0-5.el7_0.ppc64le
nm-connection-editor-1.8.0-3.el7.ppc64le
NetworkManager-team-1.8.0-9.el7.ppc64le
perf-3.10.0-693.el7.ppc64le
libgsf-1.14.26-7.el7.ppc64le
libpfm-4.7.0-4.el7.ppc64le
postgresql-9.2.21-1.el7.ppc64le
ethtool-4.8-1.el7.ppc64le
xorg-x11-server-utils-7.7-20.el7.ppc64le
attica-0.4.2-1.el7.ppc64le
xfsdump-3.1.4-1.el7.ppc64le
firewalld-filesystem-0.4.4.4-6.el7.noarch
libXfont2-2.0.1-2.el7.ppc64le
net-snmp-agent-libs-5.7.2-28.el7.ppc64le
tcl-devel-8.5.13-8.el7.ppc64le
libgxps-0.2.5-1.el7.ppc64le
cyrus-sasl-devel-2.1.26-21.el7.ppc64le
hmaccalc-0.9.13-4.el7.ppc64le
libwacom-data-0.24-1.el7.noarch
perl-Pod-Usage-1.63-3.el7.noarch
python-yubico-1.2.3-1.el7.noarch
libXxf86vm-devel-1.1.4-1.el7.ppc64le
abrt-tui-2.1.11-48.el7.centos.ppc64le
pinfo-0.6.10-9.el7.ppc64le
gnome-shell-extension-user-theme-3.22.2-10.el7.noarch
perl-File-Path-2.09-2.el7.noarch
xorg-x11-fonts-Type1-7.5-9.el7.noarch
python-firewall-0.4.4.4-6.el7.noarch
libXres-1.0.7-2.1.el7.ppc64le
libcgroup-tools-0.41-13.el7.ppc64le
libnl-devel-1.1.4-3.el7.ppc64le
gnome-user-docs-3.22.0-1.el7.noarch
perl-Pod-Simple-3.28-4.el7.noarch
systemd-libs-219-42.el7.ppc64le
ncurses-devel-5.9-13.20130511.el7.ppc64le
mesa-libEGL-devel-17.0.1-6.20170307.el7.ppc64le
audit-2.7.6-3.el7.ppc64le
iotop-0.6-2.el7.noarch
libvirt-daemon-driver-storage-logical-3.2.0-14.el7.ppc64le
perl-Module-CoreList-2.76.02-292.el7.noarch
libmbim-1.14.0-2.el7.ppc64le
xdg-desktop-portal-0.5-2.el7.ppc64le
perl-Module-Load-0.24-3.el7.noarch
caribou-gtk3-module-0.4.21-1.el7.ppc64le
sqlite-devel-3.7.17-8.el7.ppc64le
centos-indexhtml-7-9.el7.centos.noarch
elfutils-0.168-8.el7.ppc64le
centos-release-7-4.1708.el7.centos.ppc64le
trousers-0.3.14-2.el7.ppc64le
perl-Thread-Queue-3.02-2.el7.noarch
python-meh-gui-0.25.2-1.el7.noarch
gom-0.3.2-1.el7.ppc64le
lldpad-1.0.1-3.git036e314.el7.ppc64le
libgusb-0.2.9-1.el7.ppc64le
liberation-fonts-common-1.07.2-15.el7.noarch
libimobiledevice-1.2.0-1.el7.ppc64le
perl-Module-Pluggable-4.8-3.el7.noarch
ghostscript-cups-9.07-28.el7.ppc64le
osinfo-db-tools-1.1.0-1.el7.ppc64le
kbd-misc-1.15.5-13.el7.noarch
dhcp-common-4.2.5-58.el7.centos.ppc64le
control-center-filesystem-3.22.2-5.el7.ppc64le
libvirt-glib-1.0.0-1.el7.ppc64le
perl-CPAN-Meta-Requirements-2.122-7.el7.noarch
PyQt4-4.10.1-13.el7.ppc64le
btrfs-progs-4.9.1-1.el7.ppc64le
anaconda-gui-21.48.22.121-1.el7.centos.ppc64le
libatasmart-0.19-6.el7.ppc64le
shared-desktop-ontologies-0.11.0-2.el7.noarch
libvirt-daemon-config-nwfilter-3.2.0-14.el7.ppc64le
autoconf-2.69-11.el7.noarch
gnome-terminal-3.22.1-2.el7.ppc64le
python-cups-1.9.63-6.el7.ppc64le
intltool-0.50.2-7.el7.noarch
glibc-headers-2.17-196.el7.ppc64le
kdesdk-common-4.10.5-6.el7.noarch
libvirt-daemon-driver-secret-3.2.0-14.el7.ppc64le
perl-Locale-Maketext-Simple-0.21-292.el7.noarch
gnome-keyring-3.20.0-3.el7.ppc64le
python-sss-murmur-1.15.2-50.el7.ppc64le
vim-enhanced-7.4.160-2.el7.ppc64le
perl-ExtUtils-MakeMaker-6.68-3.el7.noarch
emacs-filesystem-24.3-19.el7_3.noarch
libvncserver-0.9.9-9.el7_0.1.ppc64le
perl-Object-Accessor-0.42-292.el7.noarch
gnome-desktop3-3.22.2-2.el7.ppc64le
python-backports-1.0-8.el7.ppc64le
evolution-help-3.22.6-10.el7.noarch
systemtap-devel-3.1-3.el7.ppc64le
langtable-0.0.31-3.el7.noarch
geocode-glib-3.20.1-1.el7.ppc64le
perl-Compress-Raw-Bzip2-2.061-3.el7.ppc64le
pygtk2-libglade-2.24.0-9.el7.ppc64le
python-urllib3-1.10.2-3.el7.noarch
orca-3.6.3-4.el7.ppc64le
perl-File-Fetch-0.42-2.el7.noarch
latencytop-common-0.5-13.el7.ppc64le
geoclue2-libs-2.4.5-1.el7.ppc64le
perl-Module-Loaded-0.08-292.el7.noarch
webkitgtk4-2.14.7-2.el7.ppc64le
python-paste-1.7.5.1-9.20111221hg1498.el7.noarch
totem-nautilus-3.22.1-1.el7.ppc64le
libtool-2.4.2-22.el7_3.ppc64le
smc-fonts-common-6.0-7.el7.noarch
libnice-0.1.3-4.el7.ppc64le
libdvdnav-5.0.3-1.el7.ppc64le
folks-0.11.3-1.el7.ppc64le
python-ipaddr-2.1.11-1.el7.noarch
xorg-x11-utils-7.5-22.el7.ppc64le
oxygen-icon-theme-4.10.5-2.el7.noarch
libkkc-common-0.3.1-9.el7.noarch
libgovirt-0.3.3-5.el7.ppc64le
boost-timer-1.53.0-27.el7.ppc64le
gnome-packagekit-common-3.22.1-2.el7.ppc64le
javapackages-tools-3.4.1-11.el7.noarch
sane-backends-devel-1.0.24-9.el7.ppc64le
konkretcmpi-0.9.1-5.el7.ppc64le
perl-srpm-macros-1-8.el7.noarch
chrony-3.1-2.el7.centos.ppc64le
fuse-2.9.2-8.el7.ppc64le
evolution-3.22.6-10.el7.ppc64le
python-urwid-1.1.1-3.el7.ppc64le
shotwell-0.24.5-1.el7.ppc64le
libreport-web-2.1.11-38.el7.centos.ppc64le
glibc-2.17-196.el7.ppc64le
usb_modeswitch-data-20160612-2.el7.noarch
patch-2.7.1-8.el7.ppc64le
file-roller-3.22.3-1.el7.ppc64le
python-netaddr-0.7.5-7.el7.noarch
ibus-table-chinese-1.4.6-3.el7.noarch
libreport-plugin-reportuploader-2.1.11-38.el7.centos.ppc64le
pcre-8.32-17.el7.ppc64le
libvirt-daemon-driver-network-3.2.0-14.el7.ppc64le
cyrus-sasl-plain-2.1.26-21.el7.ppc64le
glade-libs-3.20.0-1.el7.ppc64le
python-markupsafe-0.11-10.el7.ppc64le
kdenetwork-devel-4.10.5-8.el7_0.noarch
libreport-plugin-ureport-2.1.11-38.el7.centos.ppc64le
dbus-libs-1.6.12-17.el7.ppc64le
alsa-firmware-1.0.28-2.el7.noarch
mozjs17-17.0.0-19.el7.ppc64le
avahi-ui-gtk3-0.6.31-17.el7.ppc64le
python-cffi-1.6.0-5.el7.ppc64le
xdg-user-dirs-gtk-0.10-4.el7.ppc64le
gavl-1.4.0-4.el7.ppc64le
libjpeg-turbo-1.2.90-5.el7.ppc64le
device-mapper-multipath-0.4.9-111.el7.ppc64le
libcdio-0.92-1.el7.ppc64le
pulseaudio-module-bluetooth-10.0-3.el7.ppc64le
pytalloc-2.1.9-1.el7.ppc64le
ibus-sayura-1.3.2-3.el7.ppc64le
checkpolicy-2.5-4.el7.ppc64le
libICE-1.0.9-9.el7.ppc64le
libvirt-daemon-driver-interface-3.2.0-14.el7.ppc64le
libunistring-0.9.3-9.el7.ppc64le
libXScrnSaver-devel-1.2.2-6.1.el7.ppc64le
openlmi-python-base-0.5.0-4.el7.noarch
PyQt4-devel-4.10.1-13.el7.ppc64le
libndp-1.2-7.el7.ppc64le
libxml2-2.9.1-6.el7_2.3.ppc64le
sssd-krb5-common-1.15.2-50.el7.ppc64le
ncurses-5.9-13.20130511.el7.ppc64le
icedax-1.1.11-23.el7.ppc64le
libmsn-4.2.1-7.el7.ppc64le
evolution-data-server-devel-3.22.7-6.el7.ppc64le
poppler-0.26.5-16.el7.ppc64le
sed-4.2.2-5.el7.ppc64le
sssd-ldap-1.15.2-50.el7.ppc64le
fontconfig-2.10.95-11.el7.ppc64le
pinentry-qt-0.8.1-17.el7.ppc64le
cyrus-sasl-scram-2.1.26-21.el7.ppc64le
paps-0.6.8-28.el7.1.ppc64le
libyaml-0.1.4-11.el7_0.ppc64le
libgpg-error-1.12-3.el7.ppc64le
sgpio-1.2.0.10-13.el7.ppc64le
alsa-lib-1.1.3-3.el7.ppc64le
gutenprint-5.2.9-18.el7.ppc64le
openslp-2.0.0-6.el7.ppc64le
ruby-irb-2.0.0.648-30.el7.noarch
libgcrypt-1.5.3-14.el7.ppc64le
python-blivet-0.61.15.65-1.el7.noarch
gzip-1.5-9.el7.ppc64le
xorg-x11-drv-void-1.4.1-2.el7.ppc64le
nss-pem-1.0.3-4.el7.ppc64le
rubygem-rdoc-4.0.0-30.el7.noarch
libcap-ng-0.7.5-4.el7.ppc64le
rpm-build-libs-4.11.3-25.el7.ppc64le
shared-mime-info-1.8-3.el7.ppc64le
xorg-x11-drv-v4l-0.2.0-47.el7.ppc64le
nss-tools-3.28.4-8.el7.ppc64le
libsemanage-2.5-8.el7.ppc64le
libxcb-1.12-1.el7.ppc64le
flatpak-0.8.7-1.el7.ppc64le
gstreamer1-1.10.4-2.el7.ppc64le
xorg-x11-drv-nouveau-1.0.13-3.el7.ppc64le
sgml-common-0.6.3-39.el7.noarch
util-linux-2.23.2-43.el7.ppc64le
libtdb-1.3.12-2.el7.ppc64le
rpm-devel-4.11.3-25.el7.ppc64le
gobject-introspection-1.50.0-1.el7.ppc64le
qdox-1.12.1-10.el7.noarch
libteam-1.25-5.el7.ppc64le
openssh-clients-7.4p1-11.el7.ppc64le
libattr-2.4.46-12.el7.ppc64le
python-meh-0.25.2-1.el7.noarch
avahi-glib-0.6.31-17.el7.ppc64le
rhino-1.7R5-1.el7.noarch
perl-Pod-Checker-1.60-2.el7.noarch
rarian-0.8.1-11.el7.ppc64le
gmp-6.0.0-15.el7.ppc64le
createrepo-0.9.9-28.el7.noarch
python-gobject-base-3.22.0-1.el7.ppc64le
telepathy-haze-0.8.0-1.el7.ppc64le
perl-Version-Requirements-0.101022-244.el7.noarch
tog-pegasus-2.14.1-5.el7.ppc64le
lua-5.1.4-15.el7.ppc64le
libburn-1.2.8-4.el7.ppc64le
openssl-1.0.2k-8.el7.ppc64le
dleyna-server-0.5.0-1.el7.ppc64le
perl-IO-HTML-1.00-2.el7.noarch
libsemanage-python-2.5-8.el7.ppc64le
libidn-1.28-4.el7.ppc64le
nss-devel-3.28.4-8.el7.ppc64le
net-snmp-libs-5.7.2-28.el7.ppc64le
paps-libs-0.6.8-28.el7.1.ppc64le
perl-DBIx-Simple-1.35-7.el7.noarch
lzo-minilzo-2.06-8.el7.ppc64le
libref_array-0.1.5-27.el7.ppc64le
libX11-1.6.5-1.el7.ppc64le
xdg-utils-1.1.0-0.17.20120809git.el7.noarch
harfbuzz-devel-1.3.2-1.el7.ppc64le
perl-CGI-3.63-4.el7.noarch
libini_config-1.3.0-27.el7.ppc64le
xmlrpc-c-1.32.5-1905.svn2451.el7.ppc64le
libXfixes-5.0.3-1.el7.ppc64le
glibmm24-2.50.0-1.el7.ppc64le
webkitgtk4-devel-2.14.7-2.el7.ppc64le
perl-Devel-Symdump-2.10-2.el7.noarch
libpipeline-1.2.3-3.el7.ppc64le
mpfr-3.1.1-4.el7.ppc64le
libXrandr-1.5.1-2.el7.ppc64le
cyrus-sasl-gssapi-2.1.26-21.el7.ppc64le
gtk2-devel-2.24.31-1.el7.ppc64le
perl-URI-1.60-9.el7.noarch
kpartx-0.4.9-111.el7.ppc64le
file-libs-5.11-33.el7.ppc64le
libXext-devel-1.3.3-3.el7.ppc64le
libSM-devel-1.2.2-2.el7.ppc64le
qt-devel-4.8.5-13.el7.ppc64le
perl-HTTP-Date-6.02-8.el7.noarch
dracut-033-502.el7.ppc64le
libtool-ltdl-2.4.2-22.el7_3.ppc64le
libcanberra-0.30-5.el7.ppc64le
python-enum34-1.0.4-1.el7.noarch
libxkbfile-devel-1.0.9-3.el7.ppc64le
perl-HTTP-Cookies-6.01-5.el7.noarch
polkit-0.112-12.el7_3.ppc64le
libtheora-1.1.1-8.el7.ppc64le
libXpm-3.5.12-1.el7.ppc64le
libevent-2.0.21-4.el7.ppc64le
ibus-gtk2-1.5.3-13.el7.ppc64le
kdelibs-common-4.14.8-6.el7_3.ppc64le
systemd-sysv-219-42.el7.ppc64le
diffutils-3.3-4.el7.ppc64le
libXv-1.0.11-1.el7.ppc64le
pam-1.1.8-18.el7.ppc64le
imsettings-gsettings-1.6.3-9.el7.ppc64le
perl-YAML-Tiny-1.51-6.el7.noarch
GConf2-3.2.6-8.el7.ppc64le
libtasn1-4.10-1.el7.ppc64le
libxkbfile-1.0.9-3.el7.ppc64le
gettext-libs-0.19.8.1-2.el7.ppc64le
kdelibs-ktexteditor-4.14.8-6.el7_3.ppc64le
perl-Env-1.04-2.el7.noarch
libpciaccess-0.13.4-3.el7_3.ppc64le
nss-softokn-3.28.3-6.el7.ppc64le
pango-1.40.4-1.el7.ppc64le
telepathy-logger-0.8.0-5.el7.ppc64le
nepomuk-core-4.10.5-5.el7.ppc64le
perl-Net-HTTP-6.06-2.el7.noarch
samba-common-4.6.2-8.el7.noarch
libsigc++20-2.10.0-1.el7.ppc64le
cogl-1.22.2-1.el7.ppc64le
pcre-devel-8.32-17.el7.ppc64le
kdenetwork-kopete-libs-4.10.5-8.el7_0.ppc64le
icoutils-0.31.3-1.el7_3.ppc64le
pyparted-3.9-13.el7.ppc64le
apr-util-1.5.2-6.el7.ppc64le
giflib-4.1.6-9.el7.ppc64le
expat-devel-2.1.0-10.el7_3.ppc64le
kdesdk-okteta-4.10.5-6.el7.ppc64le
papi-5.2.0-23.el7.ppc64le
abrt-python-2.1.11-48.el7.centos.ppc64le
lzo-2.06-8.el7.ppc64le
java-1.8.0-openjdk-1.8.0.131-11.b12.el7.ppc64le
libffi-devel-3.0.13-18.el7.ppc64le
kwin-libs-4.11.19-8.el7.ppc64le
xorg-x11-font-utils-7.5-20.el7.ppc64le
iscsi-initiator-utils-iscsiuio-6.2.0.874-4.el7.ppc64le
file-5.11-33.el7.ppc64le
libXft-devel-2.3.2-2.el7.ppc64le
libipa_hbac-1.15.2-50.el7.ppc64le
kwin-gles-libs-4.11.19-8.el7.ppc64le
libsamplerate-0.1.8-6.el7.ppc64le
cronie-1.4.11-17.el7.ppc64le
xml-common-0.6.3-39.el7.noarch
ghostscript-9.07-28.el7.ppc64le
libpinyin-data-0.9.93-4.el7.ppc64le
kde-runtime-libs-4.10.5-8.el7.ppc64le
ipset-6.29-1.el7.ppc64le
plymouth-0.8.9-0.28.20140113.el7.centos.ppc64le
taglib-1.8-7.20130218git.el7.ppc64le
at-spi2-core-2.22.0-1.el7.ppc64le
xfsprogs-4.5.0-12.el7.ppc64le
kdepim-runtime-4.10.5-3.el7.ppc64le
libusbmuxd-1.0.10-5.el7.ppc64le
libstoragemgmt-python-1.4.0-3.el7.noarch
libseccomp-2.3.1-3.el7.ppc64le
gstreamer1-plugins-good-1.10.4-2.el7.ppc64le
pyusb-1.0.0-0.11.b1.el7.noarch
nepomuk-core-devel-4.10.5-5.el7.ppc64le
libofa-0.9.3-24.el7.ppc64le
device-mapper-event-1.02.140-8.el7.ppc64le
librtas-2.0.1-1.el7.ppc64le
libXcomposite-devel-0.4.4-4.1.el7.ppc64le
audit-libs-python-2.7.6-3.el7.ppc64le
okular-libs-4.10.5-4.el7.ppc64le
gdisk-0.8.6-5.el7.ppc64le
libibumad-13-7.el7.ppc64le
libsndfile-1.0.25-10.el7.ppc64le
libXxf86misc-1.0.3-7.1.el7.ppc64le
pyparsing-1.5.6-9.el7.noarch
kdesdk-kmtrace-libs-4.10.5-6.el7.ppc64le
attr-2.4.46-12.el7.ppc64le
rpcbind-0.2.0-42.el7.ppc64le
slang-2.2.4-11.el7.ppc64le
gtk2-2.24.31-1.el7.ppc64le
libssh2-1.4.3-10.el7_2.1.ppc64le
kdesdk-kompare-4.10.5-6.el7.ppc64le
openssl-devel-1.0.2k-8.el7.ppc64le
bluez-5.44-2.el7.ppc64le
boost-thread-1.53.0-27.el7.ppc64le
clutter-gtk-1.8.2-1.el7.ppc64le
soundtouch-1.4.0-9.el7.ppc64le
ibus-table-1.5.0-5.el7.noarch
setools-libs-3.3.8-1.1.el7.ppc64le
ppp-2.4.5-33.el7.ppc64le
libvpd-2.2.5-1.el7.ppc64le
clutter-gst3-3.0.22-1.el7.ppc64le
boost-test-1.53.0-27.el7.ppc64le
libgphoto2-2.5.2-5.el7.ppc64le
libcurl-7.29.0-42.el7.ppc64le
libmtp-1.1.6-5.el7.ppc64le
unzip-6.0-16.el7.ppc64le
vte291-0.46.2-1.el7.ppc64le
boost-random-1.53.0-27.el7.ppc64le
hplip-libs-3.15.9-3.el7.ppc64le
openldap-2.4.44-5.el7.ppc64le
rsync-3.0.9-18.el7.ppc64le
psmisc-22.20-15.el7.ppc64le
compat-cheese314-3.14.2-1.el7.ppc64le
dosfstools-3.0.20-9.el7.ppc64le
sane-backends-drivers-cameras-1.0.24-9.el7.ppc64le
kde-filesystem-4-47.el7.ppc64le
cryptsetup-1.7.4-3.el7.ppc64le
boost-program-options-1.53.0-27.el7.ppc64le
libgnomekbd-3.22.0.1-1.el7.ppc64le
libsrtp-1.4.4-10.20101004cvs.el7.ppc64le
speech-dispatcher-python-0.7.1-15.el7.ppc64le
raptor2-2.0.9-3.el7.ppc64le
grub2-tools-2.02-0.64.el7.centos.ppc64le
libiodbc-3.52.7-7.el7.ppc64le
gtk-vnc2-0.7.0-2.el7.ppc64le
libdv-1.0.0-17.el7.ppc64le
libXxf86dga-1.1.4-2.1.el7.ppc64le
python-deltarpm-3.6-3.el7.ppc64le
ibacm-13-7.el7.ppc64le
opus-1.0.2-6.el7.ppc64le
system-config-printer-libs-1.4.1-19.el7.noarch
libthai-0.1.14-9.el7.ppc64le
tracker-1.10.5-4.el7.ppc64le
shared-desktop-ontologies-devel-0.11.0-2.el7.noarch
qt-4.8.5-13.el7.ppc64le
pcre2-10.23-2.el7.ppc64le
gtkspell3-3.0.3-4.el7.ppc64le
libevdev-1.5.6-1.el7.ppc64le
totem-3.22.1-1.el7.ppc64le
virtuoso-opensource-6.1.6-6.el7.ppc64le
strigi-libs-0.7.7-12.20120626.el7.ppc64le
boost-wave-1.53.0-27.el7.ppc64le
libXmu-devel-1.1.2-2.el7.ppc64le
iproute-3.10.0-87.el7.ppc64le
firewalld-0.4.4.4-6.el7.noarch
color-filesystem-1-13.el7.noarch
automoc-1.0-0.20.rc3.el7.ppc64le
perl-Pod-Perldoc-3.20-4.el7.noarch
poppler-utils-0.26.5-16.el7.ppc64le
boost-1.53.0-27.el7.ppc64le
pcp-libs-3.11.8-7.el7.ppc64le
pykickstart-1.99.66.12-1.el7.noarch
openldap-devel-2.4.44-5.el7.ppc64le
perl-Encode-2.51-7.el7.ppc64le
python-gobject-3.22.0-1.el7.ppc64le
krb5-workstation-1.15.1-8.el7.ppc64le
libwacom-0.24-1.el7.ppc64le
isomd5sum-1.0.10-5.el7.ppc64le
abrt-addon-vmcore-2.1.11-48.el7.centos.ppc64le
perl-constant-1.27-2.el7.noarch
compat-libcogl12-1.14.0-3.el7.ppc64le
python-libipa_hbac-1.15.2-50.el7.ppc64le
gdm-3.22.3-11.el7.ppc64le
gstreamer1-devel-1.10.4-2.el7.ppc64le
abrt-retrace-client-2.1.11-48.el7.centos.ppc64le
perl-Exporter-5.68-3.el7.noarch
libXpm-devel-3.5.12-1.el7.ppc64le
python2-pyasn1-modules-0.1.9-7.el7.noarch
gnome-shell-extension-alternate-tab-3.22.2-10.el7.noarch
ttmkfdir-3.0.9-42.el7.ppc64le
samba-libs-4.6.2-8.el7.ppc64le
perl-File-Temp-0.23.01-3.el7.noarch
brltty-4.5-15.el7.ppc64le
sos-3.4-6.el7.centos.noarch
gnome-shell-extension-window-list-3.22.2-10.el7.noarch
clucene-core-2.3.3.4-11.el7.ppc64le
osinfo-db-20170423-2.el7.noarch
perl-macros-5.16.3-292.el7.ppc64le
python-brlapi-0.6.0-15.el7.ppc64le
libselinux-devel-2.5-11.el7.ppc64le
quota-nls-4.01-14.el7.noarch
elfutils-libs-0.168-8.el7.ppc64le
oddjob-mkhomedir-0.31.5-4.el7.ppc64le
perl-5.16.3-292.el7.ppc64le
opal-3.10.10-4.el7.ppc64le
gstreamer-tools-0.10.36-7.el7.ppc64le
libvirt-daemon-driver-storage-scsi-3.2.0-14.el7.ppc64le
satyr-0.13-14.el7.ppc64le
polkit-docs-0.112-12.el7_3.noarch
perl-Compress-Raw-Zlib-2.061-4.el7.ppc64le
compat-libcogl-pango12-1.14.0-3.el7.ppc64le
alsa-lib-devel-1.1.3-3.el7.ppc64le
libvirt-daemon-driver-storage-mpath-3.2.0-14.el7.ppc64le
NetworkManager-libnm-1.8.0-9.el7.ppc64le
tcsh-6.18.01-15.el7.ppc64le
perl-XML-Dumper-0.81-17.el7.noarch
libpfm-devel-4.7.0-4.el7.ppc64le
unixODBC-devel-2.3.1-11.el7.ppc64le
rcs-5.9.0-5.el7.ppc64le
ltrace-0.7.91-14.el7.ppc64le
ed-1.9-4.el7.ppc64le
wqy-zenhei-fonts-0.9.46-11.el7.noarch
lohit-bengali-fonts-2.5.3-4.el7.noarch
paratype-pt-sans-fonts-20101909-3.el7.noarch
paktype-naskh-basic-fonts-4.1-3.el7.noarch
lklug-fonts-0.6-10.20090803cvs.el7.noarch
lohit-kannada-fonts-2.5.3-3.el7.noarch
cjkuni-uming-fonts-0.2.20080216.1-53.el7.noarch
vlgothic-fonts-20130607-2.el7.noarch
lohit-telugu-fonts-2.5.3-3.el7.noarch
gnu-free-serif-fonts-20120503-8.el7.noarch
jomolhari-fonts-0.003-17.el7.noarch
scl-utils-20130529-17.el7_1.ppc64le
diffstat-1.57-4.el7.ppc64le
xorg-x11-drivers-7.7-6.el7.ppc64le
setserial-2.17-33.el7.ppc64le
vinagre-3.22.0-8.el7.ppc64le
man-pages-overrides-7.4.3-1.el7.ppc64le
gedit-3.22.0-3.el7.ppc64le
iwl5150-firmware-8.24.2.2-56.el7.noarch
gnome-contacts-3.22.1-1.el7.ppc64le
words-3.0-22.el7.noarch
setroubleshoot-3.2.28-3.el7.ppc64le
iwl7265-firmware-22.0.7.0-56.el7.noarch
gnome-system-monitor-3.22.2-2.el7.ppc64le
man-pages-3.53-5.el7.noarch
librsvg2-devel-2.40.16-1.el7.ppc64le
gpg-pubkey-f4a80eb5-53a7ff4b
system-config-printer-udev-1.4.1-19.el7.ppc64le
gnome-calculator-3.22.3-1.el7.ppc64le
libgcc-4.8.5-16.el7_4.1.ppc64le
gvfs-afp-1.30.4-3.el7.ppc64le
cpp-4.8.5-16.el7_4.1.ppc64le
latencytop-0.5-13.el7.ppc64le
gcc-c++-4.8.5-16.el7_4.1.ppc64le
gtk3-immodule-xim-3.22.10-4.el7.ppc64le
mousetweaks-3.12.0-1.el7.ppc64le
qt3-MySQL-3.3.8b-51.el7.ppc64le
xvattr-1.3-27.el7.ppc64le
yum-langpacks-0.4.2-7.el7.noarch
rpm-build-4.11.3-25.el7.ppc64le
virt-install-1.4.1-7.el7.noarch
samba-client-4.6.2-8.el7.ppc64le
qt-odbc-4.8.5-13.el7.ppc64le
NetworkManager-tui-1.8.0-9.el7.ppc64le
avahi-0.6.31-17.el7.ppc64le
httpd-manual-2.4.6-67.el7.centos.noarch
PackageKit-gstreamer-plugin-1.1.5-1.el7.centos.ppc64le
tuned-2.8.0-5.el7.noarch
qemu-guest-agent-2.8.0-2.el7.ppc64le
smartmontools-6.2-8.el7.ppc64le
openssh-server-7.4p1-11.el7.ppc64le
dracut-config-rescue-033-502.el7.ppc64le
openlmi-providers-devel-0.5.0-4.el7.ppc64le
oprofile-0.9.9-22.el7.ppc64le
perl-homedir-1.008010-4.el7.noarch
libgudev1-devel-219-42.el7.ppc64le
sudo-1.8.19p2-10.el7.ppc64le
libacl-devel-2.2.51-12.el7.ppc64le
perl-XML-Twig-3.44-2.el7.noarch
crash-trace-command-2.0-12.el7.ppc64le
crash-gcore-command-1.3.1-0.el7.ppc64le
libgnome-keyring-devel-3.12.0-1.el7.ppc64le
binutils-devel-2.25.1-31.base.el7.ppc64le
libcap-ng-devel-0.7.5-4.el7.ppc64le
bash-completion-2.1-6.el7.noarch
dstat-0.7.2-12.el7.noarch
wget-1.14-15.el7.ppc64le
gpg-pubkey-352c64e5-52ae6884
certmonger-0.78.4-3.el7.ppc64le
libatomic-static-4.8.5-16.el7.ppc64le
libicu-devel-50.1.2-15.el7.ppc64le
caribou-0.4.21-1.el7.ppc64le
grub2-common-2.02-0.64.el7.centos.noarch
plymouth-graphics-libs-0.8.9-0.28.20140113.el7.centos.ppc64le
kernel-3.10.0-693.el7.ppc64le
perl-Perl-OSType-1.003-3.el7.noarch
libvirt-daemon-3.2.0-14.el7.ppc64le
ledmon-0.80-2.el7.ppc64le
gupnp-av-0.12.10-1.el7.ppc64le
cups-1.6.3-29.el7.ppc64le
mozilla-filesystem-1.9-11.el7.ppc64le
libqmi-utils-1.16.0-1.el7.ppc64le
anaconda-core-21.48.22.121-1.el7.centos.ppc64le
perl-JSON-PP-2.27202-2.el7.noarch
libvirt-client-3.2.0-14.el7.ppc64le
numactl-devel-2.0.9-6.el7_2.ppc64le
cups-client-1.6.3-29.el7.ppc64le
mutter-3.22.3-11.el7.ppc64le
ipa-common-4.5.0-20.el7.centos.noarch
glibc-devel-2.17-196.el7.ppc64le
firefox-52.2.0-2.el7.centos.ppc64le
perl-Params-Check-0.38-2.el7.noarch
virt-manager-common-1.4.1-7.el7.noarch
indent-2.2.11-13.el7.ppc64le
python-linux-procfs-0.4.9-3.el7.noarch
gnome-session-3.22.3-4.el7.ppc64le
adwaita-cursor-theme-3.22.0-1.el7.noarch
perl-Archive-Extract-0.68-3.el7.noarch
gnome-initial-setup-3.22.1-4.el7.ppc64le
perl-IO-Compress-2.061-2.el7.noarch
geoclue2-2.4.5-1.el7.ppc64le
khmeros-base-fonts-5.0-17.el7.noarch
python-tempita-0.5.1-6.el7.noarch
gnome-online-accounts-3.22.5-1.el7.ppc64le
nhn-nanum-fonts-common-3.020-9.el7.noarch
gobject-introspection-devel-1.50.0-1.el7.ppc64le
rhythmbox-3.4.1-1.el7.ppc64le
libavc1394-0.5.3-14.el7.ppc64le
telepathy-gabble-0.18.1-4.el7.ppc64le
stix-fonts-1.1.0-5.el7.noarch
python-javapackages-3.4.1-11.el7.noarch
gnome-packagekit-installer-3.22.1-2.el7.ppc64le
mesa-filesystem-17.0.1-6.20170307.el7.ppc64le
konkretcmpi-python-0.9.1-5.el7.ppc64le
libsane-hpaio-3.15.9-3.el7.ppc64le
copy-jdk-configs-2.2-3.el7.noarch
usb_modeswitch-2.4.0-5.el7.ppc64le
nhn-nanum-gothic-fonts-3.020-9.el7.noarch
pytz-2016.10-2.el7.noarch
librsvg2-tools-2.40.16-1.el7.ppc64le
bash-4.2.46-28.el7.ppc64le
libreport-plugin-bugzilla-2.1.11-38.el7.centos.ppc64le
kde-workspace-devel-4.11.19-8.el7.ppc64le
libdb-devel-5.3.21-20.el7.ppc64le
fxload-2002_04_11-16.el7.ppc64le
google-crosextra-caladea-fonts-1.002-0.4.20130214.el7.noarch
python-pycparser-2.14-1.el7.noarch
libtimezonemap-0.4.4-1.el7.ppc64le
libcom_err-1.42.9-10.el7.ppc64le
frei0r-plugins-1.3-13.el7.ppc64le
ibus-m17n-1.3.4-13.el7.ppc64le
libcdio-paranoia-10.2+0.90-11.el7.ppc64le
netcf-libs-0.2.8-4.el7.ppc64le
lohit-punjabi-fonts-2.5.3-2.el7.noarch
cmpi-bindings-pywbem-0.9.5-6.el7.ppc64le
at-spi2-core-devel-2.22.0-1.el7.ppc64le
xz-libs-5.2.2-1.el7.ppc64le
libasyncns-0.8-7.el7.ppc64le
libcanberra-devel-0.30-5.el7.ppc64le
coreutils-8.22-18.el7.ppc64le
sssd-ad-1.15.2-50.el7.ppc64le
doxygen-1.8.5-3.el7.ppc64le
httpd-tools-2.4.6-67.el7.centos.ppc64le
libspectre-0.2.8-1.el7.ppc64le
cyrus-sasl-lib-2.1.26-21.el7.ppc64le
rubygem-bigdecimal-1.2.0-30.el7.ppc64le
icedtea-web-1.6.2-4.el7.ppc64le
libarchive-3.1.2-10.el7_2.ppc64le
python-pyblock-0.53-6.el7.ppc64le
byacc-1.9.20130304-3.el7.ppc64le
wodim-1.1.11-23.el7.ppc64le
xorg-x11-drv-qxl-0.1.5-3.el7.ppc64le
elfutils-libelf-0.168-8.el7.ppc64le
rubygem-thor-0.19.1-1.el7.noarch
file-roller-nautilus-3.22.3-1.el7.ppc64le
pkgconfig-0.27.1-4.el7.ppc64le
setroubleshoot-server-3.2.28-3.el7.ppc64le
iwl2030-firmware-18.168.6.1-56.el7.noarch
mailx-12.5-16.el7.ppc64le
xorg-x11-drv-fbdev-0.4.3-25.el7.ppc64le
libtevent-0.9.31-1.el7.ppc64le
policycoreutils-2.5-17.1.el7.ppc64le
java-1.7.0-openjdk-devel-1.7.0.141-2.6.10.5.el7.ppc64le
gsettings-desktop-schemas-3.22.0-1.el7.ppc64le
yum-3.4.3-154.el7.centos.noarch
iwl6000g2a-firmware-17.168.5.3-56.el7.noarch
perl-B-Lint-1.17-3.el7.noarch
gstreamer-plugins-bad-free-0.10.23-23.el7.ppc64le
libvorbis-1.3.3-8.el7.ppc64le
rarian-compat-0.8.1-11.el7.ppc64le
abrt-desktop-2.1.11-48.el7.centos.ppc64le
desktop-file-utils-0.23-1.el7.ppc64le
libiptcdata-1.0.4-11.el7.ppc64le
gpg-pubkey-f533f4fa-56585169
perl-DB_File-1.830-6.el7.ppc64le
compat-poppler022-qt-0.22.5-4.el7.ppc64le
libldb-1.1.29-1.el7.ppc64le
http-parser-2.7.1-1.el7.ppc64le
NetworkManager-libreswan-gnome-1.2.4-2.el7.ppc64le
centos-logos-70.0.6-3.el7.centos.noarch
libX11-common-1.6.5-1.el7.noarch
libstdc++-4.8.5-16.el7_4.1.ppc64le
perl-FCGI-0.74-8.el7.ppc64le
pango-devel-1.40.4-1.el7.ppc64le
libbasicobjects-0.1.1-27.el7.ppc64le
gtk2-immodule-xim-2.24.31-1.el7.ppc64le
libgnome-keyring-3.12.0-1.el7.ppc64le
libXrender-0.9.10-1.el7.ppc64le
libitm-devel-4.8.5-16.el7_4.1.ppc64le
perl-Business-ISBN-2.06-2.el7.noarch
freeglut-2.8.1-3.el7.ppc64le
device-mapper-1.02.140-8.el7.ppc64le
xdg-desktop-portal-gtk-0.5-1.el7.ppc64le
libudisks2-2.1.2-6.el7.ppc64le
pulseaudio-libs-10.0-3.el7.ppc64le
perl-HTTP-Daemon-6.01-5.el7.noarch
xorg-x11-xauth-1.0.9-1.el7.ppc64le
nettle-2.7.1-8.el7.ppc64le
polkit-pkla-compat-0.1-4.el7.ppc64le
startup-notification-devel-0.12-8.el7.ppc64le
genisoimage-1.1.11-23.el7.ppc64le
dbus-x11-1.6.12-17.el7.ppc64le
perl-Text-Soundex-3.04-4.el7.ppc64le
xdg-user-dirs-0.15-4.el7.ppc64le
jansson-2.10-1.el7.ppc64le
NetworkManager-glib-1.8.0-9.el7.ppc64le
rpm-sign-4.11.3-25.el7.ppc64le
gettext-0.19.8.1-2.el7.ppc64le
cairo-1.14.8-2.el7.ppc64le
perl-IO-Socket-SSL-1.94-6.el7.noarch
kdepimlibs-kxmlrpcclient-4.10.5-4.el7.ppc64le
libplist-1.12-3.el7.ppc64le
libwbclient-4.6.2-8.el7.ppc64le
cgdcbxd-1.0.2-7.el7.ppc64le
glib2-devel-2.50.3-3.el7.ppc64le
gdk-pixbuf2-devel-2.36.5-1.el7.ppc64le
theora-tools-1.1.1-8.el7.ppc64le
libkipi-4.10.5-3.el7.ppc64le
libmng-1.0.10-14.el7.ppc64le
abrt-addon-kerneloops-2.1.11-48.el7.centos.ppc64le
grub2-2.02-0.64.el7.centos.ppc64le
xz-devel-5.2.2-1.el7.ppc64le
xorg-x11-xkb-utils-7.7-12.el7.ppc64le
libverto-tevent-0.2.5-4.el7.ppc64le
libkdcraw-devel-4.10.5-4.el7.ppc64le
bzip2-1.0.6-13.el7.ppc64le
iputils-20160308-10.el7.ppc64le
cifs-utils-6.2-10.el7.ppc64le
libpinyin-0.9.93-4.el7.ppc64le
libao-1.1.0-8.el7.ppc64le
gdbm-devel-1.10-8.el7.ppc64le
kdepim-libs-4.10.5-6.el7.ppc64le
libxshmfence-1.2-1.el7.ppc64le
libstoragemgmt-1.4.0-3.el7.ppc64le
psacct-6.6.1-13.el7.ppc64le
pyliblzma-0.5.3-11.el7.ppc64le
libXcursor-devel-1.1.14-8.el7.ppc64le
hesiod-3.2.1-3.el7.ppc64le
okular-devel-4.10.5-4.el7.ppc64le
gsm-1.0.13-11.el7.ppc64le
telepathy-mission-control-5.16.3-3.el7.ppc64le
rng-tools-5-11.el7.ppc64le
python-chardet-2.2.1-1.el7_1.noarch
libcanberra-gtk3-0.30-5.el7.ppc64le
krb5-devel-1.15.1-8.el7.ppc64le
kdesdk-kompare-devel-4.10.5-6.el7.ppc64le
unixODBC-2.3.1-11.el7.ppc64le
dbus-devel-1.6.12-17.el7.ppc64le
kpatch-0.4.0-1.el7.noarch
graphite2-1.3.6-1.el7_2.ppc64le
nautilus-extensions-3.22.3-3.el7.ppc64le
libdb-utils-5.3.21-20.el7.ppc64le
sane-backends-libs-1.0.24-9.el7.ppc64le
zip-3.0-11.el7.ppc64le
mdadm-4.0-5.el7.ppc64le
memstomp-0.1.4-11.el7.ppc64le
libconfig-1.4.9-5.el7.ppc64le
clutter-gst2-2.0.18-1.el7.ppc64le
postgresql-libs-9.2.21-1.el7.ppc64le
gsound-1.0.2-2.el7.ppc64le
ilmbase-1.0.3-7.el7.ppc64le
udisks2-2.1.2-6.el7.ppc64le
perl-core-5.16.3-292.el7.ppc64le
pcsc-lite-libs-1.8.8-6.el7.ppc64le
gvnc-0.7.0-2.el7.ppc64le
qemu-img-1.5.3-141.el7.ppc64le
libappstream-glib-0.6.10-1.el7.ppc64le
sg3_utils-libs-1.37-12.el7.ppc64le
librdmacm-13-7.el7.ppc64le
adcli-0.8.1-3.el7.ppc64le
libnfnetlink-1.0.1-4.el7.ppc64le
colord-gtk-0.1.25-4.el7.ppc64le
libuser-python-0.60-7.el7_1.ppc64le
libfprint-0.5.0-4.el7.ppc64le
OpenEXR-libs-1.7.1-7.el7.ppc64le
attica-devel-0.4.2-1.el7.ppc64le
papi-devel-5.2.0-23.el7.ppc64le
m17n-lib-1.6.4-14.el7.ppc64le
qimageblitz-0.0.6-7.el7.ppc64le
python-urlgrabber-3.10-8.el7.noarch
pcp-selinux-3.11.8-7.el7.ppc64le
perl-Text-ParseWords-3.29-4.el7.noarch
apr-util-devel-1.5.2-6.el7.ppc64le
readline-devel-6.2-10.el7.ppc64le
python-kitchen-1.1.1-5.el7.noarch
gnome-abrt-0.3.4-8.el7.ppc64le
check-devel-0.9.9-5.el7.ppc64le
pulseaudio-gdm-hooks-10.0-3.el7.ppc64le
perl-Scalar-List-Utils-1.27-248.el7.ppc64le
abrt-addon-ccpp-2.1.11-48.el7.centos.ppc64le
gnome-icon-theme-extras-3.12.0-1.el7.noarch
python-slip-0.4.0-2.el7.noarch
brlapi-0.6.0-15.el7.ppc64le
qpdf-libs-5.0.1-3.el7.ppc64le
yelp-xsl-3.20.1-1.el7.noarch
perl-Storable-2.45-3.el7.ppc64le
libosinfo-1.0.0-1.el7.ppc64le
libcap-devel-2.22-9.el7.ppc64le
libepoxy-devel-1.3.1-1.el7.ppc64le
festival-1.96-28.el7.ppc64le
libusbx-1.0.20-1.el7.ppc64le
libvirt-daemon-driver-storage-disk-3.2.0-14.el7.ppc64le
perl-Test-Harness-3.28-3.el7.noarch
polkit-devel-0.112-12.el7_3.ppc64le
perl-Crypt-SSLeay-0.64-5.el7.ppc64le
libverto-devel-0.2.5-4.el7.ppc64le
caribou-gtk2-module-0.4.21-1.el7.ppc64le
vim-filesystem-7.4.160-2.el7.ppc64le
procps-ng-3.3.10-16.el7.ppc64le
NetworkManager-libreswan-1.2.4-2.el7.ppc64le
perl-Module-Metadata-1.000018-2.el7.noarch
pixman-devel-0.34.0-1.el7.ppc64le
patchutils-0.3.3-4.el7.ppc64le
filesystem-3.2-21.el7.ppc64le
cups-filesystem-1.6.3-29.el7.noarch
gettext-devel-0.19.8.1-2.el7.ppc64le
usbredir-0.7.1-2.el7.ppc64le
neon-0.30.0-3.el7.ppc64le
perl-LWP-MediaTypes-6.02-2.el7.noarch
python-qrcode-core-5.0.1-1.el7.noarch
hyphen-en-2.8.6-5.el7.noarch
gnu-free-fonts-common-20120503-8.el7.noarch
gtkmm30-3.22.0-1.el7.ppc64le
initial-setup-gui-0.3.9.40-1.el7.centos.ppc64le
libhugetlbfs-2.16-12.el7.ppc64le
subversion-libs-1.7.14-10.el7.ppc64le
perl-Encode-Locale-1.03-5.el7.noarch
python-inotify-0.9.4-4.el7.noarch
nano-2.3.1-10.el7.ppc64le
mobile-broadband-provider-info-1.20170310-1.el7.noarch
adwaita-gtk2-theme-3.22.2-1.el7.ppc64le
ipa-client-4.5.0-20.el7.centos.ppc64le
perl-IPC-Cmd-0.80-4.el7.noarch
libsoup-2.56.0-3.el7.ppc64le
perl-Term-UI-0.36-2.el7.noarch
python-setuptools-0.9.8-7.el7.noarch
dejavu-sans-mono-fonts-2.33-6.el7.noarch
bind-license-9.9.4-50.el7.noarch
webkitgtk4-jsc-2.14.7-2.el7.ppc64le
firewall-config-0.4.4.4-6.el7.noarch
perl-CPAN-1.9800-292.el7.noarch
gupnp-1.0.1-1.el7.ppc64le
boost-graph-1.53.0-27.el7.ppc64le
python-perf-3.10.0-693.el7.ppc64le
overpass-fonts-2.1-1.el7.noarch
thai-scalable-fonts-common-0.5.0-7.el7.noarch
webkitgtk4-jsc-devel-2.14.7-2.el7.ppc64le
pulseaudio-module-x11-10.0-3.el7.ppc64le
marisa-0.2.4-4.el7.ppc64le
gnutls-c++-3.3.26-9.el7.ppc64le
ca-certificates-2017.2.14-71.el7.noarch
python-idna-2.4-1.el7.noarch
strace-4.12-4.el7.ppc64le
nss-softokn-freebl-3.28.3-6.el7.ppc64le
vino-3.22.0-3.el7.ppc64le
libXaw-devel-1.0.13-4.el7.ppc64le
libreport-centos-2.1.11-38.el7.centos.ppc64le
alsa-utils-1.1.3-2.el7.ppc64le
libnl3-cli-3.2.28-4.el7.ppc64le
python-iniparse-0.4-9.el7.noarch
traceroute-2.0.22-2.el7.ppc64le
libselinux-2.5-11.el7.ppc64le
keybinder3-0.3.0-1.el7.ppc64le
kdepim-devel-4.10.5-6.el7.ppc64le
pakchois-0.4-10.el7.ppc64le
cryptsetup-python-1.7.4-3.el7.ppc64le
libjpeg-turbo-devel-1.2.90-5.el7.ppc64le
python-jwcrypto-0.2.1-1.el7.noarch
lohit-malayalam-fonts-2.5.3-2.el7.noarch
libpng-1.5.13-7.el7_2.ppc64le
freerdp-plugins-1.0.2-10.el7.ppc64le
ibus-chewing-1.4.4-14.el7.ppc64le
libfastjson-0.99.4-2.el7.ppc64le
libsss_sudo-1.15.2-50.el7.ppc64le
redhat-menus-12.0.2-8.el7.noarch
bind-libs-9.9.4-50.el7.ppc64le
gnu-free-sans-fonts-20120503-8.el7.noarch
libuuid-2.23.2-43.el7.ppc64le
festival-freebsoft-utils-0.10-7.el7.noarch
unique3-devel-3.0.2-8.el7.ppc64le
compat-poppler022-0.22.5-4.el7.ppc64le
sssd-proxy-1.15.2-50.el7.ppc64le
python-2.7.5-58.el7.ppc64le
libwvstreams-4.6.1-11.el7.ppc64le
lrzsz-0.12.20-36.el7.ppc64le
sqlite-3.7.17-8.el7.ppc64le
xorg-x11-server-common-1.19.3-11.el7.ppc64le
sushi-3.21.91-1.el7.ppc64le
rubygem-psych-2.0.0-30.el7.ppc64le
gnupg2-2.0.22-4.el7.ppc64le
libmount-2.23.2-43.el7.ppc64le
nss-3.28.4-8.el7.ppc64le
iwl3160-firmware-22.0.7.0-56.el7.noarch
libnl3-3.2.28-4.el7.ppc64le
xorg-x11-drv-ati-7.7.1-3.20160928git3fc839ff.el7.ppc64le
evolution-mapi-3.22.6-1.el7.ppc64le
libservicelog-1.1.17-2.el7.ppc64le
perl-PAR-Dist-0.49-2.el7.noarch
dbus-glib-0.100-7.el7.ppc64le
docbook-style-xsl-1.78.1-3.el7.noarch
iwl100-firmware-39.31.5.1-56.el7.noarch
libxslt-1.1.28-5.el7.ppc64le
junit-4.11-8.el7.noarch
gnome-session-xsession-3.22.3-4.el7.ppc64le
selinux-policy-3.13.1-166.el7.noarch
PackageKit-1.1.5-1.el7.centos.ppc64le
zlib-devel-1.2.7-17.el7.ppc64le
perl-libxml-perl-0.08-19.el7.noarch
iwl4965-firmware-228.61.2.24-56.el7.noarch
p11-kit-0.23.5-3.el7.ppc64le
spice-gtk3-0.33-6.el7.ppc64le
pygobject3-devel-3.22.0-1.el7.ppc64le
systemtap-runtime-3.1-3.el7.ppc64le
nss-softokn-freebl-devel-3.28.3-6.el7.ppc64le
libgee-0.18.1-1.el7.ppc64le
perl-PlRPC-0.2020-14.el7.noarch
python34-libs-3.4.5-4.el7.ppc64le
json-c-0.11-4.el7_0.ppc64le
plymouth-plugin-two-step-0.8.9-0.28.20140113.el7.centos.ppc64le
gnome-font-viewer-3.22.0-1.el7.ppc64le
sssd-client-1.15.2-50.el7.ppc64le
libXext-1.3.3-3.el7.ppc64le
nspr-devel-4.13.1-1.0.el7_3.ppc64le
perl-Algorithm-Diff-1.1902-17.el7.noarch
libgomp-4.8.5-16.el7_4.1.ppc64le
tcp_wrappers-libs-7.6-77.el7.ppc64le
libgdata-devel-0.17.8-1.el7.ppc64le
gnome-screenshot-3.22.0-1.el7.ppc64le
mtdev-1.1.5-5.el7.ppc64le
mesa-libEGL-17.0.1-6.20170307.el7.ppc64le
libpng-devel-1.5.13-7.el7_2.ppc64le
perl-Digest-SHA1-2.13-9.el7.ppc64le
libdhash-0.4.3-27.el7.ppc64le
phonon-devel-4.6.0-10.el7.ppc64le
qt3-ODBC-3.3.8b-51.el7.ppc64le
systemd-219-42.el7.ppc64le
libXinerama-1.1.3-2.1.el7.ppc64le
gdb-7.6.1-100.el7.ppc64le
perl-File-Listing-6.04-7.el7.noarch
jasper-libs-1.900.1-31.el7.ppc64le
ibus-setup-1.5.3-13.el7.noarch
spice-vdagent-0.14.0-14.el7.ppc64le
PackageKit-glib-1.1.5-1.el7.centos.ppc64le
libXmu-1.1.2-2.el7.ppc64le
atkmm-2.24.2-1.el7.ppc64le
perl-Sys-Syslog-0.33-3.el7.ppc64le
libXdmcp-1.1.2-6.el7.ppc64le
kdelibs-devel-4.14.8-6.el7_3.ppc64le
targetcli-2.1.fb46-1.el7.noarch
libcgroup-0.41-13.el7.ppc64le
qt-x11-4.8.5-13.el7.ppc64le
libxcb-devel-1.12-1.el7.ppc64le
perl-HTML-Format-2.10-7.el7.noarch
libsss_idmap-1.15.2-50.el7.ppc64le
kactivities-4.10.5-3.el7.ppc64le
httpd-devel-2.4.6-67.el7.centos.ppc64le
abrt-2.1.11-48.el7.centos.ppc64le
java-1.7.0-openjdk-headless-1.7.0.141-2.6.10.5.el7.ppc64le
apr-devel-1.4.8-3.el7.ppc64le
cdparanoia-10.2-17.el7.ppc64le
libpcap-1.5.3-9.el7.ppc64le
libkworkspace-4.11.19-8.el7.ppc64le
dbus-glib-devel-0.100-7.el7.ppc64le
crontabs-1.11-6.20121102git.el7.noarch
libXi-devel-1.7.9-1.el7.ppc64le
gnome-menus-3.13.3-3.el7.ppc64le
libieee1284-devel-0.2.11-15.el7.ppc64le
kmod-libs-20-15.el7.ppc64le
kde-runtime-4.10.5-8.el7.ppc64le
mod_ssl-2.4.6-67.el7.centos.ppc64le
cyrus-sasl-2.1.26-21.el7.ppc64le
libXScrnSaver-1.2.2-6.1.el7.ppc64le
python-augeas-0.5.0-2.el7.noarch
LibRaw-0.14.8-5.el7.20120830git98d925.ppc64le
hyphen-2.8.6-5.el7.ppc64le
kdenetwork-krdc-libs-4.10.5-8.el7_0.ppc64le
opal-prd-5.5.0-1.el7.ppc64le
rdma-core-13-7.el7.ppc64le
pulseaudio-10.0-3.el7.ppc64le
python-sssdconfig-1.15.2-50.el7.noarch
libisofs-1.2.8-4.el7.ppc64le
libverto-0.2.5-4.el7.ppc64le
kdesdk-kmtrace-devel-4.10.5-6.el7.ppc64le
systemd-devel-219-42.el7.ppc64le
mesa-dri-drivers-17.0.1-6.20170307.el7.ppc64le
clutter-1.26.0-1.el7.ppc64le
fipscheck-1.4.1-6.el7.ppc64le
dwz-0.11-3.el7.ppc64le
boost-regex-1.53.0-27.el7.ppc64le
libXaw-1.0.13-4.el7.ppc64le
systemd-python-219-42.el7.ppc64le
zenity-3.22.0-1.el7.ppc64le
boost-atomic-1.53.0-27.el7.ppc64le
rpm-libs-4.11.3-25.el7.ppc64le
GeoIP-1.5.0-11.el7.ppc64le
libksane-devel-4.10.5-4.el7.ppc64le
rubygem-bundler-1.7.8-3.el7.noarch
git-1.8.3.1-11.el7.ppc64le
brasero-libs-3.12.1-2.el7.ppc64le
c-ares-1.10.0-3.el7.ppc64le
libnfsidmap-0.25-17.el7.ppc64le
cdparanoia-libs-10.2-17.el7.ppc64le
tk-8.5.13-6.el7.ppc64le
libhugetlbfs-devel-2.16-12.el7.ppc64le
NetworkManager-wifi-1.8.0-9.el7.ppc64le
libcanberra-gtk2-0.30-5.el7.ppc64le
hostname-3.13-3.el7.ppc64le
redland-1.0.16-6.el7.ppc64le
libdaemon-0.14-7.el7.ppc64le
brasero-3.12.1-2.el7.ppc64le
cups-devel-1.6.3-29.el7.ppc64le
qca2-2.0.3-7.el7.ppc64le
pangomm-2.40.1-1.el7.ppc64le
libnetfilter_conntrack-1.0.6-1.el7_3.ppc64le
sip-devel-4.14.6-4.el7.ppc64le
perl-parent-0.225-244.el7.noarch
libkkc-0.3.1-9.el7.ppc64le
crypto-utils-2.4.1-42.el7.ppc64le
lvm2-2.02.171-8.el7.ppc64le
poppler-glib-0.26.5-16.el7.ppc64le
crash-7.1.9-2.el7.ppc64le
libbluray-0.2.3-5.el7.ppc64le
perl-Filter-1.49-3.el7.ppc64le
control-center-3.22.2-5.el7.ppc64le
c-ares-devel-1.10.0-3.el7.ppc64le
sysstat-10.1.5-12.el7.ppc64le
mesa-libGL-devel-17.0.1-6.20170307.el7.ppc64le
python-pwquality-1.2.3-4.el7.ppc64le
liblouis-python-2.5.2-10.el7.noarch
perl-PathTools-3.40-5.el7.ppc64le
gnome-shell-extension-apps-menu-3.22.2-10.el7.noarch
hunspell-devel-1.3.2-15.el7.ppc64le
policycoreutils-python-2.5-17.1.el7.ppc64le
libwnck3-3.20.1-1.el7.ppc64le
gsettings-desktop-schemas-devel-3.22.0-1.el7.ppc64le
lsof-4.87-4.el7.ppc64le
perl-Getopt-Long-2.40-2.el7.noarch
nfs-utils-1.3.0-0.48.el7.ppc64le
mtr-0.85-7.el7.ppc64le
autofs-5.0.7-69.el7.ppc64le
cairo-devel-1.14.8-2.el7.ppc64le
xorg-x11-xbitmaps-1.1.1-6.el7.noarch
libreport-2.1.11-38.el7.centos.ppc64le
perl-XML-Parser-2.41-10.el7.ppc64le
libvirt-daemon-driver-storage-3.2.0-14.el7.ppc64le
python2-caribou-0.4.21-1.el7.noarch
fontpackages-filesystem-1.44-8.el7.noarch
perl-Test-Pod-1.48-3.el7.noarch
libuuid-devel-2.23.2-43.el7.ppc64le
perl-Package-Constants-0.02-292.el7.noarch
gnutls-3.3.26-9.el7.ppc64le
libreport-cli-2.1.11-38.el7.centos.ppc64le
gettext-common-devel-0.19.8.1-2.el7.noarch
cups-filters-1.0.35-22.el7.ppc64le
xkeyboard-config-2.20-1.el7.noarch
bison-3.0.4-1.el7.ppc64le
compat-libcolord1-1.0.4-1.el7.ppc64le
perl-Digest-MD5-2.52-3.el7.ppc64le
gnutls-dane-3.3.26-9.el7.ppc64le
libusbx-devel-1.0.20-1.el7.ppc64le
initial-setup-0.3.9.40-1.el7.centos.ppc64le
libchamplain-gtk-0.12.15-1.el7.ppc64le
libreport-filesystem-2.1.11-38.el7.centos.ppc64le
m17n-contrib-1.1.14-3.el7.noarch
newt-python-0.52.15-4.el7.ppc64le
perl-Locale-Maketext-1.23-3.el7.noarch
libvirt-daemon-driver-nodedev-3.2.0-14.el7.ppc64le
perl-ExtUtils-Install-1.58-292.el7.noarch
libvirt-3.2.0-14.el7.ppc64le
gnome-themes-standard-3.22.2-1.el7.ppc64le
gl-manpages-1.1-7.20130122.el7.noarch
lohit-gujarati-fonts-2.5.3-2.el7.noarch
python-backports-ssl_match_hostname-3.4.0.2-4.el7.noarch
perl-local-lib-1.008010-4.el7.noarch
rest-0.8.0-1.el7.ppc64le
perl-Module-Build-0.40.05-2.el7.noarch
ibus-kkc-1.5.18-7.el7.ppc64le
webkitgtk4-plugin-process-gtk2-2.14.7-2.el7.ppc64le
basesystem-10.0-7.el7.centos.noarch
madan-fonts-2.000-11.el7.noarch
python-beaker-1.5.4-10.el7.noarch
boost-locale-1.53.0-27.el7.ppc64le
dleyna-core-0.5.0-1.el7.ppc64le
liberation-sans-fonts-1.07.2-15.el7.noarch
tk-devel-8.5.13-6.el7.ppc64le
gnome-packagekit-updater-3.22.1-2.el7.ppc64le
cim-schema-2.33.0-6.el7.noarch
lohit-assamese-fonts-2.5.3-2.el7.noarch
tagsoup-1.2.1-8.el7.noarch
libshout-2.2.2-11.el7.ppc64le
ntpdate-4.2.6p5-25.el7.centos.2.ppc64le
libproxy-0.4.11-10.el7.ppc64le
gvfs-gphoto2-1.30.4-3.el7.ppc64le
gspell-1.2.3-1.el7.ppc64le
sil-nuosu-fonts-2.1.1-5.el7.noarch
python-ntplib-0.3.2-1.el7.noarch
bc-1.06.95-13.el7.ppc64le
libvirt-daemon-driver-lxc-3.2.0-14.el7.ppc64le
libreport-anaconda-2.1.11-38.el7.centos.ppc64le
kdepimlibs-devel-4.10.5-4.el7.ppc64le
unique3-3.0.2-8.el7.ppc64le
freetype-2.4.11-15.el7.ppc64le
lohit-marathi-fonts-2.5.3-2.el7.noarch
python2-cryptography-1.7.2-1.el7.ppc64le
libss-1.42.9-10.el7.ppc64le
kernel-tools-libs-3.10.0-693.el7.ppc64le
libsysfs-2.1.0-16.el7.ppc64le
ibus-hangul-1.4.2-10.el7.ppc64le
freerdp-1.0.2-10.el7.ppc64le
popt-1.13-16.el7.ppc64le
open-sans-fonts-1.10-1.el7.noarch
bind-libs-lite-9.9.4-50.el7.ppc64le
lksctp-tools-1.0.17-2.el7.ppc64le
sssd-common-pac-1.15.2-50.el7.ppc64le
libtiff-4.0.3-27.el7_3.ppc64le
gnome-desktop3-devel-3.22.2-2.el7.ppc64le
cdrdao-1.2.3-20.el7.ppc64le
expat-2.1.0-10.el7_3.ppc64le
latrace-0.5.11-6.1.el7.ppc64le
perl-Net-SSLeay-1.55-6.el7.ppc64le
cups-libs-1.6.3-29.el7.ppc64le
dmraid-events-1.0.0.rc16-28.el7.ppc64le
rubygem-io-console-0.4.2-30.el7.ppc64le
gutenprint-cups-5.2.9-18.el7.ppc64le
xorg-x11-server-Xorg-1.19.3-11.el7.ppc64le
libtalloc-2.1.9-1.el7.ppc64le
iwl6000g2b-firmware-17.168.5.2-56.el7.noarch
nss-sysinit-3.28.4-8.el7.ppc64le
glib2-2.50.3-3.el7.ppc64le
rpm-python-4.11.3-25.el7.ppc64le
ustr-1.0.4-16.el7.ppc64le
gucharmap-3.18.2-1.el7.ppc64le
xorg-x11-drv-dummy-0.3.7-1.el7.ppc64le
libogg-1.3.0-7.el7.ppc64le
iwl6000-firmware-9.221.4.1-56.el7.noarch
docbook-dtds-1.0-60.el7.noarch
xorg-x11-proto-devel-7.7-20.el7.noarch
pygpgme-0.3-9.el7.ppc64le
openssh-7.4p1-11.el7.ppc64le
cheese-3.22.1-1.el7.ppc64le
jline-1.0-8.el7.noarch
libcap-2.22-9.el7.ppc64le
ivtv-firmware-20080701-26.el7.noarch
perl-Pod-LaTeX-0.61-2.el7.noarch
enchant-1.6.0-8.el7.ppc64le
python2-ipalib-4.5.0-20.el7.centos.noarch
tog-pegasus-libs-2.14.1-5.el7.ppc64le
firstboot-19.12-1.el7.ppc64le
gupnp-dlna-0.10.5-1.el7.ppc64le
which-2.20-7.el7.ppc64le
epel-release-7-9.noarch
perl-Net-Daemon-0.48-5.el7.noarch
libcroco-0.6.11-1.el7.ppc64le
liboauth-devel-0.9.7-4.el7.ppc64le
libhangul-0.1.0-8.el7.ppc64le
eog-3.20.5-2.el7.ppc64le
plymouth-theme-charge-0.8.9-0.28.20140113.el7.centos.ppc64le
libcollection-0.6.2-27.el7.ppc64le
libgfortran-4.8.5-16.el7_4.1.ppc64le
perl-Locale-Codes-3.26-2.el7.noarch
pygobject2-2.28.6-11.el7.ppc64le
libXdamage-1.1.4-4.1.el7.ppc64le
libestr-0.1.9-2.el7.ppc64le
PackageKit-gtk3-module-1.1.5-1.el7.centos.ppc64le
libgweather-devel-3.20.4-1.el7.ppc64le
xz-5.2.2-1.el7.ppc64le
perl-WWW-RobotRules-6.02-5.el7.noarch
libICE-devel-1.0.9-9.el7.ppc64le
libXft-2.3.2-2.el7.ppc64le
cryptsetup-libs-1.7.4-3.el7.ppc64le
alsa-plugins-pulseaudio-1.1.1-1.el7.ppc64le
glx-utils-8.2.0-3.el7.ppc64le
speex-1.2-0.19.rc1.el7.ppc64le
perl-HTTP-Negotiate-6.01-5.el7.noarch
libtirpc-0.2.4-0.10.el7.ppc64le
pulseaudio-libs-glib2-10.0-3.el7.ppc64le
mesa-libgbm-17.0.1-6.20170307.el7.ppc64le
pulseaudio-libs-devel-10.0-3.el7.ppc64le
imsettings-1.6.3-9.el7.ppc64le
hunspell-en-US-0.20121024-6.el7.noarch
perl-IO-Socket-IP-0.21-4.el7.noarch
nss-util-devel-3.28.4-3.el7.ppc64le
libXxf86vm-1.1.4-1.el7.ppc64le
hwdata-0.252-8.6.el7.ppc64le
kernel-tools-3.10.0-693.el7.ppc64le
nepomuk-core-libs-4.10.5-5.el7.ppc64le
exiv2-libs-0.23-6.el7.ppc64le
perl-libwww-perl-6.05-2.el7.noarch
p11-kit-devel-0.23.5-3.el7.ppc64le
librsvg2-2.40.16-1.el7.ppc64le
libsmbclient-4.6.2-8.el7.ppc64le
abrt-console-notification-2.1.11-48.el7.centos.ppc64le
kdesdk-okteta-libs-4.10.5-6.el7.ppc64le
boost-chrono-1.53.0-27.el7.ppc64le
iw-4.3-1.el7.ppc64le
libcom_err-devel-1.42.9-10.el7.ppc64le
akonadi-1.9.2-4.el7.ppc64le
accountsservice-libs-0.6.45-2.el7.ppc64le
wvdial-1.61-9.el7.ppc64le
libkexiv2-devel-4.10.5-3.el7.ppc64le
libmpc-1.0.1-3.el7.ppc64le
lm_sensors-devel-3.4.0-4.20160601gitf9185e5.el7.ppc64le
meanwhile-1.1.0-12.el7.ppc64le
libXt-devel-1.1.5-3.el7.ppc64le
plymouth-scripts-0.8.9-0.28.20140113.el7.centos.ppc64le
mod_fcgid-2.3.9-4.el7.ppc64le
kdepim-runtime-libs-4.10.5-3.el7.ppc64le
mesa-libglapi-17.0.1-6.20170307.el7.ppc64le
hunspell-en-GB-0.20121024-6.el7.noarch
sip-4.14.6-4.el7.ppc64le
cairomm-1.12.0-1.el7.ppc64le
abrt-addon-xorg-2.1.11-48.el7.centos.ppc64le
ModemManager-1.6.0-2.el7.ppc64le
kdenetwork-krdc-devel-4.10.5-8.el7_0.ppc64le
libieee1284-0.2.11-15.el7.ppc64le
highlight-3.13-3.el7.ppc64le
pyOpenSSL-0.13.1-3.el7.ppc64le
gtk-update-icon-cache-3.22.10-4.el7.ppc64le
NetworkManager-1.8.0-9.el7.ppc64le
crda-3.13_2016.02.08-1.el7.ppc64le
kdesdk-kompare-libs-4.10.5-6.el7.ppc64le
newt-0.52.15-4.el7.ppc64le
xcb-util-0.4.0-2.el7.ppc64le
automake-1.13.4-3.el7.noarch
libgweather-3.20.4-1.el7.ppc64le
lockdev-1.0.4-0.13.20111007git.el7.ppc64le
man-db-2.6.3-9.el7.ppc64le
gd-2.0.35-26.el7.ppc64le
exempi-2.2.0-8.el7.ppc64le
curl-7.29.0-42.el7.ppc64le
snappy-1.1.0-3.el7.ppc64le
libreport-gtk-2.1.11-38.el7.centos.ppc64le
unbound-libs-1.4.20-34.el7.ppc64le
tcpdump-4.9.0-5.el7.ppc64le
sane-backends-drivers-scanners-1.0.24-9.el7.ppc64le
libedit-3.0-12.20121213cvs.el7.ppc64le
liboauth-0.9.7-4.el7.ppc64le
libmpcdec-1.2.6-12.el7.ppc64le
libnm-gtk-1.8.0-3.el7.ppc64le
grub2-tools-extra-2.02-0.64.el7.centos.ppc64le
libdmx-1.1.3-3.el7.ppc64le
wavpack-4.60.1-9.el7.ppc64le
rasqal-0.9.30-4.el7.ppc64le
autogen-libopts-5.18-5.el7.ppc64le
gnome-bluetooth-libs-3.20.1-1.el7.ppc64le
qt-settings-19-23.5.el7.centos.noarch
libxslt-devel-1.1.28-5.el7.ppc64le
grilo-plugins-0.3.4-1.el7.ppc64le
SDL-1.2.15-14.el7.ppc64le
sip-macros-4.14.6-4.el7.ppc64le
iptables-1.4.21-18.0.1.el7.centos.ppc64le
gstreamer-plugins-good-0.10.31-13.el7.ppc64le
qjson-0.8.1-4.el7.ppc64le
perl-Test-Pod-Coverage-1.08-21.el7.noarch
pcp-conf-3.11.8-7.el7.ppc64le
perl-podlators-2.5.1-3.el7.noarch
libcurl-devel-7.29.0-42.el7.ppc64le
graphite2-devel-1.3.6-1.el7_2.ppc64le
pygtk2-2.24.0-9.el7.ppc64le
kexec-tools-2.0.14-17.el7.ppc64le
iptables-devel-1.4.21-18.0.1.el7.centos.ppc64le
gnome-shell-3.22.3-17.el7.ppc64le
perl-Carp-1.26-244.el7.noarch
liblouis-2.5.2-10.el7.ppc64le
dvd+rw-tools-7.1-15.el7.ppc64le
ptlib-2.10.10-6.el7.ppc64le
samba-common-libs-4.6.2-8.el7.ppc64le
gvfs-devel-1.30.4-3.el7.ppc64le
gnome-shell-extension-launch-new-instance-3.22.2-10.el7.noarch
perl-libs-5.16.3-292.el7.ppc64le
libselinux-utils-2.5-11.el7.ppc64le
libsepol-devel-2.5-6.el7.ppc64le
festival-lib-1.96-28.el7.ppc64le
oddjob-0.31.5-4.el7.ppc64le
latencytop-tui-0.5-13.el7.ppc64le
libvirt-daemon-driver-storage-core-3.2.0-14.el7.ppc64le
perl-Data-Dumper-2.145-3.el7.ppc64le
libreport-python-2.1.11-38.el7.centos.ppc64le
libical-devel-1.0.1-1.el7.ppc64le
libmx-1.4.7-10.el7.ppc64le
cups-pk-helper-0.2.6-2.el7.ppc64le
=== TEST BEGIN ===
Install prefix    /var/tmp/patchew-tester-tmp-9ukz0kme/src/install
BIOS directory    /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/share/qemu
firmware path     /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/share/qemu-firmware
binary directory  /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/bin
library directory /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/lib
module directory  /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/lib/qemu
libexec directory /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/libexec
include directory /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/include
config directory  /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/etc
local state directory   /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/var
Manual directory  /var/tmp/patchew-tester-tmp-9ukz0kme/src/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /var/tmp/patchew-tester-tmp-9ukz0kme/src
GIT binary        git
GIT submodules    ui/keycodemapdb dtc capstone
C compiler        cc
Host C compiler   cc
C++ compiler      c++
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS       -I/usr/include/pixman-1   -I$(SRC_PATH)/dtc/libfdt -Werror -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -DNCURSES_WIDECHAR   -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-strong -Wno-missing-braces -I/usr/include/p11-kit-1       -I/usr/include/libpng15   -I$(SRC_PATH)/capstone/include
LDFLAGS           -Wl,--warn-common -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          ppc64
host big endian   no
target list       aarch64-softmmu alpha-softmmu arm-softmmu cris-softmmu hppa-softmmu i386-softmmu lm32-softmmu m68k-softmmu microblazeel-softmmu microblaze-softmmu mips64el-softmmu mips64-softmmu mipsel-softmmu mips-softmmu moxie-softmmu nios2-softmmu or1k-softmmu ppc64-softmmu ppcemb-softmmu ppc-softmmu s390x-softmmu sh4eb-softmmu sh4-softmmu sparc64-softmmu sparc-softmmu tricore-softmmu unicore32-softmmu x86_64-softmmu xtensaeb-softmmu xtensa-softmmu aarch64_be-linux-user aarch64-linux-user alpha-linux-user armeb-linux-user arm-linux-user cris-linux-user hppa-linux-user i386-linux-user m68k-linux-user microblazeel-linux-user microblaze-linux-user mips64el-linux-user mips64-linux-user mipsel-linux-user mips-linux-user mipsn32el-linux-user mipsn32-linux-user nios2-linux-user or1k-linux-user ppc64abi32-linux-user ppc64le-linux-user ppc64-linux-user ppc-linux-user s390x-linux-user sh4eb-linux-user sh4-linux-user sparc32plus-linux-user sparc64-linux-user sparc-linux-user tilegx-linux-user x86_64-linux-user
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
SDL support       yes (1.2.15)
GTK support       yes (3.22.10)
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    yes
GNUTLS rnd        yes
libgcrypt         no
libgcrypt kdf     no
nettle            yes (2.7.1)
nettle kdf        yes
libtasn1          yes
curses support    yes
virgl support     no
curl support      yes
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    yes
Multipath support no
VNC support       yes
VNC SASL support  yes
VNC JPEG support  yes
VNC PNG support   yes
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               no
vde support       no
netmap support    no
Linux AIO support yes
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
HAX support       no
HVF support       no
WHPX support      no
TCG support       yes
TCG debug enabled no
TCG interpreter   no
malloc trim support yes
RDMA support      yes
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
posix_memalign    yes
libcap-ng support yes
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
vhost-user support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            yes
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
debug stack usage no
crypto afalg      no
GlusterFS support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   no
TPM emulator      yes
QOM debugging     yes
Live block migration yes
lzo support       no
snappy support    no
bzip2 support     yes
NUMA host support yes
libxml2           yes
tcmalloc support  no
jemalloc support  no
avx2 optimization no
replication support yes
VxHS block device no
capstone          git

WARNING: Use of SDL 1.2 is deprecated and will be removed in
WARNING: future releases. Please switch to using SDL 2.0
  GEN     aarch64-softmmu/config-devices.mak.tmp
  GEN     alpha-softmmu/config-devices.mak.tmp
  GEN     arm-softmmu/config-devices.mak.tmp
  GEN     cris-softmmu/config-devices.mak.tmp
  GEN     hppa-softmmu/config-devices.mak.tmp
  GEN     i386-softmmu/config-devices.mak.tmp
  GEN     lm32-softmmu/config-devices.mak.tmp
  GEN     m68k-softmmu/config-devices.mak.tmp
  GEN     microblazeel-softmmu/config-devices.mak.tmp
  GEN     microblaze-softmmu/config-devices.mak.tmp
  GEN     cris-softmmu/config-devices.mak
  GEN     alpha-softmmu/config-devices.mak
  GEN     mips64el-softmmu/config-devices.mak.tmp
  GEN     mipsel-softmmu/config-devices.mak.tmp
  GEN     ppc64-softmmu/config-devices.mak.tmp
  GEN     sparc64-softmmu/config-devices.mak.tmp
  GEN     sh4eb-softmmu/config-devices.mak.tmp
  GEN     sparc-softmmu/config-devices.mak.tmp
  GEN     tricore-softmmu/config-devices.mak.tmp
  GEN     unicore32-softmmu/config-devices.mak.tmp
  GEN     sh4-softmmu/config-devices.mak.tmp
  GEN     x86_64-softmmu/config-devices.mak.tmp
  GEN     xtensaeb-softmmu/config-devices.mak.tmp
  GEN     xtensa-softmmu/config-devices.mak.tmp
  GEN     aarch64_be-linux-user/config-devices.mak.tmp
  GEN     aarch64-linux-user/config-devices.mak.tmp
  GEN     alpha-linux-user/config-devices.mak.tmp
  GEN     ppcemb-softmmu/config-devices.mak.tmp
  GEN     ppc-softmmu/config-devices.mak.tmp
  GEN     moxie-softmmu/config-devices.mak.tmp
  GEN     sparc-softmmu/config-devices.mak
  GEN     mips-softmmu/config-devices.mak.tmp
  GEN     or1k-softmmu/config-devices.mak.tmp
  GEN     nios2-softmmu/config-devices.mak.tmp
  GEN     mips64-softmmu/config-devices.mak.tmp
  GEN     s390x-softmmu/config-devices.mak.tmp
  GEN     arm-softmmu/config-devices.mak
  GEN     microblaze-softmmu/config-devices.mak
  GEN     lm32-softmmu/config-devices.mak
  GEN     tricore-softmmu/config-devices.mak
  GEN     armeb-linux-user/config-devices.mak.tmp
  GEN     sparc64-softmmu/config-devices.mak
  GEN     arm-linux-user/config-devices.mak.tmp
  GEN     cris-linux-user/config-devices.mak.tmp
  GEN     hppa-linux-user/config-devices.mak.tmp
  GEN     i386-linux-user/config-devices.mak.tmp
  GEN     m68k-linux-user/config-devices.mak.tmp
  GEN     microblazeel-linux-user/config-devices.mak.tmp
  GEN     nios2-softmmu/config-devices.mak
  GEN     x86_64-softmmu/config-devices.mak
  GEN     m68k-softmmu/config-devices.mak
  GEN     aarch64-linux-user/config-devices.mak
  GEN     aarch64-softmmu/config-devices.mak
  GEN     i386-softmmu/config-devices.mak
  GEN     or1k-softmmu/config-devices.mak
  GEN     xtensaeb-softmmu/config-devices.mak
  GEN     sh4-softmmu/config-devices.mak
  GEN     unicore32-softmmu/config-devices.mak
  GEN     s390x-softmmu/config-devices.mak
  GEN     xtensa-softmmu/config-devices.mak
  GEN     alpha-linux-user/config-devices.mak
  GEN     sh4eb-softmmu/config-devices.mak
  GEN     moxie-softmmu/config-devices.mak
  GEN     i386-linux-user/config-devices.mak
  GEN     microblaze-linux-user/config-devices.mak.tmp
  GEN     mips64el-linux-user/config-devices.mak.tmp
  GEN     mips-linux-user/config-devices.mak.tmp
  GEN     mipsel-linux-user/config-devices.mak.tmp
  GEN     mips64-linux-user/config-devices.mak.tmp
  GEN     mipsn32el-linux-user/config-devices.mak.tmp
  GEN     nios2-linux-user/config-devices.mak.tmp
  GEN     hppa-softmmu/config-devices.mak
  GEN     or1k-linux-user/config-devices.mak.tmp
  GEN     ppc64abi32-linux-user/config-devices.mak.tmp
  GEN     ppc64le-linux-user/config-devices.mak.tmp
  GEN     ppc64-linux-user/config-devices.mak.tmp
  GEN     s390x-linux-user/config-devices.mak.tmp
  GEN     ppc-linux-user/config-devices.mak.tmp
  GEN     mipsn32-linux-user/config-devices.mak.tmp
  GEN     mips-softmmu/config-devices.mak
  GEN     sh4eb-linux-user/config-devices.mak.tmp
  GEN     armeb-linux-user/config-devices.mak
  GEN     aarch64_be-linux-user/config-devices.mak
  GEN     ppcemb-softmmu/config-devices.mak
  GEN     microblazeel-softmmu/config-devices.mak
  GEN     hppa-linux-user/config-devices.mak
  GEN     mips-linux-user/config-devices.mak
  GEN     ppc64le-linux-user/config-devices.mak
  GEN     mips64el-linux-user/config-devices.mak
  GEN     ppc-linux-user/config-devices.mak
  GEN     sh4-linux-user/config-devices.mak.tmp
  GEN     sparc32plus-linux-user/config-devices.mak.tmp
  GEN     ppc64abi32-linux-user/config-devices.mak
  GEN     mipsel-softmmu/config-devices.mak
  GEN     sparc64-linux-user/config-devices.mak.tmp
  GEN     nios2-linux-user/config-devices.mak
  GEN     mips64el-softmmu/config-devices.mak
  GEN     microblazeel-linux-user/config-devices.mak
  GEN     cris-linux-user/config-devices.mak
  GEN     ppc64-softmmu/config-devices.mak
  GEN     microblaze-linux-user/config-devices.mak
  GEN     mipsn32el-linux-user/config-devices.mak
  GEN     mips64-linux-user/config-devices.mak
  GEN     sparc-linux-user/config-devices.mak.tmp
  GEN     or1k-linux-user/config-devices.mak
  GEN     ppc64-linux-user/config-devices.mak
  GEN     tilegx-linux-user/config-devices.mak.tmp
  GEN     x86_64-linux-user/config-devices.mak.tmp
  GEN     arm-linux-user/config-devices.mak
  GEN     config-host.h
  GIT     ui/keycodemapdb dtc capstone
  GEN     ppc-softmmu/config-devices.mak
  GEN     sh4-linux-user/config-devices.mak
  GEN     qemu-options.def
  GEN     mips64-softmmu/config-devices.mak
  GEN     m68k-linux-user/config-devices.mak
  GEN     s390x-linux-user/config-devices.mak
  GEN     mipsn32-linux-user/config-devices.mak
  GEN     mipsel-linux-user/config-devices.mak
  GEN     sparc32plus-linux-user/config-devices.mak
  GEN     sh4eb-linux-user/config-devices.mak
  GEN     sparc64-linux-user/config-devices.mak
  GEN     sparc-linux-user/config-devices.mak
  GEN     tilegx-linux-user/config-devices.mak
  GEN     qmp-commands.h
  GEN     x86_64-linux-user/config-devices.mak
  GEN     qapi-types.h
  GEN     qapi-visit.h
  GEN     qapi-event.h
  GEN     qmp-marshal.c
  GEN     qapi-types.c
  GEN     qapi-visit.c
  GEN     qapi-event.c
  GEN     qmp-introspect.c
  GEN     qmp-introspect.h
  GEN     trace/generated-tcg-tracers.h
  GEN     trace/generated-helpers-wrappers.h
  GEN     trace/generated-helpers.c
  GEN     module_block.h
  GEN     trace/generated-helpers.h
  GEN     tests/test-qapi-types.h
  GEN     tests/test-qapi-visit.h
  GEN     tests/test-qmp-commands.h
  GEN     tests/test-qapi-event.h
  GEN     tests/test-qmp-introspect.h
  GEN     trace-root.h
  GEN     util/trace.h
  GEN     crypto/trace.h
  GEN     io/trace.h
  GEN     migration/trace.h
  GEN     block/trace.h
  GEN     chardev/trace.h
  GEN     hw/block/trace.h
  GEN     hw/block/dataplane/trace.h
  GEN     hw/char/trace.h
  GEN     hw/intc/trace.h
  GEN     hw/net/trace.h
  GEN     hw/rdma/trace.h
  GEN     hw/rdma/vmw/trace.h
  GEN     hw/virtio/trace.h
  GEN     hw/audio/trace.h
  GEN     hw/misc/trace.h
  GEN     hw/misc/macio/trace.h
  GEN     hw/usb/trace.h
  GEN     hw/scsi/trace.h
  GEN     hw/nvram/trace.h
  GEN     hw/display/trace.h
  GEN     hw/input/trace.h
  GEN     hw/timer/trace.h
  GEN     hw/dma/trace.h
  GEN     hw/sparc/trace.h
  GEN     hw/sparc64/trace.h
  GEN     hw/sd/trace.h
  GEN     hw/isa/trace.h
  GEN     hw/mem/trace.h
  GEN     hw/i386/trace.h
  GEN     hw/i386/xen/trace.h
  GEN     hw/9pfs/trace.h
  GEN     hw/ppc/trace.h
  GEN     hw/pci/trace.h
  GEN     hw/pci-host/trace.h
  GEN     hw/s390x/trace.h
  GEN     hw/vfio/trace.h
  GEN     hw/acpi/trace.h
  GEN     hw/arm/trace.h
  GEN     hw/alpha/trace.h
  GEN     hw/hppa/trace.h
  GEN     hw/xen/trace.h
  GEN     hw/ide/trace.h
  GEN     ui/trace.h
  GEN     audio/trace.h
  GEN     net/trace.h
  GEN     target/arm/trace.h
  GEN     target/i386/trace.h
  GEN     target/mips/trace.h
  GEN     target/sparc/trace.h
  GEN     target/s390x/trace.h
  GEN     target/ppc/trace.h
  GEN     qom/trace.h
  GEN     linux-user/trace.h
  GEN     qapi/trace.h
  GEN     accel/tcg/trace.h
  GEN     accel/kvm/trace.h
  GEN     nbd/trace.h
  GEN     scsi/trace.h
  GEN     trace-root.c
  GEN     util/trace.c
  GEN     crypto/trace.c
  GEN     io/trace.c
  GEN     migration/trace.c
  GEN     block/trace.c
  GEN     chardev/trace.c
  GEN     hw/block/trace.c
  GEN     hw/block/dataplane/trace.c
  GEN     hw/char/trace.c
  GEN     hw/intc/trace.c
  GEN     hw/net/trace.c
  GEN     hw/rdma/trace.c
  GEN     hw/rdma/vmw/trace.c
  GEN     hw/virtio/trace.c
  GEN     hw/audio/trace.c
  GEN     hw/misc/trace.c
  GEN     hw/misc/macio/trace.c
  GEN     hw/usb/trace.c
  GEN     hw/scsi/trace.c
  GEN     hw/nvram/trace.c
  GEN     hw/display/trace.c
  GEN     hw/input/trace.c
  GEN     hw/timer/trace.c
  GEN     hw/dma/trace.c
  GEN     hw/sparc/trace.c
  GEN     hw/sparc64/trace.c
  GEN     hw/sd/trace.c
  GEN     hw/isa/trace.c
  GEN     hw/mem/trace.c
  GEN     hw/i386/trace.c
  GEN     hw/i386/xen/trace.c
  GEN     hw/9pfs/trace.c
  GEN     hw/ppc/trace.c
  GEN     hw/pci/trace.c
  GEN     hw/pci-host/trace.c
  GEN     hw/s390x/trace.c
  GEN     hw/vfio/trace.c
  GEN     hw/acpi/trace.c
  GEN     hw/arm/trace.c
  GEN     hw/alpha/trace.c
  GEN     hw/hppa/trace.c
  GEN     hw/xen/trace.c
  GEN     hw/ide/trace.c
  GEN     ui/trace.c
  GEN     audio/trace.c
  GEN     net/trace.c
  GEN     target/arm/trace.c
  GEN     target/i386/trace.c
  GEN     target/mips/trace.c
  GEN     target/sparc/trace.c
  GEN     target/s390x/trace.c
  GEN     target/ppc/trace.c
  GEN     qom/trace.c
  GEN     linux-user/trace.c
  GEN     qapi/trace.c
  GEN     accel/tcg/trace.c
  GEN     accel/kvm/trace.c
  GEN     nbd/trace.c
  GEN     scsi/trace.c
  GEN     config-all-devices.mak
mkdir -p dtc/libfdt
mkdir -p dtc/tests
  GEN     ui/input-keymap-atset1-to-qcode.c
  GEN     ui/input-keymap-linux-to-qcode.c
  GEN     ui/input-keymap-qcode-to-atset1.c
  GEN     ui/input-keymap-qcode-to-atset2.c
  GEN     ui/input-keymap-qcode-to-atset3.c
  GEN     ui/input-keymap-qcode-to-linux.c
  GEN     ui/input-keymap-qcode-to-sun.c
  GEN     ui/input-keymap-qcode-to-qnum.c
  CC      cs.o
  GEN     ui/input-keymap-qnum-to-qcode.c
  GEN     ui/input-keymap-usb-to-qcode.c
  GEN     ui/input-keymap-win32-to-qcode.c
  CC      utils.o
  GEN     ui/input-keymap-x11-to-qcode.c
  CC      SStream.o
  GEN     ui/input-keymap-xorgevdev-to-qcode.c
  GEN     ui/input-keymap-xorgxquartz-to-qcode.c
  GEN     ui/input-keymap-xorgxwin-to-qcode.c
  GEN     ui/input-keymap-xorgkbd-to-qcode.c
  CC      MCInstrDesc.o
  CC      MCRegisterInfo.o
  CC      arch/ARM/ARMDisassembler.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/dumptrees.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/trees.S
  CC      arch/ARM/ARMModule.o
  CC      arch/ARM/ARMMapping.o
  CC      arch/ARM/ARMInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/testutils.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/asm_tree_dump.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/value-labels.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/truncated_property.c
  CC      arch/AArch64/AArch64BaseInfo.o
  CC      arch/AArch64/AArch64Disassembler.o
  CC      arch/AArch64/AArch64InstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/check_path.c
  CC      arch/AArch64/AArch64Mapping.o
  CC      arch/AArch64/AArch64Module.o
  CC      arch/Mips/MipsDisassembler.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/overlay_bad_fixup.c
  CC      arch/Mips/MipsInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/overlay.c
  CC      arch/Mips/MipsMapping.o
  CC      arch/Mips/MipsModule.o
  CC      arch/PowerPC/PPCDisassembler.o
  CC      arch/PowerPC/PPCInstPrinter.o
  CC      arch/PowerPC/PPCMapping.o
  CC      arch/Sparc/SparcMapping.o
  CC      arch/Sparc/SparcInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/subnode_iterate.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/property_iterate.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/integer-expressions.c
  CC      arch/Sparc/SparcDisassembler.o
  CC      arch/Sparc/SparcModule.o
  CC      arch/PowerPC/PPCModule.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/utilfdt_test.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/path_offset_aliases.c
  CC      arch/SystemZ/SystemZDisassembler.o
  CC      arch/SystemZ/SystemZInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/add_subnode_with_nops.c
  CC      arch/SystemZ/SystemZMapping.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/dtbs_equal_unordered.c
  CC      arch/SystemZ/SystemZModule.o
  CC      arch/SystemZ/SystemZMCTargetDesc.o
  CC      arch/X86/X86DisassemblerDecoder.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/dtb_reverse.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/dtbs_equal_ordered.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/references.c
  CC      arch/X86/X86Disassembler.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/extra-terminating-null.c
  CC      arch/X86/X86ATTInstPrinter.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/phandle_format.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/boot-cpuid.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/incbin.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/string_escapes.c
  CC      arch/X86/X86IntelInstPrinter.o
  CC      arch/X86/X86Mapping.o
  CC      arch/X86/X86Module.o
  CC      arch/XCore/XCoreDisassembler.o
  CC      arch/XCore/XCoreInstPrinter.o
  CC      MCInst.o
  CC      arch/XCore/XCoreModule.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/path-references.c
  CC      arch/XCore/XCoreMapping.o
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/propname_escapes.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/appendprop2.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/appendprop1.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/del_node.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/del_property.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/set_name.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/setprop.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/rw_tree1.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/open_pack.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/nopulate.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/mangle-layout.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/move_and_save.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/nop_node.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/nop_property.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/setprop_inplace.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/sw_tree1.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/stringlist.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/addr_size_cells.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/notfound.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/sized_cells.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/get_alias.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/node_offset_by_compatible.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/char_literal.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/node_offset_by_phandle.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/node_offset_by_prop_value.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/node_check_compatible.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/parent_offset.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/supernode_atdepth_offset.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/get_path.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/get_phandle.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/getprop.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/get_name.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/path_offset.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/subnode_offset.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/find_property.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/get_mem_rsv.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_overlay.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/tests/root_node.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_ro.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_empty_tree.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_rw.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_sw.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_wip.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_strerror.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/libfdt/fdt_addresses.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/util.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/fdtput.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/fdtget.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/fdtdump.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/fdtoverlay.c
	 LEX convert-dtsv0-lexer.lex.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/srcpos.c
	 BISON dtc-parser.tab.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/flattree.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/dtc.c
	 LEX dtc-lexer.lex.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/treesource.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/data.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/livetree.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/fstree.c
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/checks.c
	 DEP convert-dtsv0-lexer.lex.c
	 DEP dtc-parser.tab.c
	 DEP dtc-lexer.lex.c
	CHK version_gen.h
	UPD version_gen.h
	 DEP /var/tmp/patchew-tester-tmp-9ukz0kme/src/dtc/util.c
	 CC libfdt/fdt.o
	 CC libfdt/fdt_ro.o
	 CC libfdt/fdt_wip.o
	 CC libfdt/fdt_rw.o
	 CC libfdt/fdt_sw.o
	 CC libfdt/fdt_strerror.o
	 CC libfdt/fdt_empty_tree.o
	 CC libfdt/fdt_addresses.o
	 CC libfdt/fdt_overlay.o
	 AR libfdt/libfdt.a
ar: creating libfdt/libfdt.a
a - libfdt/fdt.o
a - libfdt/fdt_ro.o
a - libfdt/fdt_wip.o
a - libfdt/fdt_sw.o
a - libfdt/fdt_rw.o
a - libfdt/fdt_strerror.o
a - libfdt/fdt_empty_tree.o
a - libfdt/fdt_addresses.o
a - libfdt/fdt_overlay.o
  AR      libcapstone.a
ar: creating /var/tmp/patchew-tester-tmp-9ukz0kme/src/build/capstone/libcapstone.a
mkdir -p dtc/libfdt
mkdir -p dtc/tests
  CC      tests/qemu-iotests/socket_scm_helper.o
  GEN     qga/qapi-generated/qga-qapi-types.h
  GEN     qga/qapi-generated/qga-qapi-visit.h
  GEN     qga/qapi-generated/qga-qmp-commands.h
  GEN     qga/qapi-generated/qga-qapi-types.c
  GEN     qga/qapi-generated/qga-qapi-visit.c
  GEN     qga/qapi-generated/qga-qmp-marshal.c
  CC      qmp-introspect.o
  CC      qapi-types.o
  CC      qapi-visit.o
  CC      qapi-event.o
  CC      qapi/qapi-visit-core.o
  CC      qapi/qapi-dealloc-visitor.o
  CC      qapi/qobject-input-visitor.o
  CC      qapi/qobject-output-visitor.o
  CC      qapi/qmp-registry.o
  CC      qapi/qmp-dispatch.o
  CC      qapi/string-input-visitor.o
  CC      qapi/string-output-visitor.o
  CC      qapi/opts-visitor.o
  CC      qapi/qapi-clone-visitor.o
  CC      qapi/qmp-event.o
  CC      qapi/qapi-util.o
  CC      qobject/qnull.o
  CC      qobject/qnum.o
  CC      qobject/qstring.o
  CC      qobject/qdict.o
  CC      qobject/qlist.o
  CC      qobject/qlit.o
  CC      qobject/qbool.o
  CC      qobject/qjson.o
  CC      qobject/qobject.o
  CC      qobject/json-parser.o
  CC      qobject/json-lexer.o
  CC      qobject/json-streamer.o
  CC      trace/control.o
  CC      trace/qmp.o
  CC      util/osdep.o
  CC      util/cutils.o
  CC      util/unicode.o
  CC      util/qemu-timer-common.o
  CC      util/bufferiszero.o
  CC      util/lockcnt.o
  CC      util/aiocb.o
  CC      util/async.o
  CC      util/thread-pool.o
  CC      util/qemu-timer.o
  CC      util/iohandler.o
  CC      util/main-loop.o
  CC      util/aio-posix.o
  CC      util/compatfd.o
  CC      util/event_notifier-posix.o
  CC      util/oslib-posix.o
  CC      util/qemu-openpty.o
  CC      util/mmap-alloc.o
  CC      util/qemu-thread-posix.o
  CC      util/memfd.o
  CC      util/envlist.o
  CC      util/path.o
  CC      util/module.o
  CC      util/host-utils.o
  CC      util/bitops.o
  CC      util/bitmap.o
  CC      util/hbitmap.o
  CC      util/fifo8.o
  CC      util/acl.o
  CC      util/cacheinfo.o
  CC      util/error.o
  CC      util/qemu-error.o
  CC      util/id.o
  CC      util/iov.o
  CC      util/qemu-config.o
  CC      util/qemu-sockets.o
  CC      util/uri.o
  CC      util/notify.o
  CC      util/qemu-option.o
  CC      util/qemu-progress.o
  CC      util/keyval.o
  CC      util/hexdump.o
  CC      util/crc32c.o
  CC      util/throttle.o
  CC      util/uuid.o
  CC      util/readline.o
  CC      util/getauxval.o
  CC      util/rcu.o
  CC      util/qemu-coroutine.o
  CC      util/qemu-coroutine-lock.o
  CC      util/qemu-coroutine-io.o
  CC      util/qemu-coroutine-sleep.o
  CC      util/coroutine-ucontext.o
  CC      util/buffer.o
  CC      util/timed-average.o
  CC      util/log.o
  CC      util/base64.o
  CC      util/pagesize.o
  CC      util/qdist.o
  CC      util/qht.o
  CC      util/range.o
  CC      util/stats64.o
  CC      util/systemd.o
  CC      util/vfio-helpers.o
  CC      trace-root.o
  CC      util/trace.o
  CC      crypto/trace.o
  CC      io/trace.o
  CC      migration/trace.o
  CC      block/trace.o
  CC      chardev/trace.o
  CC      hw/block/trace.o
  CC      hw/block/dataplane/trace.o
  CC      hw/char/trace.o
  CC      hw/intc/trace.o
  CC      hw/net/trace.o
  CC      hw/rdma/trace.o
  CC      hw/rdma/vmw/trace.o
  CC      hw/virtio/trace.o
  CC      hw/audio/trace.o
  CC      hw/misc/trace.o
  CC      hw/misc/macio/trace.o
  CC      hw/scsi/trace.o
  CC      hw/usb/trace.o
  CC      hw/nvram/trace.o
  CC      hw/display/trace.o
  CC      hw/input/trace.o
  CC      hw/timer/trace.o
  CC      hw/dma/trace.o
  CC      hw/sparc/trace.o
  CC      hw/sparc64/trace.o
  CC      hw/isa/trace.o
  CC      hw/sd/trace.o
  CC      hw/i386/trace.o
  CC      hw/mem/trace.o
  CC      hw/i386/xen/trace.o
  CC      hw/ppc/trace.o
  CC      hw/9pfs/trace.o
  CC      hw/pci/trace.o
  CC      hw/pci-host/trace.o
  CC      hw/s390x/trace.o
  CC      hw/vfio/trace.o
  CC      hw/acpi/trace.o
  CC      hw/arm/trace.o
  CC      hw/alpha/trace.o
  CC      hw/hppa/trace.o
  CC      hw/ide/trace.o
  CC      hw/xen/trace.o
  CC      ui/trace.o
  CC      audio/trace.o
  CC      net/trace.o
  CC      target/i386/trace.o
  CC      target/arm/trace.o
  CC      target/mips/trace.o
  CC      target/sparc/trace.o
  CC      target/s390x/trace.o
  CC      target/ppc/trace.o
  CC      qom/trace.o
  CC      accel/tcg/trace.o
  CC      qapi/trace.o
  CC      linux-user/trace.o
  CC      accel/kvm/trace.o
  CC      nbd/trace.o
  CC      scsi/trace.o
  CC      crypto/pbkdf-stub.o
  CC      stubs/arch-query-cpu-def.o
  CC      stubs/arch-query-cpu-model-expansion.o
  CC      stubs/arch-query-cpu-model-comparison.o
  CC      stubs/arch-query-cpu-model-baseline.o
  CC      stubs/bdrv-next-monitor-owned.o
  CC      stubs/blk-commit-all.o
  CC      stubs/blockdev-close-all-bdrv-states.o
  CC      stubs/clock-warp.o
  CC      stubs/cpu-get-clock.o
  CC      stubs/cpu-get-icount.o
  CC      stubs/error-printf.o
  CC      stubs/dump.o
  CC      stubs/fdset.o
  CC      stubs/gdbstub.o
  CC      stubs/get-vm-name.o
  CC      stubs/iothread.o
  CC      stubs/iothread-lock.o
  CC      stubs/is-daemonized.o
  CC      stubs/linux-aio.o
  CC      stubs/machine-init-done.o
  CC      stubs/migr-blocker.o
  CC      stubs/change-state-handler.o
  CC      stubs/monitor.o
  CC      stubs/notify-event.o
  CC      stubs/qtest.o
  CC      stubs/replay.o
  CC      stubs/runstate-check.o
  CC      stubs/set-fd-handler.o
  CC      stubs/slirp.o
  CC      stubs/sysbus.o
  CC      stubs/tpm.o
  CC      stubs/trace-control.o
  CC      stubs/uuid.o
  CC      stubs/vmstate.o
  CC      stubs/vm-stop.o
  CC      stubs/qmp_pc_dimm.o
  CC      stubs/target-monitor-defs.o
  CC      stubs/target-get-monitor-def.o
  CC      stubs/pc_madt_cpu_entry.o
  CC      stubs/vmgenid.o
  CC      stubs/xen-common.o
  CC      stubs/xen-hvm.o
  CC      stubs/pci-host-piix.o
  CC      stubs/ram-block.o
  CC      contrib/ivshmem-client/ivshmem-client.o
  CC      contrib/ivshmem-client/main.o
  CC      contrib/ivshmem-server/ivshmem-server.o
  CC      contrib/ivshmem-server/main.o
  CC      qemu-nbd.o
  CC      block.o
  CC      qemu-io-cmds.o
  CC      blockjob.o
  CC      replication.o
  CC      block/raw-format.o
  CC      block/qcow.o
  CC      block/vdi.o
  CC      block/bochs.o
  CC      block/cloop.o
  CC      block/vmdk.o
  CC      block/vpc.o
  CC      block/vvfat.o
  CC      block/dmg.o
  CC      block/qcow2.o
  CC      block/qcow2-cluster.o
  CC      block/qcow2-refcount.o
  CC      block/qcow2-snapshot.o
  CC      block/qcow2-cache.o
  CC      block/qcow2-bitmap.o
  CC      block/qed.o
  CC      block/qed-l2-cache.o
  CC      block/qed-table.o
  CC      block/qed-cluster.o
  CC      block/qed-check.o
  CC      block/vhdx.o
  CC      block/vhdx-endian.o
  CC      block/vhdx-log.o
  CC      block/quorum.o
  CC      block/parallels.o
  CC      block/blkdebug.o
  CC      block/blkverify.o
  CC      block/block-backend.o
  CC      block/blkreplay.o
  CC      block/snapshot.o
  CC      block/qapi.o
  CC      block/file-posix.o
  CC      block/null.o
  CC      block/linux-aio.o
  CC      block/mirror.o
  CC      block/commit.o
  CC      block/io.o
  CC      block/throttle-groups.o
  CC      block/nvme.o
  CC      block/nbd.o
  CC      block/nbd-client.o
  CC      block/sheepdog.o
  CC      block/accounting.o
  CC      block/dirty-bitmap.o
  CC      block/write-threshold.o
  CC      block/backup.o
  CC      block/replication.o
  CC      block/throttle.o
  CC      block/crypto.o
  CC      nbd/server.o
  CC      nbd/client.o
  CC      nbd/common.o
  CC      scsi/utils.o
  CC      scsi/pr-manager.o
  CC      scsi/pr-manager-helper.o
  CC      block/curl.o
  CC      block/dmg-bz2.o
  CC      crypto/init.o
  CC      crypto/hash.o
  CC      crypto/hash-nettle.o
  CC      crypto/hmac.o
  CC      crypto/hmac-nettle.o
  CC      crypto/aes.o
  CC      crypto/desrfb.o
  CC      crypto/cipher.o
  CC      crypto/tlscreds.o
  CC      crypto/tlscredsanon.o
  CC      crypto/tlscredsx509.o
  CC      crypto/tlssession.o
  CC      crypto/secret.o
  CC      crypto/random-gnutls.o
  CC      crypto/pbkdf.o
  CC      crypto/pbkdf-nettle.o
  CC      crypto/ivgen.o
  CC      crypto/ivgen-essiv.o
  CC      crypto/ivgen-plain.o
  CC      crypto/ivgen-plain64.o
  CC      crypto/afsplit.o
  CC      crypto/xts.o
  CC      crypto/block.o
  CC      crypto/block-qcow.o
  CC      crypto/block-luks.o
  CC      io/channel.o
  CC      io/channel-buffer.o
  CC      io/channel-command.o
  CC      io/channel-file.o
  CC      io/channel-socket.o
  CC      io/channel-tls.o
  CC      io/channel-watch.o
  CC      io/channel-websock.o
  CC      io/channel-util.o
  CC      io/dns-resolver.o
  CC      io/net-listener.o
  CC      io/task.o
  CC      qom/object.o
  CC      qom/container.o
  CC      qom/qom-qobject.o
  CC      qom/object_interfaces.o
  GEN     qemu-img-cmds.h
  CC      qemu-io.o
  CC      fsdev/virtfs-proxy-helper.o
  CC      fsdev/9p-marshal.o
  CC      fsdev/9p-iov-marshal.o
  CC      scsi/qemu-pr-helper.o
/var/tmp/patchew-tester-tmp-9ukz0kme/src/blockjob.c: In function ‘block_job_txn_apply.isra.8’:
/var/tmp/patchew-tester-tmp-9ukz0kme/src/blockjob.c:511:5: error: ‘rc’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
     return rc;
     ^
  CC      qemu-bridge-helper.o
  CC      blockdev.o
  CC      blockdev-nbd.o
  CC      bootdevice.o
  CC      iothread.o
  CC      qdev-monitor.o
  CC      device-hotplug.o
  CC      os-posix.o
  CC      bt-host.o
  CC      bt-vhci.o
  CC      dma-helpers.o
  CC      vl.o
  CC      tpm.o
  CC      device_tree.o
  CC      qmp-marshal.o
  CC      qmp.o
  CC      hmp.o
  CC      cpus-common.o
  CC      audio/audio.o
cc1: all warnings being treated as errors
make: *** [blockjob.o] Error 1
make: *** Waiting for unfinished jobs....
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table John Snow
@ 2018-02-27 16:27   ` Kevin Wolf
  2018-02-27 16:45     ` John Snow
  2018-02-27 18:58   ` Eric Blake
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 16:27 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> The state transition table has mostly been implied. We're about to make
> it a bit more complex, so let's make the STM explicit instead.
> 
> Perform state transitions with a function that for now just asserts the
> transition is appropriate.
> 
> Transitions:
> Undefined -> Created: During job initialization.
> Created   -> Running: Once the job is started.
>                       Jobs cannot transition from "Created" to "Paused"
>                       directly, but will instead synchronously transition
>                       to running to paused immediately.
> Running   -> Paused:  Normal workflow for pauses.
> Running   -> Ready:   Normal workflow for jobs reaching their sync point.
>                       (e.g. mirror)
> Ready     -> Standby: Normal workflow for pausing ready jobs.
> Paused    -> Running: Normal resume.
> Standby   -> Ready:   Resume of a Standby job.
> 
> 
> +---------+
> |UNDEFINED|
> +--+------+
>    |
> +--v----+
> |CREATED|
> +--+----+
>    |
> +--v----+     +------+
> |RUNNING<----->PAUSED|
> +--+----+     +------+
>    |
> +--v--+       +-------+
> |READY<------->STANDBY|
> +-----+       +-------+
> 
> 
> Notably, there is no state presently defined as of this commit that
> deals with a job after the "running" or "ready" states, so this table
> will be adjusted alongside the commits that introduce those states.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  block/trace-events |  3 +++
>  blockjob.c         | 42 ++++++++++++++++++++++++++++++++++++------
>  2 files changed, 39 insertions(+), 6 deletions(-)
> 
> diff --git a/block/trace-events b/block/trace-events
> index 02dd80ff0c..b75a0c8409 100644
> --- a/block/trace-events
> +++ b/block/trace-events
> @@ -4,6 +4,9 @@
>  bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags 0x%x format_name \"%s\""
>  bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
>  
> +# blockjob.c
> +block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
> +
>  # block/block-backend.c
>  blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
>  blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
> diff --git a/blockjob.c b/blockjob.c
> index 1be9c20cff..d745b3bb69 100644
> --- a/blockjob.c
> +++ b/blockjob.c
> @@ -28,6 +28,7 @@
>  #include "block/block.h"
>  #include "block/blockjob_int.h"
>  #include "block/block_int.h"
> +#include "block/trace.h"
>  #include "sysemu/block-backend.h"
>  #include "qapi/error.h"
>  #include "qapi/qmp/qerror.h"
> @@ -41,6 +42,34 @@
>   * block_job_enter. */
>  static QemuMutex block_job_mutex;
>  
> +/* BlockJob State Transition Table */
> +bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
> +                                          /* U, C, R, P, Y, S */
> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},

Even at the end of the series, this is the only use of
BLOCK_JOB_STATUS_UNDEFINED.

> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},
> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},
> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},
> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},
> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
> +};
> +
> +static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
> +{
> +    BlockJobStatus s0 = job->status;
> +    if (s0 == s1) {
> +        return;
> +    }
> +    assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
> +    trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
> +                                     "allowed" : "disallowed",
> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
> +                                                      s0),
> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
> +                                                      s1));
> +    assert(BlockJobSTT[s0][s1]);
> +    job->status = s1;
> +}
> +
>  static void block_job_lock(void)
>  {
>      qemu_mutex_lock(&block_job_mutex);
> @@ -320,7 +349,7 @@ void block_job_start(BlockJob *job)
>      job->pause_count--;
>      job->busy = true;
>      job->paused = false;
> -    job->status = BLOCK_JOB_STATUS_RUNNING;
> +    block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
>      bdrv_coroutine_enter(blk_bs(job->blk), job->co);
>  }
>  
> @@ -704,6 +733,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
>      job->refcnt        = 1;
>      job->manual        = (flags & BLOCK_JOB_MANUAL);
>      job->status        = BLOCK_JOB_STATUS_CREATED;
> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);

So did you intend to start with BLOCK_JOB_STATUS_UNDEFINED and then
transition to BLOCK_JOB_STATUS_CREATED?

Or should we completely remove BLOCK_JOB_STATUS_UNDEFINED, keep the
initialisation and not call block_job_state_transition() here?

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick John Snow
@ 2018-02-27 16:32   ` Eric Blake
  2018-02-27 17:18   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 16:32 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> If speed is '0' it's not actually "less than" the previous speed.
> Kick the job in this case too.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   blockjob.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

> 
> diff --git a/blockjob.c b/blockjob.c
> index 3f52f29f75..24833ef30f 100644
> --- a/blockjob.c
> +++ b/blockjob.c
> @@ -499,7 +499,7 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
>       }
>   
>       job->speed = speed;
> -    if (speed <= old_speed) {
> +    if (speed && speed <= old_speed) {
>           return;
>       }
>   
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions John Snow
@ 2018-02-27 16:36   ` Eric Blake
  2018-02-27 17:18   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 16:36 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> model all independent jobs as single job transactions.
> 
> It's one less case we have to worry about when we add more states to the
> transition machine. This way, we can just treat all job lifetimes exactly
> the same. This helps tighten assertions of the STM graph and removes some
> conditionals that would have been needed in the coming commits adding a
> more explicit job lifetime management API.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---

Reviewed-by: Eric Blake <eblake@redhat.com>

> @@ -729,6 +727,17 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
>               return NULL;
>           }
>       }
> +
> +    /* Single jobs are modeled as single-job transactions for sake of
> +     * consolidating the job management logic */
> +    if (!txn) {
> +        txn = block_job_txn_new();
> +        block_job_txn_add_job(txn, job);
> +        block_job_txn_unref(txn);
> +    } else {
> +        block_job_txn_add_job(txn, job);
> +    }
> +
>       return job;

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property John Snow
@ 2018-02-27 16:39   ` Eric Blake
  2018-02-27 17:18   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 16:39 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> This property will be used to opt-in to the new BlockJobs workflow
> that allows a tighter, more explicit control over transitions from
> one runstate to another.
> 
> While we're here, fix up the documentation for block_job_create
> a little bit.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   blockjob.c                   |  1 +
>   include/block/blockjob.h     | 10 ++++++++++
>   include/block/blockjob_int.h |  4 +++-
>   3 files changed, 14 insertions(+), 1 deletion(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum John Snow
@ 2018-02-27 16:44   ` Eric Blake
  2018-02-27 17:19   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 16:44 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> We're about to add several new states, and booleans are becoming
> unwieldly and difficult to reason about. It would help to have a
> more explicit bookkeeping of the state of blockjobs. To this end,
> add a new "status" field and add our existing states in a redundant
> manner alongside the bools they are replacing:
> 

> Some of these states appear somewhat superfluous, but it helps define the
> expected flow of a job; so some of the states wind up being synchronous
> empty transitions. Importantly, jobs can be in only one of these states
> at any given time, which helps code and external users alike reason about
> the current condition of a job unambiguously.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---

> +++ b/qapi/block-core.json
> @@ -955,6 +955,32 @@
>   { 'enum': 'BlockJobType',
>     'data': ['commit', 'stream', 'mirror', 'backup'] }
>   
> +##
> +# @BlockJobStatus:
> +#
> +# Indicates the present state of a given blockjob in its lifetime.
> +#
> +# @undefined: Erroneous, default state. Should not ever be visible.
> +#
> +# @created: The job has been created, but not yet started.
> +#
> +# @running: The job is currently running.
> +#
> +# @paused: The job is running, but paused. The pause may be requested by
> +#          either the QMP user or by internal processes.
> +#
> +# @ready: The job is running, but is ready for the user to signal completion.
> +#         This is used for long-running jobs like mirror that are designed to
> +#         run indefinitely.
> +#
> +# @standby: The job is ready, but paused. This is nearly identical to @paused.
> +#           The job may return to @ready or otherwise be canceled.
> +#
> +# Since: 2.12
> +##
> +{ 'enum': 'BlockJobStatus',
> +  'data': ['undefined', 'created', 'running', 'paused', 'ready', 'standby'] }

Do we need 'undefined' in the list if it should never be visible?  I'm 
okay if you keep it because it makes other code easier, but as Kevin 
points out in 5/21, if you aren't even using it, it might be worth 
considering dropping the state altogether.

Otherwise, the patch looks fine to me.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-27 16:27   ` Kevin Wolf
@ 2018-02-27 16:45     ` John Snow
  2018-02-27 17:08       ` Kevin Wolf
  0 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-27 16:45 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-block, pkrempa, jtc, qemu-devel



On 02/27/2018 11:27 AM, Kevin Wolf wrote:
> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>> The state transition table has mostly been implied. We're about to make
>> it a bit more complex, so let's make the STM explicit instead.
>>
>> Perform state transitions with a function that for now just asserts the
>> transition is appropriate.
>>
>> Transitions:
>> Undefined -> Created: During job initialization.
>> Created   -> Running: Once the job is started.
>>                       Jobs cannot transition from "Created" to "Paused"
>>                       directly, but will instead synchronously transition
>>                       to running to paused immediately.
>> Running   -> Paused:  Normal workflow for pauses.
>> Running   -> Ready:   Normal workflow for jobs reaching their sync point.
>>                       (e.g. mirror)
>> Ready     -> Standby: Normal workflow for pausing ready jobs.
>> Paused    -> Running: Normal resume.
>> Standby   -> Ready:   Resume of a Standby job.
>>
>>
>> +---------+
>> |UNDEFINED|
>> +--+------+
>>    |
>> +--v----+
>> |CREATED|
>> +--+----+
>>    |
>> +--v----+     +------+
>> |RUNNING<----->PAUSED|
>> +--+----+     +------+
>>    |
>> +--v--+       +-------+
>> |READY<------->STANDBY|
>> +-----+       +-------+
>>
>>
>> Notably, there is no state presently defined as of this commit that
>> deals with a job after the "running" or "ready" states, so this table
>> will be adjusted alongside the commits that introduce those states.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>  block/trace-events |  3 +++
>>  blockjob.c         | 42 ++++++++++++++++++++++++++++++++++++------
>>  2 files changed, 39 insertions(+), 6 deletions(-)
>>
>> diff --git a/block/trace-events b/block/trace-events
>> index 02dd80ff0c..b75a0c8409 100644
>> --- a/block/trace-events
>> +++ b/block/trace-events
>> @@ -4,6 +4,9 @@
>>  bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags 0x%x format_name \"%s\""
>>  bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
>>  
>> +# blockjob.c
>> +block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
>> +
>>  # block/block-backend.c
>>  blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
>>  blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
>> diff --git a/blockjob.c b/blockjob.c
>> index 1be9c20cff..d745b3bb69 100644
>> --- a/blockjob.c
>> +++ b/blockjob.c
>> @@ -28,6 +28,7 @@
>>  #include "block/block.h"
>>  #include "block/blockjob_int.h"
>>  #include "block/block_int.h"
>> +#include "block/trace.h"
>>  #include "sysemu/block-backend.h"
>>  #include "qapi/error.h"
>>  #include "qapi/qmp/qerror.h"
>> @@ -41,6 +42,34 @@
>>   * block_job_enter. */
>>  static QemuMutex block_job_mutex;
>>  
>> +/* BlockJob State Transition Table */
>> +bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
>> +                                          /* U, C, R, P, Y, S */
>> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},
> 
> Even at the end of the series, this is the only use of
> BLOCK_JOB_STATUS_UNDEFINED.
> 
>> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},
>> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},
>> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},
>> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},
>> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
>> +};
>> +
>> +static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
>> +{
>> +    BlockJobStatus s0 = job->status;
>> +    if (s0 == s1) {
>> +        return;
>> +    }
>> +    assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
>> +    trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
>> +                                     "allowed" : "disallowed",
>> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
>> +                                                      s0),
>> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
>> +                                                      s1));
>> +    assert(BlockJobSTT[s0][s1]);
>> +    job->status = s1;
>> +}
>> +
>>  static void block_job_lock(void)
>>  {
>>      qemu_mutex_lock(&block_job_mutex);
>> @@ -320,7 +349,7 @@ void block_job_start(BlockJob *job)
>>      job->pause_count--;
>>      job->busy = true;
>>      job->paused = false;
>> -    job->status = BLOCK_JOB_STATUS_RUNNING;
>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
>>      bdrv_coroutine_enter(blk_bs(job->blk), job->co);
>>  }
>>  
>> @@ -704,6 +733,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
>>      job->refcnt        = 1;
>>      job->manual        = (flags & BLOCK_JOB_MANUAL);
>>      job->status        = BLOCK_JOB_STATUS_CREATED;
>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
> 
> So did you intend to start with BLOCK_JOB_STATUS_UNDEFINED and then
> transition to BLOCK_JOB_STATUS_CREATED?
> 
> Or should we completely remove BLOCK_JOB_STATUS_UNDEFINED, keep the
> initialisation and not call block_job_state_transition() here?
> 
> Kevin
> 

We can do that;

I had it start as "Undefined" because I liked how a g_new0() object will
default to that state, so it felt "safe."

On the negatives, it does mean that technically you COULD witness a job
in this state if QEMU did something wrong, which would be confusing
because you wouldn't be able to fix it via QMP.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-27 16:45     ` John Snow
@ 2018-02-27 17:08       ` Kevin Wolf
  2018-02-27 18:58         ` John Snow
  0 siblings, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 17:08 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 27.02.2018 um 17:45 hat John Snow geschrieben:
> 
> 
> On 02/27/2018 11:27 AM, Kevin Wolf wrote:
> > Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> >> The state transition table has mostly been implied. We're about to make
> >> it a bit more complex, so let's make the STM explicit instead.
> >>
> >> Perform state transitions with a function that for now just asserts the
> >> transition is appropriate.
> >>
> >> Transitions:
> >> Undefined -> Created: During job initialization.
> >> Created   -> Running: Once the job is started.
> >>                       Jobs cannot transition from "Created" to "Paused"
> >>                       directly, but will instead synchronously transition
> >>                       to running to paused immediately.
> >> Running   -> Paused:  Normal workflow for pauses.
> >> Running   -> Ready:   Normal workflow for jobs reaching their sync point.
> >>                       (e.g. mirror)
> >> Ready     -> Standby: Normal workflow for pausing ready jobs.
> >> Paused    -> Running: Normal resume.
> >> Standby   -> Ready:   Resume of a Standby job.
> >>
> >>
> >> +---------+
> >> |UNDEFINED|
> >> +--+------+
> >>    |
> >> +--v----+
> >> |CREATED|
> >> +--+----+
> >>    |
> >> +--v----+     +------+
> >> |RUNNING<----->PAUSED|
> >> +--+----+     +------+
> >>    |
> >> +--v--+       +-------+
> >> |READY<------->STANDBY|
> >> +-----+       +-------+
> >>
> >>
> >> Notably, there is no state presently defined as of this commit that
> >> deals with a job after the "running" or "ready" states, so this table
> >> will be adjusted alongside the commits that introduce those states.
> >>
> >> Signed-off-by: John Snow <jsnow@redhat.com>
> >> ---
> >>  block/trace-events |  3 +++
> >>  blockjob.c         | 42 ++++++++++++++++++++++++++++++++++++------
> >>  2 files changed, 39 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/block/trace-events b/block/trace-events
> >> index 02dd80ff0c..b75a0c8409 100644
> >> --- a/block/trace-events
> >> +++ b/block/trace-events
> >> @@ -4,6 +4,9 @@
> >>  bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags 0x%x format_name \"%s\""
> >>  bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
> >>  
> >> +# blockjob.c
> >> +block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
> >> +
> >>  # block/block-backend.c
> >>  blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
> >>  blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
> >> diff --git a/blockjob.c b/blockjob.c
> >> index 1be9c20cff..d745b3bb69 100644
> >> --- a/blockjob.c
> >> +++ b/blockjob.c
> >> @@ -28,6 +28,7 @@
> >>  #include "block/block.h"
> >>  #include "block/blockjob_int.h"
> >>  #include "block/block_int.h"
> >> +#include "block/trace.h"
> >>  #include "sysemu/block-backend.h"
> >>  #include "qapi/error.h"
> >>  #include "qapi/qmp/qerror.h"
> >> @@ -41,6 +42,34 @@
> >>   * block_job_enter. */
> >>  static QemuMutex block_job_mutex;
> >>  
> >> +/* BlockJob State Transition Table */
> >> +bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
> >> +                                          /* U, C, R, P, Y, S */
> >> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},
> > 
> > Even at the end of the series, this is the only use of
> > BLOCK_JOB_STATUS_UNDEFINED.
> > 
> >> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},
> >> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},
> >> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},
> >> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},
> >> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
> >> +};
> >> +
> >> +static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
> >> +{
> >> +    BlockJobStatus s0 = job->status;
> >> +    if (s0 == s1) {
> >> +        return;
> >> +    }
> >> +    assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
> >> +    trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
> >> +                                     "allowed" : "disallowed",
> >> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
> >> +                                                      s0),
> >> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
> >> +                                                      s1));
> >> +    assert(BlockJobSTT[s0][s1]);
> >> +    job->status = s1;
> >> +}
> >> +
> >>  static void block_job_lock(void)
> >>  {
> >>      qemu_mutex_lock(&block_job_mutex);
> >> @@ -320,7 +349,7 @@ void block_job_start(BlockJob *job)
> >>      job->pause_count--;
> >>      job->busy = true;
> >>      job->paused = false;
> >> -    job->status = BLOCK_JOB_STATUS_RUNNING;
> >> +    block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
> >>      bdrv_coroutine_enter(blk_bs(job->blk), job->co);
> >>  }
> >>  
> >> @@ -704,6 +733,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
> >>      job->refcnt        = 1;
> >>      job->manual        = (flags & BLOCK_JOB_MANUAL);
> >>      job->status        = BLOCK_JOB_STATUS_CREATED;
> >> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
> > 
> > So did you intend to start with BLOCK_JOB_STATUS_UNDEFINED and then
> > transition to BLOCK_JOB_STATUS_CREATED?
> > 
> > Or should we completely remove BLOCK_JOB_STATUS_UNDEFINED, keep the
> > initialisation and not call block_job_state_transition() here?
> > 
> > Kevin
> > 
> 
> We can do that;
> 
> I had it start as "Undefined" because I liked how a g_new0() object will
> default to that state, so it felt "safe."
> 
> On the negatives, it does mean that technically you COULD witness a job
> in this state if QEMU did something wrong, which would be confusing
> because you wouldn't be able to fix it via QMP.

I don't really mind which way you do it as long as the code seems
self-consistent. You could change the initialisation this way:

    job->status        = BLOCK_JOB_STATUS_UNDEFINED;
    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);

Or if you want to make use of the fact that g_new0() already results in
BLOCK_JOB_STATUS_UNDEFINED, you can omit the first line.

I'm also not strictly opposed to a CREATED -> CREATED transition, even
though it looks a bit odd. But then there is no reason to allow an
UNDEFINED -> CREATED transition that never happens in practice.
UNDEFINED would then be a completely unused state that could only be
active in the case of a bug.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick John Snow
  2018-02-27 16:32   ` Eric Blake
@ 2018-02-27 17:18   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 17:18 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> If speed is '0' it's not actually "less than" the previous speed.
> Kick the job in this case too.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions John Snow
  2018-02-27 16:36   ` Eric Blake
@ 2018-02-27 17:18   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 17:18 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> model all independent jobs as single job transactions.
> 
> It's one less case we have to worry about when we add more states to the
> transition machine. This way, we can just treat all job lifetimes exactly
> the same. This helps tighten assertions of the STM graph and removes some
> conditionals that would have been needed in the coming commits adding a
> more explicit job lifetime management API.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property John Snow
  2018-02-27 16:39   ` Eric Blake
@ 2018-02-27 17:18   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 17:18 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> This property will be used to opt-in to the new BlockJobs workflow
> that allows a tighter, more explicit control over transitions from
> one runstate to another.
> 
> While we're here, fix up the documentation for block_job_create
> a little bit.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum John Snow
  2018-02-27 16:44   ` Eric Blake
@ 2018-02-27 17:19   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 17:19 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> We're about to add several new states, and booleans are becoming
> unwieldly and difficult to reason about. It would help to have a
> more explicit bookkeeping of the state of blockjobs. To this end,
> add a new "status" field and add our existing states in a redundant
> manner alongside the bools they are replacing:
> 
> UNDEFINED: Placeholder, default state. Not currently visible to QMP
>            unless changes occur in the future to allow creating jobs
>            without starting them via QMP.
> CREATED:   replaces !!job->co && paused && !busy
> RUNNING:   replaces effectively (!paused && busy)
> PAUSED:    Nearly redundant with info->paused, which shows pause_count.
>            This reports the actual status of the job, which almost always
>            matches the paused request status. It differs in that it is
>            strictly only true when the job has actually gone dormant.
> READY:     replaces job->ready.
> STANDBY:   Paused, but job->ready is true.
> 
> New state additions in coming commits will not be quite so redundant:
> 
> WAITING:   Waiting on transaction. This job has finished all the work
>            it can until the transaction converges, fails, or is canceled.
> PENDING:   Pending authorization from user. This job has finished all the
>            work it can until the job or transaction is finalized via
>            block_job_finalize. This implies the transaction has converged
>            and left the WAITING phase.
> ABORTING:  Job has encountered an error condition and is in the process
>            of aborting.
> CONCLUDED: Job has ceased all operations and has a return code available
>            for query and may be dismissed via block_job_dismiss.
> NULL:      Job has been dismissed and (should) be destroyed. Should never
>            be visible to QMP.
> 
> Some of these states appear somewhat superfluous, but it helps define the
> expected flow of a job; so some of the states wind up being synchronous
> empty transitions. Importantly, jobs can be in only one of these states
> at any given time, which helps code and external users alike reason about
> the current condition of a job unambiguously.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait John Snow
@ 2018-02-27 17:19   ` Kevin Wolf
  2018-02-27 19:01   ` Eric Blake
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 17:19 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Split out the pause command into the actual pause and the wait.
> Not every usage presently needs to resubmit a pause request.
> 
> The intent with the next commit will be to explicitly disallow
> redundant or meaningless pause/resume requests, so the tests
> need to become more judicious to reflect that.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table John Snow
@ 2018-02-27 17:19   ` Kevin Wolf
  2018-02-27 19:25   ` Eric Blake
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-27 17:19 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Which commands ("verbs") are appropriate for jobs in which state is
> also somewhat burdensome to keep track of.
> 
> As of this commit, it looks rather useless, but begins to look more
> interesting the more states we add to the STM table.
> 
> A recurring theme is that no verb will apply to an 'undefined' job.
> 
> Further, it's not presently possible to restrict the "pause" or "resume"
> verbs any more than they are in this commit because of the asynchronous
> nature of how jobs enter the PAUSED state; justifications for some
> seemingly erroneous applications are given below.
> 
> =====
> Verbs
> =====
> 
> Cancel:    Any state except undefined.
> Pause:     Any state except undefined;
>            'created': Requests that the job pauses as it starts.
>            'running': Normal usage. (PAUSED)
>            'paused':  The job may be paused for internal reasons,
>                       but the user may wish to force an indefinite
>                       user-pause, so this is allowed.
>            'ready':   Normal usage. (STANDBY)
>            'standby': Same logic as above.
> Resume:    Any state except undefined;
>            'created': Will lift a user's pause-on-start request.
>            'running': Will lift a pause request before it takes effect.
>            'paused':  Normal usage.
>            'ready':   Will lift a pause request before it takes effect.
>            'standby': Normal usage.
> Set-speed: Any state except undefined, though ready may not be meaningful.
> Complete:  Only a 'ready' job may accept a complete request.
> 
> 
> =======
> Changes
> =======
> 
> (1)
> 
> To facilitate "nice" error checking, all five major block-job verb
> interfaces in blockjob.c now support an errp parameter:
> 
> - block_job_user_cancel is added as a new interface.
> - block_job_user_pause gains an errp paramter
> - block_job_user_resume gains an errp parameter
> - block_job_set_speed already had an errp parameter.
> - block_job_complete already had an errp parameter.
> 
> (2)
> 
> block-job-pause and block-job-resume will no longer no-op when trying
> to pause an already paused job, or trying to resume a job that isn't
> paused. These functions will now report that they did not perform the
> action requested because it was not possible.
> 
> iotests have been adjusted to address this new behavior.
> 
> (3)
> 
> block-job-complete doesn't worry about checking !block_job_started,
> because the permission table guards against this.
> 
> (4)
> 
> test-bdrv-drain's job implementation needs to announce that it is
> 'ready' now, in order to be completed.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table John Snow
  2018-02-27 16:27   ` Kevin Wolf
@ 2018-02-27 18:58   ` Eric Blake
  2018-02-27 19:06     ` John Snow
  2018-02-27 19:22     ` John Snow
  1 sibling, 2 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 18:58 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> The state transition table has mostly been implied. We're about to make
> it a bit more complex, so let's make the STM explicit instead.
> 
> Perform state transitions with a function that for now just asserts the
> transition is appropriate.
> 
> Transitions:
> Undefined -> Created: During job initialization.

Unless we use Created as the default state 0 for g_new0().

> Created   -> Running: Once the job is started.
>                        Jobs cannot transition from "Created" to "Paused"
>                        directly, but will instead synchronously transition
>                        to running to paused immediately.
> Running   -> Paused:  Normal workflow for pauses.
> Running   -> Ready:   Normal workflow for jobs reaching their sync point.
>                        (e.g. mirror)
> Ready     -> Standby: Normal workflow for pausing ready jobs.
> Paused    -> Running: Normal resume.
> Standby   -> Ready:   Resume of a Standby job.
> 
> 
> +---------+
> |UNDEFINED|
> +--+------+
>     |
> +--v----+
> |CREATED|
> +--+----+
>     |
> +--v----+     +------+
> |RUNNING<----->PAUSED|
> +--+----+     +------+
>     |
> +--v--+       +-------+
> |READY<------->STANDBY|
> +-----+       +-------+
> 
> 
> Notably, there is no state presently defined as of this commit that
> deals with a job after the "running" or "ready" states, so this table
> will be adjusted alongside the commits that introduce those states.

The ascii-art tables help in this and other patches.  Thanks for 
producing them.

> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   block/trace-events |  3 +++
>   blockjob.c         | 42 ++++++++++++++++++++++++++++++++++++------
>   2 files changed, 39 insertions(+), 6 deletions(-)
> 

> +static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
> +{
> +    BlockJobStatus s0 = job->status;
> +    if (s0 == s1) {
> +        return;
> +    }
> +    assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);

Or, if you keep the zero state distinct from valid states, this could be 
'assert(s1 > 0 && ...)'

> @@ -320,7 +349,7 @@ void block_job_start(BlockJob *job)
>       job->pause_count--;
>       job->busy = true;
>       job->paused = false;
> -    job->status = BLOCK_JOB_STATUS_RUNNING;
> +    block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
>       bdrv_coroutine_enter(blk_bs(job->blk), job->co);
>   }
>   
> @@ -704,6 +733,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
>       job->refcnt        = 1;
>       job->manual        = (flags & BLOCK_JOB_MANUAL);
>       job->status        = BLOCK_JOB_STATUS_CREATED;
> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);

Oops, missing a deletion of the job->status assignment line.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-27 17:08       ` Kevin Wolf
@ 2018-02-27 18:58         ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 18:58 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/27/2018 12:08 PM, Kevin Wolf wrote:
> Am 27.02.2018 um 17:45 hat John Snow geschrieben:
>>
>>
>> On 02/27/2018 11:27 AM, Kevin Wolf wrote:
>>> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>>>> The state transition table has mostly been implied. We're about to make
>>>> it a bit more complex, so let's make the STM explicit instead.
>>>>
>>>> Perform state transitions with a function that for now just asserts the
>>>> transition is appropriate.
>>>>
>>>> Transitions:
>>>> Undefined -> Created: During job initialization.
>>>> Created   -> Running: Once the job is started.
>>>>                       Jobs cannot transition from "Created" to "Paused"
>>>>                       directly, but will instead synchronously transition
>>>>                       to running to paused immediately.
>>>> Running   -> Paused:  Normal workflow for pauses.
>>>> Running   -> Ready:   Normal workflow for jobs reaching their sync point.
>>>>                       (e.g. mirror)
>>>> Ready     -> Standby: Normal workflow for pausing ready jobs.
>>>> Paused    -> Running: Normal resume.
>>>> Standby   -> Ready:   Resume of a Standby job.
>>>>
>>>>
>>>> +---------+
>>>> |UNDEFINED|
>>>> +--+------+
>>>>    |
>>>> +--v----+
>>>> |CREATED|
>>>> +--+----+
>>>>    |
>>>> +--v----+     +------+
>>>> |RUNNING<----->PAUSED|
>>>> +--+----+     +------+
>>>>    |
>>>> +--v--+       +-------+
>>>> |READY<------->STANDBY|
>>>> +-----+       +-------+
>>>>
>>>>
>>>> Notably, there is no state presently defined as of this commit that
>>>> deals with a job after the "running" or "ready" states, so this table
>>>> will be adjusted alongside the commits that introduce those states.
>>>>
>>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>>> ---
>>>>  block/trace-events |  3 +++
>>>>  blockjob.c         | 42 ++++++++++++++++++++++++++++++++++++------
>>>>  2 files changed, 39 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/block/trace-events b/block/trace-events
>>>> index 02dd80ff0c..b75a0c8409 100644
>>>> --- a/block/trace-events
>>>> +++ b/block/trace-events
>>>> @@ -4,6 +4,9 @@
>>>>  bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags 0x%x format_name \"%s\""
>>>>  bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
>>>>  
>>>> +# blockjob.c
>>>> +block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
>>>> +
>>>>  # block/block-backend.c
>>>>  blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
>>>>  blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
>>>> diff --git a/blockjob.c b/blockjob.c
>>>> index 1be9c20cff..d745b3bb69 100644
>>>> --- a/blockjob.c
>>>> +++ b/blockjob.c
>>>> @@ -28,6 +28,7 @@
>>>>  #include "block/block.h"
>>>>  #include "block/blockjob_int.h"
>>>>  #include "block/block_int.h"
>>>> +#include "block/trace.h"
>>>>  #include "sysemu/block-backend.h"
>>>>  #include "qapi/error.h"
>>>>  #include "qapi/qmp/qerror.h"
>>>> @@ -41,6 +42,34 @@
>>>>   * block_job_enter. */
>>>>  static QemuMutex block_job_mutex;
>>>>  
>>>> +/* BlockJob State Transition Table */
>>>> +bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
>>>> +                                          /* U, C, R, P, Y, S */
>>>> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},
>>>
>>> Even at the end of the series, this is the only use of
>>> BLOCK_JOB_STATUS_UNDEFINED.
>>>
>>>> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},
>>>> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},
>>>> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},
>>>> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},
>>>> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
>>>> +};
>>>> +
>>>> +static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
>>>> +{
>>>> +    BlockJobStatus s0 = job->status;
>>>> +    if (s0 == s1) {
>>>> +        return;
>>>> +    }
>>>> +    assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
>>>> +    trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
>>>> +                                     "allowed" : "disallowed",
>>>> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
>>>> +                                                      s0),
>>>> +                                     qapi_enum_lookup(&BlockJobStatus_lookup,
>>>> +                                                      s1));
>>>> +    assert(BlockJobSTT[s0][s1]);
>>>> +    job->status = s1;
>>>> +}
>>>> +
>>>>  static void block_job_lock(void)
>>>>  {
>>>>      qemu_mutex_lock(&block_job_mutex);
>>>> @@ -320,7 +349,7 @@ void block_job_start(BlockJob *job)
>>>>      job->pause_count--;
>>>>      job->busy = true;
>>>>      job->paused = false;
>>>> -    job->status = BLOCK_JOB_STATUS_RUNNING;
>>>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
>>>>      bdrv_coroutine_enter(blk_bs(job->blk), job->co);
>>>>  }
>>>>  
>>>> @@ -704,6 +733,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
>>>>      job->refcnt        = 1;
>>>>      job->manual        = (flags & BLOCK_JOB_MANUAL);
>>>>      job->status        = BLOCK_JOB_STATUS_CREATED;
>>>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
>>>
>>> So did you intend to start with BLOCK_JOB_STATUS_UNDEFINED and then
>>> transition to BLOCK_JOB_STATUS_CREATED?
>>>

Oh, crud, yes. This is a refactoring issue that snuck in. I didn't even
realize after your first mail because I believed so strongly that I had
not done it this way.

>>> Or should we completely remove BLOCK_JOB_STATUS_UNDEFINED, keep the
>>> initialisation and not call block_job_state_transition() here?
>>>
>>> Kevin
>>>
>>
>> We can do that;
>>
>> I had it start as "Undefined" because I liked how a g_new0() object will
>> default to that state, so it felt "safe."
>>
>> On the negatives, it does mean that technically you COULD witness a job
>> in this state if QEMU did something wrong, which would be confusing
>> because you wouldn't be able to fix it via QMP.
> 
> I don't really mind which way you do it as long as the code seems
> self-consistent. You could change the initialisation this way:
> 
>     job->status        = BLOCK_JOB_STATUS_UNDEFINED;
>     block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
> 
> Or if you want to make use of the fact that g_new0() already results in
> BLOCK_JOB_STATUS_UNDEFINED, you can omit the first line.
> 
> I'm also not strictly opposed to a CREATED -> CREATED transition, even
> though it looks a bit odd. But then there is no reason to allow an
> UNDEFINED -> CREATED transition that never happens in practice.
> UNDEFINED would then be a completely unused state that could only be
> active in the case of a bug.
> 
> Kevin
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait John Snow
  2018-02-27 17:19   ` Kevin Wolf
@ 2018-02-27 19:01   ` Eric Blake
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:01 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Split out the pause command into the actual pause and the wait.
> Not every usage presently needs to resubmit a pause request.
> 
> The intent with the next commit will be to explicitly disallow
> redundant or meaningless pause/resume requests, so the tests
> need to become more judicious to reflect that.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   tests/qemu-iotests/030        |  6 ++----
>   tests/qemu-iotests/055        | 17 ++++++-----------
>   tests/qemu-iotests/iotests.py | 12 ++++++++----
>   3 files changed, 16 insertions(+), 19 deletions(-)
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-27 18:58   ` Eric Blake
@ 2018-02-27 19:06     ` John Snow
  2018-02-27 19:22     ` John Snow
  1 sibling, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 19:06 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 01:58 PM, Eric Blake wrote:
> The ascii-art tables help in this and other patches.  Thanks for
> producing them.

Funny story: the original version of the STM present in these patches
was too complex and I was not able to draw a chart for them.

Kevin's insistence that I do draw a chart led to considerable slimming
of possible transitions.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table
  2018-02-27 18:58   ` Eric Blake
  2018-02-27 19:06     ` John Snow
@ 2018-02-27 19:22     ` John Snow
  1 sibling, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 19:22 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 01:58 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> The state transition table has mostly been implied. We're about to make
>> it a bit more complex, so let's make the STM explicit instead.
>>
>> Perform state transitions with a function that for now just asserts the
>> transition is appropriate.
>>
>> Transitions:
>> Undefined -> Created: During job initialization.
> 
> Unless we use Created as the default state 0 for g_new0().
> 

I liked the idea of letting jobs be created in an "indeterminate" state
until we actually initialize them to be of use -- that is, jobs that
could be said to semantically understand and act on the "START" verb
(which is, as of today, an internal command only.)

The only meaningful action on a job of indeterminate state, then, would
be to DEFINE that job. (I.e. what block_job_create does.)

What I'm getting at is that block_job_start() on a job that was just
created will explode, and I'd like "created" to mean "This job can be
started."

It's not a distinction that matters in the codebase RIGHT NOW, but
that's how I came to think of the STM. We could likely optimize that
transition out because we always create and immediately define it, but
it felt ... nicer from an (internal) API point of view to have defined
the construction and destruction transitions explicitly.

Anyway, it can be removed; it's not a hill worth dying on. I only insist
that the bike shed not be olive green.

>> Created   -> Running: Once the job is started.
>>                        Jobs cannot transition from "Created" to "Paused"
>>                        directly, but will instead synchronously
>> transition
>>                        to running to paused immediately.
>> Running   -> Paused:  Normal workflow for pauses.
>> Running   -> Ready:   Normal workflow for jobs reaching their sync point.
>>                        (e.g. mirror)
>> Ready     -> Standby: Normal workflow for pausing ready jobs.
>> Paused    -> Running: Normal resume.
>> Standby   -> Ready:   Resume of a Standby job.
>>
>>
>> +---------+
>> |UNDEFINED|
>> +--+------+
>>     |
>> +--v----+
>> |CREATED|
>> +--+----+
>>     |
>> +--v----+     +------+
>> |RUNNING<----->PAUSED|
>> +--+----+     +------+
>>     |
>> +--v--+       +-------+
>> |READY<------->STANDBY|
>> +-----+       +-------+
>>
>>
>> Notably, there is no state presently defined as of this commit that
>> deals with a job after the "running" or "ready" states, so this table
>> will be adjusted alongside the commits that introduce those states.
> 
> The ascii-art tables help in this and other patches.  Thanks for
> producing them.
> 
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   block/trace-events |  3 +++
>>   blockjob.c         | 42 ++++++++++++++++++++++++++++++++++++------
>>   2 files changed, 39 insertions(+), 6 deletions(-)
>>
> 
>> +static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
>> +{
>> +    BlockJobStatus s0 = job->status;
>> +    if (s0 == s1) {
>> +        return;
>> +    }

If I remove this clause, I actually would have noticed that technically
I attempt to transition from CREATED to CREATED. Maybe I ought to remove
this...

>> +    assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
> 
> Or, if you keep the zero state distinct from valid states, this could be
> 'assert(s1 > 0 && ...)'
> 
>> @@ -320,7 +349,7 @@ void block_job_start(BlockJob *job)
>>       job->pause_count--;
>>       job->busy = true;
>>       job->paused = false;
>> -    job->status = BLOCK_JOB_STATUS_RUNNING;
>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
>>       bdrv_coroutine_enter(blk_bs(job->blk), job->co);
>>   }
>>   @@ -704,6 +733,7 @@ void *block_job_create(const char *job_id, const
>> BlockJobDriver *driver,
>>       job->refcnt        = 1;
>>       job->manual        = (flags & BLOCK_JOB_MANUAL);
>>       job->status        = BLOCK_JOB_STATUS_CREATED;
>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
> 
> Oops, missing a deletion of the job->status assignment line.
> 

I am indeed.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table John Snow
  2018-02-27 17:19   ` Kevin Wolf
@ 2018-02-27 19:25   ` Eric Blake
  2018-02-27 19:38     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:25 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Which commands ("verbs") are appropriate for jobs in which state is
> also somewhat burdensome to keep track of.
> 
> As of this commit, it looks rather useless, but begins to look more
> interesting the more states we add to the STM table.
> 
> A recurring theme is that no verb will apply to an 'undefined' job.

Back to the argument of whether we even want that state.

> 
> =======
> Changes
> =======
> 
> (1)
> 
> To facilitate "nice" error checking, all five major block-job verb
> interfaces in blockjob.c now support an errp parameter:
> 
> - block_job_user_cancel is added as a new interface.
> - block_job_user_pause gains an errp paramter
> - block_job_user_resume gains an errp parameter
> - block_job_set_speed already had an errp parameter.
> - block_job_complete already had an errp parameter.
> 
> (2)
> 
> block-job-pause and block-job-resume will no longer no-op when trying
> to pause an already paused job, or trying to resume a job that isn't
> paused. These functions will now report that they did not perform the
> action requested because it was not possible.
> 
> iotests have been adjusted to address this new behavior.

Seems reasonable.  Hopefully shouldn't trip up libvirt too badly (if 
libvirt attempted a redundant job transition that used to silently 
succeed and now fails, the failure message should be pretty obvious that 
it was a no-op attempt).

> 
> (3)
> 
> block-job-complete doesn't worry about checking !block_job_started,
> because the permission table guards against this.
> 
> (4)
> 
> test-bdrv-drain's job implementation needs to announce that it is
> 'ready' now, in order to be completed.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state John Snow
@ 2018-02-27 19:34   ` Eric Blake
  2018-02-28 14:54   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:34 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Add a new state ABORTING.
> 
> This makes transitions from normative states to error states explicit
> in the STM, and serves as a disambiguation for which states may complete
> normally when normal end-states (CONCLUDED) are added in future commits.
> 
> Notably, Paused/Standby jobs do not transition directly to aborting,
> as they must wake up first and cooperate in their cancellation.
> 
> Transitions:
> Running -> Aborting: can be cancelled or encounter an error
> Ready   -> Aborting: can be cancelled or encounter an error
> 
> Verbs:
> None. The job must finish cleaning itself up and report its final status.
> 
>               +---------+
>               |UNDEFINED|
>               +--+------+
>                  |
>               +--v----+
>               |CREATED|
>               +--+----+
>                  |
>               +--v----+     +------+
>     +---------+RUNNING<----->PAUSED|
>     |         +--+----+     +------+
>     |            |
>     |         +--v--+       +-------+
>     +---------+READY<------->STANDBY|
>     |         +-----+       +-------+
>     |
> +--v-----+
> |ABORTING|
> +--------+
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   blockjob.c           | 31 ++++++++++++++++++-------------
>   qapi/block-core.json |  7 ++++++-
>   2 files changed, 24 insertions(+), 14 deletions(-)
> 

> +++ b/qapi/block-core.json
> @@ -996,10 +996,15 @@
>   # @standby: The job is ready, but paused. This is nearly identical to @paused.
>   #           The job may return to @ready or otherwise be canceled.
>   #
> +# @aborting: The job is in the process of being aborted, and will finish with
> +#            an error. The job will afterwards report that it is @concluded.

@concluded isn't defined yet, but I'm okay with the minor future 
reference, as it's less churn to get to the description that works at 
the end of the series.

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state John Snow
@ 2018-02-27 19:38   ` Eric Blake
  2018-02-27 19:44     ` John Snow
  2018-02-28 15:37   ` Kevin Wolf
  1 sibling, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:38 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> add a new state "CONCLUDED" that identifies a job that has ceased all
> operations. The wording was chosen to avoid any phrasing that might
> imply success, error, or cancellation. The task has simply ceased all
> operation and can never again perform any work.
> 
> ("finished", "done", and "completed" might all imply success.)
> 
> Transitions:
> Running  -> Concluded: normal completion
> Ready    -> Concluded: normal completion
> Aborting -> Concluded: error and cancellations
> 
> Verbs:
> None as of this commit. (a future commit adds 'dismiss')
> 


> @@ -620,7 +623,9 @@ void block_job_user_resume(BlockJob *job, Error **errp)
>   
>   void block_job_cancel(BlockJob *job)
>   {
> -    if (block_job_started(job)) {
> +    if (job->status == BLOCK_JOB_STATUS_CONCLUDED) {
> +        return;
> +    } else if (block_job_started(job)) {

It's also possible to do:

if () {
   return ;
}
if (...)

instead of chaining with an 'else if'.  Matter of personal taste, so I 
won't make you change it.

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table
  2018-02-27 19:25   ` Eric Blake
@ 2018-02-27 19:38     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 19:38 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 02:25 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> Which commands ("verbs") are appropriate for jobs in which state is
>> also somewhat burdensome to keep track of.
>>
>> As of this commit, it looks rather useless, but begins to look more
>> interesting the more states we add to the STM table.
>>
>> A recurring theme is that no verb will apply to an 'undefined' job.
> 
> Back to the argument of whether we even want that state.
> 

By design, it is intended to reject all commands.

Though, what I can do is just remove the UNDEFINED state but have the
"CREATED" state start at "1" still. In effect, this gives you the empty
row and column for the 'UNDEFINED' state, except now it's *literally*
undefined.

However, the transition then needs to be set explicitly. The way the
code is written now, the status *only* ever changes from the transition
function, which makes it easy to search for and reason about all
possible transition points which I consider a feature of the design.

>>
>> =======
>> Changes
>> =======
>>
>> (1)
>>
>> To facilitate "nice" error checking, all five major block-job verb
>> interfaces in blockjob.c now support an errp parameter:
>>
>> - block_job_user_cancel is added as a new interface.
>> - block_job_user_pause gains an errp paramter
>> - block_job_user_resume gains an errp parameter
>> - block_job_set_speed already had an errp parameter.
>> - block_job_complete already had an errp parameter.
>>
>> (2)
>>
>> block-job-pause and block-job-resume will no longer no-op when trying
>> to pause an already paused job, or trying to resume a job that isn't
>> paused. These functions will now report that they did not perform the
>> action requested because it was not possible.
>>
>> iotests have been adjusted to address this new behavior.
> 
> Seems reasonable.  Hopefully shouldn't trip up libvirt too badly (if
> libvirt attempted a redundant job transition that used to silently
> succeed and now fails, the failure message should be pretty obvious that
> it was a no-op attempt).
> 

Yeah, it's arguable whether or not this is an API change.

(A) I'm not prohibiting anything that would have worked before. I am
just notifying the client that whatever they were trying to do had no
effect.

(B) That notification is an error, though, so some code paths that may
have relied on jamming pause signals into the pipe may be surprised at
the new response.

If I can get away with it, I obviously prefer to warn the user that the
pause/resume had no effect or couldn't be applied.

>>
>> (3)
>>
>> block-job-complete doesn't worry about checking !block_job_started,
>> because the permission table guards against this.
>>
>> (4)
>>
>> test-bdrv-drain's job implementation needs to announce that it is
>> 'ready' now, in order to be completed.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
> 
> Reviewed-by: Eric Blake <eblake@redhat.com>
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state John Snow
@ 2018-02-27 19:41   ` Eric Blake
  2018-02-28 15:42   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:41 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Add a new state that specifically demarcates when we begin to permanently
> demolish a job after it has performed all work. This makes the transition
> explicit in the STM table and highlights conditions under which a job may
> be demolished.
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state
  2018-02-27 19:38   ` Eric Blake
@ 2018-02-27 19:44     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 19:44 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 02:38 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> add a new state "CONCLUDED" that identifies a job that has ceased all
>> operations. The wording was chosen to avoid any phrasing that might
>> imply success, error, or cancellation. The task has simply ceased all
>> operation and can never again perform any work.
>>
>> ("finished", "done", and "completed" might all imply success.)
>>
>> Transitions:
>> Running  -> Concluded: normal completion
>> Ready    -> Concluded: normal completion
>> Aborting -> Concluded: error and cancellations
>>
>> Verbs:
>> None as of this commit. (a future commit adds 'dismiss')
>>
> 
> 
>> @@ -620,7 +623,9 @@ void block_job_user_resume(BlockJob *job, Error
>> **errp)
>>     void block_job_cancel(BlockJob *job)
>>   {
>> -    if (block_job_started(job)) {
>> +    if (job->status == BLOCK_JOB_STATUS_CONCLUDED) {
>> +        return;
>> +    } else if (block_job_started(job)) {
> 
> It's also possible to do:
> 
> if () {
>   return ;
> }
> if (...)
> 
> instead of chaining with an 'else if'.  Matter of personal taste, so I
> won't make you change it.
> 
> Reviewed-by: Eric Blake <eblake@redhat.com>
> 

I guess because in this case, what I did adds two SLOC instead of three.
If the other code did not need to be guarded by an if(), I'd otherwise
agree.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss John Snow
@ 2018-02-27 19:44   ` Eric Blake
  2018-02-28 15:53   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:44 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> For jobs that have reached their CONCLUDED state, prior to having their
> last reference put down (meaning jobs that have completed successfully,
> unsuccessfully, or have been canceled), allow the user to dismiss the
> job's lingering status report via block-job-dismiss.
> 
> This gives management APIs the chance to conclusively determine if a job
> failed or succeeded, even if the event broadcast was missed.
> 
> Note that jobs do not yet linger in any such state, they are freed
> immediately upon reaching this previously-unnamed state. such a state is
> added immediately in the next commit.
> 
> Verbs:
> Dismiss: operates on CONCLUDED jobs only.
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs John Snow
@ 2018-02-27 19:49   ` Eric Blake
  2018-02-27 20:43     ` John Snow
  2018-02-28 16:05   ` Kevin Wolf
  1 sibling, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:49 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Presently, even if a job is canceled post-completion as a result of
> a failing peer in a transaction, it will still call .commit because
> nothing has updated or changed its return code.
> 
> The reason why this does not cause problems currently is because
> backup's implementation of .commit checks for cancellation itself.
> 
> I'd like to simplify this contract:
> 
> (1) Abort is called if the job/transaction fails
> (2) Commit is called if the job/transaction succeeds
> 
> To this end: A job's return code, if 0, will be forcibly set as
> -ECANCELED if that job has already concluded. Remove the now
> redundant check in the backup job implementation.
> 
> We need to check for cancellation in both block_job_completed
> AND block_job_completed_single, because jobs may be cancelled between
> those two calls; for instance in transactions.
> 
> The check in block_job_completed could be removed, but there's no
> point in starting to attempt to succeed a transaction that we know
> in advance will fail.
> 
> This does NOT affect mirror jobs that are "canceled" during their
> synchronous phase. The mirror job itself forcibly sets the canceled
> property to false prior to ceding control, so such cases will invoke
> the "commit" callback.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   block/backup.c     |  2 +-
>   block/trace-events |  1 +
>   blockjob.c         | 19 +++++++++++++++----
>   3 files changed, 17 insertions(+), 5 deletions(-)

More lines of code, but the contract does seem simpler and useful for 
the later patches.

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers John Snow
@ 2018-02-27 19:50   ` Eric Blake
  2018-02-28 16:07   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:50 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> The completed_single function is getting a little mucked up with
> checking to see which callbacks exist, so let's factor them out.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   blockjob.c | 35 ++++++++++++++++++++++++++---------
>   1 file changed, 26 insertions(+), 9 deletions(-)
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function John Snow
@ 2018-02-27 19:52   ` Eric Blake
  2018-02-28 16:32   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:52 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Simply apply a function transaction-wide.
> A few more uses of this in forthcoming patches.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   blockjob.c | 24 +++++++++++++++---------
>   1 file changed, 15 insertions(+), 9 deletions(-)
> 

> @@ -565,13 +577,7 @@ static void block_job_completed_txn_success(BlockJob *job)
>           }
>       }
>       /* We are the last completed job, commit the transaction. */
> -    QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
> -        ctx = blk_get_aio_context(other_job->blk);
> -        aio_context_acquire(ctx);
> -        assert(other_job->ret == 0);

We lost this assertion.  Hopefully that doesn't matter in the long run.

> -        block_job_completed_single(other_job);
> -        aio_context_release(ctx);
> -    }
> +    block_job_txn_apply(txn, block_job_completed_single);
>   }
>   
>   /* Assumes the block_job_mutex is held */
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback John Snow
@ 2018-02-27 19:56   ` Eric Blake
  2018-02-27 20:45     ` John Snow
  2018-02-28 17:04   ` Kevin Wolf
  1 sibling, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 19:56 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Some jobs upon finalization may need to perform some work that can
> still fail. If these jobs are part of a transaction, it's important
> that these callbacks fail the entire transaction.
> 
> We allow for a new callback in addition to commit/abort/clean that
> allows us the opportunity to have fairly late-breaking failures
> in the transactional process.
> 
> The expected flow is:
> 
> - All jobs in a transaction converge to the WAITING state
>    (added in a forthcoming commit)
> - All jobs prepare to call either commit/abort
> - If any job fails, is canceled, or fails preparation, all jobs
>    call their .abort callback.
> - All jobs enter the PENDING state, awaiting manual intervention
>    (also added in a forthcoming commit)
> - block-job-finalize is issued by the user/management layer
> - All jobs call their commit callbacks.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   blockjob.c                   | 34 +++++++++++++++++++++++++++++++---
>   include/block/blockjob_int.h | 10 ++++++++++
>   2 files changed, 41 insertions(+), 3 deletions(-)
> 

> @@ -467,17 +480,22 @@ static void block_job_cancel_async(BlockJob *job)
>       job->cancelled = true;
>   }
>   
> -static void block_job_txn_apply(BlockJobTxn *txn, void fn(BlockJob *))
> +static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *))
>   {
>       AioContext *ctx;
>       BlockJob *job, *next;
> +    int rc;
>   
>       QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
>           ctx = blk_get_aio_context(job->blk);
>           aio_context_acquire(ctx);
> -        fn(job);
> +        rc = fn(job);
>           aio_context_release(ctx);
> +        if (rc) {
> +            break;
> +        }

This short-circuits the application of the function to the rest of the 
group.  Is that ever going to be a problem?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status John Snow
@ 2018-02-27 20:00   ` Eric Blake
  2018-02-27 20:50     ` John Snow
  0 siblings, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 20:00 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> For jobs that are stuck waiting on others in a transaction, it would
> be nice to know that they are no longer "running" in that sense, but
> instead are waiting on other jobs in the transaction.
> 
> Jobs that are "waiting" in this sense cannot be meaningfully altered
> any longer as they have left their running loop. The only meaningful
> user verb for jobs in this state is "cancel," which will cancel the
> whole transaction, too.
> 
> Transitions:
> Running -> Waiting:   Normal transition.
> Ready   -> Waiting:   Normal transition.
> Waiting -> Aborting:  Transactional cancellation.
> Waiting -> Concluded: Normal transition.
> 
> Removed Transitions:
> Running -> Concluded: Jobs must go to WAITING first.
> Ready   -> Concluded: Jobs must go to WAITING fisrt.

s/fisrt/first/

> +++ b/blockjob.c

> @@ -3934,6 +3938,29 @@
>               'offset': 'int',
>               'speed' : 'int' } }
>   
> +##
> +# @BLOCK_JOB_WAITING:
> +#
> +# Emitted when a block job that is part of a transction has stopped work and is

s/transction/transaction/

> +# waiting for other jobs in the transaction to reach the same state.

Is this event emitted only for 'new-style' transactions (old drivers 
will never see it, because they don't request new style), or always (old 
drivers will see, but presumably ignore, it)?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event John Snow
@ 2018-02-27 20:05   ` Eric Blake
  2018-02-27 20:54     ` John Snow
  2018-02-28 17:55   ` Kevin Wolf
  1 sibling, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 20:05 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> For jobs utilizing the new manual workflow, we intend to prohibit
> them from modifying the block graph until the management layer provides
> an explicit ACK via block-job-finalize to move the process forward.
> 
> To distinguish this runstate from "ready" or "waiting," we add a new
> "pending" event.
> 
> For now, the transition from PENDING to CONCLUDED/ABORTING is automatic,
> but a future commit will add the explicit block-job-finalize step.
> 
> Transitions:
> Waiting -> Pending:   Normal transition.
> Pending -> Concluded: Normal transition.
> Pending -> Aborting:  Late transactional failures and cancellations.
> 
> Removed Transitions:
> Waiting -> Concluded: Jobs must go to PENDING first.
> 
> Verbs:
> Cancel: Can be applied to a pending job.
> 

> +##
> +# @BLOCK_JOB_PENDING:
> +#
> +# Emitted when a block job is awaiting explicit authorization to finalize graph
> +# changes via @block-job-finalize. If this job is part of a transaction, it will
> +# not emit this event until the transaction has converged first.

Same question of whether this new event is always emitted (and older 
clients presumably ignore it), or only emitted for clients that 
requested new-style state management.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize John Snow
@ 2018-02-27 20:13   ` Eric Blake
  2018-02-28 18:15   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 20:13 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Instead of automatically transitioning from PENDING to CONCLUDED, gate
> the .prepare() and .commit() phases behind an explicit acknowledgement
> provided by the QMP monitor if manual completion mode has been requested.
> 
> This allows us to perform graph changes in prepare and/or commit so that
> graph changes do not occur autonomously without knowledge of the
> controlling management layer.
> 
> Transactions that have reached the "PENDING" state together can all be
> moved to invoke their finalization methods by issuing block_job_finalize
> to any one job in the transaction.
> 
> Jobs in a transaction with mixed job->manual settings will remain stuck
> in the "WAITING" state until block_job_finalize is authored on the job(s)
> that have reached the "PENDING" state.
> 
> These jobs are not allowed to progress because other jobs in the
> transaction may still fail during their preparation phase during
> finalization, so these jobs must remain in the WAITING phase until
> success is guaranteed. These jobs will then automatically dismiss
> themselves, but jobs that had the manual property set will remain
> at CONCLUDED as normal.
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property John Snow
@ 2018-02-27 20:16   ` Eric Blake
  2018-02-27 20:42     ` John Snow
  2018-02-27 21:57     ` John Snow
  2018-02-28 18:25   ` Kevin Wolf
  1 sibling, 2 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 20:16 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Expose the "manual" property via QAPI for the backup-related jobs.
> As of this commit, this allows the management API to request the
> "concluded" and "dismiss" semantics for backup jobs.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   blockdev.c           | 19 ++++++++++++++++---
>   qapi/block-core.json | 32 ++++++++++++++++++++++++++------
>   2 files changed, 42 insertions(+), 9 deletions(-)
> 

> +++ b/qapi/block-core.json
> @@ -1177,6 +1177,16 @@
>   # @job-id: identifier for the newly-created block job. If
>   #          omitted, the device name will be used. (Since 2.7)
>   #
> +# @manual: True to use an expanded, more explicit job control flow.
> +#          Jobs may transition from a running state to a pending state,
> +#          where they must be instructed to complete manually via
> +#          block-job-finalize.
> +#          Jobs belonging to a transaction must either all or all not use this
> +#          setting. Once a transaction reaches a pending state, issuing the
> +#          finalize command to any one job in the transaction is sufficient
> +#          to finalize the entire transaction.

The previous commit message talked about mixed-manual transactions, but 
this seems to imply it is not possible.  I'm fine if we don't support 
mixed-manual transactions, but wonder if it means any changes to the series.

Otherwise looks reasonable from the UI point of view.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 20/21] iotests: test manual job dismissal
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 20/21] iotests: test manual job dismissal John Snow
@ 2018-02-27 20:21   ` Eric Blake
  2018-02-27 20:41     ` John Snow
  0 siblings, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 20:21 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   tests/qemu-iotests/056     | 195 +++++++++++++++++++++++++++++++++++++++++++++
>   tests/qemu-iotests/056.out |   4 +-
>   2 files changed, 197 insertions(+), 2 deletions(-)
> 

I'm not sure if this covers everything in the series, but it looks like 
a reasonable expansion and hits a lot of the highlights.  At any rate, 
it's always better to add tests, and the test passing is a good bet that 
the new code will be harder to regress.

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions John Snow
@ 2018-02-27 20:24   ` Eric Blake
  2018-02-28 18:29     ` Kevin Wolf
  0 siblings, 1 reply; 98+ messages in thread
From: Eric Blake @ 2018-02-27 20:24 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/23/2018 05:51 PM, John Snow wrote:
> This allows us to easily force the option for all jobs belonging
> to a transaction to ensure consistency with how all those jobs
> will be handled.
> 
> This is purely a convenience.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---

> +++ b/qapi/transaction.json
> @@ -79,7 +79,8 @@
>   ##
>   { 'struct': 'TransactionProperties',
>     'data': {
> -       '*completion-mode': 'ActionCompletionMode'
> +       '*completion-mode': 'ActionCompletionMode',
> +       '*manual-mgmt': 'bool'

Missing QAPI documentation (what you have elsewhere in the C code can 
probably be copied here, though).

The UI aspect makes sense (I can declare one manual at the transaction 
level instead of multiple manual declarations per member level within 
the transaction).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 20/21] iotests: test manual job dismissal
  2018-02-27 20:21   ` Eric Blake
@ 2018-02-27 20:41     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 20:41 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 03:21 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   tests/qemu-iotests/056     | 195
>> +++++++++++++++++++++++++++++++++++++++++++++
>>   tests/qemu-iotests/056.out |   4 +-
>>   2 files changed, 197 insertions(+), 2 deletions(-)
>>
> 
> I'm not sure if this covers everything in the series, but it looks like

It definitely doesn't!

> a reasonable expansion and hits a lot of the highlights.  At any rate,
> it's always better to add tests, and the test passing is a good bet that
> the new code will be harder to regress.
> 

More to follow, but I was afraid of wasting time if this series didn't
look on the whole serviceable.

I'll probably focus efforts on expanding blockjob-txn and blockjob unit
tests.

> Reviewed-by: Eric Blake <eblake@redhat.com>
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-27 20:16   ` Eric Blake
@ 2018-02-27 20:42     ` John Snow
  2018-02-27 21:57     ` John Snow
  1 sibling, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 20:42 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 03:16 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> Expose the "manual" property via QAPI for the backup-related jobs.
>> As of this commit, this allows the management API to request the
>> "concluded" and "dismiss" semantics for backup jobs.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   blockdev.c           | 19 ++++++++++++++++---
>>   qapi/block-core.json | 32 ++++++++++++++++++++++++++------
>>   2 files changed, 42 insertions(+), 9 deletions(-)
>>
> 
>> +++ b/qapi/block-core.json
>> @@ -1177,6 +1177,16 @@
>>   # @job-id: identifier for the newly-created block job. If
>>   #          omitted, the device name will be used. (Since 2.7)
>>   #
>> +# @manual: True to use an expanded, more explicit job control flow.
>> +#          Jobs may transition from a running state to a pending state,
>> +#          where they must be instructed to complete manually via
>> +#          block-job-finalize.
>> +#          Jobs belonging to a transaction must either all or all not
>> use this
>> +#          setting. Once a transaction reaches a pending state,
>> issuing the
>> +#          finalize command to any one job in the transaction is
>> sufficient
>> +#          to finalize the entire transaction.
> 
> The previous commit message talked about mixed-manual transactions, but
> this seems to imply it is not possible.  I'm fine if we don't support
> mixed-manual transactions, but wonder if it means any changes to the
> series.
> 
> Otherwise looks reasonable from the UI point of view.
> 

Refactor hell.

The intent (and my belief) is that as of right now you CAN mix them. In
earlier drafts, it was not always the case.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs
  2018-02-27 19:49   ` Eric Blake
@ 2018-02-27 20:43     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 20:43 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 02:49 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> Presently, even if a job is canceled post-completion as a result of
>> a failing peer in a transaction, it will still call .commit because
>> nothing has updated or changed its return code.
>>
>> The reason why this does not cause problems currently is because
>> backup's implementation of .commit checks for cancellation itself.
>>
>> I'd like to simplify this contract:
>>
>> (1) Abort is called if the job/transaction fails
>> (2) Commit is called if the job/transaction succeeds
>>
>> To this end: A job's return code, if 0, will be forcibly set as
>> -ECANCELED if that job has already concluded. Remove the now
>> redundant check in the backup job implementation.
>>
>> We need to check for cancellation in both block_job_completed
>> AND block_job_completed_single, because jobs may be cancelled between
>> those two calls; for instance in transactions.
>>
>> The check in block_job_completed could be removed, but there's no
>> point in starting to attempt to succeed a transaction that we know
>> in advance will fail.
>>
>> This does NOT affect mirror jobs that are "canceled" during their
>> synchronous phase. The mirror job itself forcibly sets the canceled
>> property to false prior to ceding control, so such cases will invoke
>> the "commit" callback.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   block/backup.c     |  2 +-
>>   block/trace-events |  1 +
>>   blockjob.c         | 19 +++++++++++++++----
>>   3 files changed, 17 insertions(+), 5 deletions(-)
> 
> More lines of code, but the contract does seem simpler and useful for
> the later patches.
> 

Unfortunately yes, but it would be less overall if more than Backup made
use of commit/abort, which I anticipate in the future when I try to
start switching jobs over to using the .prepare callback.

It was just genuinely shocking to me that we'd call commit(), but backup
secretly knew we wanted abort. That type of logic belongs in the core
dispatch layer.

> Reviewed-by: Eric Blake <eblake@redhat.com>
> 

Thanks for the reviews!

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback
  2018-02-27 19:56   ` Eric Blake
@ 2018-02-27 20:45     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 20:45 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 02:56 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> Some jobs upon finalization may need to perform some work that can
>> still fail. If these jobs are part of a transaction, it's important
>> that these callbacks fail the entire transaction.
>>
>> We allow for a new callback in addition to commit/abort/clean that
>> allows us the opportunity to have fairly late-breaking failures
>> in the transactional process.
>>
>> The expected flow is:
>>
>> - All jobs in a transaction converge to the WAITING state
>>    (added in a forthcoming commit)
>> - All jobs prepare to call either commit/abort
>> - If any job fails, is canceled, or fails preparation, all jobs
>>    call their .abort callback.
>> - All jobs enter the PENDING state, awaiting manual intervention
>>    (also added in a forthcoming commit)
>> - block-job-finalize is issued by the user/management layer
>> - All jobs call their commit callbacks.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   blockjob.c                   | 34 +++++++++++++++++++++++++++++++---
>>   include/block/blockjob_int.h | 10 ++++++++++
>>   2 files changed, 41 insertions(+), 3 deletions(-)
>>
> 
>> @@ -467,17 +480,22 @@ static void block_job_cancel_async(BlockJob *job)
>>       job->cancelled = true;
>>   }
>>   -static void block_job_txn_apply(BlockJobTxn *txn, void fn(BlockJob *))
>> +static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *))
>>   {
>>       AioContext *ctx;
>>       BlockJob *job, *next;
>> +    int rc;
>>         QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
>>           ctx = blk_get_aio_context(job->blk);
>>           aio_context_acquire(ctx);
>> -        fn(job);
>> +        rc = fn(job);
>>           aio_context_release(ctx);
>> +        if (rc) {
>> +            break;
>> +        }
> 
> This short-circuits the application of the function to the rest of the
> group.  Is that ever going to be a problem?
> 

With what I've written, I don't think so -- but I can't guarantee
someone won't misunderstand the semantics of it and it will become a
problem. It is a potentially dangerous function in that way.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status
  2018-02-27 20:00   ` Eric Blake
@ 2018-02-27 20:50     ` John Snow
  2018-02-28 17:46       ` Kevin Wolf
  0 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-27 20:50 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 03:00 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> For jobs that are stuck waiting on others in a transaction, it would
>> be nice to know that they are no longer "running" in that sense, but
>> instead are waiting on other jobs in the transaction.
>>
>> Jobs that are "waiting" in this sense cannot be meaningfully altered
>> any longer as they have left their running loop. The only meaningful
>> user verb for jobs in this state is "cancel," which will cancel the
>> whole transaction, too.
>>
>> Transitions:
>> Running -> Waiting:   Normal transition.
>> Ready   -> Waiting:   Normal transition.
>> Waiting -> Aborting:  Transactional cancellation.
>> Waiting -> Concluded: Normal transition.
>>
>> Removed Transitions:
>> Running -> Concluded: Jobs must go to WAITING first.
>> Ready   -> Concluded: Jobs must go to WAITING fisrt.
> 
> s/fisrt/first/
> 
>> +++ b/blockjob.c
> 
>> @@ -3934,6 +3938,29 @@
>>               'offset': 'int',
>>               'speed' : 'int' } }
>>   +##
>> +# @BLOCK_JOB_WAITING:
>> +#
>> +# Emitted when a block job that is part of a transction has stopped
>> work and is
> 
> s/transction/transaction/
> 
>> +# waiting for other jobs in the transaction to reach the same state.
> 
> Is this event emitted only for 'new-style' transactions (old drivers
> will never see it, because they don't request new style), or always (old
> drivers will see, but presumably ignore, it)?
> 

...! Actually, I meant to remove the WAITING *event* entirely, this is a
mistake.

It's purely an informational state that clients likely cannot make any
real use of, because regardless of old or new style, jobs will
transition automatically to "PENDING."

That said, old or new, the state is visible from query-block-jobs.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event
  2018-02-27 20:05   ` Eric Blake
@ 2018-02-27 20:54     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 20:54 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 03:05 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> For jobs utilizing the new manual workflow, we intend to prohibit
>> them from modifying the block graph until the management layer provides
>> an explicit ACK via block-job-finalize to move the process forward.
>>
>> To distinguish this runstate from "ready" or "waiting," we add a new
>> "pending" event.
>>
>> For now, the transition from PENDING to CONCLUDED/ABORTING is automatic,
>> but a future commit will add the explicit block-job-finalize step.
>>
>> Transitions:
>> Waiting -> Pending:   Normal transition.
>> Pending -> Concluded: Normal transition.
>> Pending -> Aborting:  Late transactional failures and cancellations.
>>
>> Removed Transitions:
>> Waiting -> Concluded: Jobs must go to PENDING first.
>>
>> Verbs:
>> Cancel: Can be applied to a pending job.
>>
> 
>> +##
>> +# @BLOCK_JOB_PENDING:
>> +#
>> +# Emitted when a block job is awaiting explicit authorization to
>> finalize graph
>> +# changes via @block-job-finalize. If this job is part of a
>> transaction, it will
>> +# not emit this event until the transaction has converged first.
> 
> Same question of whether this new event is always emitted (and older
> clients presumably ignore it), or only emitted for clients that
> requested new-style state management.
> 

Old style jobs will skip the broadcast of the event, but will still
transition to the state. However, since transition is synchronous, you
likely won't see this state show up in a query for old style jobs.

That was the intent, anyway.

I wanted to be nonintrusive, and felt that this event was likely not
useful in any way unless we were using the new state management scheme.
In the old style, this event will be fully synchronous with COMPLETED or
CANCELLED, for instance.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
  2018-02-25 23:25 ` no-reply
@ 2018-02-27 20:58   ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 20:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: famz, qemu-block, kwolf, pkrempa, jtc



On 02/25/2018 06:25 PM, no-reply@patchew.org wrote:
>   CC      scsi/qemu-pr-helper.o
> /var/tmp/patchew-tester-tmp-9ukz0kme/src/blockjob.c: In function ‘block_job_txn_apply.isra.8’:
> /var/tmp/patchew-tester-tmp-9ukz0kme/src/blockjob.c:511:5: error: ‘rc’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
>      return rc;
>      ^
>   CC      qemu-bridge-helper.o
>   CC      blockdev.o
>   CC      blockdev-nbd.o
>   CC      bootdevice.o
>   CC      iothread.o
>   CC      qdev-monitor.o
>   CC      device-hotplug.o
>   CC      os-posix.o
>   CC      bt-host.o
>   CC      bt-vhci.o
>   CC      dma-helpers.o
>   CC      vl.o
>   CC      tpm.o
>   CC      device_tree.o
>   CC      qmp-marshal.o
>   CC      qmp.o
>   CC      hmp.o
>   CC      cpus-common.o
>   CC      audio/audio.o
> cc1: all warnings being treated as errors
> make: *** [blockjob.o] Error 1
> make: *** Waiting for unfinished jobs....
> === OUTPUT END ===
> 
> Test command exited with code: 2
> 
> 
> ---
> Email generated automatically by Patchew [http://patchew.org/].
> Please send your feedback to patchew-devel@freelists.org

No idea why this would only trigger on ppc/be, but I'll look into it.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
  2018-02-24 14:31 ` no-reply
@ 2018-02-27 21:01   ` John Snow
  2018-02-28 18:32     ` Kevin Wolf
  0 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-27 21:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: famz, qemu-block, kwolf, pkrempa, jtc



On 02/24/2018 09:31 AM, no-reply@patchew.org wrote:
> Hi,
> 
> This series seems to have some coding style problems. See output below for
> more information:
> 
> Type: series
> Message-id: 20180223235142.21501-1-jsnow@redhat.com
> Subject: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> 
> BASE=base
> n=1
> total=$(git log --oneline $BASE.. | wc -l)
> failed=0
> 
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> git config --local diff.algorithm histogram
> 
> commits="$(git log --format=%H --reverse $BASE..)"
> for c in $commits; do
>     echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
>     if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
>         failed=1
>         echo
>     fi
>     n=$((n+1))
> done
> 
> exit $failed
> === TEST SCRIPT END ===
> 
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> Switched to a new branch 'test'
> 230e578fa2 blockjobs: add manual_mgmt option to transactions
> f278a5155a iotests: test manual job dismissal
> 8e473ab4a8 blockjobs: Expose manual property
> 7ad2d0164f blockjobs: add block-job-finalize
> 3857c91315 blockjobs: add PENDING status and event
> 18eb8a4130 blockjobs: add waiting status
> daf9613432 blockjobs: add prepare callback
> 78be501212 blockjobs: add block_job_txn_apply function
> 4b659abe69 blockjobs: add commit, abort, clean helpers
> 4023046d76 blockjobs: ensure abort is called for cancelled jobs
> e9300b122e blockjobs: add block_job_dismiss
> 4fc045eae4 blockjobs: add NULL state
> e6aa454753 blockjobs: add CONCLUDED state
> 78efa2f937 blockjobs: add ABORTING state
> 057ad2472f blockjobs: add block_job_verb permission table
> c62c5b75a3 iotests: add pause_wait
> 4aadb9c38c blockjobs: add state transition table
> afc594c4b0 blockjobs: add status enum
> 434d3811fa blockjobs: add manual property
> fc3e3eebc9 blockjobs: model single jobs as transactions
> 8d32662676 blockjobs: fix set-speed kick
> 
> === OUTPUT BEGIN ===
> Checking PATCH 1/21: blockjobs: fix set-speed kick...
> Checking PATCH 2/21: blockjobs: model single jobs as transactions...
> Checking PATCH 3/21: blockjobs: add manual property...
> Checking PATCH 4/21: blockjobs: add status enum...
> Checking PATCH 5/21: blockjobs: add state transition table...
> ERROR: space prohibited before open square bracket '['
> #81: FILE: blockjob.c:48:
> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #82: FILE: blockjob.c:49:
> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #83: FILE: blockjob.c:50:
> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #84: FILE: blockjob.c:51:
> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #85: FILE: blockjob.c:52:
> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #86: FILE: blockjob.c:53:
> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0},
> 
> total: 6 errors, 0 warnings, 90 lines checked
> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 

-EWONTFIX unless someone screams louder than me.

> Checking PATCH 6/21: iotests: add pause_wait...
> Checking PATCH 7/21: blockjobs: add block_job_verb permission table...
> Checking PATCH 8/21: blockjobs: add ABORTING state...
> ERROR: space prohibited before open square bracket '['
> #61: FILE: blockjob.c:48:
> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #62: FILE: blockjob.c:49:
> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #63: FILE: blockjob.c:50:
> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #64: FILE: blockjob.c:51:
> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #65: FILE: blockjob.c:52:
> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #66: FILE: blockjob.c:53:
> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #67: FILE: blockjob.c:54:
> +    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0},
> 
> total: 7 errors, 0 warnings, 62 lines checked

-EWONTFIX

> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 9/21: blockjobs: add CONCLUDED state...
> ERROR: space prohibited before open square bracket '['
> #63: FILE: blockjob.c:48:
> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #64: FILE: blockjob.c:49:
> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #65: FILE: blockjob.c:50:
> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #66: FILE: blockjob.c:51:
> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #67: FILE: blockjob.c:52:
> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #68: FILE: blockjob.c:53:
> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #69: FILE: blockjob.c:54:
> +    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #70: FILE: blockjob.c:55:
> +    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0},
> 
> total: 8 errors, 0 warnings, 91 lines checked

-EWONTFIX

> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 10/21: blockjobs: add NULL state...
> ERROR: space prohibited before open square bracket '['
> #65: FILE: blockjob.c:48:
> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #66: FILE: blockjob.c:49:
> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #67: FILE: blockjob.c:50:
> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #68: FILE: blockjob.c:51:
> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #69: FILE: blockjob.c:52:
> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #70: FILE: blockjob.c:53:
> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #71: FILE: blockjob.c:54:
> +    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #72: FILE: blockjob.c:55:
> +    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #73: FILE: blockjob.c:56:
> +    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0},
> 
> total: 9 errors, 0 warnings, 71 lines checked

-EWONTFIX

> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 11/21: blockjobs: add block_job_dismiss...
> Checking PATCH 12/21: blockjobs: ensure abort is called for cancelled jobs...
> Checking PATCH 13/21: blockjobs: add commit, abort, clean helpers...
> Checking PATCH 14/21: blockjobs: add block_job_txn_apply function...
> Checking PATCH 15/21: blockjobs: add prepare callback...
> Checking PATCH 16/21: blockjobs: add waiting status...
> ERROR: space prohibited before open square bracket '['
> #80: FILE: blockjob.c:48:
> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #81: FILE: blockjob.c:49:
> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #82: FILE: blockjob.c:50:
> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 1, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #83: FILE: blockjob.c:51:
> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #84: FILE: blockjob.c:52:
> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #85: FILE: blockjob.c:53:
> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #86: FILE: blockjob.c:54:
> +    /* W: */ [BLOCK_JOB_STATUS_WAITING]   = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #87: FILE: blockjob.c:55:
> +    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #88: FILE: blockjob.c:56:
> +    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #89: FILE: blockjob.c:57:
> +    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> 
> total: 10 errors, 0 warnings, 99 lines checked

-EWONTFIX

> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 17/21: blockjobs: add PENDING status and event...
> ERROR: space prohibited before open square bracket '['
> #84: FILE: blockjob.c:48:
> +    /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #85: FILE: blockjob.c:49:
> +    /* C: */ [BLOCK_JOB_STATUS_CREATED]   = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #86: FILE: blockjob.c:50:
> +    /* R: */ [BLOCK_JOB_STATUS_RUNNING]   = {0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #87: FILE: blockjob.c:51:
> +    /* P: */ [BLOCK_JOB_STATUS_PAUSED]    = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #88: FILE: blockjob.c:52:
> +    /* Y: */ [BLOCK_JOB_STATUS_READY]     = {0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #89: FILE: blockjob.c:53:
> +    /* S: */ [BLOCK_JOB_STATUS_STANDBY]   = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #90: FILE: blockjob.c:54:
> +    /* W: */ [BLOCK_JOB_STATUS_WAITING]   = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #91: FILE: blockjob.c:55:
> +    /* D: */ [BLOCK_JOB_STATUS_PENDING]   = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #92: FILE: blockjob.c:56:
> +    /* X: */ [BLOCK_JOB_STATUS_ABORTING]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
> 
> ERROR: space prohibited before open square bracket '['
> #93: FILE: blockjob.c:57:
> +    /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
> 
> ERROR: space prohibited before open square bracket '['
> #94: FILE: blockjob.c:58:
> +    /* N: */ [BLOCK_JOB_STATUS_NULL]      = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> 
> total: 11 errors, 0 warnings, 161 lines checked

-EWONTFIX

> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 18/21: blockjobs: add block-job-finalize...
> Checking PATCH 19/21: blockjobs: Expose manual property...
> Checking PATCH 20/21: iotests: test manual job dismissal...
> Checking PATCH 21/21: blockjobs: add manual_mgmt option to transactions...
> === OUTPUT END ===
> 
> Test command exited with code: 1
> 
> 
> ---
> Email generated automatically by Patchew [http://patchew.org/].
> Please send your feedback to patchew-devel@freelists.org
> 

All false positives unless someone really would like to advocate for me
to change the format of the table.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-27 20:16   ` Eric Blake
  2018-02-27 20:42     ` John Snow
@ 2018-02-27 21:57     ` John Snow
  2018-02-27 22:27       ` Eric Blake
  2018-02-28 18:23       ` Kevin Wolf
  1 sibling, 2 replies; 98+ messages in thread
From: John Snow @ 2018-02-27 21:57 UTC (permalink / raw)
  To: Eric Blake, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel



On 02/27/2018 03:16 PM, Eric Blake wrote:
> On 02/23/2018 05:51 PM, John Snow wrote:
>> Expose the "manual" property via QAPI for the backup-related jobs.
>> As of this commit, this allows the management API to request the
>> "concluded" and "dismiss" semantics for backup jobs.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   blockdev.c           | 19 ++++++++++++++++---
>>   qapi/block-core.json | 32 ++++++++++++++++++++++++++------
>>   2 files changed, 42 insertions(+), 9 deletions(-)
>>
> 
>> +++ b/qapi/block-core.json
>> @@ -1177,6 +1177,16 @@
>>   # @job-id: identifier for the newly-created block job. If
>>   #          omitted, the device name will be used. (Since 2.7)
>>   #
>> +# @manual: True to use an expanded, more explicit job control flow.
>> +#          Jobs may transition from a running state to a pending state,
>> +#          where they must be instructed to complete manually via
>> +#          block-job-finalize.
>> +#          Jobs belonging to a transaction must either all or all not
>> use this
>> +#          setting. Once a transaction reaches a pending state,
>> issuing the
>> +#          finalize command to any one job in the transaction is
>> sufficient
>> +#          to finalize the entire transaction.
> 
> The previous commit message talked about mixed-manual transactions, but
> this seems to imply it is not possible.  I'm fine if we don't support
> mixed-manual transactions, but wonder if it means any changes to the
> series.
> 
> Otherwise looks reasonable from the UI point of view.
> 

More seriously, this documentation I wrote doesn't address the totality
of the expanded flow. I omitted dismiss here by accident as well. This
is at best a partial definition of the 'manual' property.

I'd like to use _this_ patch to ask the question: "What should the
proper noun for the QEMU 2.12+ Expanded Block Job Management Flow
Mechanism be?"

I'm not too sure, but "Manual mode" leaves a lot to be desired.

I keep calling it something like "2.12+ Job Management" but that's not
really descriptive. I conceptualize the feature as the addition of a
purposefully more "needy" and less automatic completion mechanism, hence
the "manual"

Anyway, I'd like to figure out a good "documentation name" for it so I
can point all instances of the creation property (for drive-backup,
drive-mirror, and everyone else) to a central location that explains the
STM and what exactly the differences between manual=on/off are. I'd then
like to expose this property via query and link the documentation there
to this description, too.

It'd be nice-- under the same arguments that prompted 'dismiss'-- to say
that if a client crashes it can reconnect and discover what kind of
attention certain jobs will need by asking for the manual property back.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-27 21:57     ` John Snow
@ 2018-02-27 22:27       ` Eric Blake
  2018-02-28 18:23       ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-27 22:27 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, jtc, qemu-devel

On 02/27/2018 03:57 PM, John Snow wrote:
> 
> 
> On 02/27/2018 03:16 PM, Eric Blake wrote:
>> On 02/23/2018 05:51 PM, John Snow wrote:
>>> Expose the "manual" property via QAPI for the backup-related jobs.
>>> As of this commit, this allows the management API to request the
>>> "concluded" and "dismiss" semantics for backup jobs.

>>> +# @manual: True to use an expanded, more explicit job control flow.
>>> +#          Jobs may transition from a running state to a pending state,
>>> +#          where they must be instructed to complete manually via
>>> +#          block-job-finalize.
>>> +#          Jobs belonging to a transaction must either all or all not
>>> use this
>>> +#          setting. Once a transaction reaches a pending state,
>>> issuing the
>>> +#          finalize command to any one job in the transaction is
>>> sufficient
>>> +#          to finalize the entire transaction.
>>
>> The previous commit message talked about mixed-manual transactions, but
>> this seems to imply it is not possible.  I'm fine if we don't support
>> mixed-manual transactions, but wonder if it means any changes to the
>> series.
>>
>> Otherwise looks reasonable from the UI point of view.
>>
> 
> More seriously, this documentation I wrote doesn't address the totality
> of the expanded flow. I omitted dismiss here by accident as well. This
> is at best a partial definition of the 'manual' property.
> 
> I'd like to use _this_ patch to ask the question: "What should the
> proper noun for the QEMU 2.12+ Expanded Block Job Management Flow
> Mechanism be?"

"Manual" actually doesn't sound too bad; I could also see "Explicit job 
flow", as in, "within a transaction, all jobs should have the same 
setting for the choice of Explicit Job Flow" (but then the name 'manual' 
would have to be changed to match).  The idea of a central document, 
that gets referred to from multiple spots in the QAPI docs, rather than 
duplicating information throughout the QAPI docs, is reasonable.

> 
> I'm not too sure, but "Manual mode" leaves a lot to be desired.
> 
> I keep calling it something like "2.12+ Job Management" but that's not
> really descriptive.

That, and if someone ever backports the enhanced state machine to a 2.11 
branch, it becomes a misnomer.

> I conceptualize the feature as the addition of a
> purposefully more "needy" and less automatic completion mechanism, hence
> the "manual"
> 
> Anyway, I'd like to figure out a good "documentation name" for it so I
> can point all instances of the creation property (for drive-backup,
> drive-mirror, and everyone else) to a central location that explains the
> STM and what exactly the differences between manual=on/off are. I'd then
> like to expose this property via query and link the documentation there
> to this description, too.

"Explicit" and "Manual" are the two best options coming to me as I type 
this email.

> 
> It'd be nice-- under the same arguments that prompted 'dismiss'-- to say
> that if a client crashes it can reconnect and discover what kind of
> attention certain jobs will need by asking for the manual property back.
> 
> --js
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state John Snow
  2018-02-27 19:34   ` Eric Blake
@ 2018-02-28 14:54   ` Kevin Wolf
  2018-02-28 19:26     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 14:54 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Add a new state ABORTING.
> 
> This makes transitions from normative states to error states explicit
> in the STM, and serves as a disambiguation for which states may complete
> normally when normal end-states (CONCLUDED) are added in future commits.
> 
> Notably, Paused/Standby jobs do not transition directly to aborting,
> as they must wake up first and cooperate in their cancellation.
> 
> Transitions:
> Running -> Aborting: can be cancelled or encounter an error
> Ready   -> Aborting: can be cancelled or encounter an error
> 
> Verbs:
> None. The job must finish cleaning itself up and report its final status.
> 
>              +---------+
>              |UNDEFINED|
>              +--+------+
>                 |
>              +--v----+
>              |CREATED|
>              +--+----+
>                 |
>              +--v----+     +------+
>    +---------+RUNNING<----->PAUSED|
>    |         +--+----+     +------+
>    |            |
>    |         +--v--+       +-------+
>    +---------+READY<------->STANDBY|
>    |         +-----+       +-------+
>    |
> +--v-----+
> |ABORTING|
> +--------+
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

> @@ -383,6 +384,10 @@ static void block_job_completed_single(BlockJob *job)
>  {
>      assert(job->completed);
>  
> +    if (job->ret || block_job_is_cancelled(job)) {
> +        block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
> +    }
> +
>      if (!job->ret) {
>          if (job->driver->commit) {
>              job->driver->commit(job);

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

But I do have a question about the code below the new lines: I wonder
where job->ret is set to an error value? I can clearly see that the job
is marked as cancelled, so your added code should be working, but
looking at the block job code, it looks to me as if the jobs were
completing with job->cancelled = true and job->ret = 0.

For block_job_completed_single(), this means that we would call the
.commit callback and .cb with a success return code, while sending a
CANCELLED event on QMP.

Of course, the only job type that supports transactions is the backup
job, and that one seems to compensate for this by explicitly checking
block_job_is_cancelled() in its .commit implementation, but is that
really how things should be working?

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state John Snow
  2018-02-27 19:38   ` Eric Blake
@ 2018-02-28 15:37   ` Kevin Wolf
  2018-02-28 19:29     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 15:37 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> add a new state "CONCLUDED" that identifies a job that has ceased all
> operations. The wording was chosen to avoid any phrasing that might
> imply success, error, or cancellation. The task has simply ceased all
> operation and can never again perform any work.
> 
> ("finished", "done", and "completed" might all imply success.)
> 
> Transitions:
> Running  -> Concluded: normal completion
> Ready    -> Concluded: normal completion
> Aborting -> Concluded: error and cancellations
> 
> Verbs:
> None as of this commit. (a future commit adds 'dismiss')
> 
>              +---------+
>              |UNDEFINED|
>              +--+------+
>                 |
>              +--v----+
>              |CREATED|
>              +--+----+
>                 |
>              +--v----+     +------+
>    +---------+RUNNING<----->PAUSED|
>    |         +--+-+--+     +------+
>    |            | |
>    |            | +------------------+
>    |            |                    |
>    |         +--v--+       +-------+ |
>    +---------+READY<------->STANDBY| |
>    |         +--+--+       +-------+ |
>    |            |                    |
> +--v-----+   +--v------+             |
> |ABORTING+--->CONCLUDED<-------------+
> +--------+   +---------+
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

> +static void block_job_event_concluded(BlockJob *job)
> +{
> +    if (block_job_is_internal(job) || !job->manual) {
> +        return;
> +    }
> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
> +}

I don't understand why internal or automatic jobs should follow a
different state machine. Sure, they won't be in this state for long
because the job is immediately unref'ed. Though if someone holds an
additional reference, it might be visible - I would consider this a bug
fix because otherwise the job stays in READY and continues to accept the
verbs for that state.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state John Snow
  2018-02-27 19:41   ` Eric Blake
@ 2018-02-28 15:42   ` Kevin Wolf
  2018-02-28 20:04     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 15:42 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Add a new state that specifically demarcates when we begin to permanently
> demolish a job after it has performed all work. This makes the transition
> explicit in the STM table and highlights conditions under which a job may
> be demolished.
> 
> 
> Transitions:
> Created   -> Null: Early failure event before the job is started
> Concluded -> Null: Standard transition.
> 
> Verbs:
> None. This should not ever be visible to the monitor.
> 
>              +---------+
>              |UNDEFINED|
>              +--+------+
>                 |
>              +--v----+
>              |CREATED+------------------+
>              +--+----+                  |
>                 |                       |
>              +--v----+     +------+     |
>    +---------+RUNNING<----->PAUSED|     |
>    |         +--+-+--+     +------+     |
>    |            | |                     |
>    |            | +------------------+  |
>    |            |                    |  |
>    |         +--v--+       +-------+ |  |
>    +---------+READY<------->STANDBY| |  |
>    |         +--+--+       +-------+ |  |
>    |            |                    |  |
> +--v-----+   +--v------+             |  |
> |ABORTING+--->CONCLUDED<-------------+  |
> +--------+   +--+------+                |
>                 |                       |
>              +--v-+                     |
>              |NULL<---------------------+
>              +----+
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

The commit message does not match the code:

> @@ -423,6 +424,7 @@ static void block_job_completed_single(BlockJob *job)
>      QLIST_REMOVE(job, txn_list);
>      block_job_txn_unref(job->txn);
>      block_job_event_concluded(job);
> +    block_job_state_transition(job, BLOCK_JOB_STATUS_NULL);
>      block_job_unref(job);
>  }
>  
> @@ -734,9 +736,6 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
>  
>  static void block_job_event_concluded(BlockJob *job)
>  {
> -    if (block_job_is_internal(job) || !job->manual) {
> -        return;
> -    }
>      block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
>  }

Any job that transition to NULL goes first through CONCLUDED. There is
no way to reach NULL directly from CREATED.

The second hunk addresses my comment in the previous patch, so it should
probably be squashed in there.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss John Snow
  2018-02-27 19:44   ` Eric Blake
@ 2018-02-28 15:53   ` Kevin Wolf
  2018-02-28 20:35     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 15:53 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> For jobs that have reached their CONCLUDED state, prior to having their
> last reference put down (meaning jobs that have completed successfully,
> unsuccessfully, or have been canceled), allow the user to dismiss the
> job's lingering status report via block-job-dismiss.
> 
> This gives management APIs the chance to conclusively determine if a job
> failed or succeeded, even if the event broadcast was missed.
> 
> Note that jobs do not yet linger in any such state, they are freed
> immediately upon reaching this previously-unnamed state. such a state is
> added immediately in the next commit.
> 
> Verbs:
> Dismiss: operates on CONCLUDED jobs only.

You want to insert an empty line here.

> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  block/trace-events       |  1 +
>  blockdev.c               | 14 ++++++++++++++
>  blockjob.c               | 34 ++++++++++++++++++++++++++++++++--
>  include/block/blockjob.h |  9 +++++++++
>  qapi/block-core.json     | 24 +++++++++++++++++++++++-
>  5 files changed, 79 insertions(+), 3 deletions(-)

> @@ -841,6 +865,9 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
>          block_job_txn_add_job(txn, job);
>      }
>  
> +    /* For the expanded job control STM, grab an extra
> +     * reference for finalize() to put down */

Do you mean dismiss()?

> +    block_job_ref(job);
>      return job;
>  }
>  
> @@ -859,6 +886,9 @@ void block_job_pause_all(void)
>  
>  void block_job_early_fail(BlockJob *job)
>  {
> +    /* One for creation, one for finalize() */

And here?

> +    assert(job->status == BLOCK_JOB_STATUS_CREATED);
> +    block_job_unref(job);
>      block_job_unref(job);
>  }

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs John Snow
  2018-02-27 19:49   ` Eric Blake
@ 2018-02-28 16:05   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 16:05 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Presently, even if a job is canceled post-completion as a result of
> a failing peer in a transaction, it will still call .commit because
> nothing has updated or changed its return code.
> 
> The reason why this does not cause problems currently is because
> backup's implementation of .commit checks for cancellation itself.
> 
> I'd like to simplify this contract:
> 
> (1) Abort is called if the job/transaction fails
> (2) Commit is called if the job/transaction succeeds
> 
> To this end: A job's return code, if 0, will be forcibly set as
> -ECANCELED if that job has already concluded. Remove the now
> redundant check in the backup job implementation.

Thanks, another fix that addresses a comment I made on an earlier patch!

> We need to check for cancellation in both block_job_completed
> AND block_job_completed_single, because jobs may be cancelled between
> those two calls; for instance in transactions.
> 
> The check in block_job_completed could be removed, but there's no
> point in starting to attempt to succeed a transaction that we know
> in advance will fail.
> 
> This does NOT affect mirror jobs that are "canceled" during their
> synchronous phase. The mirror job itself forcibly sets the canceled
> property to false prior to ceding control, so such cases will invoke
> the "commit" callback.

Which is a sign that mirror is abusing the interface. But yes, we need
to keep it working.

> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  block/backup.c     |  2 +-
>  block/trace-events |  1 +
>  blockjob.c         | 19 +++++++++++++++----
>  3 files changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/block/backup.c b/block/backup.c
> index 7e254dabff..453cd62c24 100644
> --- a/block/backup.c
> +++ b/block/backup.c
> @@ -206,7 +206,7 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
>      BdrvDirtyBitmap *bm;
>      BlockDriverState *bs = blk_bs(job->common.blk);
>  
> -    if (ret < 0 || block_job_is_cancelled(&job->common)) {
> +    if (ret < 0) {
>          /* Merge the successor back into the parent, delete nothing. */
>          bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
>          assert(bm);
> diff --git a/block/trace-events b/block/trace-events
> index 266afd9e99..5e531e0310 100644
> --- a/block/trace-events
> +++ b/block/trace-events
> @@ -5,6 +5,7 @@ bdrv_open_common(void *bs, const char *filename, int flags, const char *format_n
>  bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
>  
>  # blockjob.c
> +block_job_completed(void *job, int ret, int jret) "job %p ret %d corrected ret %d"
>  block_job_state_transition(void *job,  int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
>  block_job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)"
>  
> diff --git a/blockjob.c b/blockjob.c
> index 4d29391673..ef17dea004 100644
> --- a/blockjob.c
> +++ b/blockjob.c
> @@ -384,13 +384,22 @@ void block_job_start(BlockJob *job)
>      bdrv_coroutine_enter(blk_bs(job->blk), job->co);
>  }
>  
> +static void block_job_update_rc(BlockJob *job)
> +{
> +    if (!job->ret && block_job_is_cancelled(job)) {
> +        job->ret = -ECANCELED;
> +    }
> +    if (job->ret) {
> +        block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
> +    }
> +}
> +
>  static void block_job_completed_single(BlockJob *job)
>  {
>      assert(job->completed);
>  
> -    if (job->ret || block_job_is_cancelled(job)) {
> -        block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
> -    }
> +    /* Ensure abort is called for late-transactional failures */
> +    block_job_update_rc(job);
>  
>      if (!job->ret) {
>          if (job->driver->commit) {
> @@ -898,7 +907,9 @@ void block_job_completed(BlockJob *job, int ret)
>      assert(blk_bs(job->blk)->job == job);
>      job->completed = true;
>      job->ret = ret;
> -    if (ret < 0 || block_job_is_cancelled(job)) {
> +    block_job_update_rc(job);

Hmm... We are transitioning to ABORTED here now. This means that in
block_job_completed_single() we get an ABORTED -> ABORTED transition.
A bit ugly, but not really a problem. If you decide to remove the
s0 == s1 special case in block_job_state_transition(), you'll need to
allow this transition in the table.

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers John Snow
  2018-02-27 19:50   ` Eric Blake
@ 2018-02-28 16:07   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 16:07 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> The completed_single function is getting a little mucked up with
> checking to see which callbacks exist, so let's factor them out.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function John Snow
  2018-02-27 19:52   ` Eric Blake
@ 2018-02-28 16:32   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 16:32 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Simply apply a function transaction-wide.
> A few more uses of this in forthcoming patches.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  blockjob.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/blockjob.c b/blockjob.c
> index 431ce9c220..8f02c03880 100644
> --- a/blockjob.c
> +++ b/blockjob.c
> @@ -467,6 +467,19 @@ static void block_job_cancel_async(BlockJob *job)
>      job->cancelled = true;
>  }
>  
> +static void block_job_txn_apply(BlockJobTxn *txn, void fn(BlockJob *))
> +{
> +    AioContext *ctx;
> +    BlockJob *job, *next;
> +
> +    QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
> +        ctx = blk_get_aio_context(job->blk);
> +        aio_context_acquire(ctx);
> +        fn(job);
> +        aio_context_release(ctx);
> +    }
> +}
> +
>  static void block_job_do_dismiss(BlockJob *job)
>  {
>      assert(job);
> @@ -552,9 +565,8 @@ static void block_job_completed_txn_abort(BlockJob *job)
>  
>  static void block_job_completed_txn_success(BlockJob *job)
>  {
> -    AioContext *ctx;
>      BlockJobTxn *txn = job->txn;
> -    BlockJob *other_job, *next;
> +    BlockJob *other_job;
>      /*
>       * Successful completion, see if there are other running jobs in this
>       * txn.
> @@ -565,13 +577,7 @@ static void block_job_completed_txn_success(BlockJob *job)
>          }
>      }
>      /* We are the last completed job, commit the transaction. */
> -    QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
> -        ctx = blk_get_aio_context(other_job->blk);
> -        aio_context_acquire(ctx);
> -        assert(other_job->ret == 0);

Can we just move the assertion up a few lines (after checking
other_job->completed) instead of removing it?

> -        block_job_completed_single(other_job);
> -        aio_context_release(ctx);
> -    }
> +    block_job_txn_apply(txn, block_job_completed_single);
>  }

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback John Snow
  2018-02-27 19:56   ` Eric Blake
@ 2018-02-28 17:04   ` Kevin Wolf
  2018-03-07  3:19     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 17:04 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Some jobs upon finalization may need to perform some work that can
> still fail. If these jobs are part of a transaction, it's important
> that these callbacks fail the entire transaction.
> 
> We allow for a new callback in addition to commit/abort/clean that
> allows us the opportunity to have fairly late-breaking failures
> in the transactional process.
> 
> The expected flow is:
> 
> - All jobs in a transaction converge to the WAITING state
>   (added in a forthcoming commit)
> - All jobs prepare to call either commit/abort
> - If any job fails, is canceled, or fails preparation, all jobs
>   call their .abort callback.
> - All jobs enter the PENDING state, awaiting manual intervention
>   (also added in a forthcoming commit)
> - block-job-finalize is issued by the user/management layer
> - All jobs call their commit callbacks.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

You almost made me believe the scary thought that we need transactional
graph modifications, but after writing half of the reply, I think it's
just that your order here is wrong.

So .prepare is the last thing in the whole process that is allowed to
fail. Graph manipulations such as bdrv_replace_node() can fail. Graph
manipulations can also only be made in response to block-job-finalize
because the management layer must be aware of them. Take them together
and you have a problem.

Didn't we already establish earlier that .prepare/.commit/.abort must be
called together and cannot be separated by waiting for a QMP command
because of locking and things?

So if you go to PENDING first, then wait for block-job-finalize and only
then call .prepare/.commit/.abort, we should be okay for both problems.

And taking a look at the final state, that seems to be what you do, so
in the end, it's probably just the commit message that needs a fix.

>  blockjob.c                   | 34 +++++++++++++++++++++++++++++++---
>  include/block/blockjob_int.h | 10 ++++++++++
>  2 files changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/blockjob.c b/blockjob.c
> index 8f02c03880..1c010ec100 100644
> --- a/blockjob.c
> +++ b/blockjob.c
> @@ -394,6 +394,18 @@ static void block_job_update_rc(BlockJob *job)
>      }
>  }
>  
> +static int block_job_prepare(BlockJob *job)
> +{
> +    if (job->ret) {
> +        goto out;
> +    }
> +    if (job->driver->prepare) {
> +        job->ret = job->driver->prepare(job);
> +    }
> + out:
> +    return job->ret;
> +}

Why not just if (job->ret == 0 && job->driver->prepare) and save the
goto?

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status
  2018-02-27 20:50     ` John Snow
@ 2018-02-28 17:46       ` Kevin Wolf
  0 siblings, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 17:46 UTC (permalink / raw)
  To: John Snow; +Cc: Eric Blake, qemu-block, pkrempa, jtc, qemu-devel

Am 27.02.2018 um 21:50 hat John Snow geschrieben:
> 
> 
> On 02/27/2018 03:00 PM, Eric Blake wrote:
> > On 02/23/2018 05:51 PM, John Snow wrote:
> >> For jobs that are stuck waiting on others in a transaction, it would
> >> be nice to know that they are no longer "running" in that sense, but
> >> instead are waiting on other jobs in the transaction.
> >>
> >> Jobs that are "waiting" in this sense cannot be meaningfully altered
> >> any longer as they have left their running loop. The only meaningful
> >> user verb for jobs in this state is "cancel," which will cancel the
> >> whole transaction, too.
> >>
> >> Transitions:
> >> Running -> Waiting:   Normal transition.
> >> Ready   -> Waiting:   Normal transition.
> >> Waiting -> Aborting:  Transactional cancellation.
> >> Waiting -> Concluded: Normal transition.
> >>
> >> Removed Transitions:
> >> Running -> Concluded: Jobs must go to WAITING first.
> >> Ready   -> Concluded: Jobs must go to WAITING fisrt.
> > 
> > s/fisrt/first/
> > 
> >> +++ b/blockjob.c
> > 
> >> @@ -3934,6 +3938,29 @@
> >>               'offset': 'int',
> >>               'speed' : 'int' } }
> >>   +##
> >> +# @BLOCK_JOB_WAITING:
> >> +#
> >> +# Emitted when a block job that is part of a transction has stopped
> >> work and is
> > 
> > s/transction/transaction/
> > 
> >> +# waiting for other jobs in the transaction to reach the same state.
> > 
> > Is this event emitted only for 'new-style' transactions (old drivers
> > will never see it, because they don't request new style), or always (old
> > drivers will see, but presumably ignore, it)?
> > 
> 
> ...! Actually, I meant to remove the WAITING *event* entirely, this is a
> mistake.
> 
> It's purely an informational state that clients likely cannot make any
> real use of, because regardless of old or new style, jobs will
> transition automatically to "PENDING."
> 
> That said, old or new, the state is visible from query-block-jobs.

It means that the block job isn't working any more, which could possibly
be useful information.

Umm... When mirror transitions into WAITING, it stops working, but
doesn't change the graph yet. Isn't that a problem? Currently it doesn't
cause bugs because mirror doesn't support transactions, but we should
design things so that mirror could become transactionable later on.

I suppose one way to achieve this would be that mirror only transitions
into WAITING when the whole transaction is ready to move forward. In
this case, block-job-complete wouldn't tell mirror any more to actually
complete, but just to signal that the user is ready to have this job
completed.

Essentially this would split READY in two: The first state is when the
job has completed the bulk job and waits for the user, and the second
state is after the user sent block-job-complete. The second state
automatically transitions into WAITING as soon as all other jobs in the
transaction are either WAITING or in the second READY state.

Alternatively, mirror jobs could stay active in the WAITING phase, which
would then become the second READY phase. In this case, the state
machine would stay as it is, just the semantics of WAITING would change.

The result is either way that the WAITING event becomes uninteresting,
so after all I think I agree with completely removing it.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event John Snow
  2018-02-27 20:05   ` Eric Blake
@ 2018-02-28 17:55   ` Kevin Wolf
  1 sibling, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 17:55 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> For jobs utilizing the new manual workflow, we intend to prohibit
> them from modifying the block graph until the management layer provides
> an explicit ACK via block-job-finalize to move the process forward.
> 
> To distinguish this runstate from "ready" or "waiting," we add a new
> "pending" event.
> 
> For now, the transition from PENDING to CONCLUDED/ABORTING is automatic,
> but a future commit will add the explicit block-job-finalize step.
> 
> Transitions:
> Waiting -> Pending:   Normal transition.
> Pending -> Concluded: Normal transition.
> Pending -> Aborting:  Late transactional failures and cancellations.
> 
> Removed Transitions:
> Waiting -> Concluded: Jobs must go to PENDING first.
> 
> Verbs:
> Cancel: Can be applied to a pending job.
> 
>              +---------+
>              |UNDEFINED|
>              +--+------+
>                 |
>              +--v----+
>              |CREATED+-----------------+
>              +--+----+                 |
>                 |                      |
>              +--+----+     +------+    |
>    +---------+RUNNING<----->PAUSED|    |
>    |         +--+-+--+     +------+    |
>    |            | |                    |
>    |            | +------------------+ |
>    |            |                    | |
>    |         +--v--+       +-------+ | |
>    +---------+READY<------->STANDBY| | |
>    |         +--+--+       +-------+ | |
>    |            |                    | |
>    |         +--v----+               | |
>    +---------+WAITING+---------------+ |
>    |         +--+----+                 |
>    |            |                      |
>    |         +--v----+                 |
>    +---------+PENDING|                 |
>    |         +--+----+                 |
>    |            |                      |
> +--v-----+   +--v------+               |
> |ABORTING+--->CONCLUDED|               |
> +--------+   +--+------+               |
>                 |                      |
>              +--v-+                    |
>              |NULL+--------------------+
>              +----+
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Your diagram lost two arrow heads in this commit. :-)

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize John Snow
  2018-02-27 20:13   ` Eric Blake
@ 2018-02-28 18:15   ` Kevin Wolf
  2018-02-28 19:14     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 18:15 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Instead of automatically transitioning from PENDING to CONCLUDED, gate
> the .prepare() and .commit() phases behind an explicit acknowledgement
> provided by the QMP monitor if manual completion mode has been requested.
> 
> This allows us to perform graph changes in prepare and/or commit so that
> graph changes do not occur autonomously without knowledge of the
> controlling management layer.
> 
> Transactions that have reached the "PENDING" state together can all be
> moved to invoke their finalization methods by issuing block_job_finalize
> to any one job in the transaction.
> 
> Jobs in a transaction with mixed job->manual settings will remain stuck
> in the "WAITING" state until block_job_finalize is authored on the job(s)
> that have reached the "PENDING" state.

Why? Removing this inconsistency would make the code slightly simpler.

Is it because you want to avoid that the user picks an automatic job for
completing the mixed transaction?

> These jobs are not allowed to progress because other jobs in the
> transaction may still fail during their preparation phase during
> finalization, so these jobs must remain in the WAITING phase until
> success is guaranteed. These jobs will then automatically dismiss
> themselves, but jobs that had the manual property set will remain
> at CONCLUDED as normal.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  block/trace-events       |  1 +
>  blockdev.c               | 14 ++++++++++
>  blockjob.c               | 69 +++++++++++++++++++++++++++++++++++++-----------
>  include/block/blockjob.h | 17 ++++++++++++
>  qapi/block-core.json     | 23 +++++++++++++++-
>  5 files changed, 108 insertions(+), 16 deletions(-)
> 
> diff --git a/block/trace-events b/block/trace-events
> index 5e531e0310..a81b66ff36 100644
> --- a/block/trace-events
> +++ b/block/trace-events
> @@ -51,6 +51,7 @@ qmp_block_job_cancel(void *job) "job %p"
>  qmp_block_job_pause(void *job) "job %p"
>  qmp_block_job_resume(void *job) "job %p"
>  qmp_block_job_complete(void *job) "job %p"
> +qmp_block_job_finalize(void *job) "job %p"
>  qmp_block_job_dismiss(void *job) "job %p"
>  qmp_block_stream(void *bs, void *job) "bs %p job %p"
>  
> diff --git a/blockdev.c b/blockdev.c
> index 3180130782..05fd421cdc 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -3852,6 +3852,20 @@ void qmp_block_job_complete(const char *device, Error **errp)
>      aio_context_release(aio_context);
>  }
>  
> +void qmp_block_job_finalize(const char *id, Error **errp)
> +{
> +    AioContext *aio_context;
> +    BlockJob *job = find_block_job(id, &aio_context, errp);
> +
> +    if (!job) {
> +        return;
> +    }
> +
> +    trace_qmp_block_job_finalize(job);
> +    block_job_finalize(job, errp);
> +    aio_context_release(aio_context);
> +}
> +
>  void qmp_block_job_dismiss(const char *id, Error **errp)
>  {
>      AioContext *aio_context;
> diff --git a/blockjob.c b/blockjob.c
> index 23b4b99fd4..f9e8a64261 100644
> --- a/blockjob.c
> +++ b/blockjob.c
> @@ -65,14 +65,15 @@ bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
>      [BLOCK_JOB_VERB_RESUME]               = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
>      [BLOCK_JOB_VERB_SET_SPEED]            = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
>      [BLOCK_JOB_VERB_COMPLETE]             = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
> +    [BLOCK_JOB_VERB_FINALIZE]             = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
>      [BLOCK_JOB_VERB_DISMISS]              = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
>  };
>  
> -static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
> +static bool block_job_state_transition(BlockJob *job, BlockJobStatus s1)
>  {
>      BlockJobStatus s0 = job->status;
>      if (s0 == s1) {
> -        return;
> +        return false;
>      }
>      assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
>      trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
> @@ -83,6 +84,7 @@ static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
>                                                        s1));
>      assert(BlockJobSTT[s0][s1]);
>      job->status = s1;
> +    return true;
>  }
>  
>  static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
> @@ -432,7 +434,7 @@ static void block_job_clean(BlockJob *job)
>      }
>  }
>  
> -static int block_job_completed_single(BlockJob *job)
> +static int block_job_finalize_single(BlockJob *job)
>  {
>      assert(job->completed);
>  
> @@ -581,18 +583,44 @@ static void block_job_completed_txn_abort(BlockJob *job)
>              assert(other_job->cancelled);
>              block_job_finish_sync(other_job, NULL, NULL);
>          }
> -        block_job_completed_single(other_job);
> +        block_job_finalize_single(other_job);
>          aio_context_release(ctx);
>      }
>  
>      block_job_txn_unref(txn);
>  }
>  
> +static int block_job_is_manual(BlockJob *job)
> +{
> +    return job->manual;
> +}
> +
> +static void block_job_do_finalize(BlockJob *job)
> +{
> +    int rc;
> +    assert(job && job->txn);
> +
> +    /* For jobs set !job->manual, transition to pending synchronously now */
> +    block_job_txn_apply(job->txn, block_job_event_pending, false);
> +
> +    /* prepare the transaction to complete */
> +    rc = block_job_txn_apply(job->txn, block_job_prepare, true);
> +    if (rc) {
> +        block_job_completed_txn_abort(job);
> +    } else {
> +        block_job_txn_apply(job->txn, block_job_finalize_single, true);
> +    }
> +}
> +
> +static int block_job_pending_conditional(BlockJob *job)
> +{
> +    return job->manual ? block_job_event_pending(job) : 0;
> +}

As I said above, I'd get rid of this function altogether, but if not,
can we have something like this:

    if (job->manual) {
        ret = block_job_event_pending()
        assert(ret == 0);
    }
    return 0;

Because if block_job_event_pending() ever started returning errors, the
abort-on-error semantics of block_job_txn_apply() would break this
function.

>  static void block_job_completed_txn_success(BlockJob *job)
>  {
>      BlockJobTxn *txn = job->txn;
>      BlockJob *other_job;
> -    int rc = 0;
>  
>      block_job_state_transition(job, BLOCK_JOB_STATUS_WAITING);
>  
> @@ -606,16 +634,15 @@ static void block_job_completed_txn_success(BlockJob *job)
>          }
>      }
>  
> -    /* Jobs may require some prep-work to complete without failure */
> -    rc = block_job_txn_apply(txn, block_job_prepare, true);
> -    if (rc) {
> -        block_job_completed_txn_abort(job);
> -        return;
> -    }
> +    /* For jobs with (job->manual), transition to the PENDING state.
> +     * jobs with !job->manual are left WAITING (on their pending comrades). */
> +    block_job_txn_apply(txn, block_job_pending_conditional, false);
>  
> -    /* We are the last completed job, commit the transaction. */
> -    block_job_txn_apply(txn, block_job_event_pending, false);
> -    block_job_txn_apply(txn, block_job_completed_single, true);
> +    /* Transactions with any manual jobs must await finalization.
> +     * do_finalize will handle lingering WAITING->PENDING transitions. */
> +    if (!block_job_txn_apply(txn, block_job_is_manual, false)) {
> +        block_job_do_finalize(job);
> +    }
>  }
>  
>  /* Assumes the block_job_mutex is held */
> @@ -667,6 +694,15 @@ void block_job_complete(BlockJob *job, Error **errp)
>      job->driver->complete(job, errp);
>  }
>  
> +void block_job_finalize(BlockJob *job, Error **errp)
> +{
> +    assert(job && job->id && job->txn);
> +    if (block_job_apply_verb(job, BLOCK_JOB_VERB_FINALIZE, errp)) {
> +        return;
> +    }
> +    block_job_do_finalize(job);
> +}
> +
>  void block_job_dismiss(BlockJob **jobptr, Error **errp)
>  {
>      BlockJob *job = *jobptr;
> @@ -826,7 +862,10 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
>  
>  static int block_job_event_pending(BlockJob *job)
>  {
> -    block_job_state_transition(job, BLOCK_JOB_STATUS_PENDING);
> +    /* If we're already pending, don't re-announce */
> +    if (!block_job_state_transition(job, BLOCK_JOB_STATUS_PENDING)) {
> +        return 0;
> +    }

Without the exception for manual jobs, you wouldn't get double
transitions and could avoid adding a return value to
block_job_state_transition(), where we were considering dropping the
s0 == s1 case anyway.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-27 21:57     ` John Snow
  2018-02-27 22:27       ` Eric Blake
@ 2018-02-28 18:23       ` Kevin Wolf
  2018-02-28 19:19         ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 18:23 UTC (permalink / raw)
  To: John Snow; +Cc: Eric Blake, qemu-block, pkrempa, jtc, qemu-devel

Am 27.02.2018 um 22:57 hat John Snow geschrieben:
> 
> 
> On 02/27/2018 03:16 PM, Eric Blake wrote:
> > On 02/23/2018 05:51 PM, John Snow wrote:
> >> Expose the "manual" property via QAPI for the backup-related jobs.
> >> As of this commit, this allows the management API to request the
> >> "concluded" and "dismiss" semantics for backup jobs.
> >>
> >> Signed-off-by: John Snow <jsnow@redhat.com>
> >> ---
> >>   blockdev.c           | 19 ++++++++++++++++---
> >>   qapi/block-core.json | 32 ++++++++++++++++++++++++++------
> >>   2 files changed, 42 insertions(+), 9 deletions(-)
> >>
> > 
> >> +++ b/qapi/block-core.json
> >> @@ -1177,6 +1177,16 @@
> >>   # @job-id: identifier for the newly-created block job. If
> >>   #          omitted, the device name will be used. (Since 2.7)
> >>   #
> >> +# @manual: True to use an expanded, more explicit job control flow.
> >> +#          Jobs may transition from a running state to a pending state,
> >> +#          where they must be instructed to complete manually via
> >> +#          block-job-finalize.
> >> +#          Jobs belonging to a transaction must either all or all not
> >> use this
> >> +#          setting. Once a transaction reaches a pending state,
> >> issuing the
> >> +#          finalize command to any one job in the transaction is
> >> sufficient
> >> +#          to finalize the entire transaction.
> > 
> > The previous commit message talked about mixed-manual transactions, but
> > this seems to imply it is not possible.  I'm fine if we don't support
> > mixed-manual transactions, but wonder if it means any changes to the
> > series.
> > 
> > Otherwise looks reasonable from the UI point of view.
> > 
> 
> More seriously, this documentation I wrote doesn't address the totality
> of the expanded flow. I omitted dismiss here by accident as well. This
> is at best a partial definition of the 'manual' property.
> 
> I'd like to use _this_ patch to ask the question: "What should the
> proper noun for the QEMU 2.12+ Expanded Block Job Management Flow
> Mechanism be?"
> 
> I'm not too sure, but "Manual mode" leaves a lot to be desired.

I still think that the best way to expose it is like this:

    # both default to true
    '*auto-finalize': 'bool',
    '*auto-dismiss': 'bool',

These options would be very easy to describe because they just invoke
the functionality of a specific QMP command automatically as soon as it
becomes available for the job.

But given how often I already said that and people still don't consider
it as an option, this doesn't appear to have been very convincing. So
whatever... *shrug*

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-23 23:51 ` [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property John Snow
  2018-02-27 20:16   ` Eric Blake
@ 2018-02-28 18:25   ` Kevin Wolf
  2018-02-28 19:20     ` John Snow
  1 sibling, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 18:25 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pkrempa, jtc, qemu-devel

Am 24.02.2018 um 00:51 hat John Snow geschrieben:
> Expose the "manual" property via QAPI for the backup-related jobs.
> As of this commit, this allows the management API to request the
> "concluded" and "dismiss" semantics for backup jobs.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  blockdev.c           | 19 ++++++++++++++++---
>  qapi/block-core.json | 32 ++++++++++++++++++++++++++------
>  2 files changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index 05fd421cdc..2eddb0e726 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -3260,7 +3260,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
>      AioContext *aio_context;
>      QDict *options = NULL;
>      Error *local_err = NULL;
> -    int flags;
> +    int flags, job_flags = BLOCK_JOB_DEFAULT;
>      int64_t size;
>      bool set_backing_hd = false;
>  
> @@ -3279,6 +3279,9 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
>      if (!backup->has_job_id) {
>          backup->job_id = NULL;
>      }
> +    if (!backup->has_manual) {
> +        backup->manual = false;
> +    }

I think this is unnecessary these days, NULL/0/false is the default
value for QMP/QAPI.

>      if (!backup->has_compress) {
>          backup->compress = false;
>      }
> @@ -3422,6 +3429,9 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
>      if (!backup->has_job_id) {
>          backup->job_id = NULL;
>      }
> +    if (!backup->has_manual) {
> +        backup->manual = false;
> +    }

Same here.

>      if (!backup->has_compress) {
>          backup->compress = false;
>      }

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions
  2018-02-27 20:24   ` Eric Blake
@ 2018-02-28 18:29     ` Kevin Wolf
  2018-02-28 19:24       ` John Snow
  0 siblings, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 18:29 UTC (permalink / raw)
  To: Eric Blake; +Cc: John Snow, qemu-block, pkrempa, jtc, qemu-devel

Am 27.02.2018 um 21:24 hat Eric Blake geschrieben:
> On 02/23/2018 05:51 PM, John Snow wrote:
> > This allows us to easily force the option for all jobs belonging
> > to a transaction to ensure consistency with how all those jobs
> > will be handled.
> > 
> > This is purely a convenience.
> > 
> > Signed-off-by: John Snow <jsnow@redhat.com>
> > ---
> 
> > +++ b/qapi/transaction.json
> > @@ -79,7 +79,8 @@
> >   ##
> >   { 'struct': 'TransactionProperties',
> >     'data': {
> > -       '*completion-mode': 'ActionCompletionMode'
> > +       '*completion-mode': 'ActionCompletionMode',
> > +       '*manual-mgmt': 'bool'
> 
> Missing QAPI documentation (what you have elsewhere in the C code can
> probably be copied here, though).
> 
> The UI aspect makes sense (I can declare one manual at the transaction level
> instead of multiple manual declarations per member level within the
> transaction).

I'm not so sure if I like the interface, it duplicates functionality in
two places.

At th very least I would make job creation without BLOCK_JOB_MANUAL an
error if the transaction requires it instead of silently overriding the
option that was given to the individual job. But honestly, it might be
better to just leave this one away.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management
  2018-02-27 21:01   ` John Snow
@ 2018-02-28 18:32     ` Kevin Wolf
  0 siblings, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-02-28 18:32 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-devel, famz, qemu-block, pkrempa, jtc

Am 27.02.2018 um 22:01 hat John Snow geschrieben:
> All false positives unless someone really would like to advocate for me
> to change the format of the table.

Agreed, this isn't going to stop the series. Changing the format of the
table would make it much harder to read.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize
  2018-02-28 18:15   ` Kevin Wolf
@ 2018-02-28 19:14     ` John Snow
  2018-03-01 10:01       ` Kevin Wolf
  0 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-28 19:14 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/28/2018 01:15 PM, Kevin Wolf wrote:
> Is it because you want to avoid that the user picks an automatic job for
> completing the mixed transaction?

I wanted to avoid the case that a job without the manual property would
be stuck "pending" -- which I have defined to mean that it is waiting on
an authorization from the user -- which isn't really true: it's waiting
on its peers in the transaction to receive that authorization.

It would indeed be simpler to just let them stick around in PENDING like
their peers, but it felt like a hacky way to allow mixed-mode
transactions -- like they had been promoted for just a subset of their
lifetime.

So, mostly it was a semantic decision and not a functional one based on
what I considered "WAITING" to mean vs "PENDING".

If the definitions (and documentation) are adjusted it can be changed
for the simpler layout if it seems just as good from the API
perspective. (It's certainly better implementationally, as you say.)

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-28 18:23       ` Kevin Wolf
@ 2018-02-28 19:19         ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-28 19:19 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: Eric Blake, qemu-block, pkrempa, jtc, qemu-devel



On 02/28/2018 01:23 PM, Kevin Wolf wrote:
> But given how often I already said that and people still don't consider
> it as an option, this doesn't appear to have been very convincing. So
> whatever... *shrug*
> 

Sorry, I didn't mean to give that impression.

I initially *did* use two (or more?) variables to describe different
points, and I was convinced to collapse it down into one boolean that
meant "new or old" syntax.

I was just hesitant to run out and change it back until further comments
on what the series looked like at the moment.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-28 18:25   ` Kevin Wolf
@ 2018-02-28 19:20     ` John Snow
  2018-02-28 19:27       ` [Qemu-devel] [Qemu-block] " Eric Blake
  0 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-28 19:20 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/28/2018 01:25 PM, Kevin Wolf wrote:
> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>> Expose the "manual" property via QAPI for the backup-related jobs.
>> As of this commit, this allows the management API to request the
>> "concluded" and "dismiss" semantics for backup jobs.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>  blockdev.c           | 19 ++++++++++++++++---
>>  qapi/block-core.json | 32 ++++++++++++++++++++++++++------
>>  2 files changed, 42 insertions(+), 9 deletions(-)
>>
>> diff --git a/blockdev.c b/blockdev.c
>> index 05fd421cdc..2eddb0e726 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -3260,7 +3260,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
>>      AioContext *aio_context;
>>      QDict *options = NULL;
>>      Error *local_err = NULL;
>> -    int flags;
>> +    int flags, job_flags = BLOCK_JOB_DEFAULT;
>>      int64_t size;
>>      bool set_backing_hd = false;
>>  
>> @@ -3279,6 +3279,9 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
>>      if (!backup->has_job_id) {
>>          backup->job_id = NULL;
>>      }
>> +    if (!backup->has_manual) {
>> +        backup->manual = false;
>> +    }
> 
> I think this is unnecessary these days, NULL/0/false is the default
> value for QMP/QAPI.
> 

That's what I get for cargo cult. Eric, confirm/deny? Should I remove
the other auto-false defaults too?

Either we have them all or none of them for consistency.

--js

>>      if (!backup->has_compress) {
>>          backup->compress = false;
>>      }
>> @@ -3422,6 +3429,9 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
>>      if (!backup->has_job_id) {
>>          backup->job_id = NULL;
>>      }
>> +    if (!backup->has_manual) {
>> +        backup->manual = false;
>> +    }
> 
> Same here.
> 
>>      if (!backup->has_compress) {
>>          backup->compress = false;
>>      }
> 
> Kevin
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions
  2018-02-28 18:29     ` Kevin Wolf
@ 2018-02-28 19:24       ` John Snow
  2018-03-01 10:10         ` Kevin Wolf
  0 siblings, 1 reply; 98+ messages in thread
From: John Snow @ 2018-02-28 19:24 UTC (permalink / raw)
  To: Kevin Wolf, Eric Blake; +Cc: qemu-block, pkrempa, jtc, qemu-devel



On 02/28/2018 01:29 PM, Kevin Wolf wrote:
> Am 27.02.2018 um 21:24 hat Eric Blake geschrieben:
>> On 02/23/2018 05:51 PM, John Snow wrote:
>>> This allows us to easily force the option for all jobs belonging
>>> to a transaction to ensure consistency with how all those jobs
>>> will be handled.
>>>
>>> This is purely a convenience.
>>>
>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>> ---
>>
>>> +++ b/qapi/transaction.json
>>> @@ -79,7 +79,8 @@
>>>   ##
>>>   { 'struct': 'TransactionProperties',
>>>     'data': {
>>> -       '*completion-mode': 'ActionCompletionMode'
>>> +       '*completion-mode': 'ActionCompletionMode',
>>> +       '*manual-mgmt': 'bool'
>>
>> Missing QAPI documentation (what you have elsewhere in the C code can
>> probably be copied here, though).
>>
>> The UI aspect makes sense (I can declare one manual at the transaction level
>> instead of multiple manual declarations per member level within the
>> transaction).
> 
> I'm not so sure if I like the interface, it duplicates functionality in
> two places.
> 
> At th very least I would make job creation without BLOCK_JOB_MANUAL an
> error if the transaction requires it instead of silently overriding the
> option that was given to the individual job. But honestly, it might be
> better to just leave this one away.
> 
> Kevin
> 

Sure, I put it in the trailing position here because I see it as
optional. I don't like the idea of having to specify manual for each and
every item in a transaction, but if mixed-mode is possible then this is
less important.

I'll leave it off for now, but I will always fondly remember it, and
then maybe try to sneak it back in for v6.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state
  2018-02-28 14:54   ` Kevin Wolf
@ 2018-02-28 19:26     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-28 19:26 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/28/2018 09:54 AM, Kevin Wolf wrote:
> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>> Add a new state ABORTING.
>>
>> This makes transitions from normative states to error states explicit
>> in the STM, and serves as a disambiguation for which states may complete
>> normally when normal end-states (CONCLUDED) are added in future commits.
>>
>> Notably, Paused/Standby jobs do not transition directly to aborting,
>> as they must wake up first and cooperate in their cancellation.
>>
>> Transitions:
>> Running -> Aborting: can be cancelled or encounter an error
>> Ready   -> Aborting: can be cancelled or encounter an error
>>
>> Verbs:
>> None. The job must finish cleaning itself up and report its final status.
>>
>>              +---------+
>>              |UNDEFINED|
>>              +--+------+
>>                 |
>>              +--v----+
>>              |CREATED|
>>              +--+----+
>>                 |
>>              +--v----+     +------+
>>    +---------+RUNNING<----->PAUSED|
>>    |         +--+----+     +------+
>>    |            |
>>    |         +--v--+       +-------+
>>    +---------+READY<------->STANDBY|
>>    |         +-----+       +-------+
>>    |
>> +--v-----+
>> |ABORTING|
>> +--------+
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
> 
>> @@ -383,6 +384,10 @@ static void block_job_completed_single(BlockJob *job)
>>  {
>>      assert(job->completed);
>>  
>> +    if (job->ret || block_job_is_cancelled(job)) {
>> +        block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
>> +    }
>> +
>>      if (!job->ret) {
>>          if (job->driver->commit) {
>>              job->driver->commit(job);
> 
> Reviewed-by: Kevin Wolf <kwolf@redhat.com>
> 
> But I do have a question about the code below the new lines: I wonder
> where job->ret is set to an error value? I can clearly see that the job
> is marked as cancelled, so your added code should be working, but
> looking at the block job code, it looks to me as if the jobs were
> completing with job->cancelled = true and job->ret = 0.
> 
> For block_job_completed_single(), this means that we would call the
> .commit callback and .cb with a success return code, while sending a
> CANCELLED event on QMP.
> 
> Of course, the only job type that supports transactions is the backup
> job, and that one seems to compensate for this by explicitly checking
> block_job_is_cancelled() in its .commit implementation, but is that
> really how things should be working?
> 
> Kevin
> 

You re-discovered the same nonsensical thing that I discovered, which
led to patch 12.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [RFC v4 19/21] blockjobs: Expose manual property
  2018-02-28 19:20     ` John Snow
@ 2018-02-28 19:27       ` Eric Blake
  0 siblings, 0 replies; 98+ messages in thread
From: Eric Blake @ 2018-02-28 19:27 UTC (permalink / raw)
  To: John Snow, Kevin Wolf; +Cc: jtc, qemu-devel, qemu-block

On 02/28/2018 01:20 PM, John Snow wrote:

>>> +    if (!backup->has_manual) {
>>> +        backup->manual = false;
>>> +    }
>>
>> I think this is unnecessary these days, NULL/0/false is the default
>> value for QMP/QAPI.
>>
> 
> That's what I get for cargo cult. Eric, confirm/deny? Should I remove
> the other auto-false defaults too?
> 
> Either we have them all or none of them for consistency.

Someday it would be nice to have QAPI provide decent non-0 defaults as 
desired.  But for now, Kevin is correct - the QAPI generator guarantees 
that you will have NULL/0/false values for 'has' anywhere that 'has_foo' 
is false.  We're less consistent on whether we ensure that we don't 
access 'foo' without checking 'has_foo' first, but if you want to 
simplify by relying on the default initialization to 0, you will not be 
the first person to do so.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state
  2018-02-28 15:37   ` Kevin Wolf
@ 2018-02-28 19:29     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-28 19:29 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/28/2018 10:37 AM, Kevin Wolf wrote:
> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>> add a new state "CONCLUDED" that identifies a job that has ceased all
>> operations. The wording was chosen to avoid any phrasing that might
>> imply success, error, or cancellation. The task has simply ceased all
>> operation and can never again perform any work.
>>
>> ("finished", "done", and "completed" might all imply success.)
>>
>> Transitions:
>> Running  -> Concluded: normal completion
>> Ready    -> Concluded: normal completion
>> Aborting -> Concluded: error and cancellations
>>
>> Verbs:
>> None as of this commit. (a future commit adds 'dismiss')
>>
>>              +---------+
>>              |UNDEFINED|
>>              +--+------+
>>                 |
>>              +--v----+
>>              |CREATED|
>>              +--+----+
>>                 |
>>              +--v----+     +------+
>>    +---------+RUNNING<----->PAUSED|
>>    |         +--+-+--+     +------+
>>    |            | |
>>    |            | +------------------+
>>    |            |                    |
>>    |         +--v--+       +-------+ |
>>    +---------+READY<------->STANDBY| |
>>    |         +--+--+       +-------+ |
>>    |            |                    |
>> +--v-----+   +--v------+             |
>> |ABORTING+--->CONCLUDED<-------------+
>> +--------+   +---------+
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
> 
>> +static void block_job_event_concluded(BlockJob *job)
>> +{
>> +    if (block_job_is_internal(job) || !job->manual) {
>> +        return;
>> +    }
>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
>> +}
> 
> I don't understand why internal or automatic jobs should follow a
> different state machine. Sure, they won't be in this state for long

The very simple answer is because I overlooked this change from when I
did implement separate graphs for the old and new models.

> because the job is immediately unref'ed. Though if someone holds an
> additional reference, it might be visible - I would consider this a bug
> fix because otherwise the job stays in READY and continues to accept the
> verbs for that state.
> 
> Kevin
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state
  2018-02-28 15:42   ` Kevin Wolf
@ 2018-02-28 20:04     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-28 20:04 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/28/2018 10:42 AM, Kevin Wolf wrote:
> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>> Add a new state that specifically demarcates when we begin to permanently
>> demolish a job after it has performed all work. This makes the transition
>> explicit in the STM table and highlights conditions under which a job may
>> be demolished.
>>
>>
>> Transitions:
>> Created   -> Null: Early failure event before the job is started
>> Concluded -> Null: Standard transition.
>>
>> Verbs:
>> None. This should not ever be visible to the monitor.
>>
>>              +---------+
>>              |UNDEFINED|
>>              +--+------+
>>                 |
>>              +--v----+
>>              |CREATED+------------------+
>>              +--+----+                  |
>>                 |                       |
>>              +--v----+     +------+     |
>>    +---------+RUNNING<----->PAUSED|     |
>>    |         +--+-+--+     +------+     |
>>    |            | |                     |
>>    |            | +------------------+  |
>>    |            |                    |  |
>>    |         +--v--+       +-------+ |  |
>>    +---------+READY<------->STANDBY| |  |
>>    |         +--+--+       +-------+ |  |
>>    |            |                    |  |
>> +--v-----+   +--v------+             |  |
>> |ABORTING+--->CONCLUDED<-------------+  |
>> +--------+   +--+------+                |
>>                 |                       |
>>              +--v-+                     |
>>              |NULL<---------------------+
>>              +----+
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
> 
> The commit message does not match the code:
> 
>> @@ -423,6 +424,7 @@ static void block_job_completed_single(BlockJob *job)
>>      QLIST_REMOVE(job, txn_list);
>>      block_job_txn_unref(job->txn);
>>      block_job_event_concluded(job);
>> +    block_job_state_transition(job, BLOCK_JOB_STATUS_NULL);
>>      block_job_unref(job);
>>  }
>>  
>> @@ -734,9 +736,6 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
>>  
>>  static void block_job_event_concluded(BlockJob *job)
>>  {
>> -    if (block_job_is_internal(job) || !job->manual) {
>> -        return;
>> -    }
>>      block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
>>  }
> 
> Any job that transition to NULL goes first through CONCLUDED. There is
> no way to reach NULL directly from CREATED.
> 

Ah, that's true... I was trying to think of the case in which we do an
early uninit, but actually we just dismantle the job without having it
go to "null" first. I guess I found that edge case and then never did
anything about it except acknowledge it in the graph.

Something to fix...

> The second hunk addresses my comment in the previous patch, so it should
> probably be squashed in there.
> 
> Kevin
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss
  2018-02-28 15:53   ` Kevin Wolf
@ 2018-02-28 20:35     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-02-28 20:35 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/28/2018 10:53 AM, Kevin Wolf wrote:
> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>> For jobs that have reached their CONCLUDED state, prior to having their
>> last reference put down (meaning jobs that have completed successfully,
>> unsuccessfully, or have been canceled), allow the user to dismiss the
>> job's lingering status report via block-job-dismiss.
>>
>> This gives management APIs the chance to conclusively determine if a job
>> failed or succeeded, even if the event broadcast was missed.
>>
>> Note that jobs do not yet linger in any such state, they are freed
>> immediately upon reaching this previously-unnamed state. such a state is
>> added immediately in the next commit.
>>
>> Verbs:
>> Dismiss: operates on CONCLUDED jobs only.
> 
> You want to insert an empty line here.
> 

Don't tell me what I want.

(Seriously though, what the heck is wrong with my script? When I go to
edit this commend message there *IS* a newline here. This has been
happening a bit lately and I haven't really had the chance to catch it
happening in action yet... sorry.)

>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>  block/trace-events       |  1 +
>>  blockdev.c               | 14 ++++++++++++++
>>  blockjob.c               | 34 ++++++++++++++++++++++++++++++++--
>>  include/block/blockjob.h |  9 +++++++++
>>  qapi/block-core.json     | 24 +++++++++++++++++++++++-
>>  5 files changed, 79 insertions(+), 3 deletions(-)
> 
>> @@ -841,6 +865,9 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
>>          block_job_txn_add_job(txn, job);
>>      }
>>  
>> +    /* For the expanded job control STM, grab an extra
>> +     * reference for finalize() to put down */
> 
> Do you mean dismiss()?
> 

Sure. We'll say yes.

>> +    block_job_ref(job);
>>      return job;
>>  }
>>  
>> @@ -859,6 +886,9 @@ void block_job_pause_all(void)
>>  
>>  void block_job_early_fail(BlockJob *job)
>>  {
>> +    /* One for creation, one for finalize() */
> 
> And here?
> 

Sure. We'll say yes again.

>> +    assert(job->status == BLOCK_JOB_STATUS_CREATED);
>> +    block_job_unref(job);
>>      block_job_unref(job);
>>  }
> 
> Kevin
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize
  2018-02-28 19:14     ` John Snow
@ 2018-03-01 10:01       ` Kevin Wolf
  2018-03-01 19:24         ` John Snow
  0 siblings, 1 reply; 98+ messages in thread
From: Kevin Wolf @ 2018-03-01 10:01 UTC (permalink / raw)
  To: John Snow; +Cc: pkrempa, jtc, qemu-devel, qemu-block

Am 28.02.2018 um 20:14 hat John Snow geschrieben:
> 
> 
> On 02/28/2018 01:15 PM, Kevin Wolf wrote:
> > Is it because you want to avoid that the user picks an automatic job for
> > completing the mixed transaction?
> 
> I wanted to avoid the case that a job without the manual property would
> be stuck "pending" -- which I have defined to mean that it is waiting on
> an authorization from the user -- which isn't really true: it's waiting
> on its peers in the transaction to receive that authorization.
> 
> It would indeed be simpler to just let them stick around in PENDING like
> their peers, but it felt like a hacky way to allow mixed-mode
> transactions -- like they had been promoted for just a subset of their
> lifetime.
> 
> So, mostly it was a semantic decision and not a functional one based on
> what I considered "WAITING" to mean vs "PENDING".
> 
> If the definitions (and documentation) are adjusted it can be changed
> for the simpler layout if it seems just as good from the API
> perspective. (It's certainly better implementationally, as you say.)

I actually like it better conceptually, too, because I think of WAITING
as a state that waits for jobs in earlier states (i.e. RUNNING/READY
usually) and then everything moves forward together. Also waiting for
jobs that are already in a later state like PENDING, but only for
automatic jobs, makes the mental model more complex (or maybe it's just
me...).

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions
  2018-02-28 19:24       ` John Snow
@ 2018-03-01 10:10         ` Kevin Wolf
  0 siblings, 0 replies; 98+ messages in thread
From: Kevin Wolf @ 2018-03-01 10:10 UTC (permalink / raw)
  To: John Snow; +Cc: Eric Blake, qemu-block, pkrempa, jtc, qemu-devel

Am 28.02.2018 um 20:24 hat John Snow geschrieben:
> 
> 
> On 02/28/2018 01:29 PM, Kevin Wolf wrote:
> > Am 27.02.2018 um 21:24 hat Eric Blake geschrieben:
> >> On 02/23/2018 05:51 PM, John Snow wrote:
> >>> This allows us to easily force the option for all jobs belonging
> >>> to a transaction to ensure consistency with how all those jobs
> >>> will be handled.
> >>>
> >>> This is purely a convenience.
> >>>
> >>> Signed-off-by: John Snow <jsnow@redhat.com>
> >>> ---
> >>
> >>> +++ b/qapi/transaction.json
> >>> @@ -79,7 +79,8 @@
> >>>   ##
> >>>   { 'struct': 'TransactionProperties',
> >>>     'data': {
> >>> -       '*completion-mode': 'ActionCompletionMode'
> >>> +       '*completion-mode': 'ActionCompletionMode',
> >>> +       '*manual-mgmt': 'bool'
> >>
> >> Missing QAPI documentation (what you have elsewhere in the C code can
> >> probably be copied here, though).
> >>
> >> The UI aspect makes sense (I can declare one manual at the transaction level
> >> instead of multiple manual declarations per member level within the
> >> transaction).
> > 
> > I'm not so sure if I like the interface, it duplicates functionality in
> > two places.
> > 
> > At th very least I would make job creation without BLOCK_JOB_MANUAL an
> > error if the transaction requires it instead of silently overriding the
> > option that was given to the individual job. But honestly, it might be
> > better to just leave this one away.
> > 
> > Kevin
> > 
> 
> Sure, I put it in the trailing position here because I see it as
> optional. I don't like the idea of having to specify manual for each and
> every item in a transaction, but if mixed-mode is possible then this is
> less important.

For management tools it shouldn't really matter if they have that one
line of code when creating TransactionProperties or in the loop that
creates the individual jobs.

> I'll leave it off for now, but I will always fondly remember it, and
> then maybe try to sneak it back in for v6.

:-)

If you try to sneak it in, just make sure that conflicting settings
result in an error rather than one of them being silently overridden.

Kevin

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize
  2018-03-01 10:01       ` Kevin Wolf
@ 2018-03-01 19:24         ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-03-01 19:24 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 03/01/2018 05:01 AM, Kevin Wolf wrote:
> Am 28.02.2018 um 20:14 hat John Snow geschrieben:
>>
>>
>> On 02/28/2018 01:15 PM, Kevin Wolf wrote:
>>> Is it because you want to avoid that the user picks an automatic job for
>>> completing the mixed transaction?
>>
>> I wanted to avoid the case that a job without the manual property would
>> be stuck "pending" -- which I have defined to mean that it is waiting on
>> an authorization from the user -- which isn't really true: it's waiting
>> on its peers in the transaction to receive that authorization.
>>
>> It would indeed be simpler to just let them stick around in PENDING like
>> their peers, but it felt like a hacky way to allow mixed-mode
>> transactions -- like they had been promoted for just a subset of their
>> lifetime.
>>
>> So, mostly it was a semantic decision and not a functional one based on
>> what I considered "WAITING" to mean vs "PENDING".
>>
>> If the definitions (and documentation) are adjusted it can be changed
>> for the simpler layout if it seems just as good from the API
>> perspective. (It's certainly better implementationally, as you say.)
> 
> I actually like it better conceptually, too, because I think of WAITING
> as a state that waits for jobs in earlier states (i.e. RUNNING/READY
> usually) and then everything moves forward together. Also waiting for
> jobs that are already in a later state like PENDING, but only for
> automatic jobs, makes the mental model more complex (or maybe it's just
> me...).
> 
> Kevin
> 

No, that's a good point. I'll go with the simpler implementation, but
I'll leave a mention of the other approach in the RFC and we'll see if
there are other comments.

At some point I'll need to prod Pkrempa and make sure the design looks
tenable to him, too.

--js

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback
  2018-02-28 17:04   ` Kevin Wolf
@ 2018-03-07  3:19     ` John Snow
  0 siblings, 0 replies; 98+ messages in thread
From: John Snow @ 2018-03-07  3:19 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pkrempa, jtc, qemu-devel, qemu-block



On 02/28/2018 12:04 PM, Kevin Wolf wrote:
> Am 24.02.2018 um 00:51 hat John Snow geschrieben:
>> Some jobs upon finalization may need to perform some work that can
>> still fail. If these jobs are part of a transaction, it's important
>> that these callbacks fail the entire transaction.
>>
>> We allow for a new callback in addition to commit/abort/clean that
>> allows us the opportunity to have fairly late-breaking failures
>> in the transactional process.
>>
>> The expected flow is:
>>
>> - All jobs in a transaction converge to the WAITING state
>>   (added in a forthcoming commit)
>> - All jobs prepare to call either commit/abort
>> - If any job fails, is canceled, or fails preparation, all jobs
>>   call their .abort callback.
>> - All jobs enter the PENDING state, awaiting manual intervention
>>   (also added in a forthcoming commit)
>> - block-job-finalize is issued by the user/management layer
>> - All jobs call their commit callbacks.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
> 
> You almost made me believe the scary thought that we need transactional
> graph modifications, but after writing half of the reply, I think it's
> just that your order here is wrong.
> 

Sorry, yes, this blurb was outdated. I regret that it wasted your time.

> So .prepare is the last thing in the whole process that is allowed to
> fail. Graph manipulations such as bdrv_replace_node() can fail. Graph
> manipulations can also only be made in response to block-job-finalize
> because the management layer must be aware of them. Take them together
> and you have a problem.
> 
> Didn't we already establish earlier that .prepare/.commit/.abort must be
> called together and cannot be separated by waiting for a QMP command
> because of locking and things?
> 

Right; so what really happens is that in response to the FINALIZE verb,
the prepare loop is done first to check for success, and then commit or
abort are dispatched as appropriate.

> So if you go to PENDING first, then wait for block-job-finalize and only
> then call .prepare/.commit/.abort, we should be okay for both problems.
> 
> And taking a look at the final state, that seems to be what you do, so
> in the end, it's probably just the commit message that needs a fix.

Yep, sorry.

> 
>>  blockjob.c                   | 34 +++++++++++++++++++++++++++++++---
>>  include/block/blockjob_int.h | 10 ++++++++++
>>  2 files changed, 41 insertions(+), 3 deletions(-)
>>
>> diff --git a/blockjob.c b/blockjob.c
>> index 8f02c03880..1c010ec100 100644
>> --- a/blockjob.c
>> +++ b/blockjob.c
>> @@ -394,6 +394,18 @@ static void block_job_update_rc(BlockJob *job)
>>      }
>>  }
>>  
>> +static int block_job_prepare(BlockJob *job)
>> +{
>> +    if (job->ret) {
>> +        goto out;
>> +    }
>> +    if (job->driver->prepare) {
>> +        job->ret = job->driver->prepare(job);
>> +    }
>> + out:
>> +    return job->ret;
>> +}
> 
> Why not just if (job->ret == 0 && job->driver->prepare) and save the
> goto?
> 

Churn. ¯\_(ツ)_/¯

> Kevin
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2018-03-07  3:19 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-23 23:51 [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 01/21] blockjobs: fix set-speed kick John Snow
2018-02-27 16:32   ` Eric Blake
2018-02-27 17:18   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 02/21] blockjobs: model single jobs as transactions John Snow
2018-02-27 16:36   ` Eric Blake
2018-02-27 17:18   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 03/21] blockjobs: add manual property John Snow
2018-02-27 16:39   ` Eric Blake
2018-02-27 17:18   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 04/21] blockjobs: add status enum John Snow
2018-02-27 16:44   ` Eric Blake
2018-02-27 17:19   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 05/21] blockjobs: add state transition table John Snow
2018-02-27 16:27   ` Kevin Wolf
2018-02-27 16:45     ` John Snow
2018-02-27 17:08       ` Kevin Wolf
2018-02-27 18:58         ` John Snow
2018-02-27 18:58   ` Eric Blake
2018-02-27 19:06     ` John Snow
2018-02-27 19:22     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 06/21] iotests: add pause_wait John Snow
2018-02-27 17:19   ` Kevin Wolf
2018-02-27 19:01   ` Eric Blake
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 07/21] blockjobs: add block_job_verb permission table John Snow
2018-02-27 17:19   ` Kevin Wolf
2018-02-27 19:25   ` Eric Blake
2018-02-27 19:38     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 08/21] blockjobs: add ABORTING state John Snow
2018-02-27 19:34   ` Eric Blake
2018-02-28 14:54   ` Kevin Wolf
2018-02-28 19:26     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 09/21] blockjobs: add CONCLUDED state John Snow
2018-02-27 19:38   ` Eric Blake
2018-02-27 19:44     ` John Snow
2018-02-28 15:37   ` Kevin Wolf
2018-02-28 19:29     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 10/21] blockjobs: add NULL state John Snow
2018-02-27 19:41   ` Eric Blake
2018-02-28 15:42   ` Kevin Wolf
2018-02-28 20:04     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 11/21] blockjobs: add block_job_dismiss John Snow
2018-02-27 19:44   ` Eric Blake
2018-02-28 15:53   ` Kevin Wolf
2018-02-28 20:35     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 12/21] blockjobs: ensure abort is called for cancelled jobs John Snow
2018-02-27 19:49   ` Eric Blake
2018-02-27 20:43     ` John Snow
2018-02-28 16:05   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 13/21] blockjobs: add commit, abort, clean helpers John Snow
2018-02-27 19:50   ` Eric Blake
2018-02-28 16:07   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 14/21] blockjobs: add block_job_txn_apply function John Snow
2018-02-27 19:52   ` Eric Blake
2018-02-28 16:32   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 15/21] blockjobs: add prepare callback John Snow
2018-02-27 19:56   ` Eric Blake
2018-02-27 20:45     ` John Snow
2018-02-28 17:04   ` Kevin Wolf
2018-03-07  3:19     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 16/21] blockjobs: add waiting status John Snow
2018-02-27 20:00   ` Eric Blake
2018-02-27 20:50     ` John Snow
2018-02-28 17:46       ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 17/21] blockjobs: add PENDING status and event John Snow
2018-02-27 20:05   ` Eric Blake
2018-02-27 20:54     ` John Snow
2018-02-28 17:55   ` Kevin Wolf
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 18/21] blockjobs: add block-job-finalize John Snow
2018-02-27 20:13   ` Eric Blake
2018-02-28 18:15   ` Kevin Wolf
2018-02-28 19:14     ` John Snow
2018-03-01 10:01       ` Kevin Wolf
2018-03-01 19:24         ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 19/21] blockjobs: Expose manual property John Snow
2018-02-27 20:16   ` Eric Blake
2018-02-27 20:42     ` John Snow
2018-02-27 21:57     ` John Snow
2018-02-27 22:27       ` Eric Blake
2018-02-28 18:23       ` Kevin Wolf
2018-02-28 19:19         ` John Snow
2018-02-28 18:25   ` Kevin Wolf
2018-02-28 19:20     ` John Snow
2018-02-28 19:27       ` [Qemu-devel] [Qemu-block] " Eric Blake
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 20/21] iotests: test manual job dismissal John Snow
2018-02-27 20:21   ` Eric Blake
2018-02-27 20:41     ` John Snow
2018-02-23 23:51 ` [Qemu-devel] [RFC v4 21/21] blockjobs: add manual_mgmt option to transactions John Snow
2018-02-27 20:24   ` Eric Blake
2018-02-28 18:29     ` Kevin Wolf
2018-02-28 19:24       ` John Snow
2018-03-01 10:10         ` Kevin Wolf
2018-02-24  0:30 ` [Qemu-devel] [RFC v4 00/21] blockjobs: add explicit job management no-reply
2018-02-24 14:31 ` no-reply
2018-02-27 21:01   ` John Snow
2018-02-28 18:32     ` Kevin Wolf
2018-02-25 23:25 ` no-reply
2018-02-27 20:58   ` John Snow

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.