diff options
author | Markus Armbruster <armbru@redhat.com> | 2010-06-25 13:42:14 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2010-07-02 13:18:02 +0200 |
commit | 7d0d69509a966a5328e4fed7d0a942112d431c35 (patch) | |
tree | e2d3a6cb0b5f07d8220f2361605ba689220560b1 /hw/fdc.c | |
parent | 3ac906f771c42363dc05e0a393defd21a57d3790 (diff) | |
download | qemu-7d0d69509a966a5328e4fed7d0a942112d431c35.zip qemu-7d0d69509a966a5328e4fed7d0a942112d431c35.tar.gz qemu-7d0d69509a966a5328e4fed7d0a942112d431c35.tar.bz2 |
block: Fix virtual media change for if=none
BlockDriverState member removable controls whether virtual media
change (monitor commands change, eject) is allowed. It is set when
the "type hint" is BDRV_TYPE_CDROM or BDRV_TYPE_FLOPPY.
The type hint is only set by drive_init(). It sets BDRV_TYPE_FLOPPY
for if=floppy. It sets BDRV_TYPE_CDROM for media=cdrom and if=ide,
scsi, xen, or none.
if=ide and if=scsi work, because the type hint makes it a CD-ROM.
if=xen likewise, I think.
For the same reason, if=none works when it's used by ide-drive or
scsi-disk. For other guest devices, there are problems:
* fdc: you can't change virtual media
$ qemu [...] -drive if=none,id=foo,... -global isa-fdc.driveA=foo
QEMU 0.12.50 monitor - type 'help' for more information
(qemu) eject foo
Device 'foo' is not removable
unless you add media=cdrom, but that makes it readonly.
* virtio: if you add media=cdrom, you can change virtual media. If
you eject, the guest gets I/O errors. If you change, the guest sees
the drive's contents suddenly change.
* scsi-generic: if you add media=cdrom, you can change virtual media.
I didn't test what that does to the guest or the physical device,
but it can't be pretty.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/fdc.c')
-rw-r--r-- | hw/fdc.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -1847,10 +1847,16 @@ static void fdctrl_result_timer(void *opaque) static void fdctrl_connect_drives(FDCtrl *fdctrl) { unsigned int i; + FDrive *drive; for (i = 0; i < MAX_FD; i++) { - fd_init(&fdctrl->drives[i]); - fd_revalidate(&fdctrl->drives[i]); + drive = &fdctrl->drives[i]; + + fd_init(drive); + fd_revalidate(drive); + if (drive->bs) { + bdrv_set_removable(drive->bs, 1); + } } } |