Introduce new command vcpu-bandwidth to change and query bandwidth for each vcpu. Usage: 1. query bandwidth for all vcpus: # virsh vcpu-bandwidth <domain> 2. query bandwidth for a vcpu: # virsh vcpu-bandwidth <domain> <vcpuid> 3. change bandwidth for a vcpu: # virsh vcpu-bandwidth <domain> <vcpuid> <period> <quota> You can omit period or quota. The option --live, --config, and --current is the same as the other commands. --- tools/virsh.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- tools/virsh.pod | 16 ++++++ 2 files changed, 157 insertions(+), 1 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index d15d206..b5a49dd 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3049,7 +3049,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) flags |= VIR_DOMAIN_AFFECT_LIVE; /* neither option is specified */ if (!live && !config) - flags = -1; + flags = VIR_DOMAIN_AFFECT_CURRENT; } if (!vshConnectionUsability(ctl, ctl->conn)) @@ -3239,6 +3239,144 @@ parse_error: } /* + * "vcpu-bandwidth" command + */ +static const vshCmdInfo info_vcpu_bandwidth[] = { + {"help", N_("control or query domain vcpu bandwidth")}, + {"desc", N_("Change or query the bandwidth of virtual CPUs in the guest domain.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_vcpu_bandwidth[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"vcpu", VSH_OT_INT, 0, N_("vcpu number")}, + {"period", VSH_OT_INT, VSH_OFLAG_EMPTY_OK, N_("bandwidth period in usecs")}, + {"quota", VSH_OT_INT, VSH_OFLAG_EMPTY_OK, + N_("cpu bandwidth (in usecs) that this vcpu will be allowed to consume over period")}, + {"config", VSH_OT_BOOL, 0, N_("affect next boot")}, + {"live", VSH_OT_BOOL, 0, N_("affect running domain")}, + {"current", VSH_OT_BOOL, 0, N_("affect current domain")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdVcpuBandwidth(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + int vcpu = -1; + int max_vcpus, nvcpus = 0; + unsigned long long period = 0; + long long quota = 0; + int period_found, quota_found; + virDomainVcpuBWDefPtr vcpubw_list = NULL; + virDomainVcpuBWDefPtr vcpubw = NULL; + bool ret = false; + bool config = vshCommandOptBool(cmd, "config"); + bool live = vshCommandOptBool(cmd, "live"); + bool current = vshCommandOptBool(cmd, "current"); + bool query = false; /* Query mode if no period and no quota */ + int flags = 0; + int rc; + int i; + + if (current) { + if (live || config) { + vshError(ctl, "%s", _("--current must be specified exclusively")); + return false; + } + flags = VIR_DOMAIN_AFFECT_CURRENT; + } else { + if (config) + flags |= VIR_DOMAIN_AFFECT_CONFIG; + if (live) + flags |= VIR_DOMAIN_AFFECT_LIVE; + /* neither option is specified */ + if (!live && !config) + flags = VIR_DOMAIN_AFFECT_CURRENT; + } + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if ((period_found = vshCommandOptULongLong(cmd, "period", &period)) < 0) { + vshError(ctl, "%s", _("Invalid value of period")); + goto cleanup; + } + + if ((quota_found = vshCommandOptLongLong(cmd, "quota", "a)) < 0) { + vshError(ctl, "%s", _("Invalid value of quota")); + goto cleanup; + } + + query = quota_found == 0 && period_found == 0; + + /* In query mode, "vcpu" is optional */ + if (vshCommandOptInt(cmd, "vcpu", &vcpu) < !query) { + vshError(ctl, "%s", _("Invalid or missing VCPU number.")); + goto cleanup; + } + + max_vcpus = virDomainGetVcpusFlags(dom, flags | VIR_DOMAIN_VCPU_MAXIMUM); + if (max_vcpus < 0) + goto cleanup; + + /* In query mode, we need to know current setting. In change mode, if user + * does not specify period or quota, we need to know its origin setting. + */ + if (quota_found == 0 || period_found == 0) { + nvcpus = max_vcpus; + vcpubw_list = vshMalloc(ctl, nvcpus * sizeof(*vcpubw_list)); + rc = virDomainGetVcpuBW(dom, vcpubw_list, &nvcpus, flags); + if (rc < 0) + goto cleanup; + } + + /* Query mode: show CPU bandwidth information then exit.*/ + if (query) { + vshPrint(ctl, "%s %s %s\n", _("vcpu:"), _("period"), _("quota")); + vshPrint(ctl, "----------------------------------\n"); + for (i = 0; i < nvcpus; i++) { + if (vcpu != -1 && i != vcpu) + continue; + vshPrint(ctl, "%4d: ", i); + vshPrint(ctl, "%6llu ", vcpubw_list[i].period); + vshPrint(ctl, "%5lld\n", vcpubw_list[i].quota); + } + goto cleanup; + } + + if (vcpu >= max_vcpus) { + vshError(ctl, _("Virtual CPU %d doesn't exist."), vcpu); + goto cleanup; + } + + vcpubw = vshMalloc(ctl, sizeof(*vcpubw)); + vcpubw[0].vcpuid = vcpu; + if (period_found) + vcpubw[0].period = period; + else + vcpubw[0].period = vcpubw_list[vcpu].period; + if (quota_found) + vcpubw[0].quota = quota; + else + vcpubw[0].quota = vcpubw_list[vcpu].quota; + rc = virDomainSetVcpuBW(dom, vcpubw, 1, flags); + if (rc < 0) + goto cleanup; + + ret = true; + +cleanup: + VIR_FREE(vcpubw_list); + VIR_FREE(vcpubw); + virDomainFree(dom); + return ret; +} + +/* * "setvcpus" command */ static const vshCmdInfo info_setvcpus[] = { @@ -11675,6 +11813,8 @@ static const vshCmdDef domManagementCmds[] = { {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount, 0}, {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo, 0}, {"vcpupin", cmdVcpuPin, opts_vcpupin, info_vcpupin, 0}, + {"vcpu-bandwidth", cmdVcpuBandwidth, opts_vcpu_bandwidth, + info_vcpu_bandwidth, 0}, {"version", cmdVersion, opts_version, info_version, 0}, {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay, 0}, {NULL, NULL, NULL, NULL, 0} diff --git a/tools/virsh.pod b/tools/virsh.pod index 736b919..686d8ba 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -849,6 +849,22 @@ If no flag is specified, behavior is different depending on hypervisor. B<Note>: The expression is sequentially evaluated, so "0-15,^8" is identical to "9-14,0-7,15" but not identical to "^8,0-15". +=item B<vcpu-bandwidth> I<domain-id> optional I<vcpu> I<period> I<quota> +I<--live> I<--config> I<--current> + +Change or query the bandwidth of domain vcpus. To change a single I<vcpu>, +specify I<period> or I<quota>; otherwise, you can query one I<vcpu> or omit +I<vcpu> to list all at once. + +I<period> is bandwidth period in usecs, and I<quota> is cpu bandwidth (in usecs) +that this vcpu will be allowed to consume over period. +If I<--live> is specified, affect a running guest. +If I<--config> is specified, affect the next boot of a persistent guest. +If I<--current> is specified, affect the current guest state. +Both I<--live> and I<--config> flags may be given if I<period> or I<quota> is +present, but I<--current> is exclusive. +If no flag is specified, it is identical to I<--current>. + =item B<vncdisplay> I<domain-id> Output the IP address and port number for the VNC display. If the information -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list