[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v3 22/23] block: Lift device model API into Bloc
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v3 22/23] block: Lift device model API into BlockBackend |
Date: |
Mon, 22 Sep 2014 14:54:39 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Benoît Canet <address@hidden> writes:
> On Tue, Sep 16, 2014 at 08:12:27PM +0200, Markus Armbruster wrote:
>> Move device model attachment / detachment and the BlockDevOps device
>> model callbacks and their wrappers from BlockDriverState to
>> BlockBackend.
>>
>> Signed-off-by: Markus Armbruster <address@hidden>
>> ---
>> block.c | 126 ++++------------------------------
>> block/block-backend.c | 151
>> ++++++++++++++++++++++++++++++++++++++---
>> block/qapi.c | 8 +--
>> blockdev.c | 8 +--
>> include/block/block.h | 45 ------------
>> include/block/block_int.h | 12 ++--
>> include/sysemu/block-backend.h | 35 ++++++++++
>> 7 files changed, 203 insertions(+), 182 deletions(-)
>>
>> diff --git a/block.c b/block.c
>> index 1d9a680..fac1211 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -58,9 +58,6 @@ struct BdrvDirtyBitmap {
>>
>> #define NOT_DONE 0x7fffffff /* used while emulated sync operation in
>> progress */
>>
>> -#define COROUTINE_POOL_RESERVATION 64 /* number of coroutines to reserve */
>> -
>> -static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
>> static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
>> int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
>> BlockCompletionFunc *cb, void *opaque);
>> @@ -1527,7 +1524,9 @@ int bdrv_open(BlockDriverState **pbs, const char
>> *filename,
>> }
>>
>> if (!bdrv_key_required(bs)) {
>> - bdrv_dev_change_media_cb(bs, true);
>> + if (bs->blk) {
>> + blk_dev_change_media_cb(bs->blk, true);
>> + }
>> } else if (!runstate_check(RUN_STATE_PRELAUNCH)
>> && !runstate_check(RUN_STATE_INMIGRATE)
>> && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
>> @@ -1852,7 +1851,9 @@ void bdrv_close(BlockDriverState *bs)
>> }
>> }
>>
>> - bdrv_dev_change_media_cb(bs, false);
>> + if (bs->blk) {
>> + blk_dev_change_media_cb(bs->blk, false);
>> + }
>>
>> /*throttling disk I/O limits*/
>> if (bs->io_limits_enabled) {
>> @@ -1971,9 +1972,6 @@ static void bdrv_move_feature_fields(BlockDriverState
>> *bs_dest,
>> /* move some fields that need to stay attached to the device */
>>
>> /* dev info */
>> - bs_dest->dev_ops = bs_src->dev_ops;
>> - bs_dest->dev_opaque = bs_src->dev_opaque;
>> - bs_dest->dev = bs_src->dev;
>> bs_dest->guest_block_size = bs_src->guest_block_size;
>> bs_dest->copy_on_read = bs_src->copy_on_read;
>>
>> @@ -2041,7 +2039,6 @@ void bdrv_swap(BlockDriverState *bs_new,
>> BlockDriverState *bs_old)
>> assert(!bs_new->blk);
>> assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
>> assert(bs_new->job == NULL);
>> - assert(bs_new->dev == NULL);
>> assert(bs_new->io_limits_enabled == false);
>> assert(!throttle_have_timer(&bs_new->throttle_state));
>>
>> @@ -2058,7 +2055,6 @@ void bdrv_swap(BlockDriverState *bs_new,
>> BlockDriverState *bs_old)
>> assert(!bs_new->blk);
>>
>> /* Check a few fields that should remain attached to the device */
>> - assert(bs_new->dev == NULL);
>> assert(bs_new->job == NULL);
>> assert(bs_new->io_limits_enabled == false);
>> assert(!throttle_have_timer(&bs_new->throttle_state));
>> @@ -2097,7 +2093,6 @@ void bdrv_append(BlockDriverState *bs_new,
>> BlockDriverState *bs_top)
>>
>> static void bdrv_delete(BlockDriverState *bs)
>> {
>> - assert(!bs->dev);
>> assert(!bs->job);
>> assert(bdrv_op_blocker_is_empty(bs));
>> assert(!bs->refcnt);
>> @@ -2111,105 +2106,6 @@ static void bdrv_delete(BlockDriverState *bs)
>> g_free(bs);
>> }
>>
>> -int bdrv_attach_dev(BlockDriverState *bs, void *dev)
>> -/* TODO change to DeviceState *dev when all users are qdevified */
>> -{
>> - if (bs->dev) {
>> - return -EBUSY;
>> - }
>> - bs->dev = dev;
>> - bdrv_iostatus_reset(bs);
>> -
>> - /* We're expecting I/O from the device so bump up coroutine pool size */
>> - qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
>> - return 0;
>> -}
>> -
>> -/* TODO qdevified devices don't use this, remove when devices are qdevified
>> */
>> -void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
>> -{
>> - if (bdrv_attach_dev(bs, dev) < 0) {
>> - abort();
>> - }
>> -}
>> -
>> -void bdrv_detach_dev(BlockDriverState *bs, void *dev)
>> -/* TODO change to DeviceState *dev when all users are qdevified */
>> -{
>> - assert(bs->dev == dev);
>> - bs->dev = NULL;
>> - bs->dev_ops = NULL;
>> - bs->dev_opaque = NULL;
>> - bs->guest_block_size = 512;
>> - qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
>> -}
>> -
>> -/* TODO change to return DeviceState * when all users are qdevified */
>> -void *bdrv_get_attached_dev(BlockDriverState *bs)
>> -{
>> - return bs->dev;
>> -}
>> -
>> -void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
>> - void *opaque)
>> -{
>> - bs->dev_ops = ops;
>> - bs->dev_opaque = opaque;
>> -}
>> -
>> -static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
>> -{
>> - if (bs->dev_ops && bs->dev_ops->change_media_cb) {
>> - bool tray_was_closed = !bdrv_dev_is_tray_open(bs);
>> - bs->dev_ops->change_media_cb(bs->dev_opaque, load);
>> - if (tray_was_closed) {
>> - /* tray open */
>> - qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
>> - true, &error_abort);
>> - }
>> - if (load) {
>> - /* tray close */
>> - qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
>> - false, &error_abort);
>> - }
>> - }
>> -}
>> -
>> -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) {
>> - return bs->dev_ops->is_tray_open(bs->dev_opaque);
>> - }
>> - return false;
>> -}
>> -
>> -static void bdrv_dev_resize_cb(BlockDriverState *bs)
>> -{
>> - if (bs->dev_ops && bs->dev_ops->resize_cb) {
>> - bs->dev_ops->resize_cb(bs->dev_opaque);
>> - }
>> -}
>> -
>> -bool 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 false;
>> -}
>> -
>> /*
>> * Run consistency checks on an image
>> *
>> @@ -3543,7 +3439,9 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
>> ret = drv->bdrv_truncate(bs, offset);
>> if (ret == 0) {
>> ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
>> - bdrv_dev_resize_cb(bs);
>> + if (bs->blk) {
>> + blk_dev_resize_cb(bs->blk);
>> + }
>> }
>> return ret;
>> }
>> @@ -3744,8 +3642,10 @@ int bdrv_set_key(BlockDriverState *bs, const char
>> *key)
>> bs->valid_key = 0;
>> } else if (!bs->valid_key) {
>> bs->valid_key = 1;
>> - /* call the change callback now, we skipped it on open */
>> - bdrv_dev_change_media_cb(bs, true);
>> + if (bs->blk) {
>> + /* call the change callback now, we skipped it on open */
>> + blk_dev_change_media_cb(bs->blk, true);
>> + }
>> }
>> return ret;
>> }
>> diff --git a/block/block-backend.c b/block/block-backend.c
>> index b55f0b4..d49c988 100644
>> --- a/block/block-backend.c
>> +++ b/block/block-backend.c
>> @@ -13,6 +13,10 @@
>> #include "sysemu/block-backend.h"
>> #include "block/block_int.h"
>> #include "sysemu/blockdev.h"
>> +#include "qapi-event.h"
>> +
>> +/* Number of coroutines to reserve per attached device model */
>> +#define COROUTINE_POOL_RESERVATION 64
>>
>> struct BlockBackend {
>> char *name;
>> @@ -20,6 +24,11 @@ struct BlockBackend {
>> BlockDriverState *bs;
>> DriveInfo *legacy_dinfo;
>> QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
>> +
>> + void *dev; /* attached device model, if any */
>> + /* TODO change to DeviceState when all users are qdevified */
>> + const BlockDevOps *dev_ops;
>> + void *dev_opaque;
>> };
>>
>> static void drive_info_del(DriveInfo *dinfo);
>> @@ -81,6 +90,7 @@ BlockBackend *blk_new_with_bs(const char *name, Error
>> **errp)
>> static void blk_delete(BlockBackend *blk)
>> {
>> assert(!blk->refcnt);
>> + assert(!blk->dev);
>> if (blk->bs) {
>> assert(blk->bs->blk == blk);
>> blk->bs->blk = NULL;
>> @@ -233,34 +243,153 @@ void blk_hide_on_behalf_of_do_drive_del(BlockBackend
>> *blk)
>> }
>> }
>>
>> -void blk_iostatus_enable(BlockBackend *blk)
>> -{
>> - bdrv_iostatus_enable(blk->bs);
>> -}
>> -
>> +/*
>> + * Attach device model @dev to @blk.
>> + * Return 0 on success, -EBUSY when a device model is attached already.
>> + */
>> int blk_attach_dev(BlockBackend *blk, void *dev)
>> +/* TODO change to DeviceState *dev when all users are qdevified */
>> {
>> - return bdrv_attach_dev(blk->bs, dev);
>> + if (blk->dev) {
>> + return -EBUSY;
>> + }
>> + blk->dev = dev;
>> + bdrv_iostatus_reset(blk->bs);
>> +
>> + /* We're expecting I/O from the device so bump up coroutine pool size */
>> + qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
>> + return 0;
>> }
>>
>> +/*
>> + * Attach device model @dev to @blk.
>> + * @blk must not have a device model attached already.
>> + * TODO qdevified devices don't use this, remove when devices are qdevified
>> + */
>> void blk_attach_dev_nofail(BlockBackend *blk, void *dev)
>> {
>> - bdrv_attach_dev_nofail(blk->bs, dev);
>> + if (blk_attach_dev(blk, dev) < 0) {
>> + abort();
>> + }
>> }
>>
>> +/*
>> + * Detach device model @dev from @blk.
>> + * @dev must be currently attached to @blk.
>> + */
>> void blk_detach_dev(BlockBackend *blk, void *dev)
>> +/* TODO change to DeviceState *dev when all users are qdevified */
>> {
>> - bdrv_detach_dev(blk->bs, dev);
>> + assert(blk->dev == dev);
>> + blk->dev = NULL;
>> + blk->dev_ops = NULL;
>> + blk->dev_opaque = NULL;
>> + bdrv_set_guest_block_size(blk->bs, 512);
>> + qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
>> }
>>
>> +/*
>> + * Return the device model attached to @blk if any, else null.
>> + */
>> void *blk_get_attached_dev(BlockBackend *blk)
>> +/* TODO change to return DeviceState * when all users are qdevified */
>> {
>> - return bdrv_get_attached_dev(blk->bs);
>> + return blk->dev;
>> }
>>
>> -void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void
>> *opaque)
>> +/*
>> + * Set @blk's device model callbacks to @ops.
>> + * @opaque is the opaque argument to pass to the callbacks.
>> + * This is for use by device models.
>> + */
>> +void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
>> + void *opaque)
>> {
>> - bdrv_set_dev_ops(blk->bs, ops, opaque);
>> + blk->dev_ops = ops;
>> + blk->dev_opaque = opaque;
>> +}
>> +
>> +/*
>> + * Notify @blk's attached device model of media change.
>> + * If @load is true, notify of media load.
>> + * Else, notify of media eject.
>> + * Also send DEVICE_TRAY_MOVED events as appropriate.
>> + */
>> +void blk_dev_change_media_cb(BlockBackend *blk, bool load)
>> +{
>> + if (blk->dev_ops && blk->dev_ops->change_media_cb) {
>> + bool tray_was_closed = !blk_dev_is_tray_open(blk);
>> +
>> + blk->dev_ops->change_media_cb(blk->dev_opaque, load);
>> + if (tray_was_closed) {
>> + /* tray open */
>> + qapi_event_send_device_tray_moved(blk_name(blk),
>> + true, &error_abort);
>> + }
>> + if (load) {
>> + /* tray close */
>> + qapi_event_send_device_tray_moved(blk_name(blk),
>> + false, &error_abort);
>> + }
>> + }
>> +}
>> +
>> +/*
>> + * Does @blk's attached device model have removable media?
>> + * %true if no device model is attached.
>> + */
>> +bool blk_dev_has_removable_media(BlockBackend *blk)
>> +{
>> + return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
>> +}
>> +
>> +/*
>> + * Notify @blk's attached device model of a media eject request.
>> + * If @force is true, the medium is about to be yanked out forcefully.
>> + */
>> +void blk_dev_eject_request(BlockBackend *blk, bool force)
>> +{
>> + if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
>> + blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
>> + }
>> +}
>> +
>> +/*
>> + * Does @blk's attached device model have a tray, and is it open?
>> + */
>> +bool blk_dev_is_tray_open(BlockBackend *blk)
>> +{
>> + if (blk->dev_ops && blk->dev_ops->is_tray_open) {
>> + return blk->dev_ops->is_tray_open(blk->dev_opaque);
>> + }
>> + return false;
>> +}
>> +
>> +/*
>> + * Does @blk's attached device model have the medium locked?
>> + * %false if the device model has no such lock.
>> + */
>> +bool blk_dev_is_medium_locked(BlockBackend *blk)
>> +{
>> + if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
>> + return blk->dev_ops->is_medium_locked(blk->dev_opaque);
>> + }
>> + return false;
>> +}
>> +
>> +/*
>> + * Notify @blk's attached device model of a backend size change.
>> + */
>> +void blk_dev_resize_cb(BlockBackend *blk)
>> +{
>> + if (blk->dev_ops && blk->dev_ops->resize_cb) {
>> + blk->dev_ops->resize_cb(blk->dev_opaque);
>> + }
>> +}
>> +
>> +void blk_iostatus_enable(BlockBackend *blk)
>> +{
>> + bdrv_iostatus_enable(blk->bs);
>> }
>>
>> int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
>> diff --git a/block/qapi.c b/block/qapi.c
>> index fca981d..1301144 100644
>> --- a/block/qapi.c
>> +++ b/block/qapi.c
>> @@ -275,12 +275,12 @@ static void bdrv_query_info(BlockBackend *blk,
>> BlockInfo **p_info,
>> Error *local_err = NULL;
>> info->device = g_strdup(blk_name(blk));
>> info->type = g_strdup("unknown");
>> - info->locked = bdrv_dev_is_medium_locked(bs);
>> - info->removable = bdrv_dev_has_removable_media(bs);
>> + info->locked = blk_dev_is_medium_locked(blk);
>> + info->removable = blk_dev_has_removable_media(blk);
>>
>> - if (bdrv_dev_has_removable_media(bs)) {
>> + if (blk_dev_has_removable_media(blk)) {
>> info->has_tray_open = true;
>> - info->tray_open = bdrv_dev_is_tray_open(bs);
>> + info->tray_open = blk_dev_is_tray_open(blk);
>> }
>>
>> if (bdrv_iostatus_is_enabled(bs)) {
>> diff --git a/blockdev.c b/blockdev.c
>> index e115bde..d3dccb9 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -1509,14 +1509,14 @@ static void eject_device(BlockBackend *blk, int
>> force, Error **errp)
>> if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
>> return;
>> }
>> - if (!bdrv_dev_has_removable_media(bs)) {
>> + if (!blk_dev_has_removable_media(blk)) {
>> error_setg(errp, "Device '%s' is not removable",
>> bdrv_get_device_name(bs));
>> return;
>> }
>>
>> - if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) {
>> - bdrv_dev_eject_request(bs, force);
>> + if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) {
>> + blk_dev_eject_request(blk, force);
>> if (!force) {
>> error_setg(errp, "Device '%s' is locked",
>> bdrv_get_device_name(bs));
>> @@ -1753,7 +1753,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict,
>> QObject **ret_data)
>> * can be removed. If this is a drive with no device backing
>> * then we can just get rid of the block driver state right here.
>> */
>> - if (bdrv_get_attached_dev(bs)) {
>> + if (blk_get_attached_dev(blk)) {
>> blk_hide_on_behalf_of_do_drive_del(blk);
>> /* Further I/O must not pause the guest */
>> bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
>> diff --git a/include/block/block.h b/include/block/block.h
>> index 5b45743..bc9ec50 100644
>> --- a/include/block/block.h
>> +++ b/include/block/block.h
>> @@ -48,41 +48,6 @@ typedef struct BlockFragInfo {
>> uint64_t compressed_clusters;
>> } BlockFragInfo;
>>
>> -/* Callbacks for block device models */
>> -typedef struct BlockDevOps {
>> - /*
>> - * Runs when virtual media changed (monitor commands eject, change)
>> - * Argument load is true on load and false on eject.
>> - * Beware: doesn't run when a host device's physical media
>> - * changes. Sure would be useful if it did.
>> - * Device models with removable media must implement this callback.
>> - */
>> - 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.
>> - */
>> - bool (*is_tray_open)(void *opaque);
>> - /*
>> - * Is the virtual medium locked into the device?
>> - * Device models implement this only when device has 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);
>> -} BlockDevOps;
>> -
>> typedef enum {
>> BDRV_REQ_COPY_ON_READ = 0x1,
>> BDRV_REQ_ZERO_WRITE = 0x2,
>> @@ -230,16 +195,6 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state);
>> void bdrv_reopen_abort(BDRVReopenState *reopen_state);
>> void bdrv_close(BlockDriverState *bs);
>> void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify);
>> -int bdrv_attach_dev(BlockDriverState *bs, void *dev);
>> -void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev);
>> -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);
>> int bdrv_read(BlockDriverState *bs, int64_t sector_num,
>> uint8_t *buf, int nb_sectors);
>> int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
>> diff --git a/include/block/block_int.h b/include/block/block_int.h
>> index e8e33a8..8898c6c 100644
>> --- a/include/block/block_int.h
>> +++ b/include/block/block_int.h
>> @@ -326,11 +326,6 @@ struct BlockDriverState {
>>
>> BlockBackend *blk; /* owning backend, if any */
>>
>> - void *dev; /* attached device model, if any */
>> - /* TODO change to DeviceState when all users are qdevified */
>> - const BlockDevOps *dev_ops;
>> - void *dev_opaque;
>> -
>> AioContext *aio_context; /* event loop used for fd handlers, timers,
>> etc */
>> /* long-running tasks intended to always use the same AioContext as this
>> * BDS may register themselves in this list to be notified of changes
>> @@ -587,4 +582,11 @@ void backup_start(BlockDriverState *bs,
>> BlockDriverState *target,
>> BlockCompletionFunc *cb, void *opaque,
>> Error **errp);
>>
>> +void blk_dev_change_media_cb(BlockBackend *blk, bool load);
>> +bool blk_dev_has_removable_media(BlockBackend *blk);
>> +void blk_dev_eject_request(BlockBackend *blk, bool force);
>> +bool blk_dev_is_tray_open(BlockBackend *blk);
>> +bool blk_dev_is_medium_locked(BlockBackend *blk);
>> +void blk_dev_resize_cb(BlockBackend *blk);
>> +
>> #endif /* BLOCK_INT_H */
>> diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
>> index e4bfea5..02305a1 100644
>> --- a/include/sysemu/block-backend.h
>> +++ b/include/sysemu/block-backend.h
>> @@ -25,6 +25,41 @@
>> */
>> #include "block/block.h"
>>
>> +/* Callbacks for block device models */
>> +typedef struct BlockDevOps {
>> + /*
>> + * Runs when virtual media changed (monitor commands eject, change)
>> + * Argument load is true on load and false on eject.
>> + * Beware: doesn't run when a host device's physical media
>> + * changes. Sure would be useful if it did.
>> + * Device models with removable media must implement this callback.
>> + */
>> + 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.
>> + */
>> + bool (*is_tray_open)(void *opaque);
>> + /*
>> + * Is the virtual medium locked into the device?
>> + * Device models implement this only when device has 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);
>> +} BlockDevOps;
>> +
>> BlockBackend *blk_new(const char *name, Error **errp);
>> BlockBackend *blk_new_with_bs(const char *name, Error **errp);
>> void blk_ref(BlockBackend *blk);
>> --
>> 1.9.3
>>
>
> This one is difficult to review.
> Could it be splitted in multiple baby steps ?
Not sure, but I'll think about it.
I certainly can try harder in the commit message.
- Re: [Qemu-devel] [PATCH v3 16/23] pc87312: Drop unused members of PC87312State, (continued)