Requires new BlockDevOps member is_medium_locked(). Implement for IDE and SCSI CD-ROMs.
Signed-off-by: Markus Armbruster <arm...@redhat.com> --- block.c | 16 +++++++++------- block.h | 7 ++++++- block_int.h | 1 - blockdev.c | 2 +- hw/ide/core.c | 6 ++++++ hw/scsi-disk.c | 6 ++++++ 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 70928af..af9bbb2 100644 --- a/block.c +++ b/block.c @@ -776,6 +776,14 @@ static void bdrv_dev_resize_cb(BlockDriverState *bs) } } +int bdrv_dev_is_medium_locked(BlockDriverState *bs) +{ + if (bs->dev_ops && bs->dev_ops->is_medium_locked) { + return bs->dev_ops->is_medium_locked(bs->dev_opaque); + } + return 0; +} + /* * Run consistency checks on an image * @@ -1762,7 +1770,7 @@ void bdrv_info(Monitor *mon, QObject **ret_data) bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', " "'removable': %i, 'locked': %i }", bs->device_name, bs->removable, - bs->locked); + bdrv_dev_is_medium_locked(bs)); bs_dict = qobject_to_qdict(bs_obj); if (bdrv_dev_is_medium_ejected(bs)) { @@ -2787,11 +2795,6 @@ void bdrv_eject(BlockDriverState *bs, int eject_flag) } } -int bdrv_is_locked(BlockDriverState *bs) -{ - return bs->locked; -} - /** * Lock or unlock the media (if it is locked, the user won't be able * to eject it manually). @@ -2802,7 +2805,6 @@ void bdrv_set_locked(BlockDriverState *bs, int locked) trace_bdrv_set_locked(bs, locked); - bs->locked = locked; if (drv && drv->bdrv_set_locked) { drv->bdrv_set_locked(bs, locked); } diff --git a/block.h b/block.h index 7cc7919..f2f8dad 100644 --- a/block.h +++ b/block.h @@ -41,6 +41,11 @@ typedef struct BlockDevOps { */ bool (*is_medium_ejected)(void *opaque); /* + * Is the virtual medium locked into the device? + * Null means device doesn't have such a lock. + */ + bool (*is_medium_locked)(void *opaque); + /* * Runs when the size changed (e.g. monitor command block_resize) */ void (*resize_cb)(void *opaque); @@ -98,6 +103,7 @@ void *bdrv_get_attached_dev(BlockDriverState *bs); void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, void *opaque); bool bdrv_dev_is_medium_ejected(BlockDriverState *bs); +int bdrv_dev_is_medium_locked(BlockDriverState *bs); int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); int bdrv_write(BlockDriverState *bs, int64_t sector_num, @@ -207,7 +213,6 @@ int bdrv_is_sg(BlockDriverState *bs); int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); -int bdrv_is_locked(BlockDriverState *bs); void bdrv_set_locked(BlockDriverState *bs, int locked); void bdrv_eject(BlockDriverState *bs, int eject_flag); void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size); diff --git a/block_int.h b/block_int.h index b142dee..a049f1a 100644 --- a/block_int.h +++ b/block_int.h @@ -147,7 +147,6 @@ struct BlockDriverState { int keep_read_only; /* if true, the media was requested to stay read only */ int open_flags; /* flags used to open the file, re-used for re-open */ int removable; /* if true, the media can be removed */ - int locked; /* if true, the media cannot temporarily be ejected */ int encrypted; /* if true, the media is encrypted */ int valid_key; /* if true, a valid encryption key has been set */ int sg; /* if true, the device is a /dev/sg* */ diff --git a/blockdev.c b/blockdev.c index 13a9b41..4c58128 100644 --- a/blockdev.c +++ b/blockdev.c @@ -649,7 +649,7 @@ 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_is_locked(bs)) { + if (!force && bdrv_dev_is_medium_locked(bs)) { qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); return -1; } diff --git a/hw/ide/core.c b/hw/ide/core.c index b07a4d7..35beb93 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -1774,9 +1774,15 @@ static bool ide_cd_medium_ejected(void *opaque) return ((IDEState *)opaque)->tray_open; } +static bool ide_cd_is_medium_locked(void *opaque) +{ + return ((IDEState *)opaque)->tray_locked; +} + static const BlockDevOps ide_cd_block_ops = { .change_media_cb = ide_cd_change_cb, .is_medium_ejected = ide_cd_medium_ejected, + .is_medium_locked = ide_cd_is_medium_locked, }; int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index a4ed499..f804739 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1271,8 +1271,14 @@ static bool scsi_cd_is_medium_ejected(void *opaque) return ((SCSIDiskState *)opaque)->tray_open; } +static bool scsi_cd_is_medium_locked(void *opaque) +{ + return ((SCSIDiskState *)opaque)->tray_locked; +} + static const BlockDevOps scsi_cd_block_ops = { .is_medium_ejected = scsi_cd_is_medium_ejected, + .is_medium_locked = scsi_cd_is_medium_locked, }; static int scsi_initfn(SCSIDevice *dev, SCSIDriveKind kind) -- 1.7.2.3