[PATCH 2/2] virsh: Fix completion logic to guestvcpus command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In case of non-continuous vCPU topology, We can't infer the bitmap size
from the combination of onlineVcpuStr and nvcpus.
We should use virBitmapParseUnlimited here instead of virBitmapParse due
to the bitmap size is unknown.

e.g.:

  <vcpus>
    <vcpu id='0' enabled='yes' hotpluggable='no' order='1'/>
    <vcpu id='1' enabled='yes' hotpluggable='yes' order='2'/>
    <vcpu id='2' enabled='yes' hotpluggable='yes' order='3'/>
    <vcpu id='3' enabled='yes' hotpluggable='yes' order='4'/>
    <vcpu id='4' enabled='yes' hotpluggable='yes' order='5'/>
    <vcpu id='5' enabled='yes' hotpluggable='yes' order='6'/>
    <vcpu id='6' enabled='no' hotpluggable='yes'/>
    <vcpu id='7' enabled='no' hotpluggable='yes'/>
  </vcpus>

 # virsh guestvcpus --domain VM
vcpus          : 0-5
online         : 0-5
offlinable     : 1-5

 # virsh setvcpu --domain VM --disable --vcpulist 2

 # virsh guestvcpus --domain VM --disable --cpulist 4,5

 # virsh guestvcpus --domain VM
vcpus          : 0-1,3-5
online         : 0-1,3
offlinable     : 1,3-5

Before:
 # virsh guestvcpus --domain VM --enable --cpulist <TAB><TAB>
2  4

After:
 # virsh guestvcpus --domain VM --enable --cpulist <TAB><TAB>
4  5

Signed-off-by: Lin Ma <lma@xxxxxxxx>
---
 tools/virsh-completer-domain.c | 61 ++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 17 deletions(-)

diff --git a/tools/virsh-completer-domain.c b/tools/virsh-completer-domain.c
index f56dc40125..998aa5d646 100644
--- a/tools/virsh-completer-domain.c
+++ b/tools/virsh-completer-domain.c
@@ -624,36 +624,63 @@ virshDomainVcpulistViaAgentCompleter(vshControl *ctl,
             cpulist[i] = g_strdup_printf("%zu", i);
     } else {
         g_autofree char *onlineVcpuStr = NULL;
-        g_autofree unsigned char *vcpumap = NULL;
-        g_autoptr(virBitmap) vcpus = NULL;
-        size_t offset = 0;
+        g_autofree char *offlinableVcpuStr = NULL;
+        g_autofree unsigned char *onlineVcpumap = NULL;
+        g_autofree unsigned char *offlinableVcpumap = NULL;
+        g_autoptr(virBitmap) onlineVcpus = NULL;
+        g_autoptr(virBitmap) offlinableVcpus = NULL;
+        size_t j = 0;
+        int lastcpu;
         int dummy;
 
         if (virDomainGetGuestVcpus(dom, &params, &nparams, 0) < 0)
             goto cleanup;
 
         onlineVcpuStr = vshGetTypedParamValue(ctl, &params[1]);
-        if (virBitmapParse(onlineVcpuStr, &vcpus, nvcpus) < 0)
+        if (!(onlineVcpus = virBitmapParseUnlimited(onlineVcpuStr)))
             goto cleanup;
 
-        if (virBitmapToData(vcpus, &vcpumap, &dummy) < 0)
+        if (virBitmapToData(onlineVcpus, &onlineVcpumap, &dummy) < 0)
             goto cleanup;
 
         if (enable) {
-            cpulist = g_new0(char *, nvcpus - virBitmapCountBits(vcpus) + 1);
-            for (i = 0; i < nvcpus; i++) {
-                if (VIR_CPU_USED(vcpumap, i) != 0)
-                    continue;
-
-                cpulist[offset++] = g_strdup_printf("%zu", i);
+            offlinableVcpuStr = vshGetTypedParamValue(ctl, &params[2]);
+
+            if (!(offlinableVcpus = virBitmapParseUnlimited(offlinableVcpuStr)))
+                goto cleanup;
+
+            if (virBitmapToData(offlinableVcpus, &offlinableVcpumap, &dummy) < 0)
+                goto cleanup;
+
+            lastcpu = virBitmapLastSetBit(offlinableVcpus);
+            cpulist = g_new0(char *, nvcpus - virBitmapCountBits(onlineVcpus) + 1);
+            for (i = 0; i < nvcpus - virBitmapCountBits(onlineVcpus); i++) {
+                while (j <= lastcpu) {
+                    if (VIR_CPU_USED(onlineVcpumap, j) != 0 ||
+                        VIR_CPU_USED(offlinableVcpumap, j) == 0) {
+                        j += 1;
+                        continue;
+                    } else {
+                        break;
+                    }
+                }
+
+                cpulist[i] = g_strdup_printf("%zu", j++);
             }
         } else if (disable) {
-            cpulist = g_new0(char *, virBitmapCountBits(vcpus) + 1);
-            for (i = 0; i < nvcpus; i++) {
-                if (VIR_CPU_USED(vcpumap, i) == 0)
-                    continue;
-
-                cpulist[offset++] = g_strdup_printf("%zu", i);
+            lastcpu = virBitmapLastSetBit(onlineVcpus);
+            cpulist = g_new0(char *, virBitmapCountBits(onlineVcpus) + 1);
+            for (i = 0; i < virBitmapCountBits(onlineVcpus); i++) {
+                while (j <= lastcpu) {
+                    if (VIR_CPU_USED(onlineVcpumap, j) == 0) {
+                        j += 1;
+                        continue;
+                    } else {
+                        break;
+                    }
+                }
+
+                cpulist[i] = g_strdup_printf("%zu", j++);
             }
         }
     }
-- 
2.26.2





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux