On Sat, May 03, 2025 at 07:57:24AM +0800, Sunny Zhu wrote: > On Fri, May 09, 2025 at 03:40:25PM -0500, Eric Blake wrote: > > QEMU has an optimization for a just-created drive-mirror destination > > that is not possible for blockdev-mirror (which can't create the > > destination) - any time we know the destination starts life as all > > zeroes, we can skip a pre-zeroing pass on the destination. Recent > > patches have added an improved heuristic for detecting if a file > > contains all zeroes, and we plan to use that heuristic in upcoming > > patches. But since a heuristic cannot quickly detect all scenarios, > > and there may be cases where the caller is aware of information that > > QEMU cannot learn quickly, it makes sense to have a way to tell QEMU > > to assume facts about the destination that can make the mirror > > operation faster. Given our existing example of "qemu-img convert > > --target-is-zero", it is time to expose this override in QMP for > > blockdev-mirror as well. > >
> > +++ b/qapi/block-core.json > > @@ -2538,6 +2538,11 @@ > > # disappear from the query list without user intervention. > > # Defaults to true. (Since 3.1) > > # > > +# @target-is-zero: Assume the destination reads as all zeroes before > > +# the mirror started. Setting this to true can speed up the > > +# mirror. Setting this to true when the destination is not > > +# actually all zero can corrupt the destination. (Since 10.1) > > It appears feasible to add target-is-zero to the drive-mirror qmp as well, > provided this is done under the NEW_IMAGE_MODE_EXISTING scenario. This would > allow users to pass target-is-zero for optimizations whether using > blockdev-mirror > or drive-mirror when they have pre-prepared destination image. I didn't want to touch drive-mirror, since it is an older command that has some awkward semantics that were improved on when we added blockdev-mirror (that's why libvirt only uses blockdev-mirror). If we still think it is worth bolting features onto the old command, instead of encouraging users to migrate to the new one, then that should be a separate patch. > > @@ -3044,6 +3044,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) > > zero_target = (arg->sync == MIRROR_SYNC_MODE_FULL && > > (arg->mode == NEW_IMAGE_MODE_EXISTING || > > !bdrv_has_zero_init(target_bs))); > > + target_is_zero = (arg->mode != NEW_IMAGE_MODE_EXISTING && > > + bdrv_has_zero_init(target_bs)); > > Similarly, if the qmp_drive_mirror supports the target-is-zero parameter, we > would then > be able to determine whether the destination image is fully zero-initialized > when > arg->mode is NEW_IMAGE_MODE_EXISTING. Determination of whether a pre-existing image is fully zero-initialized for drive-mirror comes for free later in the patch series (at the same time that blockdev-mirror is able to infer that information without an explicit target-is-zero parameter). -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org