On 08/02/2018 02:35, Fam Zheng wrote:
> On Wed, 02/07 17:36, Paolo Bonzini wrote:
>> @@ -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");
> 
> An alternative way would be adding BLOCK_OP_TYPE_DIRTY_BITMAP. The error 
> message
> will not be as nice but it can be useful for another (blockjob) operation that
> requires dirty bitmap support, or another device that doesn't support dirty
> bitmaps. Though there isn't one for now.

Yeah, I thought about it.  Another possibility is make BLOCK_OP_TYPE_* a
bitmask.  Then you can easily add a single Error * for multiple
blockers, and BLOCK_OP_TYPE_DIRTY_BITMAP can be defined as
BLOCK_OP_TYPE_MIRROR_SOURCE|BLOCK_OP_TYPE_COMMIT_SOURCE; likewise for
notifiers below.

Paolo

>> +
>> +    /* 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
>>
>>
> 
> Fam
> 


Reply via email to