* "vcpupin" command
*/
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.")},
{NULL, NULL}
};
static const vshCmdOptDef opts_vcpupin[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
- {"vcpu", VSH_OT_INT, VSH_OFLAG_REQ, N_("vcpu number")},
- {"cpulist", VSH_OT_DATA, VSH_OFLAG_REQ, N_("host cpu number(s) (comma separated)")},
+ {"vcpu", VSH_OT_INT, 0, N_("vcpu number")},
+ {"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")},
{"live", VSH_OT_BOOL, 0, N_("affect running domain")},
{"current", VSH_OT_BOOL, 0, N_("affect current domain")},
virDomainInfo info;
virDomainPtr dom;
virNodeInfo nodeinfo;
- int vcpu;
+ int vcpu = -1;
const char *cpulist = NULL;
bool ret = true;
- unsigned char *cpumap;
+ unsigned char *cpumap = NULL;
+ unsigned char *cpumaps = NULL;
int cpumaplen;
- int i, cpu, lastcpu, maxcpu;
+ bool bit, lastbit, isInvert;
+ int i, cpu, lastcpu, maxcpu, ncpus;
bool unuse = false;
const char *cur;
int config = vshCommandOptBool(cmd, "config");
int live = vshCommandOptBool(cmd, "live");
int current = vshCommandOptBool(cmd, "current");
+ bool query = false; /* Query mode if no cpulist */
int flags = 0;
if (current) {
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
- if (vshCommandOptInt(cmd, "vcpu", &vcpu) <= 0) {
- vshError(ctl, "%s", _("vcpupin: Invalid or missing vCPU number."));
+ if (vshCommandOptString(cmd, "cpulist", &cpulist) < 0) {
+ vshError(ctl, "%s", _("vcpupin: Missing cpulist."));
virDomainFree(dom);
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);
return false;
}
}
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);
return false;
}
maxcpu = VIR_NODEINFO_MAXCPUS(nodeinfo);
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 */
cur = cpulist;
if (*cur == 0) {
Returns basic information about the domain virtual CPUs, like the number of
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>
-Pin domain VCPUs to host physical CPUs. The I<vcpu> number must be provided
-and I<cpulist> is a list of physical CPU numbers. Its syntax is a comma
+Query or change the pinning of domain VCPUs to host physical CPUs. To
+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
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 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, 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.
-B<Note>: The expression is sequentially evaluated, so "0-15,^8" is not identical
-to "^8,0-15".
+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<vncdisplay> I<domain-id>