From 2a2c61156e6049f7cd16e219be1da24f18d1b92b Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Fri, 18 Dec 2009 19:23:43 -0200 Subject: [PATCH 2/2] monitor: allow device to be ejected if no disk is inserted RH-Author: Eduardo Habkost <ehabkost@redhat.com> Message-id: <20091218192343.GI6538@blackpad.lan.raisama.net> Patchwork-id: 5807 O-Subject: [RHEL-5.5 KVM PATCH] monitor: allow device to be ejected if no disk is inserted Bugzilla: 539250 RH-Acked-by: Markus Armbruster <armbru@redhat.com> RH-Acked-by: Juan Quintela <quintela@redhat.com> RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com> RH-Acked-by: Naphtali Sprei <nsprei@redhat.com> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=539250 Upstream status: submitted and entered staging tree last week, but had to be rebased due to conflicts with the monitor QMP changes. A new rebased version was submitted today. (http://article.gmane.org/gmane.comp.emulators.qemu/59813) This changes the monitor eject_device() function to not check for bdrv_is_inserted(). Example run where the bug manifests itself: (output of 'info block' is stripped to include only the CD-ROM device) QEMU 0.11.50 monitor - type 'help' for more information (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 [not inserted] (qemu) change ide1-cd0 /mnt/common/images/smalldisk1.img (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 file=/mnt/common/images/smalldisk1.img ro=0 drv=raw encrypted=0 (qemu) eject ide1-cd0 (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 [not inserted] When using a file, eject works as expected. But when using a host cdrom device: (qemu) change ide1-cd0 /dev/cdrom (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=0 drv=host_cdrom encrypted=0 (qemu) eject ide1-cd0 (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=0 drv=host_cdrom encrypted=0 Eject didn't work because the is_inserted() check fails. I have no clue why the code had the is_inserted() check, as it doesn't matter if there is a disk present at the host drive, when the user wants the virtual device to be disconnected from the host device. The is_inserted() has another side effect: a memory leak if the "change" command is used multiple times, as do_change() calls eject_device() before re-opening the block device, but bdrv_close() is never called. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/monitor.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-) Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/monitor.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-) diff --git a/qemu/monitor.c b/qemu/monitor.c index ee33bfc..1ab6ac6 100644 --- a/qemu/monitor.c +++ b/qemu/monitor.c @@ -504,19 +504,17 @@ static void do_quit(void) static int eject_device(BlockDriverState *bs, int force) { - if (bdrv_is_inserted(bs)) { - if (!force) { - if (!bdrv_is_removable(bs)) { - term_printf("device is not removable\n"); - return -1; - } - if (bdrv_is_locked(bs)) { - term_printf("device is locked\n"); - return -1; - } + if (!force) { + if (!bdrv_is_removable(bs)) { + term_printf("device is not removable\n"); + return -1; + } + if (bdrv_is_locked(bs)) { + term_printf("device is locked\n"); + return -1; } - bdrv_close(bs); } + bdrv_close(bs); return 0; } -- 1.6.3.rc4.29.g8146