diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-08-18 11:59:26 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-08-18 11:59:27 +0100 |
commit | da398fcc256b226217c92c8a83abf3a6ff247e8b (patch) | |
tree | e9d8ec4f6ff1b43933644fa8d5b422c05f46380e /hw/block/dataplane/virtio-blk.c | |
parent | 142f4ac5d5e024670ef4725e8943702b027e4218 (diff) | |
parent | 39ba3bf69c4ef4d8a8b683ee7282efd25b3f01ff (diff) | |
download | qemu-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.c | 39 |
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; } |