1
The following changes since commit 411ad78115ebeb3411cf4b7622784b93dfabe259:
1
The following changes since commit 741e1a618b126e664f7b723e6fe1b7ace511caf7:
2
2
3
Merge remote-tracking branch 'remotes/stefanberger/tags/pull-tpm-2017-12-15-1' into staging (2017-12-17 15:27:41 +0000)
3
Merge remote-tracking branch 'remotes/stefanberger/tags/pull-tpm-2018-09-07-1' into staging (2018-09-24 18:12:54 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/stefanha/qemu.git tags/block-pull-request
7
git://github.com/codyprime/qemu-kvm-jtc.git tags/block-pull-request
8
8
9
for you to fetch changes up to 585426c518958aa768564596091474be786aae51:
9
for you to fetch changes up to 637fa44ab80c6b317adf1d117494325a95daad60:
10
10
11
qemu-iotests: add 203 savevm with IOThreads test (2017-12-18 13:12:53 +0000)
11
curl: Make sslverify=off disable host as well as peer verification. (2018-09-24 23:46:05 -0400)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
RBD and Curl patches
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
16
17
Mao Zhongyi (4):
17
Jeff Cody (4):
18
hw/block/nvme: Convert to realize
18
block/rbd: pull out qemu_rbd_convert_options
19
hw/block: Fix the return type
19
block/rbd: Attempt to parse legacy filenames
20
hw/block: Use errp directly rather than local_err
20
block/rbd: add iotest for rbd legacy keyvalue filename parsing
21
dev-storage: Fix the unusual function name
21
block/rbd: add deprecation documentation for filename keyvalue pairs
22
22
23
Mark Kanda (2):
23
Richard W.M. Jones (1):
24
virtio-blk: make queue size configurable
24
curl: Make sslverify=off disable host as well as peer verification.
25
virtio-blk: reject configs with logical block size > physical block
26
size
27
25
28
Paolo Bonzini (1):
26
block/curl.c | 2 +
29
block: avoid recursive AioContext acquire in bdrv_inactivate_all()
27
block/rbd.c | 90 ++++++++++++++++++++++++++++++++------
30
28
qemu-deprecated.texi | 15 +++++++
31
Stefan Hajnoczi (16):
29
tests/qemu-iotests/231 | 62 ++++++++++++++++++++++++++
32
coroutine: simplify co_aio_sleep_ns() prototype
30
tests/qemu-iotests/231.out | 9 ++++
33
qdev: drop unused #include "sysemu/iothread.h"
31
tests/qemu-iotests/group | 1 +
34
blockdev: hold AioContext for bdrv_unref() in
32
6 files changed, 165 insertions(+), 14 deletions(-)
35
external_snapshot_clean()
33
create mode 100755 tests/qemu-iotests/231
36
block: don't keep AioContext acquired after
34
create mode 100644 tests/qemu-iotests/231.out
37
external_snapshot_prepare()
38
block: don't keep AioContext acquired after drive_backup_prepare()
39
block: don't keep AioContext acquired after blockdev_backup_prepare()
40
block: don't keep AioContext acquired after
41
internal_snapshot_prepare()
42
block: drop unused BlockDirtyBitmapState->aio_context field
43
iothread: add iothread_by_id() API
44
blockdev: add x-blockdev-set-iothread testing command
45
qemu-iotests: add 202 external snapshots IOThread test
46
docs: mark nested AioContext locking as a legacy API
47
blockdev: add x-blockdev-set-iothread force boolean
48
iotests: add VM.add_object()
49
iothread: fix iothread_stop() race condition
50
qemu-iotests: add 203 savevm with IOThreads test
51
52
docs/devel/multiple-iothreads.txt | 7 +-
53
qapi/block-core.json | 40 ++++++
54
hw/block/dataplane/virtio-blk.h | 2 +-
55
include/hw/block/block.h | 4 +-
56
include/hw/virtio/virtio-blk.h | 1 +
57
include/qemu/coroutine.h | 6 +-
58
include/sysemu/iothread.h | 4 +-
59
block.c | 14 ++-
60
block/null.c | 3 +-
61
block/sheepdog.c | 3 +-
62
blockdev.c | 259 +++++++++++++++++++++++++++-----------
63
hw/block/block.c | 15 ++-
64
hw/block/dataplane/virtio-blk.c | 12 +-
65
hw/block/fdc.c | 17 +--
66
hw/block/nvme.c | 23 ++--
67
hw/block/virtio-blk.c | 35 ++++--
68
hw/core/qdev-properties-system.c | 1 -
69
hw/ide/qdev.c | 12 +-
70
hw/scsi/scsi-disk.c | 13 +-
71
hw/usb/dev-storage.c | 29 ++---
72
iothread.c | 27 +++-
73
util/qemu-coroutine-sleep.c | 4 +-
74
tests/qemu-iotests/202 | 95 ++++++++++++++
75
tests/qemu-iotests/202.out | 11 ++
76
tests/qemu-iotests/203 | 59 +++++++++
77
tests/qemu-iotests/203.out | 6 +
78
tests/qemu-iotests/group | 2 +
79
tests/qemu-iotests/iotests.py | 5 +
80
28 files changed, 532 insertions(+), 177 deletions(-)
81
create mode 100755 tests/qemu-iotests/202
82
create mode 100644 tests/qemu-iotests/202.out
83
create mode 100755 tests/qemu-iotests/203
84
create mode 100644 tests/qemu-iotests/203.out
85
35
86
--
36
--
87
2.14.3
37
2.17.1
88
38
89
39
diff view generated by jsdifflib
Deleted patch
1
The AioContext pointer argument to co_aio_sleep_ns() is only used for
2
the sleep timer. It does not affect where the caller coroutine is
3
resumed.
4
1
5
Due to changes to coroutine and AIO APIs it is now possible to drop the
6
AioContext pointer argument. This is safe to do since no caller has
7
specific requirements for which AioContext the timer must run in.
8
9
This patch drops the AioContext pointer argument and renames the
10
function to simplify the API.
11
12
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
13
Reported-by: Eric Blake <eblake@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Message-id: 20171109102652.6360-1-stefanha@redhat.com
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
19
include/qemu/coroutine.h | 6 +-----
20
block/null.c | 3 +--
21
block/sheepdog.c | 3 +--
22
util/qemu-coroutine-sleep.c | 4 ++--
23
4 files changed, 5 insertions(+), 11 deletions(-)
24
25
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/qemu/coroutine.h
28
+++ b/include/qemu/coroutine.h
29
@@ -XXX,XX +XXX,XX @@ void qemu_co_rwlock_unlock(CoRwlock *lock);
30
31
/**
32
* Yield the coroutine for a given duration
33
- *
34
- * Behaves similarly to co_sleep_ns(), but the sleeping coroutine will be
35
- * resumed when using aio_poll().
36
*/
37
-void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
38
- int64_t ns);
39
+void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns);
40
41
/**
42
* Yield until a file descriptor becomes readable
43
diff --git a/block/null.c b/block/null.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/block/null.c
46
+++ b/block/null.c
47
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int null_co_common(BlockDriverState *bs)
48
BDRVNullState *s = bs->opaque;
49
50
if (s->latency_ns) {
51
- co_aio_sleep_ns(bdrv_get_aio_context(bs), QEMU_CLOCK_REALTIME,
52
- s->latency_ns);
53
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, s->latency_ns);
54
}
55
return 0;
56
}
57
diff --git a/block/sheepdog.c b/block/sheepdog.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/sheepdog.c
60
+++ b/block/sheepdog.c
61
@@ -XXX,XX +XXX,XX @@ static coroutine_fn void reconnect_to_sdog(void *opaque)
62
if (s->fd < 0) {
63
DPRINTF("Wait for connection to be established\n");
64
error_report_err(local_err);
65
- co_aio_sleep_ns(bdrv_get_aio_context(s->bs), QEMU_CLOCK_REALTIME,
66
- 1000000000ULL);
67
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000000ULL);
68
}
69
};
70
71
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/util/qemu-coroutine-sleep.c
74
+++ b/util/qemu-coroutine-sleep.c
75
@@ -XXX,XX +XXX,XX @@ static void co_sleep_cb(void *opaque)
76
aio_co_wake(sleep_cb->co);
77
}
78
79
-void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
80
- int64_t ns)
81
+void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns)
82
{
83
+ AioContext *ctx = qemu_get_current_aio_context();
84
CoSleepCB sleep_cb = {
85
.co = qemu_coroutine_self(),
86
};
87
--
88
2.14.3
89
90
diff view generated by jsdifflib
Deleted patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
1
3
Convert nvme_init() to realize and rename it to nvme_realize().
4
5
Cc: John Snow <jsnow@redhat.com>
6
Cc: Keith Busch <keith.busch@intel.com>
7
Cc: Kevin Wolf <kwolf@redhat.com>
8
Cc: Max Reitz <mreitz@redhat.com>
9
Cc: Markus Armbruster <armbru@redhat.com>
10
11
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
12
Message-id: 2882e72d795e04cbe2120f569d551aef2467ac60.1511317952.git.maozy.fnst@cn.fujitsu.com
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
---
15
hw/block/nvme.c | 18 ++++++++++--------
16
1 file changed, 10 insertions(+), 8 deletions(-)
17
18
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/block/nvme.c
21
+++ b/hw/block/nvme.c
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvme_cmb_ops = {
23
},
24
};
25
26
-static int nvme_init(PCIDevice *pci_dev)
27
+static void nvme_realize(PCIDevice *pci_dev, Error **errp)
28
{
29
NvmeCtrl *n = NVME(pci_dev);
30
NvmeIdCtrl *id = &n->id_ctrl;
31
@@ -XXX,XX +XXX,XX @@ static int nvme_init(PCIDevice *pci_dev)
32
Error *local_err = NULL;
33
34
if (!n->conf.blk) {
35
- return -1;
36
+ error_setg(errp, "drive property not set");
37
+ return;
38
}
39
40
bs_size = blk_getlength(n->conf.blk);
41
if (bs_size < 0) {
42
- return -1;
43
+ error_setg(errp, "could not get backing file size");
44
+ return;
45
}
46
47
blkconf_serial(&n->conf, &n->serial);
48
if (!n->serial) {
49
- return -1;
50
+ error_setg(errp, "serial property not set");
51
+ return;
52
}
53
blkconf_blocksizes(&n->conf);
54
blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
55
false, &local_err);
56
if (local_err) {
57
- error_report_err(local_err);
58
- return -1;
59
+ error_propagate(errp, local_err);
60
+ return;
61
}
62
63
pci_conf = pci_dev->config;
64
@@ -XXX,XX +XXX,XX @@ static int nvme_init(PCIDevice *pci_dev)
65
cpu_to_le64(n->ns_size >>
66
id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas)].ds);
67
}
68
- return 0;
69
}
70
71
static void nvme_exit(PCIDevice *pci_dev)
72
@@ -XXX,XX +XXX,XX @@ static void nvme_class_init(ObjectClass *oc, void *data)
73
DeviceClass *dc = DEVICE_CLASS(oc);
74
PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc);
75
76
- pc->init = nvme_init;
77
+ pc->realize = nvme_realize;
78
pc->exit = nvme_exit;
79
pc->class_id = PCI_CLASS_STORAGE_EXPRESS;
80
pc->vendor_id = PCI_VENDOR_ID_INTEL;
81
--
82
2.14.3
83
84
diff view generated by jsdifflib
Deleted patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
1
3
When the function no success value to transmit, it usually make the
4
function return void. It has turned out not to be a success, because
5
it means that the extra local_err variable and error_propagate() will
6
be needed. It leads to cumbersome code, therefore, transmit success/
7
failure in the return value is worth.
8
9
So fix the return type of blkconf_apply_backend_options(),
10
blkconf_geometry() and virtio_blk_data_plane_create() to avoid it.
11
12
Cc: John Snow <jsnow@redhat.com>
13
Cc: Kevin Wolf <kwolf@redhat.com>
14
Cc: Max Reitz <mreitz@redhat.com>
15
Cc: Stefan Hajnoczi <stefanha@redhat.com>
16
17
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
18
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Message-id: ac0edc1fc70c4457e5cec94405eb7d1f89f9c2c1.1511317952.git.maozy.fnst@cn.fujitsu.com
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
---
22
hw/block/dataplane/virtio-blk.h | 2 +-
23
include/hw/block/block.h | 4 ++--
24
hw/block/block.c | 15 +++++++++------
25
hw/block/dataplane/virtio-blk.c | 12 +++++++-----
26
4 files changed, 19 insertions(+), 14 deletions(-)
27
28
diff --git a/hw/block/dataplane/virtio-blk.h b/hw/block/dataplane/virtio-blk.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/block/dataplane/virtio-blk.h
31
+++ b/hw/block/dataplane/virtio-blk.h
32
@@ -XXX,XX +XXX,XX @@
33
34
typedef struct VirtIOBlockDataPlane VirtIOBlockDataPlane;
35
36
-void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
37
+bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
38
VirtIOBlockDataPlane **dataplane,
39
Error **errp);
40
void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s);
41
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/hw/block/block.h
44
+++ b/include/hw/block/block.h
45
@@ -XXX,XX +XXX,XX @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
46
/* Configuration helpers */
47
48
void blkconf_serial(BlockConf *conf, char **serial);
49
-void blkconf_geometry(BlockConf *conf, int *trans,
50
+bool blkconf_geometry(BlockConf *conf, int *trans,
51
unsigned cyls_max, unsigned heads_max, unsigned secs_max,
52
Error **errp);
53
void blkconf_blocksizes(BlockConf *conf);
54
-void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
55
+bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
56
bool resizable, Error **errp);
57
58
/* Hard disk geometry */
59
diff --git a/hw/block/block.c b/hw/block/block.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/block/block.c
62
+++ b/hw/block/block.c
63
@@ -XXX,XX +XXX,XX @@ void blkconf_blocksizes(BlockConf *conf)
64
}
65
}
66
67
-void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
68
+bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
69
bool resizable, Error **errp)
70
{
71
BlockBackend *blk = conf->blk;
72
@@ -XXX,XX +XXX,XX @@ void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
73
74
ret = blk_set_perm(blk, perm, shared_perm, errp);
75
if (ret < 0) {
76
- return;
77
+ return false;
78
}
79
80
switch (conf->wce) {
81
@@ -XXX,XX +XXX,XX @@ void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
82
83
blk_set_enable_write_cache(blk, wce);
84
blk_set_on_error(blk, rerror, werror);
85
+
86
+ return true;
87
}
88
89
-void blkconf_geometry(BlockConf *conf, int *ptrans,
90
+bool blkconf_geometry(BlockConf *conf, int *ptrans,
91
unsigned cyls_max, unsigned heads_max, unsigned secs_max,
92
Error **errp)
93
{
94
@@ -XXX,XX +XXX,XX @@ void blkconf_geometry(BlockConf *conf, int *ptrans,
95
if (conf->cyls || conf->heads || conf->secs) {
96
if (conf->cyls < 1 || conf->cyls > cyls_max) {
97
error_setg(errp, "cyls must be between 1 and %u", cyls_max);
98
- return;
99
+ return false;
100
}
101
if (conf->heads < 1 || conf->heads > heads_max) {
102
error_setg(errp, "heads must be between 1 and %u", heads_max);
103
- return;
104
+ return false;
105
}
106
if (conf->secs < 1 || conf->secs > secs_max) {
107
error_setg(errp, "secs must be between 1 and %u", secs_max);
108
- return;
109
+ return false;
110
}
111
}
112
+ return true;
113
}
114
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/hw/block/dataplane/virtio-blk.c
117
+++ b/hw/block/dataplane/virtio-blk.c
118
@@ -XXX,XX +XXX,XX @@ static void notify_guest_bh(void *opaque)
119
}
120
121
/* Context: QEMU global mutex held */
122
-void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
123
+bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
124
VirtIOBlockDataPlane **dataplane,
125
Error **errp)
126
{
127
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
128
error_setg(errp,
129
"device is incompatible with iothread "
130
"(transport does not support notifiers)");
131
- return;
132
+ return false;
133
}
134
if (!virtio_device_ioeventfd_enabled(vdev)) {
135
error_setg(errp, "ioeventfd is required for iothread");
136
- return;
137
+ return false;
138
}
139
140
/* If dataplane is (re-)enabled while the guest is running there could
141
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
142
*/
143
if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
144
error_prepend(errp, "cannot start virtio-blk dataplane: ");
145
- return;
146
+ return false;
147
}
148
}
149
/* Don't try if transport does not support notifiers. */
150
if (!virtio_device_ioeventfd_enabled(vdev)) {
151
- return;
152
+ return false;
153
}
154
155
s = g_new0(VirtIOBlockDataPlane, 1);
156
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
157
s->batch_notify_vqs = bitmap_new(conf->num_queues);
158
159
*dataplane = s;
160
+
161
+ return true;
162
}
163
164
/* Context: QEMU global mutex held */
165
--
166
2.14.3
167
168
diff view generated by jsdifflib
Deleted patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
1
3
Cc: John Snow <jsnow@redhat.com>
4
Cc: Kevin Wolf <kwolf@redhat.com>
5
Cc: Max Reitz <mreitz@redhat.com>
6
Cc: Keith Busch <keith.busch@intel.com>
7
Cc: Stefan Hajnoczi <stefanha@redhat.com>
8
Cc: "Michael S. Tsirkin" <mst@redhat.com>
9
Cc: Paolo Bonzini <pbonzini@redhat.com>
10
Cc: Gerd Hoffmann <kraxel@redhat.com>
11
Cc: Markus Armbruster <armbru@redhat.com>
12
13
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Message-id: e77848d3735ba590f23ffbf8094379c646c33d79.1511317952.git.maozy.fnst@cn.fujitsu.com
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
---
18
hw/block/fdc.c | 17 ++++++-----------
19
hw/block/nvme.c | 7 ++-----
20
hw/block/virtio-blk.c | 18 ++++++------------
21
hw/ide/qdev.c | 12 ++++--------
22
hw/scsi/scsi-disk.c | 13 ++++---------
23
hw/usb/dev-storage.c | 9 +++------
24
6 files changed, 25 insertions(+), 51 deletions(-)
25
26
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/block/fdc.c
29
+++ b/hw/block/fdc.c
30
@@ -XXX,XX +XXX,XX @@ static void fd_revalidate(FDrive *drv)
31
static void fd_change_cb(void *opaque, bool load, Error **errp)
32
{
33
FDrive *drive = opaque;
34
- Error *local_err = NULL;
35
36
if (!load) {
37
blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
38
} else {
39
- blkconf_apply_backend_options(drive->conf,
40
- blk_is_read_only(drive->blk), false,
41
- &local_err);
42
- if (local_err) {
43
- error_propagate(errp, local_err);
44
+ if (!blkconf_apply_backend_options(drive->conf,
45
+ blk_is_read_only(drive->blk), false,
46
+ errp)) {
47
return;
48
}
49
}
50
@@ -XXX,XX +XXX,XX @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
51
FloppyDrive *dev = FLOPPY_DRIVE(qdev);
52
FloppyBus *bus = FLOPPY_BUS(qdev->parent_bus);
53
FDrive *drive;
54
- Error *local_err = NULL;
55
int ret;
56
57
if (dev->unit == -1) {
58
@@ -XXX,XX +XXX,XX @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
59
dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
60
dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
61
62
- blkconf_apply_backend_options(&dev->conf, blk_is_read_only(dev->conf.blk),
63
- false, &local_err);
64
- if (local_err) {
65
- error_propagate(errp, local_err);
66
+ if (!blkconf_apply_backend_options(&dev->conf,
67
+ blk_is_read_only(dev->conf.blk),
68
+ false, errp)) {
69
return;
70
}
71
72
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/block/nvme.c
75
+++ b/hw/block/nvme.c
76
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
77
int i;
78
int64_t bs_size;
79
uint8_t *pci_conf;
80
- Error *local_err = NULL;
81
82
if (!n->conf.blk) {
83
error_setg(errp, "drive property not set");
84
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
85
return;
86
}
87
blkconf_blocksizes(&n->conf);
88
- blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
89
- false, &local_err);
90
- if (local_err) {
91
- error_propagate(errp, local_err);
92
+ if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
93
+ false, errp)) {
94
return;
95
}
96
97
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/hw/block/virtio-blk.c
100
+++ b/hw/block/virtio-blk.c
101
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
102
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
103
VirtIOBlock *s = VIRTIO_BLK(dev);
104
VirtIOBlkConf *conf = &s->conf;
105
- Error *err = NULL;
106
unsigned i;
107
108
if (!conf->conf.blk) {
109
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
110
}
111
112
blkconf_serial(&conf->conf, &conf->serial);
113
- blkconf_apply_backend_options(&conf->conf,
114
- blk_is_read_only(conf->conf.blk), true,
115
- &err);
116
- if (err) {
117
- error_propagate(errp, err);
118
+ if (!blkconf_apply_backend_options(&conf->conf,
119
+ blk_is_read_only(conf->conf.blk), true,
120
+ errp)) {
121
return;
122
}
123
s->original_wce = blk_enable_write_cache(conf->conf.blk);
124
- blkconf_geometry(&conf->conf, NULL, 65535, 255, 255, &err);
125
- if (err) {
126
- error_propagate(errp, err);
127
+ if (!blkconf_geometry(&conf->conf, NULL, 65535, 255, 255, errp)) {
128
return;
129
}
130
+
131
blkconf_blocksizes(&conf->conf);
132
133
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
134
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
135
for (i = 0; i < conf->num_queues; i++) {
136
virtio_add_queue(vdev, 128, virtio_blk_handle_output);
137
}
138
- virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err);
139
- if (err != NULL) {
140
- error_propagate(errp, err);
141
+ if (!virtio_blk_data_plane_create(vdev, conf, &s->dataplane, errp)) {
142
virtio_cleanup(vdev);
143
return;
144
}
145
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/hw/ide/qdev.c
148
+++ b/hw/ide/qdev.c
149
@@ -XXX,XX +XXX,XX @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
150
{
151
IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
152
IDEState *s = bus->ifs + dev->unit;
153
- Error *err = NULL;
154
int ret;
155
156
if (!dev->conf.blk) {
157
@@ -XXX,XX +XXX,XX @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
158
159
blkconf_serial(&dev->conf, &dev->serial);
160
if (kind != IDE_CD) {
161
- blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255, &err);
162
- if (err) {
163
- error_propagate(errp, err);
164
+ if (!blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255,
165
+ errp)) {
166
return;
167
}
168
}
169
- blkconf_apply_backend_options(&dev->conf, kind == IDE_CD, kind != IDE_CD,
170
- &err);
171
- if (err) {
172
- error_propagate(errp, err);
173
+ if (!blkconf_apply_backend_options(&dev->conf, kind == IDE_CD,
174
+ kind != IDE_CD, errp)) {
175
return;
176
}
177
178
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/hw/scsi/scsi-disk.c
181
+++ b/hw/scsi/scsi-disk.c
182
@@ -XXX,XX +XXX,XX @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
183
static void scsi_realize(SCSIDevice *dev, Error **errp)
184
{
185
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
186
- Error *err = NULL;
187
188
if (!s->qdev.conf.blk) {
189
error_setg(errp, "drive property not set");
190
@@ -XXX,XX +XXX,XX @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
191
}
192
193
if (dev->type == TYPE_DISK) {
194
- blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);
195
- if (err) {
196
- error_propagate(errp, err);
197
+ if (!blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, errp)) {
198
return;
199
}
200
}
201
- blkconf_apply_backend_options(&dev->conf,
202
- blk_is_read_only(s->qdev.conf.blk),
203
- dev->type == TYPE_DISK, &err);
204
- if (err) {
205
- error_propagate(errp, err);
206
+ if (!blkconf_apply_backend_options(&dev->conf,
207
+ blk_is_read_only(s->qdev.conf.blk),
208
+ dev->type == TYPE_DISK, errp)) {
209
return;
210
}
211
212
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
213
index XXXXXXX..XXXXXXX 100644
214
--- a/hw/usb/dev-storage.c
215
+++ b/hw/usb/dev-storage.c
216
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
217
MSDState *s = USB_STORAGE_DEV(dev);
218
BlockBackend *blk = s->conf.blk;
219
SCSIDevice *scsi_dev;
220
- Error *err = NULL;
221
222
if (!blk) {
223
error_setg(errp, "drive property not set");
224
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
225
226
blkconf_serial(&s->conf, &dev->serial);
227
blkconf_blocksizes(&s->conf);
228
- blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true, &err);
229
- if (err) {
230
- error_propagate(errp, err);
231
+ if (!blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true,
232
+ errp)) {
233
return;
234
}
235
236
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
237
&usb_msd_scsi_info_storage, NULL);
238
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
239
s->conf.bootindex, dev->serial,
240
- &err);
241
+ errp);
242
blk_unref(blk);
243
if (!scsi_dev) {
244
- error_propagate(errp, err);
245
return;
246
}
247
usb_msd_handle_reset(dev);
248
--
249
2.14.3
250
251
diff view generated by jsdifflib
Deleted patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
1
3
The function name of usb_msd_{realize,unrealize}_*,
4
usb_msd_class_initfn_* are unusual. Rename it to
5
usb_msd_*_{realize,unrealize}, usb_msd_class_*_initfn.
6
7
Cc: Gerd Hoffmann <kraxel@redhat.com>
8
9
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 11e6003433abce35f3f4970e1acc71ee92dbcf51.1511317952.git.maozy.fnst@cn.fujitsu.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
hw/usb/dev-storage.c | 20 ++++++++++----------
15
1 file changed, 10 insertions(+), 10 deletions(-)
16
17
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/usb/dev-storage.c
20
+++ b/hw/usb/dev-storage.c
21
@@ -XXX,XX +XXX,XX @@ static void usb_msd_unrealize_storage(USBDevice *dev, Error **errp)
22
object_unref(OBJECT(&s->bus));
23
}
24
25
-static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
26
+static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
27
{
28
MSDState *s = USB_STORAGE_DEV(dev);
29
BlockBackend *blk = s->conf.blk;
30
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
31
s->scsi_dev = scsi_dev;
32
}
33
34
-static void usb_msd_unrealize_bot(USBDevice *dev, Error **errp)
35
+static void usb_msd_bot_unrealize(USBDevice *dev, Error **errp)
36
{
37
MSDState *s = USB_STORAGE_DEV(dev);
38
39
object_unref(OBJECT(&s->bus));
40
}
41
42
-static void usb_msd_realize_bot(USBDevice *dev, Error **errp)
43
+static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
44
{
45
MSDState *s = USB_STORAGE_DEV(dev);
46
DeviceState *d = DEVICE(dev);
47
@@ -XXX,XX +XXX,XX @@ static void usb_msd_class_initfn_common(ObjectClass *klass, void *data)
48
dc->vmsd = &vmstate_usb_msd;
49
}
50
51
-static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data)
52
+static void usb_msd_class_storage_initfn(ObjectClass *klass, void *data)
53
{
54
DeviceClass *dc = DEVICE_CLASS(klass);
55
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
56
57
- uc->realize = usb_msd_realize_storage;
58
+ uc->realize = usb_msd_storage_realize;
59
uc->unrealize = usb_msd_unrealize_storage;
60
dc->props = msd_properties;
61
}
62
@@ -XXX,XX +XXX,XX @@ static void usb_msd_instance_init(Object *obj)
63
object_property_set_int(obj, -1, "bootindex", NULL);
64
}
65
66
-static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
67
+static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data)
68
{
69
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
70
71
- uc->realize = usb_msd_realize_bot;
72
- uc->unrealize = usb_msd_unrealize_bot;
73
+ uc->realize = usb_msd_bot_realize;
74
+ uc->unrealize = usb_msd_bot_unrealize;
75
uc->attached_settable = true;
76
}
77
78
static const TypeInfo msd_info = {
79
.name = "usb-storage",
80
.parent = TYPE_USB_STORAGE,
81
- .class_init = usb_msd_class_initfn_storage,
82
+ .class_init = usb_msd_class_storage_initfn,
83
.instance_init = usb_msd_instance_init,
84
};
85
86
static const TypeInfo bot_info = {
87
.name = "usb-bot",
88
.parent = TYPE_USB_STORAGE,
89
- .class_init = usb_msd_class_initfn_bot,
90
+ .class_init = usb_msd_class_bot_initfn,
91
};
92
93
static void usb_msd_register_types(void)
94
--
95
2.14.3
96
97
diff view generated by jsdifflib
Deleted patch
1
Commit 1351d1ec89eabebc9fdff20451a62c413d7accc1 ("qdev: drop iothread
2
property type") forgot to remove this include.
3
1
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Message-id: 20171205133954.31006-1-stefanha@redhat.com
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
8
hw/core/qdev-properties-system.c | 1 -
9
1 file changed, 1 deletion(-)
10
11
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/core/qdev-properties-system.c
14
+++ b/hw/core/qdev-properties-system.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "qapi/visitor.h"
17
#include "chardev/char-fe.h"
18
#include "sysemu/tpm_backend.h"
19
-#include "sysemu/iothread.h"
20
21
static void get_pointer(Object *obj, Visitor *v, Property *prop,
22
char *(*print)(void *ptr),
23
--
24
2.14.3
25
26
diff view generated by jsdifflib
Deleted patch
1
bdrv_unref() requires the AioContext lock because bdrv_flush() uses
2
BDRV_POLL_WHILE(), which assumes the AioContext is currently held. If
3
BDRV_POLL_WHILE() runs without AioContext held the
4
pthread_mutex_unlock() call in aio_context_release() fails.
5
1
6
This patch moves bdrv_unref() into the AioContext locked region to solve
7
the following pthread_mutex_unlock() failure:
8
9
#0 0x00007f566181969b in raise () at /lib64/libc.so.6
10
#1 0x00007f566181b3b1 in abort () at /lib64/libc.so.6
11
#2 0x00005592cd590458 in error_exit (err=<optimized out>, msg=msg@entry=0x5592cdaf6d60 <__func__.23977> "qemu_mutex_unlock") at util/qemu-thread-posix.c:36
12
#3 0x00005592cd96e738 in qemu_mutex_unlock (mutex=mutex@entry=0x5592ce9505e0) at util/qemu-thread-posix.c:96
13
#4 0x00005592cd969b69 in aio_context_release (ctx=ctx@entry=0x5592ce950580) at util/async.c:507
14
#5 0x00005592cd8ead78 in bdrv_flush (bs=bs@entry=0x5592cfa87210) at block/io.c:2478
15
#6 0x00005592cd89df30 in bdrv_close (bs=0x5592cfa87210) at block.c:3207
16
#7 0x00005592cd89df30 in bdrv_delete (bs=0x5592cfa87210) at block.c:3395
17
#8 0x00005592cd89df30 in bdrv_unref (bs=0x5592cfa87210) at block.c:4418
18
#9 0x00005592cd6b7f86 in qmp_transaction (dev_list=<optimized out>, has_props=<optimized out>, props=<optimized out>, errp=errp@entry=0x7ffe4a1fc9d8) at blockdev.c:2308
19
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
22
Reviewed-by: Eric Blake <eblake@redhat.com>
23
Message-id: 20171206144550.22295-2-stefanha@redhat.com
24
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
25
---
26
blockdev.c | 2 +-
27
1 file changed, 1 insertion(+), 1 deletion(-)
28
29
diff --git a/blockdev.c b/blockdev.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/blockdev.c
32
+++ b/blockdev.c
33
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_clean(BlkActionState *common)
34
DO_UPCAST(ExternalSnapshotState, common, common);
35
if (state->aio_context) {
36
bdrv_drained_end(state->old_bs);
37
- aio_context_release(state->aio_context);
38
bdrv_unref(state->new_bs);
39
+ aio_context_release(state->aio_context);
40
}
41
}
42
43
--
44
2.14.3
45
46
diff view generated by jsdifflib
Deleted patch
1
It is not necessary to hold AioContext across transactions anymore since
2
bdrv_drained_begin/end() is used to keep the nodes quiesced. In fact,
3
using the AioContext lock for this purpose was always buggy.
4
1
5
This patch reduces the scope of AioContext locked regions. This is not
6
just a cleanup but also fixes hangs that occur in BDRV_POLL_WHILE()
7
because it is unware of recursive locking and does not release the
8
AioContext the necessary number of times to allow progress to be made.
9
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Message-id: 20171206144550.22295-3-stefanha@redhat.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
16
blockdev.c | 71 ++++++++++++++++++++++++++++++++++++++++++--------------------
17
1 file changed, 48 insertions(+), 23 deletions(-)
18
19
diff --git a/blockdev.c b/blockdev.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/blockdev.c
22
+++ b/blockdev.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct ExternalSnapshotState {
24
BlkActionState common;
25
BlockDriverState *old_bs;
26
BlockDriverState *new_bs;
27
- AioContext *aio_context;
28
bool overlay_appended;
29
} ExternalSnapshotState;
30
31
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
32
ExternalSnapshotState *state =
33
DO_UPCAST(ExternalSnapshotState, common, common);
34
TransactionAction *action = common->action;
35
+ AioContext *aio_context;
36
37
/* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar
38
* purpose but a different set of parameters */
39
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
40
return;
41
}
42
43
- /* Acquire AioContext now so any threads operating on old_bs stop */
44
- state->aio_context = bdrv_get_aio_context(state->old_bs);
45
- aio_context_acquire(state->aio_context);
46
+ aio_context = bdrv_get_aio_context(state->old_bs);
47
+ aio_context_acquire(aio_context);
48
+
49
+ /* Paired with .clean() */
50
bdrv_drained_begin(state->old_bs);
51
52
if (!bdrv_is_inserted(state->old_bs)) {
53
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
54
- return;
55
+ goto out;
56
}
57
58
if (bdrv_op_is_blocked(state->old_bs,
59
BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, errp)) {
60
- return;
61
+ goto out;
62
}
63
64
if (!bdrv_is_read_only(state->old_bs)) {
65
if (bdrv_flush(state->old_bs)) {
66
error_setg(errp, QERR_IO_ERROR);
67
- return;
68
+ goto out;
69
}
70
}
71
72
if (!bdrv_is_first_non_filter(state->old_bs)) {
73
error_setg(errp, QERR_FEATURE_DISABLED, "snapshot");
74
- return;
75
+ goto out;
76
}
77
78
if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) {
79
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
80
81
if (node_name && !snapshot_node_name) {
82
error_setg(errp, "New snapshot node name missing");
83
- return;
84
+ goto out;
85
}
86
87
if (snapshot_node_name &&
88
bdrv_lookup_bs(snapshot_node_name, snapshot_node_name, NULL)) {
89
error_setg(errp, "New snapshot node name already in use");
90
- return;
91
+ goto out;
92
}
93
94
flags = state->old_bs->open_flags;
95
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
96
int64_t size = bdrv_getlength(state->old_bs);
97
if (size < 0) {
98
error_setg_errno(errp, -size, "bdrv_getlength failed");
99
- return;
100
+ goto out;
101
}
102
bdrv_img_create(new_image_file, format,
103
state->old_bs->filename,
104
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
105
NULL, size, flags, false, &local_err);
106
if (local_err) {
107
error_propagate(errp, local_err);
108
- return;
109
+ goto out;
110
}
111
}
112
113
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
114
errp);
115
/* We will manually add the backing_hd field to the bs later */
116
if (!state->new_bs) {
117
- return;
118
+ goto out;
119
}
120
121
if (bdrv_has_blk(state->new_bs)) {
122
error_setg(errp, "The snapshot is already in use");
123
- return;
124
+ goto out;
125
}
126
127
if (bdrv_op_is_blocked(state->new_bs, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
128
errp)) {
129
- return;
130
+ goto out;
131
}
132
133
if (state->new_bs->backing != NULL) {
134
error_setg(errp, "The snapshot already has a backing image");
135
- return;
136
+ goto out;
137
}
138
139
if (!state->new_bs->drv->supports_backing) {
140
error_setg(errp, "The snapshot does not support backing images");
141
- return;
142
+ goto out;
143
}
144
145
- bdrv_set_aio_context(state->new_bs, state->aio_context);
146
+ bdrv_set_aio_context(state->new_bs, aio_context);
147
148
/* This removes our old bs and adds the new bs. This is an operation that
149
* can fail, so we need to do it in .prepare; undoing it for abort is
150
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
151
bdrv_append(state->new_bs, state->old_bs, &local_err);
152
if (local_err) {
153
error_propagate(errp, local_err);
154
- return;
155
+ goto out;
156
}
157
state->overlay_appended = true;
158
+
159
+out:
160
+ aio_context_release(aio_context);
161
}
162
163
static void external_snapshot_commit(BlkActionState *common)
164
{
165
ExternalSnapshotState *state =
166
DO_UPCAST(ExternalSnapshotState, common, common);
167
+ AioContext *aio_context;
168
+
169
+ aio_context = bdrv_get_aio_context(state->old_bs);
170
+ aio_context_acquire(aio_context);
171
172
/* We don't need (or want) to use the transactional
173
* bdrv_reopen_multiple() across all the entries at once, because we
174
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_commit(BlkActionState *common)
175
bdrv_reopen(state->old_bs, state->old_bs->open_flags & ~BDRV_O_RDWR,
176
NULL);
177
}
178
+
179
+ aio_context_release(aio_context);
180
}
181
182
static void external_snapshot_abort(BlkActionState *common)
183
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_abort(BlkActionState *common)
184
DO_UPCAST(ExternalSnapshotState, common, common);
185
if (state->new_bs) {
186
if (state->overlay_appended) {
187
+ AioContext *aio_context;
188
+
189
+ aio_context = bdrv_get_aio_context(state->old_bs);
190
+ aio_context_acquire(aio_context);
191
+
192
bdrv_ref(state->old_bs); /* we can't let bdrv_set_backind_hd()
193
close state->old_bs; we need it */
194
bdrv_set_backing_hd(state->new_bs, NULL, &error_abort);
195
bdrv_replace_node(state->new_bs, state->old_bs, &error_abort);
196
bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */
197
+
198
+ aio_context_release(aio_context);
199
}
200
}
201
}
202
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_clean(BlkActionState *common)
203
{
204
ExternalSnapshotState *state =
205
DO_UPCAST(ExternalSnapshotState, common, common);
206
- if (state->aio_context) {
207
- bdrv_drained_end(state->old_bs);
208
- bdrv_unref(state->new_bs);
209
- aio_context_release(state->aio_context);
210
+ AioContext *aio_context;
211
+
212
+ if (!state->old_bs) {
213
+ return;
214
}
215
+
216
+ aio_context = bdrv_get_aio_context(state->old_bs);
217
+ aio_context_acquire(aio_context);
218
+
219
+ bdrv_drained_end(state->old_bs);
220
+ bdrv_unref(state->new_bs);
221
+
222
+ aio_context_release(aio_context);
223
}
224
225
typedef struct DriveBackupState {
226
--
227
2.14.3
228
229
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Message-id: 20171206144550.22295-4-stefanha@redhat.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
blockdev.c | 42 ++++++++++++++++++++++++++++++++++--------
8
1 file changed, 34 insertions(+), 8 deletions(-)
9
1
10
diff --git a/blockdev.c b/blockdev.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/blockdev.c
13
+++ b/blockdev.c
14
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_clean(BlkActionState *common)
15
typedef struct DriveBackupState {
16
BlkActionState common;
17
BlockDriverState *bs;
18
- AioContext *aio_context;
19
BlockJob *job;
20
} DriveBackupState;
21
22
@@ -XXX,XX +XXX,XX @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
23
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
24
BlockDriverState *bs;
25
DriveBackup *backup;
26
+ AioContext *aio_context;
27
Error *local_err = NULL;
28
29
assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
30
@@ -XXX,XX +XXX,XX @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
31
return;
32
}
33
34
- /* AioContext is released in .clean() */
35
- state->aio_context = bdrv_get_aio_context(bs);
36
- aio_context_acquire(state->aio_context);
37
+ aio_context = bdrv_get_aio_context(bs);
38
+ aio_context_acquire(aio_context);
39
+
40
+ /* Paired with .clean() */
41
bdrv_drained_begin(bs);
42
+
43
state->bs = bs;
44
45
state->job = do_drive_backup(backup, common->block_job_txn, &local_err);
46
if (local_err) {
47
error_propagate(errp, local_err);
48
- return;
49
+ goto out;
50
}
51
+
52
+out:
53
+ aio_context_release(aio_context);
54
}
55
56
static void drive_backup_commit(BlkActionState *common)
57
{
58
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
59
+ AioContext *aio_context;
60
+
61
+ aio_context = bdrv_get_aio_context(state->bs);
62
+ aio_context_acquire(aio_context);
63
+
64
assert(state->job);
65
block_job_start(state->job);
66
+
67
+ aio_context_release(aio_context);
68
}
69
70
static void drive_backup_abort(BlkActionState *common)
71
@@ -XXX,XX +XXX,XX @@ static void drive_backup_abort(BlkActionState *common)
72
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
73
74
if (state->job) {
75
+ AioContext *aio_context;
76
+
77
+ aio_context = bdrv_get_aio_context(state->bs);
78
+ aio_context_acquire(aio_context);
79
+
80
block_job_cancel_sync(state->job);
81
+
82
+ aio_context_release(aio_context);
83
}
84
}
85
86
static void drive_backup_clean(BlkActionState *common)
87
{
88
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
89
+ AioContext *aio_context;
90
91
- if (state->aio_context) {
92
- bdrv_drained_end(state->bs);
93
- aio_context_release(state->aio_context);
94
+ if (!state->bs) {
95
+ return;
96
}
97
+
98
+ aio_context = bdrv_get_aio_context(state->bs);
99
+ aio_context_acquire(aio_context);
100
+
101
+ bdrv_drained_end(state->bs);
102
+
103
+ aio_context_release(aio_context);
104
}
105
106
typedef struct BlockdevBackupState {
107
--
108
2.14.3
109
110
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Message-id: 20171206144550.22295-5-stefanha@redhat.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
blockdev.c | 44 ++++++++++++++++++++++++++++++++++----------
8
1 file changed, 34 insertions(+), 10 deletions(-)
9
1
10
diff --git a/blockdev.c b/blockdev.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/blockdev.c
13
+++ b/blockdev.c
14
@@ -XXX,XX +XXX,XX @@ typedef struct BlockdevBackupState {
15
BlkActionState common;
16
BlockDriverState *bs;
17
BlockJob *job;
18
- AioContext *aio_context;
19
} BlockdevBackupState;
20
21
static BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
22
@@ -XXX,XX +XXX,XX @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
23
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
24
BlockdevBackup *backup;
25
BlockDriverState *bs, *target;
26
+ AioContext *aio_context;
27
Error *local_err = NULL;
28
29
assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
30
@@ -XXX,XX +XXX,XX @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
31
return;
32
}
33
34
- /* AioContext is released in .clean() */
35
- state->aio_context = bdrv_get_aio_context(bs);
36
- if (state->aio_context != bdrv_get_aio_context(target)) {
37
- state->aio_context = NULL;
38
+ aio_context = bdrv_get_aio_context(bs);
39
+ if (aio_context != bdrv_get_aio_context(target)) {
40
error_setg(errp, "Backup between two IO threads is not implemented");
41
return;
42
}
43
- aio_context_acquire(state->aio_context);
44
+ aio_context_acquire(aio_context);
45
state->bs = bs;
46
+
47
+ /* Paired with .clean() */
48
bdrv_drained_begin(state->bs);
49
50
state->job = do_blockdev_backup(backup, common->block_job_txn, &local_err);
51
if (local_err) {
52
error_propagate(errp, local_err);
53
- return;
54
+ goto out;
55
}
56
+
57
+out:
58
+ aio_context_release(aio_context);
59
}
60
61
static void blockdev_backup_commit(BlkActionState *common)
62
{
63
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
64
+ AioContext *aio_context;
65
+
66
+ aio_context = bdrv_get_aio_context(state->bs);
67
+ aio_context_acquire(aio_context);
68
+
69
assert(state->job);
70
block_job_start(state->job);
71
+
72
+ aio_context_release(aio_context);
73
}
74
75
static void blockdev_backup_abort(BlkActionState *common)
76
@@ -XXX,XX +XXX,XX @@ static void blockdev_backup_abort(BlkActionState *common)
77
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
78
79
if (state->job) {
80
+ AioContext *aio_context;
81
+
82
+ aio_context = bdrv_get_aio_context(state->bs);
83
+ aio_context_acquire(aio_context);
84
+
85
block_job_cancel_sync(state->job);
86
+
87
+ aio_context_release(aio_context);
88
}
89
}
90
91
static void blockdev_backup_clean(BlkActionState *common)
92
{
93
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
94
+ AioContext *aio_context;
95
96
- if (state->aio_context) {
97
- bdrv_drained_end(state->bs);
98
- aio_context_release(state->aio_context);
99
+ if (!state->bs) {
100
+ return;
101
}
102
+
103
+ aio_context = bdrv_get_aio_context(state->bs);
104
+ aio_context_acquire(aio_context);
105
+
106
+ bdrv_drained_end(state->bs);
107
+
108
+ aio_context_release(aio_context);
109
}
110
111
typedef struct BlockDirtyBitmapState {
112
--
113
2.14.3
114
115
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Message-id: 20171206144550.22295-6-stefanha@redhat.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
blockdev.c | 47 +++++++++++++++++++++++++++++++----------------
8
1 file changed, 31 insertions(+), 16 deletions(-)
9
1
10
diff --git a/blockdev.c b/blockdev.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/blockdev.c
13
+++ b/blockdev.c
14
@@ -XXX,XX +XXX,XX @@ struct BlkActionState {
15
typedef struct InternalSnapshotState {
16
BlkActionState common;
17
BlockDriverState *bs;
18
- AioContext *aio_context;
19
QEMUSnapshotInfo sn;
20
bool created;
21
} InternalSnapshotState;
22
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
23
qemu_timeval tv;
24
BlockdevSnapshotInternal *internal;
25
InternalSnapshotState *state;
26
+ AioContext *aio_context;
27
int ret1;
28
29
g_assert(common->action->type ==
30
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
31
return;
32
}
33
34
- /* AioContext is released in .clean() */
35
- state->aio_context = bdrv_get_aio_context(bs);
36
- aio_context_acquire(state->aio_context);
37
+ aio_context = bdrv_get_aio_context(bs);
38
+ aio_context_acquire(aio_context);
39
40
state->bs = bs;
41
+
42
+ /* Paired with .clean() */
43
bdrv_drained_begin(bs);
44
45
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
46
- return;
47
+ goto out;
48
}
49
50
if (bdrv_is_read_only(bs)) {
51
error_setg(errp, "Device '%s' is read only", device);
52
- return;
53
+ goto out;
54
}
55
56
if (!bdrv_can_snapshot(bs)) {
57
error_setg(errp, "Block format '%s' used by device '%s' "
58
"does not support internal snapshots",
59
bs->drv->format_name, device);
60
- return;
61
+ goto out;
62
}
63
64
if (!strlen(name)) {
65
error_setg(errp, "Name is empty");
66
- return;
67
+ goto out;
68
}
69
70
/* check whether a snapshot with name exist */
71
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
72
&local_err);
73
if (local_err) {
74
error_propagate(errp, local_err);
75
- return;
76
+ goto out;
77
} else if (ret) {
78
error_setg(errp,
79
"Snapshot with name '%s' already exists on device '%s'",
80
name, device);
81
- return;
82
+ goto out;
83
}
84
85
/* 3. take the snapshot */
86
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
87
error_setg_errno(errp, -ret1,
88
"Failed to create snapshot '%s' on device '%s'",
89
name, device);
90
- return;
91
+ goto out;
92
}
93
94
/* 4. succeed, mark a snapshot is created */
95
state->created = true;
96
+
97
+out:
98
+ aio_context_release(aio_context);
99
}
100
101
static void internal_snapshot_abort(BlkActionState *common)
102
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_abort(BlkActionState *common)
103
DO_UPCAST(InternalSnapshotState, common, common);
104
BlockDriverState *bs = state->bs;
105
QEMUSnapshotInfo *sn = &state->sn;
106
+ AioContext *aio_context;
107
Error *local_error = NULL;
108
109
if (!state->created) {
110
return;
111
}
112
113
+ aio_context = bdrv_get_aio_context(state->bs);
114
+ aio_context_acquire(aio_context);
115
+
116
if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) {
117
error_reportf_err(local_error,
118
"Failed to delete snapshot with id '%s' and "
119
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_abort(BlkActionState *common)
120
sn->id_str, sn->name,
121
bdrv_get_device_name(bs));
122
}
123
+
124
+ aio_context_release(aio_context);
125
}
126
127
static void internal_snapshot_clean(BlkActionState *common)
128
{
129
InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState,
130
common, common);
131
+ AioContext *aio_context;
132
133
- if (state->aio_context) {
134
- if (state->bs) {
135
- bdrv_drained_end(state->bs);
136
- }
137
- aio_context_release(state->aio_context);
138
+ if (!state->bs) {
139
+ return;
140
}
141
+
142
+ aio_context = bdrv_get_aio_context(state->bs);
143
+ aio_context_acquire(aio_context);
144
+
145
+ bdrv_drained_end(state->bs);
146
+
147
+ aio_context_release(aio_context);
148
}
149
150
/* external snapshot private data */
151
--
152
2.14.3
153
154
diff view generated by jsdifflib
Deleted patch
1
The dirty bitmap actions in qmp_transaction have not used AioContext
2
since the dirty bitmap locking discipline was introduced in commit
3
2119882c7eb7e2c612b24fc0c8d86f5887d6f1c3 ("block: introduce
4
dirty_bitmap_mutex"). Remove the unused field.
5
1
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Message-id: 20171206144550.22295-7-stefanha@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
blockdev.c | 13 -------------
13
1 file changed, 13 deletions(-)
14
15
diff --git a/blockdev.c b/blockdev.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
18
+++ b/blockdev.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDirtyBitmapState {
20
BlkActionState common;
21
BdrvDirtyBitmap *bitmap;
22
BlockDriverState *bs;
23
- AioContext *aio_context;
24
HBitmap *backup;
25
bool prepared;
26
} BlockDirtyBitmapState;
27
@@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common,
28
}
29
30
bdrv_clear_dirty_bitmap(state->bitmap, &state->backup);
31
- /* AioContext is released in .clean() */
32
}
33
34
static void block_dirty_bitmap_clear_abort(BlkActionState *common)
35
@@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_clear_commit(BlkActionState *common)
36
hbitmap_free(state->backup);
37
}
38
39
-static void block_dirty_bitmap_clear_clean(BlkActionState *common)
40
-{
41
- BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
42
- common, common);
43
-
44
- if (state->aio_context) {
45
- aio_context_release(state->aio_context);
46
- }
47
-}
48
-
49
static void abort_prepare(BlkActionState *common, Error **errp)
50
{
51
error_setg(errp, "Transaction aborted using Abort action");
52
@@ -XXX,XX +XXX,XX @@ static const BlkActionOps actions[] = {
53
.prepare = block_dirty_bitmap_clear_prepare,
54
.commit = block_dirty_bitmap_clear_commit,
55
.abort = block_dirty_bitmap_clear_abort,
56
- .clean = block_dirty_bitmap_clear_clean,
57
}
58
};
59
60
--
61
2.14.3
62
63
diff view generated by jsdifflib
Deleted patch
1
Encapsulate IOThread QOM object lookup so that callers don't need to
2
know how and where IOThread objects live.
3
1
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-id: 20171206144550.22295-8-stefanha@redhat.com
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
10
include/sysemu/iothread.h | 1 +
11
iothread.c | 7 +++++++
12
2 files changed, 8 insertions(+)
13
14
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/sysemu/iothread.h
17
+++ b/include/sysemu/iothread.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
OBJECT_CHECK(IOThread, obj, TYPE_IOTHREAD)
20
21
char *iothread_get_id(IOThread *iothread);
22
+IOThread *iothread_by_id(const char *id);
23
AioContext *iothread_get_aio_context(IOThread *iothread);
24
void iothread_stop_all(void);
25
GMainContext *iothread_get_g_main_context(IOThread *iothread);
26
diff --git a/iothread.c b/iothread.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/iothread.c
29
+++ b/iothread.c
30
@@ -XXX,XX +XXX,XX @@ void iothread_destroy(IOThread *iothread)
31
{
32
object_unparent(OBJECT(iothread));
33
}
34
+
35
+/* Lookup IOThread by its id. Only finds user-created objects, not internal
36
+ * iothread_create() objects. */
37
+IOThread *iothread_by_id(const char *id)
38
+{
39
+ return IOTHREAD(object_resolve_path_type(id, TYPE_IOTHREAD, NULL));
40
+}
41
--
42
2.14.3
43
44
diff view generated by jsdifflib
1
When a node is already associated with a BlockBackend the
1
Code movement to pull the conversion from Qdict to BlockdevOptionsRbd
2
x-blockdev-set-iothread command refuses to set the IOThread. This is to
2
into a helper function.
3
prevent accidentally changing the IOThread when the nodes are in use.
4
3
5
When the nodes are created with -drive they automatically get a
4
Reviewed-by: Eric Blake <eblake@redhat.com>
6
BlockBackend. In that case we know nothing is using them yet and it's
5
Reviewed-by: John Snow <jsnow@redhat.com>
7
safe to set the IOThread. Add a force boolean to override the check.
6
Signed-off-by: Jeff Cody <jcody@redhat.com>
7
Message-id: 5b49a980f2cde6610ab1df41bb0277d00b5db893.1536704901.git.jcody@redhat.com
8
Signed-off-by: Jeff Cody <jcody@redhat.com>
9
---
10
block/rbd.c | 36 ++++++++++++++++++++++++------------
11
1 file changed, 24 insertions(+), 12 deletions(-)
8
12
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
diff --git a/block/rbd.c b/block/rbd.c
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Message-id: 20171207201320.19284-4-stefanha@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
qapi/block-core.json | 6 +++++-
15
blockdev.c | 11 ++++++-----
16
2 files changed, 11 insertions(+), 6 deletions(-)
17
18
diff --git a/qapi/block-core.json b/qapi/block-core.json
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/qapi/block-core.json
15
--- a/block/rbd.c
21
+++ b/qapi/block-core.json
16
+++ b/block/rbd.c
22
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ failed_opts:
23
#
18
return r;
24
# @iothread: the name of the IOThread object or null for the main loop
25
#
26
+# @force: true if the node and its children should be moved when a BlockBackend
27
+# is already attached
28
+#
29
# Note: this command is experimental and intended for test cases that need
30
# control over IOThreads only.
31
#
32
@@ -XXX,XX +XXX,XX @@
33
##
34
{ 'command': 'x-blockdev-set-iothread',
35
'data' : { 'node-name': 'str',
36
- 'iothread': 'StrOrNull' } }
37
+ 'iothread': 'StrOrNull',
38
+ '*force': 'bool' } }
39
diff --git a/blockdev.c b/blockdev.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/blockdev.c
42
+++ b/blockdev.c
43
@@ -XXX,XX +XXX,XX @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
44
}
19
}
45
20
46
void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
21
+static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts,
47
- Error **errp)
22
+ Error **errp)
48
+ bool has_force, bool force, Error **errp)
23
+{
24
+ Visitor *v;
25
+ Error *local_err = NULL;
26
+
27
+ /* Convert the remaining options into a QAPI object */
28
+ v = qobject_input_visitor_new_flat_confused(options, errp);
29
+ if (!v) {
30
+ return -EINVAL;
31
+ }
32
+
33
+ visit_type_BlockdevOptionsRbd(v, NULL, opts, &local_err);
34
+ visit_free(v);
35
+
36
+ if (local_err) {
37
+ error_propagate(errp, local_err);
38
+ return -EINVAL;
39
+ }
40
+
41
+ return 0;
42
+}
43
+
44
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
45
Error **errp)
49
{
46
{
50
AioContext *old_context;
47
BDRVRBDState *s = bs->opaque;
51
AioContext *new_context;
48
BlockdevOptionsRbd *opts = NULL;
52
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
49
- Visitor *v;
53
return;
50
const QDictEntry *e;
51
Error *local_err = NULL;
52
char *keypairs, *secretid;
53
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
54
qdict_del(options, "password-secret");
54
}
55
}
55
56
56
- /* If we want to allow more extreme test scenarios this guard could be
57
- /* Convert the remaining options into a QAPI object */
57
- * removed. For now it protects against accidents. */
58
- v = qobject_input_visitor_new_flat_confused(options, errp);
58
- if (bdrv_has_blk(bs)) {
59
- if (!v) {
59
- error_setg(errp, "Node %s is in use", node_name);
60
- r = -EINVAL;
60
+ /* Protects against accidents. */
61
- goto out;
61
+ if (!(has_force && force) && bdrv_has_blk(bs)) {
62
- }
62
+ error_setg(errp, "Node %s is associated with a BlockBackend and could "
63
-
63
+ "be in use (use force=true to override this check)",
64
- visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err);
64
+ node_name);
65
- visit_free(v);
65
return;
66
-
67
+ r = qemu_rbd_convert_options(options, &opts, &local_err);
68
if (local_err) {
69
error_propagate(errp, local_err);
70
- r = -EINVAL;
71
goto out;
66
}
72
}
67
73
68
--
74
--
69
2.14.3
75
2.17.1
70
76
71
77
diff view generated by jsdifflib
1
Currently there is no easy way for iotests to ensure that a BDS is bound
1
When we converted rbd to get rid of the older key/value-centric
2
to a particular IOThread. Normally the virtio-blk device calls
2
encoding format, we broke compatibility with image files with backing
3
blk_set_aio_context() when dataplane is enabled during guest driver
3
file strings encoded in the old format.
4
initialization. This never happens in iotests since -machine
5
accel=qtest means there is no guest activity (including device driver
6
initialization).
7
4
8
This patch adds a QMP command to explicitly assign IOThreads in test
5
This leaves a bit of an ugly conundrum, and a hacky solution.
9
cases. See qapi/block-core.json for a description of the command.
10
6
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
If the initial attempt to parse the "proper" options fails, it assumes
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
that we may have an older key/value encoded filename. Fall back to
9
attempting to parse the filename, and extract the required options from
10
it. If that fails, pass along the original error message.
11
12
We do not support mixed modern usage alongside legacy keyvalue pair
13
usage.
14
15
A deprecation warning has been added, although care should be taken
16
when actually deprecating since the impact is not limited to
17
commandline or qapi usage, but also opening existing images.
18
13
Reviewed-by: Eric Blake <eblake@redhat.com>
19
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Message-id: 20171206144550.22295-9-stefanha@redhat.com
20
Signed-off-by: Jeff Cody <jcody@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Message-id: 15b332e5432ad069441f7275a46080f465d789a0.1536704901.git.jcody@redhat.com
22
Signed-off-by: Jeff Cody <jcody@redhat.com>
16
---
23
---
17
qapi/block-core.json | 36 ++++++++++++++++++++++++++++++++++++
24
block/rbd.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--
18
blockdev.c | 41 +++++++++++++++++++++++++++++++++++++++++
25
1 file changed, 52 insertions(+), 2 deletions(-)
19
2 files changed, 77 insertions(+)
20
26
21
diff --git a/qapi/block-core.json b/qapi/block-core.json
27
diff --git a/block/rbd.c b/block/rbd.c
22
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
23
--- a/qapi/block-core.json
29
--- a/block/rbd.c
24
+++ b/qapi/block-core.json
30
+++ b/block/rbd.c
25
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts,
26
'data' : { 'parent': 'str',
32
return 0;
27
'*child': 'str',
33
}
28
'*node': 'str' } }
34
35
+static int qemu_rbd_attempt_legacy_options(QDict *options,
36
+ BlockdevOptionsRbd **opts,
37
+ char **keypairs)
38
+{
39
+ char *filename;
40
+ int r;
29
+
41
+
30
+##
42
+ filename = g_strdup(qdict_get_try_str(options, "filename"));
31
+# @x-blockdev-set-iothread:
43
+ if (!filename) {
32
+#
44
+ return -EINVAL;
33
+# Move @node and its children into the @iothread. If @iothread is null then
45
+ }
34
+# move @node and its children into the main loop.
46
+ qdict_del(options, "filename");
35
+#
36
+# The node must not be attached to a BlockBackend.
37
+#
38
+# @node-name: the name of the block driver node
39
+#
40
+# @iothread: the name of the IOThread object or null for the main loop
41
+#
42
+# Note: this command is experimental and intended for test cases that need
43
+# control over IOThreads only.
44
+#
45
+# Since: 2.12
46
+#
47
+# Example:
48
+#
49
+# 1. Move a node into an IOThread
50
+# -> { "execute": "x-blockdev-set-iothread",
51
+# "arguments": { "node-name": "disk1",
52
+# "iothread": "iothread0" } }
53
+# <- { "return": {} }
54
+#
55
+# 2. Move a node into the main loop
56
+# -> { "execute": "x-blockdev-set-iothread",
57
+# "arguments": { "node-name": "disk1",
58
+# "iothread": null } }
59
+# <- { "return": {} }
60
+#
61
+##
62
+{ 'command': 'x-blockdev-set-iothread',
63
+ 'data' : { 'node-name': 'str',
64
+ 'iothread': 'StrOrNull' } }
65
diff --git a/blockdev.c b/blockdev.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/blockdev.c
68
+++ b/blockdev.c
69
@@ -XXX,XX +XXX,XX @@
70
#include "qapi/qmp/qerror.h"
71
#include "qapi/qobject-output-visitor.h"
72
#include "sysemu/sysemu.h"
73
+#include "sysemu/iothread.h"
74
#include "block/block_int.h"
75
#include "qmp-commands.h"
76
#include "block/trace.h"
77
@@ -XXX,XX +XXX,XX @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
78
return head;
79
}
80
81
+void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
82
+ Error **errp)
83
+{
84
+ AioContext *old_context;
85
+ AioContext *new_context;
86
+ BlockDriverState *bs;
87
+
47
+
88
+ bs = bdrv_find_node(node_name);
48
+ qemu_rbd_parse_filename(filename, options, NULL);
89
+ if (!bs) {
49
+
90
+ error_setg(errp, "Cannot find node %s", node_name);
50
+ /* keypairs freed by caller */
91
+ return;
51
+ *keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs"));
52
+ if (*keypairs) {
53
+ qdict_del(options, "=keyvalue-pairs");
92
+ }
54
+ }
93
+
55
+
94
+ /* If we want to allow more extreme test scenarios this guard could be
56
+ r = qemu_rbd_convert_options(options, opts, NULL);
95
+ * removed. For now it protects against accidents. */
96
+ if (bdrv_has_blk(bs)) {
97
+ error_setg(errp, "Node %s is in use", node_name);
98
+ return;
99
+ }
100
+
57
+
101
+ if (iothread->type == QTYPE_QSTRING) {
58
+ g_free(filename);
102
+ IOThread *obj = iothread_by_id(iothread->u.s);
59
+ return r;
103
+ if (!obj) {
60
+}
104
+ error_setg(errp, "Cannot find iothread %s", iothread->u.s);
61
+
105
+ return;
62
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
63
Error **errp)
64
{
65
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
66
67
r = qemu_rbd_convert_options(options, &opts, &local_err);
68
if (local_err) {
69
- error_propagate(errp, local_err);
70
- goto out;
71
+ /* If keypairs are present, that means some options are present in
72
+ * the modern option format. Don't attempt to parse legacy option
73
+ * formats, as we won't support mixed usage. */
74
+ if (keypairs) {
75
+ error_propagate(errp, local_err);
76
+ goto out;
106
+ }
77
+ }
107
+
78
+
108
+ new_context = iothread_get_aio_context(obj);
79
+ /* If the initial attempt to convert and process the options failed,
109
+ } else {
80
+ * we may be attempting to open an image file that has the rbd options
110
+ new_context = qemu_get_aio_context();
81
+ * specified in the older format consisting of all key/value pairs
111
+ }
82
+ * encoded in the filename. Go ahead and attempt to parse the
112
+
83
+ * filename, and see if we can pull out the required options. */
113
+ old_context = bdrv_get_aio_context(bs);
84
+ r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs);
114
+ aio_context_acquire(old_context);
85
+ if (r < 0) {
115
+
86
+ /* Propagate the original error, not the legacy parsing fallback
116
+ bdrv_set_aio_context(bs, new_context);
87
+ * error, as the latter was just a best-effort attempt. */
117
+
88
+ error_propagate(errp, local_err);
118
+ aio_context_release(old_context);
89
+ goto out;
119
+}
90
+ }
120
+
91
+ /* Take care whenever deciding to actually deprecate; once this ability
121
QemuOptsList qemu_common_drive_opts = {
92
+ * is removed, we will not be able to open any images with legacy-styled
122
.name = "drive",
93
+ * backing image strings. */
123
.head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
94
+ error_report("RBD options encoded in the filename as keyvalue pairs "
95
+ "is deprecated");
96
}
97
98
/* Remove the processed options from the QDict (the visitor processes
124
--
99
--
125
2.14.3
100
2.17.1
126
101
127
102
diff view generated by jsdifflib
Deleted patch
1
QMP 'transaction' blockdev-snapshot-sync with multiple disks in an
2
IOThread is an untested code path. Several bugs have been found in
3
connection with this command. This patch adds a test case to prevent
4
future regressions.
5
1
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Message-id: 20171206144550.22295-10-stefanha@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
tests/qemu-iotests/202 | 95 ++++++++++++++++++++++++++++++++++++++++++++++
13
tests/qemu-iotests/202.out | 11 ++++++
14
tests/qemu-iotests/group | 1 +
15
3 files changed, 107 insertions(+)
16
create mode 100755 tests/qemu-iotests/202
17
create mode 100644 tests/qemu-iotests/202.out
18
19
diff --git a/tests/qemu-iotests/202 b/tests/qemu-iotests/202
20
new file mode 100755
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/tests/qemu-iotests/202
24
@@ -XXX,XX +XXX,XX @@
25
+#!/usr/bin/env python
26
+#
27
+# Copyright (C) 2017 Red Hat, Inc.
28
+#
29
+# This program is free software; you can redistribute it and/or modify
30
+# it under the terms of the GNU General Public License as published by
31
+# the Free Software Foundation; either version 2 of the License, or
32
+# (at your option) any later version.
33
+#
34
+# This program is distributed in the hope that it will be useful,
35
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
36
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37
+# GNU General Public License for more details.
38
+#
39
+# You should have received a copy of the GNU General Public License
40
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
41
+#
42
+# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com>
43
+#
44
+# Check that QMP 'transaction' blockdev-snapshot-sync with multiple drives on a
45
+# single IOThread completes successfully. This particular command triggered a
46
+# hang due to recursive AioContext locking and BDRV_POLL_WHILE(). Protect
47
+# against regressions.
48
+
49
+import iotests
50
+
51
+iotests.verify_image_format(supported_fmts=['qcow2'])
52
+iotests.verify_platform(['linux'])
53
+
54
+with iotests.FilePath('disk0.img') as disk0_img_path, \
55
+ iotests.FilePath('disk1.img') as disk1_img_path, \
56
+ iotests.FilePath('disk0-snap.img') as disk0_snap_img_path, \
57
+ iotests.FilePath('disk1-snap.img') as disk1_snap_img_path, \
58
+ iotests.VM() as vm:
59
+
60
+ img_size = '10M'
61
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size)
62
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size)
63
+
64
+ iotests.log('Launching VM...')
65
+ vm.launch()
66
+
67
+ iotests.log('Adding IOThread...')
68
+ iotests.log(vm.qmp('object-add',
69
+ qom_type='iothread',
70
+ id='iothread0'))
71
+
72
+ iotests.log('Adding blockdevs...')
73
+ iotests.log(vm.qmp('blockdev-add',
74
+ driver=iotests.imgfmt,
75
+ node_name='disk0',
76
+ file={
77
+ 'driver': 'file',
78
+ 'filename': disk0_img_path,
79
+ }))
80
+ iotests.log(vm.qmp('blockdev-add',
81
+ driver=iotests.imgfmt,
82
+ node_name='disk1',
83
+ file={
84
+ 'driver': 'file',
85
+ 'filename': disk1_img_path,
86
+ }))
87
+
88
+ iotests.log('Setting iothread...')
89
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
90
+ node_name='disk0',
91
+ iothread='iothread0'))
92
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
93
+ node_name='disk1',
94
+ iothread='iothread0'))
95
+
96
+ iotests.log('Creating external snapshots...')
97
+ iotests.log(vm.qmp(
98
+ 'transaction',
99
+ actions=[
100
+ {
101
+ 'data': {
102
+ 'node-name': 'disk0',
103
+ 'snapshot-file': disk0_snap_img_path,
104
+ 'snapshot-node-name': 'disk0-snap',
105
+ 'mode': 'absolute-paths',
106
+ 'format': iotests.imgfmt,
107
+ },
108
+ 'type': 'blockdev-snapshot-sync'
109
+ }, {
110
+ 'data': {
111
+ 'node-name': 'disk1',
112
+ 'snapshot-file': disk1_snap_img_path,
113
+ 'snapshot-node-name': 'disk1-snap',
114
+ 'mode': 'absolute-paths',
115
+ 'format': iotests.imgfmt
116
+ },
117
+ 'type': 'blockdev-snapshot-sync'
118
+ }
119
+ ]))
120
diff --git a/tests/qemu-iotests/202.out b/tests/qemu-iotests/202.out
121
new file mode 100644
122
index XXXXXXX..XXXXXXX
123
--- /dev/null
124
+++ b/tests/qemu-iotests/202.out
125
@@ -XXX,XX +XXX,XX @@
126
+Launching VM...
127
+Adding IOThread...
128
+{u'return': {}}
129
+Adding blockdevs...
130
+{u'return': {}}
131
+{u'return': {}}
132
+Setting iothread...
133
+{u'return': {}}
134
+{u'return': {}}
135
+Creating external snapshots...
136
+{u'return': {}}
137
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
138
index XXXXXXX..XXXXXXX 100644
139
--- a/tests/qemu-iotests/group
140
+++ b/tests/qemu-iotests/group
141
@@ -XXX,XX +XXX,XX @@
142
197 rw auto quick
143
198 rw auto
144
200 rw auto
145
+202 rw auto quick
146
--
147
2.14.3
148
149
diff view generated by jsdifflib
Deleted patch
1
From: Mark Kanda <mark.kanda@oracle.com>
2
1
3
Depending on the configuration, it can be beneficial to adjust the virtio-blk
4
queue size to something other than the current default of 128. Add a new
5
property to make the queue size configurable.
6
7
Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
8
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
9
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
10
Reviewed-by: Ameya More <ameya.more@oracle.com>
11
Message-id: 52e6d742811f10dbd16e996e86cf375b9577c187.1513005190.git.mark.kanda@oracle.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
include/hw/virtio/virtio-blk.h | 1 +
15
hw/block/virtio-blk.c | 10 +++++++++-
16
2 files changed, 10 insertions(+), 1 deletion(-)
17
18
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/virtio/virtio-blk.h
21
+++ b/include/hw/virtio/virtio-blk.h
22
@@ -XXX,XX +XXX,XX @@ struct VirtIOBlkConf
23
uint32_t config_wce;
24
uint32_t request_merging;
25
uint16_t num_queues;
26
+ uint16_t queue_size;
27
};
28
29
struct VirtIOBlockDataPlane;
30
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/block/virtio-blk.c
33
+++ b/hw/block/virtio-blk.c
34
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
35
error_setg(errp, "num-queues property must be larger than 0");
36
return;
37
}
38
+ if (!is_power_of_2(conf->queue_size) ||
39
+ conf->queue_size > VIRTQUEUE_MAX_SIZE) {
40
+ error_setg(errp, "invalid queue-size property (%" PRIu16 "), "
41
+ "must be a power of 2 (max %d)",
42
+ conf->queue_size, VIRTQUEUE_MAX_SIZE);
43
+ return;
44
+ }
45
46
blkconf_serial(&conf->conf, &conf->serial);
47
if (!blkconf_apply_backend_options(&conf->conf,
48
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
49
s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
50
51
for (i = 0; i < conf->num_queues; i++) {
52
- virtio_add_queue(vdev, 128, virtio_blk_handle_output);
53
+ virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output);
54
}
55
if (!virtio_blk_data_plane_create(vdev, conf, &s->dataplane, errp)) {
56
virtio_cleanup(vdev);
57
@@ -XXX,XX +XXX,XX @@ static Property virtio_blk_properties[] = {
58
DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
59
true),
60
DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues, 1),
61
+ DEFINE_PROP_UINT16("queue-size", VirtIOBlock, conf.queue_size, 128),
62
DEFINE_PROP_LINK("iothread", VirtIOBlock, conf.iothread, TYPE_IOTHREAD,
63
IOThread *),
64
DEFINE_PROP_END_OF_LIST(),
65
--
66
2.14.3
67
68
diff view generated by jsdifflib
Deleted patch
1
From: Mark Kanda <mark.kanda@oracle.com>
2
1
3
virtio-blk logical block size should never be larger than physical block
4
size because it doesn't make sense to have such configurations. QEMU doesn't
5
have a way to effectively express this condition; the best it can do is
6
report the physical block exponent as 0 - indicating the logical block size
7
equals the physical block size.
8
9
This is identical to commit 3da023b5827543ee4c022986ea2ad9d1274410b2
10
but applied to virtio-blk (instead of virtio-scsi).
11
12
Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
13
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
14
Reviewed-by: Ameya More <ameya.more@oracle.com>
15
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Message-id: 773169891f9f2deb4cb7c4ef2655580dbe24c1d1.1513005190.git.mark.kanda@oracle.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
---
20
hw/block/virtio-blk.c | 7 +++++++
21
1 file changed, 7 insertions(+)
22
23
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/block/virtio-blk.c
26
+++ b/hw/block/virtio-blk.c
27
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
28
29
blkconf_blocksizes(&conf->conf);
30
31
+ if (conf->conf.logical_block_size >
32
+ conf->conf.physical_block_size) {
33
+ error_setg(errp,
34
+ "logical_block_size > physical_block_size not supported");
35
+ return;
36
+ }
37
+
38
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
39
sizeof(struct virtio_blk_config));
40
41
--
42
2.14.3
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
BDRV_POLL_WHILE() does not support recursive AioContext locking. It
4
only releases the AioContext lock once regardless of how many times the
5
caller has acquired it. This results in a hang since the IOThread does
6
not make progress while the AioContext is still locked.
7
8
The following steps trigger the hang:
9
10
$ qemu-system-x86_64 -M accel=kvm -m 1G -cpu host \
11
-object iothread,id=iothread0 \
12
-device virtio-scsi-pci,iothread=iothread0 \
13
-drive if=none,id=drive0,file=test.img,format=raw \
14
-device scsi-hd,drive=drive0 \
15
-drive if=none,id=drive1,file=test.img,format=raw \
16
-device scsi-hd,drive=drive1
17
$ qemu-system-x86_64 ...same options... \
18
-incoming tcp::1234
19
(qemu) migrate tcp:127.0.0.1:1234
20
...hang...
21
22
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
23
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
24
Reviewed-by: Eric Blake <eblake@redhat.com>
25
Message-id: 20171207201320.19284-2-stefanha@redhat.com
26
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
27
---
28
block.c | 14 +++++++++++---
29
1 file changed, 11 insertions(+), 3 deletions(-)
30
31
diff --git a/block.c b/block.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block.c
34
+++ b/block.c
35
@@ -XXX,XX +XXX,XX @@ int bdrv_inactivate_all(void)
36
BdrvNextIterator it;
37
int ret = 0;
38
int pass;
39
+ GSList *aio_ctxs = NULL, *ctx;
40
41
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
42
- aio_context_acquire(bdrv_get_aio_context(bs));
43
+ AioContext *aio_context = bdrv_get_aio_context(bs);
44
+
45
+ if (!g_slist_find(aio_ctxs, aio_context)) {
46
+ aio_ctxs = g_slist_prepend(aio_ctxs, aio_context);
47
+ aio_context_acquire(aio_context);
48
+ }
49
}
50
51
/* We do two passes of inactivation. The first pass calls to drivers'
52
@@ -XXX,XX +XXX,XX @@ int bdrv_inactivate_all(void)
53
}
54
55
out:
56
- for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
57
- aio_context_release(bdrv_get_aio_context(bs));
58
+ for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) {
59
+ AioContext *aio_context = ctx->data;
60
+ aio_context_release(aio_context);
61
}
62
+ g_slist_free(aio_ctxs);
63
64
return ret;
65
}
66
--
67
2.14.3
68
69
diff view generated by jsdifflib
Deleted patch
1
See the patch for why nested AioContext locking is no longer allowed.
2
1
3
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Message-id: 20171207201320.19284-3-stefanha@redhat.com
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
8
docs/devel/multiple-iothreads.txt | 7 ++++---
9
1 file changed, 4 insertions(+), 3 deletions(-)
10
11
diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt
12
index XXXXXXX..XXXXXXX 100644
13
--- a/docs/devel/multiple-iothreads.txt
14
+++ b/docs/devel/multiple-iothreads.txt
15
@@ -XXX,XX +XXX,XX @@
16
-Copyright (c) 2014 Red Hat Inc.
17
+Copyright (c) 2014-2017 Red Hat Inc.
18
19
This work is licensed under the terms of the GNU GPL, version 2 or later. See
20
the COPYING file in the top-level directory.
21
@@ -XXX,XX +XXX,XX @@ aio_context_acquire()/aio_context_release() for mutual exclusion. Once the
22
context is acquired no other thread can access it or run event loop iterations
23
in this AioContext.
24
25
-aio_context_acquire()/aio_context_release() calls may be nested. This
26
-means you can call them if you're not sure whether #2 applies.
27
+Legacy code sometimes nests aio_context_acquire()/aio_context_release() calls.
28
+Do not use nesting anymore, it is incompatible with the BDRV_POLL_WHILE() macro
29
+used in the block layer and can lead to hangs.
30
31
There is currently no lock ordering rule if a thread needs to acquire multiple
32
AioContexts simultaneously. Therefore, it is only safe for code holding the
33
--
34
2.14.3
35
36
diff view generated by jsdifflib
1
This test case will prevent future regressions with savevm and
1
This is a small test that will check for the ability to parse
2
IOThreads.
2
both legacy and modern options for rbd.
3
3
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
The way the test is set up is for failure to occur, but without
5
having to wait to timeout on a non-existent rbd server. The error
6
messages in the success path show that the arguments were parsed.
7
8
The failure behavior prior to the patch series that has this test, is
9
qemu-img complaining about mandatory options (e.g. 'pool') not being
10
provided.
11
5
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Message-id: 20171207201320.19284-7-stefanha@redhat.com
13
Signed-off-by: Jeff Cody <jcody@redhat.com>
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Message-id: f830580e339b974a83ed4870d11adcdc17f49a47.1536704901.git.jcody@redhat.com
15
Signed-off-by: Jeff Cody <jcody@redhat.com>
8
---
16
---
9
tests/qemu-iotests/203 | 59 ++++++++++++++++++++++++++++++++++++++++++++++
17
tests/qemu-iotests/231 | 62 ++++++++++++++++++++++++++++++++++++++
10
tests/qemu-iotests/203.out | 6 +++++
18
tests/qemu-iotests/231.out | 9 ++++++
11
tests/qemu-iotests/group | 1 +
19
tests/qemu-iotests/group | 1 +
12
3 files changed, 66 insertions(+)
20
3 files changed, 72 insertions(+)
13
create mode 100755 tests/qemu-iotests/203
21
create mode 100755 tests/qemu-iotests/231
14
create mode 100644 tests/qemu-iotests/203.out
22
create mode 100644 tests/qemu-iotests/231.out
15
23
16
diff --git a/tests/qemu-iotests/203 b/tests/qemu-iotests/203
24
diff --git a/tests/qemu-iotests/231 b/tests/qemu-iotests/231
17
new file mode 100755
25
new file mode 100755
18
index XXXXXXX..XXXXXXX
26
index XXXXXXX..XXXXXXX
19
--- /dev/null
27
--- /dev/null
20
+++ b/tests/qemu-iotests/203
28
+++ b/tests/qemu-iotests/231
21
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
22
+#!/usr/bin/env python
30
+#!/bin/bash
23
+#
31
+#
24
+# Copyright (C) 2017 Red Hat, Inc.
32
+# Test legacy and modern option parsing for rbd/ceph. This will not
33
+# actually connect to a ceph server, but rather looks for the appropriate
34
+# error message that indicates we parsed the options correctly.
35
+#
36
+# Copyright (C) 2018 Red Hat, Inc.
25
+#
37
+#
26
+# This program is free software; you can redistribute it and/or modify
38
+# This program is free software; you can redistribute it and/or modify
27
+# it under the terms of the GNU General Public License as published by
39
+# it under the terms of the GNU General Public License as published by
28
+# the Free Software Foundation; either version 2 of the License, or
40
+# the Free Software Foundation; either version 2 of the License, or
29
+# (at your option) any later version.
41
+# (at your option) any later version.
...
...
34
+# GNU General Public License for more details.
46
+# GNU General Public License for more details.
35
+#
47
+#
36
+# You should have received a copy of the GNU General Public License
48
+# You should have received a copy of the GNU General Public License
37
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
49
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
38
+#
50
+#
39
+# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com>
40
+#
41
+# Check that QMP 'migrate' with multiple drives on a single IOThread completes
42
+# successfully. This particular command triggered a hang in the source QEMU
43
+# process due to recursive AioContext locking in bdrv_invalidate_all() and
44
+# BDRV_POLL_WHILE().
45
+
51
+
46
+import iotests
52
+# creator
53
+owner=jcody@redhat.com
47
+
54
+
48
+iotests.verify_image_format(supported_fmts=['qcow2'])
55
+seq=`basename $0`
49
+iotests.verify_platform(['linux'])
56
+echo "QA output created by $seq"
50
+
57
+
51
+with iotests.FilePath('disk0.img') as disk0_img_path, \
58
+here=`pwd`
52
+ iotests.FilePath('disk1.img') as disk1_img_path, \
59
+status=1    # failure is the default!
53
+ iotests.VM() as vm:
54
+
60
+
55
+ img_size = '10M'
61
+_cleanup()
56
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size)
62
+{
57
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size)
63
+ rm "${BOGUS_CONF}"
64
+}
65
+trap "_cleanup; exit \$status" 0 1 2 3 15
58
+
66
+
59
+ iotests.log('Launching VM...')
67
+# get standard environment, filters and checks
60
+ (vm.add_object('iothread,id=iothread0')
68
+. ./common.rc
61
+ .add_drive(disk0_img_path, 'node-name=drive0-node', interface='none')
69
+. ./common.filter
62
+ .add_drive(disk1_img_path, 'node-name=drive1-node', interface='none')
63
+ .launch())
64
+
70
+
65
+ iotests.log('Setting IOThreads...')
71
+_supported_fmt generic
66
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
72
+_supported_proto rbd
67
+ node_name='drive0-node', iothread='iothread0',
73
+_supported_os Linux
68
+ force=True))
69
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
70
+ node_name='drive1-node', iothread='iothread0',
71
+ force=True))
72
+
74
+
73
+ iotests.log('Starting migration...')
75
+BOGUS_CONF=${TEST_DIR}/ceph-$$.conf
74
+ iotests.log(vm.qmp('migrate', uri='exec:cat >/dev/null'))
76
+touch "${BOGUS_CONF}"
75
+ while True:
77
+
76
+ vm.get_qmp_event(wait=60.0)
78
+_filter_conf()
77
+ result = vm.qmp('query-migrate')
79
+{
78
+ status = result.get('return', {}).get('status', None)
80
+ sed -e "s#$BOGUS_CONF#BOGUS_CONF#g"
79
+ if status == 'completed':
81
+}
80
+ break
82
+
81
diff --git a/tests/qemu-iotests/203.out b/tests/qemu-iotests/203.out
83
+# We expect this to fail, with no monitor ip provided and a null conf file. Just want it
84
+# to fail in the right way.
85
+$QEMU_IMG info "json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=${BOGUS_CONF}'}" 2>&1 | _filter_conf
86
+$QEMU_IMG info "json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'${BOGUS_CONF}'}" 2>&1 | _filter_conf
87
+
88
+# success, all done
89
+echo "*** done"
90
+rm -f $seq.full
91
+status=0
92
diff --git a/tests/qemu-iotests/231.out b/tests/qemu-iotests/231.out
82
new file mode 100644
93
new file mode 100644
83
index XXXXXXX..XXXXXXX
94
index XXXXXXX..XXXXXXX
84
--- /dev/null
95
--- /dev/null
85
+++ b/tests/qemu-iotests/203.out
96
+++ b/tests/qemu-iotests/231.out
86
@@ -XXX,XX +XXX,XX @@
97
@@ -XXX,XX +XXX,XX @@
87
+Launching VM...
98
+QA output created by 231
88
+Setting IOThreads...
99
+qemu-img: RBD options encoded in the filename as keyvalue pairs is deprecated. Future versions may cease to parse these options in the future.
89
+{u'return': {}}
100
+unable to get monitor info from DNS SRV with service name: ceph-mon
90
+{u'return': {}}
101
+no monitors specified to connect to.
91
+Starting migration...
102
+qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory
92
+{u'return': {}}
103
+unable to get monitor info from DNS SRV with service name: ceph-mon
104
+no monitors specified to connect to.
105
+qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory
106
+*** done
93
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
107
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
94
index XXXXXXX..XXXXXXX 100644
108
index XXXXXXX..XXXXXXX 100644
95
--- a/tests/qemu-iotests/group
109
--- a/tests/qemu-iotests/group
96
+++ b/tests/qemu-iotests/group
110
+++ b/tests/qemu-iotests/group
97
@@ -XXX,XX +XXX,XX @@
111
@@ -XXX,XX +XXX,XX @@
98
198 rw auto
112
226 auto quick
99
200 rw auto
113
227 auto quick
100
202 rw auto quick
114
229 auto quick
101
+203 rw auto
115
+231 auto quick
102
--
116
--
103
2.14.3
117
2.17.1
104
118
105
119
diff view generated by jsdifflib
1
There is a small chance that iothread_stop() hangs as follows:
1
Signed-off-by: Jeff Cody <jcody@redhat.com>
2
Message-id: 647f5b5ab7efd8bf567a504c832b1d2d6f719b23.1536704901.git.jcody@redhat.com
3
Signed-off-by: Jeff Cody <jcody@redhat.com>
4
---
5
qemu-deprecated.texi | 15 +++++++++++++++
6
1 file changed, 15 insertions(+)
2
7
3
Thread 3 (Thread 0x7f63eba5f700 (LWP 16105)):
8
diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
4
#0 0x00007f64012c09b6 in ppoll () at /lib64/libc.so.6
5
#1 0x000055959992eac9 in ppoll (__ss=0x0, __timeout=0x0, __nfds=<optimized out>, __fds=<optimized out>) at /usr/include/bits/poll2.h:77
6
#2 0x000055959992eac9 in qemu_poll_ns (fds=<optimized out>, nfds=<optimized out>, timeout=<optimized out>) at util/qemu-timer.c:322
7
#3 0x0000559599930711 in aio_poll (ctx=0x55959bdb83c0, blocking=blocking@entry=true) at util/aio-posix.c:629
8
#4 0x00005595996806fe in iothread_run (opaque=0x55959bd78400) at iothread.c:59
9
#5 0x00007f640159f609 in start_thread () at /lib64/libpthread.so.0
10
#6 0x00007f64012cce6f in clone () at /lib64/libc.so.6
11
12
Thread 1 (Thread 0x7f640b45b280 (LWP 16103)):
13
#0 0x00007f64015a0b6d in pthread_join () at /lib64/libpthread.so.0
14
#1 0x00005595999332ef in qemu_thread_join (thread=<optimized out>) at util/qemu-thread-posix.c:547
15
#2 0x00005595996808ae in iothread_stop (iothread=<optimized out>) at iothread.c:91
16
#3 0x000055959968094d in iothread_stop_iter (object=<optimized out>, opaque=<optimized out>) at iothread.c:102
17
#4 0x0000559599857d97 in do_object_child_foreach (obj=obj@entry=0x55959bdb8100, fn=fn@entry=0x559599680930 <iothread_stop_iter>, opaque=opaque@entry=0x0, recurse=recurse@entry=false) at qom/object.c:852
18
#5 0x0000559599859477 in object_child_foreach (obj=obj@entry=0x55959bdb8100, fn=fn@entry=0x559599680930 <iothread_stop_iter>, opaque=opaque@entry=0x0) at qom/object.c:867
19
#6 0x0000559599680a6e in iothread_stop_all () at iothread.c:341
20
#7 0x000055959955b1d5 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4913
21
22
The relevant code from iothread_run() is:
23
24
while (!atomic_read(&iothread->stopping)) {
25
aio_poll(iothread->ctx, true);
26
27
and iothread_stop():
28
29
iothread->stopping = true;
30
aio_notify(iothread->ctx);
31
...
32
qemu_thread_join(&iothread->thread);
33
34
The following scenario can occur:
35
36
1. IOThread:
37
while (!atomic_read(&iothread->stopping)) -> stopping=false
38
39
2. Main loop:
40
iothread->stopping = true;
41
aio_notify(iothread->ctx);
42
43
3. IOThread:
44
aio_poll(iothread->ctx, true); -> hang
45
46
The bug is explained by the AioContext->notify_me doc comments:
47
48
"If this field is 0, everything (file descriptors, bottom halves,
49
timers) will be re-evaluated before the next blocking poll(), thus the
50
event_notifier_set call can be skipped."
51
52
The problem is that "everything" does not include checking
53
iothread->stopping. This means iothread_run() will block in aio_poll()
54
if aio_notify() was called just before aio_poll().
55
56
This patch fixes the hang by replacing aio_notify() with
57
aio_bh_schedule_oneshot(). This makes aio_poll() or g_main_loop_run()
58
to return.
59
60
Implementing this properly required a new bool running flag. The new
61
flag prevents races that are tricky if we try to use iothread->stopping.
62
Now iothread->stopping is purely for iothread_stop() and
63
iothread->running is purely for the iothread_run() thread.
64
65
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
66
Reviewed-by: Eric Blake <eblake@redhat.com>
67
Message-id: 20171207201320.19284-6-stefanha@redhat.com
68
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
69
---
70
include/sysemu/iothread.h | 3 ++-
71
iothread.c | 20 +++++++++++++++-----
72
2 files changed, 17 insertions(+), 6 deletions(-)
73
74
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
75
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
76
--- a/include/sysemu/iothread.h
10
--- a/qemu-deprecated.texi
77
+++ b/include/sysemu/iothread.h
11
+++ b/qemu-deprecated.texi
78
@@ -XXX,XX +XXX,XX @@ typedef struct {
12
@@ -XXX,XX +XXX,XX @@ used instead.
79
GOnce once;
13
In order to prevent QEMU from automatically opening an image's backing
80
QemuMutex init_done_lock;
14
chain, use ``"backing": null'' instead.
81
QemuCond init_done_cond; /* is thread initialization done? */
15
82
- bool stopping;
16
+@subsubsection rbd keyvalue pair encoded filenames: "" (since 3.1.0)
83
+ bool stopping; /* has iothread_stop() been called? */
84
+ bool running; /* should iothread_run() continue? */
85
int thread_id;
86
87
/* AioContext poll parameters */
88
diff --git a/iothread.c b/iothread.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/iothread.c
91
+++ b/iothread.c
92
@@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque)
93
qemu_cond_signal(&iothread->init_done_cond);
94
qemu_mutex_unlock(&iothread->init_done_lock);
95
96
- while (!atomic_read(&iothread->stopping)) {
97
+ while (iothread->running) {
98
aio_poll(iothread->ctx, true);
99
100
if (atomic_read(&iothread->worker_context)) {
101
@@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque)
102
return NULL;
103
}
104
105
+/* Runs in iothread_run() thread */
106
+static void iothread_stop_bh(void *opaque)
107
+{
108
+ IOThread *iothread = opaque;
109
+
17
+
110
+ iothread->running = false; /* stop iothread_run() */
18
+Options for ``rbd'' should be specified according to its runtime options,
19
+like other block drivers. Legacy parsing of keyvalue pair encoded
20
+filenames is useful to open images with the old format for backing files;
21
+These image files should be updated to use the current format.
111
+
22
+
112
+ if (iothread->main_loop) {
23
+Example of legacy encoding:
113
+ g_main_loop_quit(iothread->main_loop);
114
+ }
115
+}
116
+
24
+
117
void iothread_stop(IOThread *iothread)
25
+@code{json:@{"file.driver":"rbd", "file.filename":"rbd:rbd/name"@}}
118
{
26
+
119
if (!iothread->ctx || iothread->stopping) {
27
+The above, converted to the current supported format:
120
return;
28
+
121
}
29
+@code{json:@{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"@}}
122
iothread->stopping = true;
30
+
123
- aio_notify(iothread->ctx);
31
@subsection vio-spapr-device device options
124
- if (atomic_read(&iothread->main_loop)) {
32
125
- g_main_loop_quit(iothread->main_loop);
33
@subsubsection "irq": "" (since 3.0.0)
126
- }
127
+ aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread);
128
qemu_thread_join(&iothread->thread);
129
}
130
131
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
132
char *name, *thread_name;
133
134
iothread->stopping = false;
135
+ iothread->running = true;
136
iothread->thread_id = -1;
137
iothread->ctx = aio_context_new(&local_error);
138
if (!iothread->ctx) {
139
--
34
--
140
2.14.3
35
2.17.1
141
36
142
37
diff view generated by jsdifflib
1
The VM.add_object() method can be used to add IOThreads or memory
1
From: "Richard W.M. Jones" <rjones@redhat.com>
2
backend objects.
3
2
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
3
The sslverify setting is supposed to turn off all TLS certificate
5
Reviewed-by: Eric Blake <eblake@redhat.com>
4
checks in libcurl. However because of the way we use it, it only
6
Message-id: 20171207201320.19284-5-stefanha@redhat.com
5
turns off peer certificate authenticity checks
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
(CURLOPT_SSL_VERIFYPEER). This patch makes it also turn off the check
7
that the server name in the certificate is the same as the server
8
you're connecting to (CURLOPT_SSL_VERIFYHOST).
9
10
We can use Google's server at 8.8.8.8 which happens to have a bad TLS
11
certificate to demonstrate this:
12
13
$ ./qemu-img create -q -f qcow2 -b 'json: { "file.sslverify": "off", "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2
14
qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: SSL: no alternative certificate subject name matches target host name '8.8.8.8'
15
Could not open backing image to determine size.
16
17
With this patch applied, qemu-img connects to the server regardless of
18
the bad certificate:
19
20
$ ./qemu-img create -q -f qcow2 -b 'json: { "file.sslverify": "off", "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2
21
qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: The requested URL returned error: 404 Not Found
22
23
(The 404 error is expected because 8.8.8.8 is not actually serving a
24
file called "/foo".)
25
26
Of course the default (without sslverify=off) remains to always check
27
the certificate:
28
29
$ ./qemu-img create -q -f qcow2 -b 'json: { "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2
30
qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: SSL: no alternative certificate subject name matches target host name '8.8.8.8'
31
Could not open backing image to determine size.
32
33
Further information about the two settings is available here:
34
35
https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html
36
https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
37
38
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
39
Message-id: 20180914095622.19698-1-rjones@redhat.com
40
Signed-off-by: Jeff Cody <jcody@redhat.com>
8
---
41
---
9
tests/qemu-iotests/iotests.py | 5 +++++
42
block/curl.c | 2 ++
10
1 file changed, 5 insertions(+)
43
1 file changed, 2 insertions(+)
11
44
12
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
45
diff --git a/block/curl.c b/block/curl.c
13
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/iotests.py
47
--- a/block/curl.c
15
+++ b/tests/qemu-iotests/iotests.py
48
+++ b/block/curl.c
16
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
49
@@ -XXX,XX +XXX,XX @@ static int curl_init_state(BDRVCURLState *s, CURLState *state)
17
socket_scm_helper=socket_scm_helper)
50
curl_easy_setopt(state->curl, CURLOPT_URL, s->url);
18
self._num_drives = 0
51
curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYPEER,
19
52
(long) s->sslverify);
20
+ def add_object(self, opts):
53
+ curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYHOST,
21
+ self._args.append('-object')
54
+ s->sslverify ? 2L : 0L);
22
+ self._args.append(opts)
55
if (s->cookie) {
23
+ return self
56
curl_easy_setopt(state->curl, CURLOPT_COOKIE, s->cookie);
24
+
57
}
25
def add_device(self, opts):
26
self._args.append('-device')
27
self._args.append(opts)
28
--
58
--
29
2.14.3
59
2.17.1
30
60
31
61
diff view generated by jsdifflib