From 3f12b5fa1e7491b9e794ecce3809d4980e5f46ad Mon Sep 17 00:00:00 2001 From: Darek Stojaczyk Date: Tue, 16 Oct 2018 06:57:01 +0200 Subject: [PATCH] vhost/blk: check against hotremoved bdev in GET_CONFIG handler We always need to ensure bvdev->bdev is not NULL before accessing it. GET_CONFIG handler was standing out in this matter, causing segfaults when connecting to a vhost block device that went through a bdev hotremove. If the bdev has been hotremoved we'll now report blocksize == 0 and blockcount == 0. From what I checked, QEMU will still expose a virtio-blk device to the VM, but linux (because that's what I checked) won't create a block device for it. Note: The behavior above can be tricky to investigate as neither QEMU nor VM doesn't log any messages about it. We should eventually reject any new connections to a vhost-blk socket with hotremoved bdev, but that's a task for later. Fixes #460 Change-Id: I266257f4b35d07f35ba03adf46cb18425f3cf39a Signed-off-by: Darek Stojaczyk Reviewed-on: https://review.gerrithub.io/417934 Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Pawel Wodkowski Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Tested-by: SPDK CI Jenkins --- lib/vhost/vhost_blk.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/vhost/vhost_blk.c b/lib/vhost/vhost_blk.c index 0f2def8a6..6a9a1896f 100644 --- a/lib/vhost/vhost_blk.c +++ b/lib/vhost/vhost_blk.c @@ -718,8 +718,24 @@ spdk_vhost_blk_get_config(struct spdk_vhost_dev *vdev, uint8_t *config, } bdev = bvdev->bdev; - blk_size = spdk_bdev_get_block_size(bdev); - blkcnt = spdk_bdev_get_num_blocks(bdev); + if (bdev == NULL) { + /* We can't just return -1 here as this GET_CONFIG message might + * be caused by a QEMU VM reboot. Returning -1 will indicate an + * error to QEMU, who might then decide to terminate itself. + * We don't want that. A simple reboot shouldn't break the system. + * + * Presenting a block device with block size 0 and block count 0 + * doesn't cause any problems on QEMU side and the virtio-pci + * device is even still available inside the VM, but there will + * be no block device created for it - the kernel drivers will + * silently reject it. + */ + blk_size = 0; + blkcnt = 0; + } else { + blk_size = spdk_bdev_get_block_size(bdev); + blkcnt = spdk_bdev_get_num_blocks(bdev); + } memset(blkcfg, 0, sizeof(*blkcfg)); blkcfg->blk_size = blk_size;