]> xenbits.xensource.com Git - libvirt.git/commitdiff
vcpupin: add query option to virsh vcpupin command
authorTaku Izumi <izumi.taku@jp.fujitsu.com>
Fri, 24 Jun 2011 09:02:28 +0000 (18:02 +0900)
committerEric Blake <eblake@redhat.com>
Fri, 24 Jun 2011 23:00:22 +0000 (17:00 -0600)
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>
tools/virsh.c
tools/virsh.pod

index dbbb117f8d1925fc64755d7b7fb62f127f0ac477..31fbeb78701ec0cd8983d6dd36f19dee04c9a356 100644 (file)
@@ -2998,15 +2998,16 @@ cmdVcpuinfo(vshControl *ctl, const vshCmd *cmd)
  * "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")},
@@ -3019,17 +3020,20 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
     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) {
@@ -3054,13 +3058,17 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
     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;
     }
@@ -3071,7 +3079,7 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
     }
 
     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;
     }
@@ -3084,8 +3092,61 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
 
     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) {
index 734811bdd7bfa1ceea0a04fe53e920602b4946d2..736b9191181dc525004eeef7eec7f0489f388bdb 100644 (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
 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,
@@ -839,11 +842,12 @@ simply specify 'r' as a cpulist.
 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>