Reuse the approach and helper from the last patch. --- tools/virsh-domain.c | 31 +++++++++++++++++++------------ tools/virsh.pod | 8 +++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index cd616a8..4053c75 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2245,6 +2245,10 @@ static const vshCmdOptDef opts_block_copy[] = { .type = VSH_OT_INT, .help = N_("maximum amount of in-flight data during the copy") }, + {.name = "bytes", + .type = VSH_OT_BOOL, + .help = N_("the bandwidth limit is in bytes/s rather than MiB/s") + }, {.name = NULL} }; @@ -2265,6 +2269,7 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) bool blockdev = vshCommandOptBool(cmd, "blockdev"); bool blocking = vshCommandOptBool(cmd, "wait") || finish || pivot; bool async = vshCommandOptBool(cmd, "async"); + bool bytes = vshCommandOptBool(cmd, "bytes"); int timeout = 0; const char *path = NULL; int abort_flags = 0; @@ -2282,11 +2287,7 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) return false; if (vshCommandOptStringReq(ctl, cmd, "format", &format) < 0) return false; - /* XXX: Parse bandwidth as scaled input, rather than forcing - * MiB/s, and either reject negative input or treat it as 0 rather - * than trying to guess which value will work well across both - * APIs with their different sizes and scales. */ - if (vshCommandOptULWrap(ctl, cmd, "bandwidth", &bandwidth) < 0) + if (vshBlockJobOptionBandwidth(ctl, cmd, bytes, &bandwidth) < 0) return false; if (vshCommandOptUInt(ctl, cmd, "granularity", &granularity) < 0) return false; @@ -2351,17 +2352,21 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) if (bandwidth || granularity || buf_size) { params = vshCalloc(ctl, 3, sizeof(*params)); if (bandwidth) { - /* bandwidth is ulong MiB/s, but the typed parameter is - * ullong bytes/s; make sure we don't overflow */ - unsigned long long limit = MIN(ULONG_MAX, ULLONG_MAX >> 20); - if (bandwidth > limit) { - vshError(ctl, _("bandwidth must be less than %llu"), limit); - goto cleanup; + if (!bytes) { + /* bandwidth is ulong MiB/s, but the typed parameter is + * ullong bytes/s; make sure we don't overflow */ + unsigned long long limit = MIN(ULONG_MAX, ULLONG_MAX >> 20); + if (bandwidth > limit) { + vshError(ctl, _("bandwidth must be less than %llu"), limit); + goto cleanup; + } + + bandwidth <<= 20ULL; } if (virTypedParameterAssign(¶ms[nparams++], VIR_DOMAIN_BLOCK_COPY_BANDWIDTH, VIR_TYPED_PARAM_ULLONG, - bandwidth << 20ULL) < 0) + bandwidth) < 0) goto cleanup; } if (granularity && @@ -2402,6 +2407,8 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd) flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_DEV; if (STREQ_NULLABLE(format, "raw")) flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_RAW; + if (bytes) + flags |= VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES; if (virDomainBlockRebase(dom, path, dest, bandwidth, flags) < 0) goto cleanup; diff --git a/tools/virsh.pod b/tools/virsh.pod index 7d61f22..26cfe35 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -991,7 +991,7 @@ command. =item B<blockcopy> I<domain> I<path> { I<dest> [I<format>] [I<--blockdev>] | I<--xml> B<file> } [I<--shallow>] [I<--reuse-external>] [I<bandwidth>] [I<--wait> [I<--async>] [I<--verbose>]] [{I<--pivot> | I<--finish>}] -[I<--timeout> B<seconds>] [I<granularity>] [I<buf-size>] +[I<--timeout> B<seconds>] [I<granularity>] [I<buf-size>] [I<--bytes>] Copy a disk backing image chain to a destination. Either I<dest> as the destination file name, or I<--xml> with the name of an XML file containing @@ -1036,8 +1036,10 @@ I<path> specifies fully-qualified path of the disk. I<bandwidth> specifies copying bandwidth limit in MiB/s. Specifying a negative value is interpreted as an unsigned long long value that might be essentially unlimited, but more likely would overflow; it is safer to use 0 for that -purpose. Specifying I<granularity> allows fine-tuning of the granularity that -will be copied when a dirty region is detected; larger values trigger less +purpose. For further information on the I<bandwidth> argument see the +corresponding section for the B<blockjob> command. +Specifying I<granularity> allows fine-tuning of the granularity that will be +copied when a dirty region is detected; larger values trigger less I/O overhead but may end up copying more data overall (the default value is usually correct); hypervisors may restrict this to be a power of two or fall within a certain range. Specifying I<buf-size> will control how much data can -- 2.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list