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>
This commit is contained in:
Markus Armbruster 2010-06-29 16:58:30 +02:00 committed by Kevin Wolf
parent dfb0acd887
commit 18846dee1a
11 changed files with 74 additions and 15 deletions

View file

@ -532,12 +532,13 @@ static int usb_msd_initfn(USBDevice *dev)
/*
* Hack alert: this pretends to be a block device, but it's really
* a SCSI bus that can serve only a single device, which it
* creates automatically. Two drive properties pointing to the
* same drive is not good: free_drive() dies for the second one.
* Zap the one we're not going to use.
* creates automatically. But first it needs to detach from its
* blockdev, or else scsi_bus_legacy_add_drive() dies when it
* attaches again.
*
* The hack is probably a bad idea.
*/
bdrv_detach(bs, &s->dev.qdev);
s->conf.bs = NULL;
s->dev.speed = USB_SPEED_FULL;
@ -609,7 +610,10 @@ static USBDevice *usb_msd_init(const char *filename)
if (!dev) {
return NULL;
}
qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv);
if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
qdev_free(&dev->qdev);
return NULL;
}
if (qdev_init(&dev->qdev) < 0)
return NULL;