[libvirt] [PATCH 13/13] Improve vcpupin to support hypervisorpin dynically.

tangchen tangchen at cn.fujitsu.com
Tue Jul 10 09:20:24 UTC 2012


Modify vcpupin command to support hypervisor threads pin.
    1) add "--hypervisor" option to get hypervisor threads info.
    2) add "--hypervisor cpuset" to set hypervisor threads to specified cpuset.

Signed-off-by: Tang Chen <tangchen at cn.fujitsu.com>
---
 tests/vcpupin   |    6 +--
 tools/virsh.c   |  147 ++++++++++++++++++++++++++++++++++++-------------------
 tools/virsh.pod |   16 +++---
 3 files changed, 111 insertions(+), 58 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 85b1185..6d59897 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5463,14 +5463,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")},
@@ -5479,6 +5480,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)
 {
@@ -5491,13 +5531,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;
 
@@ -5532,8 +5572,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;
     }
@@ -5565,47 +5615,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;
-
-               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");
+        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);
+                    ret = printPinInfo(cpumaps, cpumaplen, maxcpu, i);
+                    vshPrint(ctl, "\n");
+                    if (!ret)
+                        break;
+                }
+            } else {
+                ret = false;
             }
+            VIR_FREE(cpumaps);
+        }
 
-        } else {
-            ret = false;
+        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");
+
+                vshPrint(ctl, "   *: ");
+                ret = printPinInfo(cpumaps, cpumaplen, maxcpu, 0);
+                vshPrint(ctl, "\n");
+            } else if (nhyper < 0) {
+                ret = false;
+            }
+            VIR_FREE(cpumaps);
         }
-        VIR_FREE(cpumaps);
         goto cleanup;
     }
 
@@ -5683,13 +5731,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 93fdac7..61b7772 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1574,12 +1574,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.10.2




More information about the libvir-list mailing list