[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH v5 19/21] blockjobs: Expose manual property
From: |
John Snow |
Subject: |
[Qemu-block] [PATCH v5 19/21] blockjobs: Expose manual property |
Date: |
Sat, 10 Mar 2018 03:27:44 -0500 |
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 <address@hidden>
---
blockdev.c | 31 +++++++++++++++++++++++++++---
blockjob.c | 2 ++
qapi/block-core.json | 48 ++++++++++++++++++++++++++++++++++++++--------
tests/qemu-iotests/109.out | 24 +++++++++++------------
4 files changed, 82 insertions(+), 23 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index efd3ab2e99..809adbe7f9 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3261,7 +3261,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;
@@ -3280,6 +3280,12 @@ static BlockJob *do_drive_backup(DriveBackup *backup,
BlockJobTxn *txn,
if (!backup->has_job_id) {
backup->job_id = NULL;
}
+ if (!backup->has_auto_finalize) {
+ backup->auto_finalize = true;
+ }
+ if (!backup->has_auto_dismiss) {
+ backup->auto_dismiss = true;
+ }
if (!backup->has_compress) {
backup->compress = false;
}
@@ -3371,11 +3377,17 @@ static BlockJob *do_drive_backup(DriveBackup *backup,
BlockJobTxn *txn,
goto out;
}
}
+ if (!backup->auto_finalize) {
+ job_flags |= BLOCK_JOB_MANUAL_FINALIZE;
+ }
+ if (!backup->auto_dismiss) {
+ job_flags |= BLOCK_JOB_MANUAL_DISMISS;
+ }
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);
@@ -3410,6 +3422,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;
@@ -3423,6 +3436,12 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup,
BlockJobTxn *txn,
if (!backup->has_job_id) {
backup->job_id = NULL;
}
+ if (!backup->has_auto_finalize) {
+ backup->auto_finalize = true;
+ }
+ if (!backup->has_auto_dismiss) {
+ backup->auto_dismiss = true;
+ }
if (!backup->has_compress) {
backup->compress = false;
}
@@ -3451,10 +3470,16 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup,
BlockJobTxn *txn,
goto out;
}
}
+ if (!backup->auto_finalize) {
+ job_flags |= BLOCK_JOB_MANUAL_FINALIZE;
+ }
+ if (!backup->auto_dismiss) {
+ job_flags |= BLOCK_JOB_MANUAL_DISMISS;
+ }
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/blockjob.c b/blockjob.c
index 4b73cb0263..ba538c93dd 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -821,6 +821,8 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
info->io_status = job->iostatus;
info->ready = job->ready;
info->status = job->status;
+ info->auto_finalize = job->auto_finalize;
+ info->auto_dismiss = job->auto_dismiss;
return info;
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 961c4a3d0c..9e1534d70d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1054,13 +1054,20 @@
#
# @status: Current job state/status (since 2.12)
#
+# @auto-finalize: Job will finalize itself when PENDING, moving to
+# the CONCLUDED state. (since 2.12)
+#
+# @auto-dismiss: Job will dismiss itself when CONCLUDED, moving to the NULL
+# state and disappearing from the query list. (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',
- 'status': 'BlockJobStatus' } }
+ 'status': 'BlockJobStatus',
+ 'auto-finalize': 'bool', 'auto-dismiss': 'bool' } }
##
# @query-block-jobs:
@@ -1210,6 +1217,18 @@
# default 'report' (no limitations, since this applies to
# a different block device than @device).
#
+# @auto-finalize: When false, this job will wait in a PENDING state after it
has
+# finished its work, waiting for @block-job-finalize.
+# When true, this job will automatically perform its abort or
+# commit actions.
+# Defaults to true. (Since 2.12)
+#
+# @auto-dismiss: When false, this job will wait in a CONCLUDED state after it
+# has completed ceased all work, and wait for
@block-job-dismiss.
+# When true, this job will automatically disappear from the
query
+# list without user intervention.
+# Defaults to true. (Since 2.12)
+#
# Note: @on-source-error and @on-target-error only affect background
# I/O. If an error occurs during a guest write request, the device's
# rerror/werror actions will be used.
@@ -1218,10 +1237,12 @@
##
{ 'struct': 'DriveBackup',
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
- '*format': 'str', 'sync': 'MirrorSyncMode', '*mode':
'NewImageMode',
- '*speed': 'int', '*bitmap': 'str', '*compress': 'bool',
+ '*format': 'str', 'sync': 'MirrorSyncMode',
+ '*mode': 'NewImageMode', '*speed': 'int',
+ '*bitmap': 'str', '*compress': 'bool',
'*on-source-error': 'BlockdevOnError',
- '*on-target-error': 'BlockdevOnError' } }
+ '*on-target-error': 'BlockdevOnError',
+ '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
##
# @BlockdevBackup:
@@ -1251,6 +1272,18 @@
# default 'report' (no limitations, since this applies to
# a different block device than @device).
#
+# @auto-finalize: When false, this job will wait in a PENDING state after it
has
+# finished its work, waiting for @block-job-finalize.
+# When true, this job will automatically perform its abort or
+# commit actions.
+# Defaults to true. (Since 2.12)
+#
+# @auto-dismiss: When false, this job will wait in a CONCLUDED state after it
+# has completed ceased all work, and wait for
@block-job-dismiss.
+# When true, this job will automatically disappear from the
query
+# list without user intervention.
+# Defaults to true. (Since 2.12)
+#
# Note: @on-source-error and @on-target-error only affect background
# I/O. If an error occurs during a guest write request, the device's
# rerror/werror actions will be used.
@@ -1259,11 +1292,10 @@
##
{ 'struct': 'BlockdevBackup',
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
- 'sync': 'MirrorSyncMode',
- '*speed': 'int',
- '*compress': 'bool',
+ 'sync': 'MirrorSyncMode', '*speed': 'int', '*compress': 'bool',
'*on-source-error': 'BlockdevOnError',
- '*on-target-error': 'BlockdevOnError' } }
+ '*on-target-error': 'BlockdevOnError',
+ '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
##
# @blockdev-snapshot-sync:
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
index d288f2eef6..8a9b93672b 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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready":
true, "type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready":
true, "type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0,
"ready": true, "type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready":
true, "type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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, "status": "ready", "paused": false, "speed": 0, "ready": true,
"type": "mirror"}]}
+{"return": [{"auto-finalize": true, "io-status": "ok", "device": "src",
"auto-dismiss": true, "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
- [Qemu-block] [PATCH v5 13/21] blockjobs: add commit, abort, clean helpers, (continued)
- [Qemu-block] [PATCH v5 13/21] blockjobs: add commit, abort, clean helpers, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 05/21] blockjobs: add state transition table, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 02/21] blockjobs: model single jobs as transactions, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 16/21] blockjobs: add waiting status, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 18/21] blockjobs: add block-job-finalize, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 04/21] blockjobs: add status enum, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 20/21] iotests: test manual job dismissal, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 21/21] tests/test-blockjob: test cancellations, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 17/21] blockjobs: add PENDING status and event, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 07/21] blockjobs: add block_job_verb permission table, John Snow, 2018/03/10
- [Qemu-block] [PATCH v5 19/21] blockjobs: Expose manual property,
John Snow <=
- Re: [Qemu-block] [PATCH v5 00/21] blockjobs: add explicit job management, Kevin Wolf, 2018/03/12
- Re: [Qemu-block] [Qemu-devel] [PATCH v5 00/21] blockjobs: add explicit job management, no-reply, 2018/03/12