On Thu, 30 Jun 2011 11:19:14 +0800
Wen Congyang <wency(a)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(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
--
Taku Izumi <izumi.taku(a)jp.fujitsu.com>