From d1010a912825c867580ebc15a4140e1f920cdf63 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 14 Dec 2011 15:12:35 +0100 Subject: [PATCH 1/2] block: add eject request callback RH-Author: Paolo Bonzini Message-id: <1323875557-18796-2-git-send-email-pbonzini@redhat.com> Patchwork-id: 35818 O-Subject: [RHEL 6.3 qemu-kvm PATCH 1/3] block: add eject request callback Bugzilla: 739944 RH-Acked-by: Kevin Wolf RH-Acked-by: Markus Armbruster RH-Acked-by: Amit Shah Bugzilla: 739944 Recent versions of udev always keep the tray locked so that the kernel can observe "eject request" events (aka tray button presses) even on discs that aren't mounted. Add support for generating these events when the user invokes the "eject" monitor command. Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf (cherry picked from upstream commit 025ccaa7f9d2f54a79567599d3eb402100bed7a4) --- block.c | 7 +++++++ block.h | 10 ++++++++++ blockdev.c | 10 ++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) Signed-off-by: Michal Novotny --- block.c | 7 +++++++ block.h | 10 ++++++++++ blockdev.c | 10 ++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/block.c b/block.c index 680dd8f..9899696 100644 --- a/block.c +++ b/block.c @@ -755,6 +755,13 @@ bool bdrv_dev_has_removable_media(BlockDriverState *bs) return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb); } +void bdrv_dev_eject_request(BlockDriverState *bs, bool force) +{ + if (bs->dev_ops && bs->dev_ops->eject_request_cb) { + bs->dev_ops->eject_request_cb(bs->dev_opaque, force); + } +} + bool bdrv_dev_is_tray_open(BlockDriverState *bs) { if (bs->dev_ops && bs->dev_ops->is_tray_open) { diff --git a/block.h b/block.h index 8ea13de..0883580 100644 --- a/block.h +++ b/block.h @@ -36,6 +36,15 @@ typedef struct BlockDevOps { */ void (*change_media_cb)(void *opaque, bool load); /* + * Runs when an eject request is issued from the monitor, the tray + * is closed, and the medium is locked. + * Device models that do not implement is_medium_locked will not need + * this callback. Device models that can lock the medium or tray might + * want to implement the callback and unlock the tray when "force" is + * true, even if they do not support eject requests. + */ + void (*eject_request_cb)(void *opaque, bool force); + /* * Is the virtual tray open? * Device models implement this only when the device has a tray. */ @@ -109,6 +118,7 @@ void bdrv_detach_dev(BlockDriverState *bs, void *dev); void *bdrv_get_attached_dev(BlockDriverState *bs); void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, void *opaque); +void bdrv_dev_eject_request(BlockDriverState *bs, bool force); bool bdrv_dev_has_removable_media(BlockDriverState *bs); bool bdrv_dev_is_tray_open(BlockDriverState *bs); bool bdrv_dev_is_medium_locked(BlockDriverState *bs); diff --git a/blockdev.c b/blockdev.c index 4ef24a7..d07bf67 100644 --- a/blockdev.c +++ b/blockdev.c @@ -915,10 +915,12 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force) qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs)); return -1; } - if (!force && !bdrv_dev_is_tray_open(bs) - && bdrv_dev_is_medium_locked(bs)) { - qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); - return -1; + if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) { + bdrv_dev_eject_request(bs, force); + if (!force) { + qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); + return -1; + } } bdrv_close(bs); return 0; -- 1.7.7.5