On 20.06.19 03:03, John Snow wrote: > We don't need or want a new sync mode for simple differences in > semantics. Create a new mode simply named "BITMAP" that is designed to > make use of the new Bitmap Sync Mode field. > > Because the only bitmap mode is 'conditional', this adds no new > functionality to the backup job (yet). The old incremental backup mode > is maintained as a syntactic sugar for sync=bitmap, mode=conditional. > > Add all of the plumbing necessary to support this new instruction. > > Signed-off-by: John Snow <js...@redhat.com> > --- > qapi/block-core.json | 30 ++++++++++++++++++++++-------- > include/block/block_int.h | 6 +++++- > block/backup.c | 35 ++++++++++++++++++++++++++++------- > block/mirror.c | 6 ++++-- > block/replication.c | 2 +- > blockdev.c | 8 ++++++-- > 6 files changed, 66 insertions(+), 21 deletions(-) > > diff --git a/qapi/block-core.json b/qapi/block-core.json > index caf28a71a0..6d05ad8f47 100644 > --- a/qapi/block-core.json > +++ b/qapi/block-core.json > @@ -1127,12 +1127,15 @@ > # > # @none: only copy data written from now on > # > -# @incremental: only copy data described by the dirty bitmap. Since: 2.4 > +# @incremental: only copy data described by the dirty bitmap. (since: 2.4)
Why not deprecate this in the process and note that this is equal to sync=bitmap, bitmap-mode=conditional? (I don’t think there is a rule that forces us to actually remove deprecated stuff after two releases if it doesn’t hurt to keep it.) > +# > +# @bitmap: only copy data described by the dirty bitmap. (since: 4.1) > +# Behavior on completion is determined by the BitmapSyncMode. > # > # Since: 1.3 > ## > { 'enum': 'MirrorSyncMode', > - 'data': ['top', 'full', 'none', 'incremental'] } > + 'data': ['top', 'full', 'none', 'incremental', 'bitmap'] } > > ## > # @BitmapSyncMode: > @@ -1352,10 +1355,14 @@ > # > # @speed: the maximum speed, in bytes per second > # > -# @bitmap: the name of dirty bitmap if sync is "incremental". > -# Must be present if sync is "incremental", must NOT be present > +# @bitmap: the name of dirty bitmap if sync is "bitmap". > +# Must be present if sync is "bitmap", must NOT be present > # otherwise. (Since 2.4) Er, well, now this is too fast of a deprecation. :-) It must still also be present if sync is “incremental”. > # > +# @bitmap-mode: Specifies the type of data the bitmap should contain after > +# the operation concludes. Must be present if sync is "bitmap". > +# Must NOT be present otherwise. (Since 4.1) Do we have any rule that qemu must enforce “must not”s? :-) (No, I don’t think so. I think it’s very reasonable that you accept bitmap-mode=conditional for sync=incremental.) > # @compress: true to compress data, if the target format supports it. > # (default: false) (since 2.8) > # > @@ -1390,7 +1397,8 @@ > 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', > '*format': 'str', 'sync': 'MirrorSyncMode', > '*mode': 'NewImageMode', '*speed': 'int', > - '*bitmap': 'str', '*compress': 'bool', > + '*bitmap': 'str', '*bitmap-mode': 'BitmapSyncMode', > + '*compress': 'bool', > '*on-source-error': 'BlockdevOnError', > '*on-target-error': 'BlockdevOnError', > '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } > @@ -1412,10 +1420,14 @@ > # @speed: the maximum speed, in bytes per second. The default is 0, > # for unlimited. > # > -# @bitmap: the name of dirty bitmap if sync is "incremental". > -# Must be present if sync is "incremental", must NOT be present > +# @bitmap: the name of dirty bitmap if sync is "bitmap". > +# Must be present if sync is "bitmap", must NOT be present > # otherwise. (Since 3.1) Same as above. > +# @bitmap-mode: Specifies the type of data the bitmap should contain after > +# the operation concludes. Must be present if sync is "bitmap". > +# Must NOT be present otherwise. (Since 4.1) > +# > # @compress: true to compress data, if the target format supports it. > # (default: false) (since 2.8) > # > @@ -1449,7 +1461,9 @@ > { 'struct': 'BlockdevBackup', > 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', > 'sync': 'MirrorSyncMode', '*speed': 'int', > - '*bitmap': 'str', '*compress': 'bool', > + '*bitmap': 'str', > + '*bitmap-mode': 'BitmapSyncMode', > + '*compress': 'bool', > '*on-source-error': 'BlockdevOnError', > '*on-target-error': 'BlockdevOnError', > '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } > diff --git a/include/block/block_int.h b/include/block/block_int.h > index d6415b53c1..89370c1b9b 100644 > --- a/include/block/block_int.h > +++ b/include/block/block_int.h > @@ -1132,7 +1132,9 @@ void mirror_start(const char *job_id, BlockDriverState > *bs, > * @target: Block device to write to. > * @speed: The maximum speed, in bytes per second, or 0 for unlimited. > * @sync_mode: What parts of the disk image should be copied to the > destination. > - * @sync_bitmap: The dirty bitmap if sync_mode is > MIRROR_SYNC_MODE_INCREMENTAL. > + * @sync_bitmap: The dirty bitmap if sync_mode is 'bitmap' or 'incremental' > + * @has_bitmap_mode: true if @bitmap_sync carries a meaningful value. Hmm... If you moved the conversion of incremental/- => bitmap/conditional into blockdev.c, you could get rid of this parameter because it would be equal to (sync_bitmap != NULL). (It itches me to get rid of this parameter because there is no other has* parameter for this function yet.) > + * @bitmap_mode: The bitmap synchronization policy to use. > * @on_source_error: The action to take upon error reading from the source. > * @on_target_error: The action to take upon error writing to the target. > * @creation_flags: Flags that control the behavior of the Job lifetime. > @@ -1148,6 +1150,8 @@ BlockJob *backup_job_create(const char *job_id, > BlockDriverState *bs, > BlockDriverState *target, int64_t speed, > MirrorSyncMode sync_mode, > BdrvDirtyBitmap *sync_bitmap, > + bool has_bitmap_mode, > + BitmapSyncMode bitmap_mode, > bool compress, > BlockdevOnError on_source_error, > BlockdevOnError on_target_error, > diff --git a/block/backup.c b/block/backup.c > index 715e1d3be8..c4f83d4ef7 100644 > --- a/block/backup.c > +++ b/block/backup.c [...] > @@ -584,9 +586,28 @@ BlockJob *backup_job_create(const char *job_id, > BlockDriverState *bs, > } > > if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) { > + if (has_bitmap_mode && > + bitmap_mode != BITMAP_SYNC_MODE_CONDITIONAL) { > + error_setg(errp, "Bitmap sync mode must be 'conditional' " > + "when using sync mode '%s'", > + MirrorSyncMode_str(sync_mode)); > + return NULL; > + } > + has_bitmap_mode = true; > + bitmap_mode = BITMAP_SYNC_MODE_CONDITIONAL; > + effective_mode = MIRROR_SYNC_MODE_BITMAP; > + } > + I also just don’t quite feel like this is the correct place to put this. It’s a deprecated interface, so it should be translated in the interface code, i.e. in blockdev.c. (Sure, this gives you a central place for the translation, but you can just as well add a function to the same effect to blockdev.c.) Max
signature.asc
Description: OpenPGP digital signature