Signed-off-by: Tang Chen <tangchen(a)cn.fujitsu.com>
---
tests/vcpupin | 6 +-
tools/virsh.c | 145 +++++++++++++++++++++++++++++++++++++------------------
tools/virsh.pod | 16 ++++--
3 files changed, 110 insertions(+), 57 deletions(-)
diff --git a/tests/vcpupin b/tests/vcpupin
index 5952862..ffd16fa 100755
--- a/tests/vcpupin
+++ b/tests/vcpupin
@@ -30,16 +30,16 @@ fi
fail=0
# Invalid syntax.
-$abs_top_builddir/tools/virsh --connect test:///default vcpupin test a 0,1 > out
2>&1
+$abs_top_builddir/tools/virsh --connect test:///default vcpupin test a --vcpu 0,1 >
out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
-error: vcpupin: Invalid or missing vCPU number.
+error: vcpupin: Invalid or missing vCPU number, or missing --hypervisor option.
EOF
compare exp out || fail=1
# An out-of-range vCPU number deserves a diagnostic, too.
-$abs_top_builddir/tools/virsh --connect test:///default vcpupin test 100 0,1 > out
2>&1
+$abs_top_builddir/tools/virsh --connect test:///default vcpupin test --vcpu 100 0,1 >
out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: vcpupin: Invalid vCPU number.
diff --git a/tools/virsh.c b/tools/virsh.c
index e177684..7820d8a 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5213,14 +5213,15 @@ cmdVcpuinfo(vshControl *ctl, const vshCmd *cmd)
* "vcpupin" command
*/
static const vshCmdInfo info_vcpupin[] = {
- {"help", N_("control or query domain vcpu affinity")},
- {"desc", N_("Pin domain VCPUs to host physical CPUs.")},
+ {"help", N_("control or query domain vcpu and hypervisor threads
affinities")},
+ {"desc", N_("Pin domain VCPUs or hypervisor threads 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, 0, N_("vcpu number")},
+ {"vcpu", VSH_OT_INT, VSH_OFLAG_REQ_OPT, N_("vcpu number")},
+ {"hypervisor", VSH_OT_BOOL, VSH_OFLAG_REQ_OPT, N_("pin hypervisor
threads")},
{"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")},
@@ -5229,6 +5230,45 @@ static const vshCmdOptDef opts_vcpupin[] = {
{NULL, 0, 0, NULL}
};
+/*
+ * Helper function to print vcpupin and hypervisorpin info.
+ */
+static bool
+printPinInfo(unsigned char *cpumaps, size_t cpumaplen,
+ int maxcpu, int vcpuindex)
+{
+ int cpu, lastcpu;
+ bool bit, lastbit, isInvert;
+
+ if (!cpumaps || cpumaplen <= 0 || maxcpu <= 0 || vcpuindex < 0) {
+ return false;
+ }
+
+ bit = lastbit = isInvert = false;
+ lastcpu = -1;
+
+ for (cpu = 0; cpu < maxcpu; cpu++) {
+ bit = VIR_CPU_USABLE(cpumaps, cpumaplen, vcpuindex, 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);
+ }
+
+ return true;
+}
+
static bool
cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
{
@@ -5241,13 +5281,13 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
unsigned char *cpumap = NULL;
unsigned char *cpumaps = NULL;
size_t cpumaplen;
- bool bit, lastbit, isInvert;
- int i, cpu, lastcpu, maxcpu, ncpus;
+ int i, cpu, lastcpu, maxcpu, ncpus, nhyper;
bool unuse = false;
const char *cur;
bool config = vshCommandOptBool(cmd, "config");
bool live = vshCommandOptBool(cmd, "live");
bool current = vshCommandOptBool(cmd, "current");
+ bool hypervisor = vshCommandOptBool(cmd, "hypervisor");
bool query = false; /* Query mode if no cpulist */
unsigned int flags = 0;
@@ -5282,8 +5322,18 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
/* In query mode, "vcpu" is optional */
if (vshCommandOptInt(cmd, "vcpu", &vcpu) < !query) {
- vshError(ctl, "%s",
- _("vcpupin: Invalid or missing vCPU number."));
+ if (!hypervisor) {
+ vshError(ctl, "%s",
+ _("vcpupin: Invalid or missing vCPU number, "
+ "or missing --hypervisor option."));
+ virDomainFree(dom);
+ return false;
+ }
+ }
+
+ if (hypervisor && vcpu != -1) {
+ vshError(ctl, "%s", _("vcpupin: --hypervisor must be specified
"
+ "exclusively to --vcpu."));
virDomainFree(dom);
return false;
}
@@ -5315,47 +5365,45 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
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;
+ if (!hypervisor) {
+ 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;
- vshPrint(ctl, "%4d: ", i);
- for (cpu = 0; cpu < maxcpu; cpu++) {
+ vshPrint(ctl, "%4d: ", i);
+ ret = printPinInfo(cpumaps, cpumaplen, maxcpu, i);
+ vshPrint(ctl, "\n");
+ if (!ret)
+ break;
+ }
+ } else {
+ ret = false;
+ }
+ VIR_FREE(cpumaps);
+ }
- bit = VIR_CPU_USABLE(cpumaps, cpumaplen, i, cpu);
+ if (vcpu == -1) {
+ cpumaps = vshMalloc(ctl, cpumaplen);
+ if ((nhyper = virDomainGetHypervisorPinInfo(dom, cpumaps,
+ cpumaplen, flags)) >= 0) {
+ if (!hypervisor)
+ vshPrint(ctl, "\n");
+ vshPrint(ctl, "%s %s\n", _("Hypervisor:"),
_("CPU Affinity"));
+ vshPrint(ctl, "----------------------------------\n");
- 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");
+ vshPrint(ctl, " *: ");
+ ret = printPinInfo(cpumaps, cpumaplen, maxcpu, 0);
+ vshPrint(ctl, "\n");
+ } else if (nhyper < 0) {
+ ret = false;
}
-
- } else {
- ret = false;
+ VIR_FREE(cpumaps);
}
- VIR_FREE(cpumaps);
goto cleanup;
}
@@ -5433,13 +5481,14 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
}
if (flags == -1) {
- if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) {
+ flags = VIR_DOMAIN_AFFECT_LIVE;
+ }
+ if (!hypervisor) {
+ if (virDomainPinVcpuFlags(dom, vcpu, cpumap, cpumaplen, flags) != 0)
ret = false;
- }
} else {
- if (virDomainPinVcpuFlags(dom, vcpu, cpumap, cpumaplen, flags) != 0) {
+ if (virDomainPinHypervisorFlags(dom, cpumap, cpumaplen, flags) != 0)
ret = false;
- }
}
cleanup:
diff --git a/tools/virsh.pod b/tools/virsh.pod
index ef71717..0cdabb4 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1522,12 +1522,16 @@ Thus, this command always takes exactly zero or two flags.
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>]
[[I<--live>]
-[I<--config>] | [I<--current>]]
-
-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.
+=item B<vcpupin> I<domain-id> [I<vcpu>] [I<hypervicor>]
[I<cpulist>]
+[[I<--live>] [I<--config>] | [I<--current>]]
+
+Query or change the pinning of domain VCPUs or hypervisor threads to host physical CPUs.
+To pin a single I<vcpu>, specify I<cpulist>; otherwise, you can query one
+I<vcpu>.
+To pin all I<hypervisor> threads, specify I<cpulist>; otherwise, you can
+query I<hypervisor>.
+You can also omit I<vcpu> or I<hypervisor> to list vcpus and hypervisor
threads
+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
--
1.7.3.1