[libvirt] [PATCH 09/10] vcpubandwidth: Implement virsh support
Taku Izumi
izumi.taku at jp.fujitsu.com
Thu Jun 30 07:27:45 UTC 2011
On Thu, 30 Jun 2011 11:19:14 +0800
Wen Congyang <wency at cn.fujitsu.com> wrote:
> 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.
I try the following:
# virsh domstate VM
shut off
# virsh vcpu-bandwidth VM --config
vcpu: period quota
----------------------------------
0: 100000 50000
1: 100000 50000
2: 100000 50000
3: 100000 50000
# virsh start VM
Domain VM started
# virsh vcpu-bandwidth VM --live
vcpu: period quota
----------------------------------
0: 100000 -1
1: 100000 -1
2: 100000 -1
3: 100000 -1
This behavior doesn't make sense to me.
Is this what you intend?
Or, do I make a mistake?
>
> ---
> 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;
Is the following case OK? VCPU#4-7 are not present.
<vcpu current='4'>8</vcpu>
> +
> + /* 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;
> + }
This check should be done before querying?
> +
> + 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 at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
>
--
Taku Izumi <izumi.taku at jp.fujitsu.com>
More information about the libvir-list
mailing list