[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 2/2] scsi: add block job opblockers for scsi-block
From: |
Paolo Bonzini |
Subject: |
[Qemu-block] [PATCH 2/2] scsi: add block job opblockers for scsi-block |
Date: |
Wed, 7 Feb 2018 17:36:22 +0100 |
scsi-block bypasses the dirty bitmaps and pre-write notifiers, so it
cannot be the source of a block job. The gist of the fix is to add
op-blockers to the BlockBackend, and remove them at "unrealize" time,
but things are a little more complex because quit closes the BlockBackend
without going through unrealize.
So use Notifiers: the remove_bs notifier is called by bdrv_close_all, and
the insert_bs notifier might not be really necessary but make things a
little more symmetric.
Suggested-by: Karen Noel <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
block/block-backend.c | 9 ++++++
hw/scsi/scsi-disk.c | 62 ++++++++++++++++++++++++++++++++++++++++++
include/sysemu/block-backend.h | 1 +
3 files changed, 72 insertions(+)
diff --git a/block/block-backend.c b/block/block-backend.c
index baef8e7abc..1759639a4a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1747,6 +1747,15 @@ bool blk_op_is_blocked(BlockBackend *blk, BlockOpType
op, Error **errp)
return bdrv_op_is_blocked(bs, op, errp);
}
+void blk_op_block(BlockBackend *blk, BlockOpType op, Error *reason)
+{
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_op_block(bs, op, reason);
+ }
+}
+
void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
{
BlockDriverState *bs = blk_bs(blk);
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 49d2559d93..023673cb04 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2578,9 +2578,39 @@ static int get_device_type(SCSIDiskState *s)
return 0;
}
+typedef struct SCSIBlockState {
+ SCSIDiskState sd;
+ Error *mirror_source;
+ Error *backup_source;
+ Error *commit_source;
+ Notifier insert_bs;
+ Notifier remove_bs;
+} SCSIBlockState;
+
+static void scsi_block_insert_bs(Notifier *n, void *opaque)
+{
+ SCSIBlockState *sb = container_of(n, SCSIBlockState, insert_bs);
+ SCSIDiskState *s = &sb->sd;
+
+ blk_op_block(s->qdev.conf.blk, BLOCK_OP_TYPE_MIRROR_SOURCE,
sb->mirror_source);
+ blk_op_block(s->qdev.conf.blk, BLOCK_OP_TYPE_COMMIT_SOURCE,
sb->commit_source);
+ blk_op_block(s->qdev.conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE,
sb->backup_source);
+}
+
+static void scsi_block_remove_bs(Notifier *n, void *opaque)
+{
+ SCSIBlockState *sb = container_of(n, SCSIBlockState, remove_bs);
+ SCSIDiskState *s = &sb->sd;
+
+ blk_op_unblock(s->qdev.conf.blk, BLOCK_OP_TYPE_MIRROR_SOURCE,
sb->mirror_source);
+ blk_op_unblock(s->qdev.conf.blk, BLOCK_OP_TYPE_COMMIT_SOURCE,
sb->commit_source);
+ blk_op_unblock(s->qdev.conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE,
sb->backup_source);
+}
+
static void scsi_block_realize(SCSIDevice *dev, Error **errp)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+ SCSIBlockState *sb = DO_UPCAST(SCSIBlockState, sd, s);
int sg_version;
int rc;
@@ -2626,6 +2656,36 @@ static void scsi_block_realize(SCSIDevice *dev, Error
**errp)
scsi_realize(&s->qdev, errp);
scsi_generic_read_device_identification(&s->qdev);
+
+ /* For op blockers, due to lack of support for dirty bitmaps. */
+ error_setg(&sb->mirror_source,
+ "scsi-block does not support acting as a mirroring source");
+ error_setg(&sb->commit_source,
+ "scsi-block does not support acting as an active commit
source");
+
+ /* For op blockers, due to lack of support for write notifiers. */
+ error_setg(&sb->backup_source,
+ "scsi-block does not support acting as a backup source");
+
+ sb->insert_bs.notify = scsi_block_insert_bs;
+ blk_add_insert_bs_notifier(s->qdev.conf.blk, &sb->insert_bs);
+ sb->remove_bs.notify = scsi_block_remove_bs;
+ blk_add_remove_bs_notifier(s->qdev.conf.blk, &sb->remove_bs);
+
+ scsi_block_insert_bs(&sb->insert_bs, s->qdev.conf.blk);
+}
+
+static void scsi_block_unrealize(SCSIDevice *dev, Error **errp)
+{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+ SCSIBlockState *sb = DO_UPCAST(SCSIBlockState, sd, s);
+
+ notifier_remove(&sb->insert_bs);
+ notifier_remove(&sb->remove_bs);
+ scsi_block_remove_bs(&sb->insert_bs, s->qdev.conf.blk);
+ error_free(sb->mirror_source);
+ error_free(sb->commit_source);
+ error_free(sb->backup_source);
}
typedef struct SCSIBlockReq {
@@ -3017,6 +3077,7 @@ static void scsi_block_class_initfn(ObjectClass *klass,
void *data)
SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass);
sc->realize = scsi_block_realize;
+ sc->unrealize = scsi_block_unrealize;
sc->alloc_req = scsi_block_new_request;
sc->parse_cdb = scsi_block_parse_cdb;
sdc->dma_readv = scsi_block_dma_readv;
@@ -3031,6 +3092,7 @@ static const TypeInfo scsi_block_info = {
.name = "scsi-block",
.parent = TYPE_SCSI_DISK_BASE,
.class_init = scsi_block_class_initfn,
+ .instance_size = sizeof(SCSIBlockState),
};
#endif
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index c4e52a5fa3..a48a49ca79 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -182,6 +182,7 @@ void blk_set_guest_block_size(BlockBackend *blk, int align);
void *blk_try_blockalign(BlockBackend *blk, size_t size);
void *blk_blockalign(BlockBackend *blk, size_t size);
bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
+void blk_op_block(BlockBackend *blk, BlockOpType op, Error *reason);
void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
void blk_op_block_all(BlockBackend *blk, Error *reason);
void blk_op_unblock_all(BlockBackend *blk, Error *reason);
--
2.14.3
- [Qemu-block] [PATCH 0/2] scsi: add block job opblockers for scsi-block, Paolo Bonzini, 2018/02/07
- [Qemu-block] [PATCH 1/2] scsi: add unrealize method for SCSI devices, Paolo Bonzini, 2018/02/07
- [Qemu-block] [PATCH 2/2] scsi: add block job opblockers for scsi-block,
Paolo Bonzini <=
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Fam Zheng, 2018/02/07
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Paolo Bonzini, 2018/02/08
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Kevin Wolf, 2018/02/12
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Paolo Bonzini, 2018/02/12
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Kevin Wolf, 2018/02/12
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Paolo Bonzini, 2018/02/12
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Kevin Wolf, 2018/02/12
- Re: [Qemu-block] [Qemu-devel] [PATCH 2/2] scsi: add block job opblockers for scsi-block, Paolo Bonzini, 2018/02/12