summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
authorMarkus Armbruster2010-06-29 16:58:30 +0200
committerKevin Wolf2010-07-02 13:18:02 +0200
commit18846dee1a795b4345ac0bd10b70a3a46fd14287 (patch)
treeae5d0224a6e9733c38835c39fab70e5f42393867 /block.c
parentblockdev: drive_get_by_id() is no longer used, remove (diff)
downloadqemu-18846dee1a795b4345ac0bd10b70a3a46fd14287.tar.gz
qemu-18846dee1a795b4345ac0bd10b70a3a46fd14287.tar.xz
qemu-18846dee1a795b4345ac0bd10b70a3a46fd14287.zip
block: Catch attempt to attach multiple devices to a blockdev
For instance, -device scsi-disk,drive=foo -device scsi-disk,drive=foo happily creates two SCSI disks connected to the same block device. It's all downhill from there. Device usb-storage deliberately attaches twice to the same blockdev, which fails with the fix in place. Detach before the second attach there. Also catch attempt to delete while a guest device model is attached. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/block.c b/block.c
index 31ca4c5a43..4c65035313 100644
--- a/block.c
+++ b/block.c
@@ -665,6 +665,8 @@ void bdrv_close_all(void)
void bdrv_delete(BlockDriverState *bs)
{
+ assert(!bs->peer);
+
/* remove from list, if necessary */
if (bs->device_name[0] != '\0') {
QTAILQ_REMOVE(&bdrv_states, bs, list);
@@ -678,6 +680,26 @@ void bdrv_delete(BlockDriverState *bs)
qemu_free(bs);
}
+int bdrv_attach(BlockDriverState *bs, DeviceState *qdev)
+{
+ if (bs->peer) {
+ return -EBUSY;
+ }
+ bs->peer = qdev;
+ return 0;
+}
+
+void bdrv_detach(BlockDriverState *bs, DeviceState *qdev)
+{
+ assert(bs->peer == qdev);
+ bs->peer = NULL;
+}
+
+DeviceState *bdrv_get_attached(BlockDriverState *bs)
+{
+ return bs->peer;
+}
+
/*
* Run consistency checks on an image
*