summaryrefslogtreecommitdiff
path: root/hw/block/dataplane/virtio-blk.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-08-18 11:59:26 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-08-18 11:59:27 +0100
commitda398fcc256b226217c92c8a83abf3a6ff247e8b (patch)
treee9d8ec4f6ff1b43933644fa8d5b422c05f46380e /hw/block/dataplane/virtio-blk.c
parent142f4ac5d5e024670ef4725e8943702b027e4218 (diff)
parent39ba3bf69c4ef4d8a8b683ee7282efd25b3f01ff (diff)
downloadqemu-da398fcc256b226217c92c8a83abf3a6ff247e8b.tar.gz
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request # gpg: Signature made Fri 15 Aug 2014 18:04:23 BST using RSA key ID 81AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" * remotes/stefanha/tags/block-pull-request: (55 commits) qcow2: fix new_blocks double-free in alloc_refcount_block() image-fuzzer: Reduce number of generator functions in __init__ image-fuzzer: Add generators of L1/L2 tables image-fuzzer: Add fuzzing functions for L1/L2 table entries docs: Expand the list of supported image elements with L1/L2 tables image-fuzzer: Public API for image-fuzzer/runner/runner.py image-fuzzer: Generator of fuzzed qcow2 images image-fuzzer: Fuzzing functions for qcow2 images image-fuzzer: Tool for fuzz tests execution docs: Specification for the image fuzzer ide: only constrain read/write requests to drive size, not other types virtio-blk: Correct bug in support for flexible descriptor layout libqos: Change free function called in malloc libqos: Correct mask to align size to PAGE_SIZE in malloc-pc libqtest: add QTEST_LOG for debugging qtest testcases ide: Fix segfault when flushing a device that doesn't exist qemu-options: add missing -drive discard option to cmdline help parallels: 2TB+ parallels images support parallels: split check for parallels format in parallels_open parallels: replace tabs with spaces in block/parallels.c ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/block/dataplane/virtio-blk.c')
-rw-r--r--hw/block/dataplane/virtio-blk.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index d6ba65ca23..24a6b71395 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -28,6 +28,7 @@ struct VirtIOBlockDataPlane {
bool started;
bool starting;
bool stopping;
+ bool disabled;
VirtIOBlkConf *blk;
@@ -218,8 +219,9 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
VirtQueue *vq;
+ int r;
- if (s->started) {
+ if (s->started || s->disabled) {
return;
}
@@ -231,22 +233,23 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
vq = virtio_get_queue(s->vdev, 0);
if (!vring_setup(&s->vring, s->vdev, 0)) {
- s->starting = false;
- return;
+ goto fail_vring;
}
/* Set up guest notifier (irq) */
- if (k->set_guest_notifiers(qbus->parent, 1, true) != 0) {
- fprintf(stderr, "virtio-blk failed to set guest notifier, "
- "ensure -enable-kvm is set\n");
- exit(1);
+ r = k->set_guest_notifiers(qbus->parent, 1, true);
+ if (r != 0) {
+ fprintf(stderr, "virtio-blk failed to set guest notifier (%d), "
+ "ensure -enable-kvm is set\n", r);
+ goto fail_guest_notifiers;
}
s->guest_notifier = virtio_queue_get_guest_notifier(vq);
/* Set up virtqueue notify */
- if (k->set_host_notifier(qbus->parent, 0, true) != 0) {
- fprintf(stderr, "virtio-blk failed to set host notifier\n");
- exit(1);
+ r = k->set_host_notifier(qbus->parent, 0, true);
+ if (r != 0) {
+ fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r);
+ goto fail_host_notifier;
}
s->host_notifier = *virtio_queue_get_host_notifier(vq);
@@ -266,6 +269,15 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
aio_context_acquire(s->ctx);
aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify);
aio_context_release(s->ctx);
+ return;
+
+ fail_host_notifier:
+ k->set_guest_notifiers(qbus->parent, 1, false);
+ fail_guest_notifiers:
+ vring_teardown(&s->vring, s->vdev, 0);
+ s->disabled = true;
+ fail_vring:
+ s->starting = false;
}
/* Context: QEMU global mutex held */
@@ -274,6 +286,13 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
+
+
+ /* Better luck next time. */
+ if (s->disabled) {
+ s->disabled = false;
+ return;
+ }
if (!s->started || s->stopping) {
return;
}