vcpupin: add query option to virsh vcpupin command

This patch teaches "virsh vcpupin" command to query if no list
is given. Its feature is to show CPU affinity information in more
reader-friendly way.

 # virsh vcpupin VM --config
 VCPU: CPU Affinity
 ----------------------------------
    0: 1-6,9-20
    1: 10
    2: 5,9-11,15-20
    3: 1,3,5,7,9,11,13,15

When cpulist is omitted, vcpu number is optional. When vcpu number is
provided, information of only specified vcpu is displayed.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Taku Izumi 2011-06-24 18:02:28 +09:00 committed by Eric Blake
parent ffb552ebf0
commit e0858026a2
2 changed files with 82 additions and 17 deletions

View File

@ -2998,15 +2998,16 @@ cmdVcpuinfo(vshControl *ctl, const vshCmd *cmd)
* "vcpupin" command * "vcpupin" command
*/ */
static const vshCmdInfo info_vcpupin[] = { static const vshCmdInfo info_vcpupin[] = {
{"help", N_("control domain vcpu affinity")}, {"help", N_("control or query domain vcpu affinity")},
{"desc", N_("Pin domain VCPUs to host physical CPUs.")}, {"desc", N_("Pin domain VCPUs to host physical CPUs.")},
{NULL, NULL} {NULL, NULL}
}; };
static const vshCmdOptDef opts_vcpupin[] = { static const vshCmdOptDef opts_vcpupin[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
{"vcpu", VSH_OT_INT, VSH_OFLAG_REQ, N_("vcpu number")}, {"vcpu", VSH_OT_INT, 0, N_("vcpu number")},
{"cpulist", VSH_OT_DATA, VSH_OFLAG_REQ, N_("host cpu number(s) (comma separated)")}, {"cpulist", VSH_OT_DATA, VSH_OFLAG_EMPTY_OK,
N_("host cpu number(s) to set, or omit option to query")},
{"config", VSH_OT_BOOL, 0, N_("affect next boot")}, {"config", VSH_OT_BOOL, 0, N_("affect next boot")},
{"live", VSH_OT_BOOL, 0, N_("affect running domain")}, {"live", VSH_OT_BOOL, 0, N_("affect running domain")},
{"current", VSH_OT_BOOL, 0, N_("affect current domain")}, {"current", VSH_OT_BOOL, 0, N_("affect current domain")},
@ -3019,17 +3020,20 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
virDomainInfo info; virDomainInfo info;
virDomainPtr dom; virDomainPtr dom;
virNodeInfo nodeinfo; virNodeInfo nodeinfo;
int vcpu; int vcpu = -1;
const char *cpulist = NULL; const char *cpulist = NULL;
bool ret = true; bool ret = true;
unsigned char *cpumap; unsigned char *cpumap = NULL;
unsigned char *cpumaps = NULL;
int cpumaplen; int cpumaplen;
int i, cpu, lastcpu, maxcpu; bool bit, lastbit, isInvert;
int i, cpu, lastcpu, maxcpu, ncpus;
bool unuse = false; bool unuse = false;
const char *cur; const char *cur;
int config = vshCommandOptBool(cmd, "config"); int config = vshCommandOptBool(cmd, "config");
int live = vshCommandOptBool(cmd, "live"); int live = vshCommandOptBool(cmd, "live");
int current = vshCommandOptBool(cmd, "current"); int current = vshCommandOptBool(cmd, "current");
bool query = false; /* Query mode if no cpulist */
int flags = 0; int flags = 0;
if (current) { if (current) {
@ -3054,13 +3058,17 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false; return false;
if (vshCommandOptInt(cmd, "vcpu", &vcpu) <= 0) { if (vshCommandOptString(cmd, "cpulist", &cpulist) < 0) {
vshError(ctl, "%s", _("vcpupin: Invalid or missing vCPU number.")); vshError(ctl, "%s", _("vcpupin: Missing cpulist."));
virDomainFree(dom); virDomainFree(dom);
return false; return false;
} }
query = !cpulist;
if (vshCommandOptString(cmd, "cpulist", &cpulist) <= 0) { /* In query mode, "vcpu" is optional */
if (vshCommandOptInt(cmd, "vcpu", &vcpu) < !query) {
vshError(ctl, "%s",
_("vcpupin: Invalid or missing vCPU number."));
virDomainFree(dom); virDomainFree(dom);
return false; return false;
} }
@ -3071,7 +3079,7 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
} }
if (virDomainGetInfo(dom, &info) != 0) { if (virDomainGetInfo(dom, &info) != 0) {
vshError(ctl, "%s", _("vcpupin: failed to get domain informations.")); vshError(ctl, "%s", _("vcpupin: failed to get domain information."));
virDomainFree(dom); virDomainFree(dom);
return false; return false;
} }
@ -3084,8 +3092,61 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
maxcpu = VIR_NODEINFO_MAXCPUS(nodeinfo); maxcpu = VIR_NODEINFO_MAXCPUS(nodeinfo);
cpumaplen = VIR_CPU_MAPLEN(maxcpu); cpumaplen = VIR_CPU_MAPLEN(maxcpu);
cpumap = vshCalloc(ctl, 0, cpumaplen);
/* Query mode: show CPU affinity information then exit.*/
if (query) {
/* When query mode and neither "live", "config" nor "current"
* is specified, set VIR_DOMAIN_AFFECT_CURRENT as flags */
if (flags == -1)
flags = VIR_DOMAIN_AFFECT_CURRENT;
cpumaps = vshMalloc(ctl, info.nrVirtCpu * cpumaplen);
if ((ncpus = virDomainGetVcpupinInfo(dom, info.nrVirtCpu,
cpumaps, cpumaplen, flags)) >= 0) {
vshPrint(ctl, "%s %s\n", _("VCPU:"), _("CPU Affinity"));
vshPrint(ctl, "----------------------------------\n");
for (i = 0; i < ncpus; i++) {
if (vcpu != -1 && i != vcpu)
continue;
bit = lastbit = isInvert = false;
lastcpu = -1;
vshPrint(ctl, "%4d: ", i);
for (cpu = 0; cpu < maxcpu; cpu++) {
bit = VIR_CPU_USABLE(cpumaps, cpumaplen, i, cpu);
isInvert = (bit ^ lastbit);
if (bit && isInvert) {
if (lastcpu == -1)
vshPrint(ctl, "%d", cpu);
else
vshPrint(ctl, ",%d", cpu);
lastcpu = cpu;
}
if (!bit && isInvert && lastcpu != cpu - 1)
vshPrint(ctl, "-%d", cpu - 1);
lastbit = bit;
}
if (bit && !isInvert) {
vshPrint(ctl, "-%d", maxcpu - 1);
}
vshPrint(ctl, "\n");
}
} else {
ret = false;
}
VIR_FREE(cpumaps);
goto cleanup;
}
/* Pin mode: pinning specified vcpu to specified physical cpus*/
cpumap = vshCalloc(ctl, 0, cpumaplen);
/* Parse cpulist */ /* Parse cpulist */
cur = cpulist; cur = cpulist;
if (*cur == 0) { if (*cur == 0) {

View File

@ -827,11 +827,14 @@ values; these two flags cannot both be specified.
Returns basic information about the domain virtual CPUs, like the number of Returns basic information about the domain virtual CPUs, like the number of
vCPUs, the running time, the affinity to physical processors. vCPUs, the running time, the affinity to physical processors.
=item B<vcpupin> I<domain-id> I<vcpu> I<cpulist> optional I<--live> I<--config> =item B<vcpupin> I<domain-id> optional I<vcpu> I<cpulist> I<--live> I<--config>
I<--current> I<--current>
Pin domain VCPUs to host physical CPUs. The I<vcpu> number must be provided Query or change the pinning of domain VCPUs to host physical CPUs. To
and I<cpulist> is a list of physical CPU numbers. Its syntax is a comma pin a single I<vcpu>, specify I<cpulist>; otherwise, you can query one
I<vcpu> or omit I<vcpu> to list all at once.
I<cpulist> is a list of physical CPU numbers. Its syntax is a comma
separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can
also be allowed. The '-' denotes the range and the '^' denotes exclusive. also be allowed. The '-' denotes the range and the '^' denotes exclusive.
If you want to reset vcpupin setting, that is, to pin vcpu all physical cpus, If you want to reset vcpupin setting, that is, to pin vcpu all physical cpus,
@ -839,11 +842,12 @@ simply specify 'r' as a cpulist.
If I<--live> is specified, affect a running guest. If I<--live> is specified, affect a running guest.
If I<--config> is specified, affect the next boot of a persistent guest. If I<--config> is specified, affect the next boot of a persistent guest.
If I<--current> is specified, affect the current guest state. If I<--current> is specified, affect the current guest state.
Both I<--live> and I<--config> flags may be given, but I<--current> is exclusive. Both I<--live> and I<--config> flags may be given if I<cpulist> is present,
but I<--current> is exclusive.
If no flag is specified, behavior is different depending on hypervisor. If no flag is specified, behavior is different depending on hypervisor.
B<Note>: The expression is sequentially evaluated, so "0-15,^8" is not identical B<Note>: The expression is sequentially evaluated, so "0-15,^8" is
to "^8,0-15". identical to "9-14,0-7,15" but not identical to "^8,0-15".
=item B<vncdisplay> I<domain-id> =item B<vncdisplay> I<domain-id>