When we pass a invalid cpulist or the lastcpu in the cpulist exceed the maxcpu, we cannot get any error. like this: # virsh vcpupin test3 1 aaa # virsh vcpupin test3 1 1000 Because virBitmapParse() use virReportError() to set the error message, vshCommandRun would output the error in vshReportError, but in the meantime it is overwriten by the virResetLastError in virDomainFree. If we want use the error which set by virReportError(), we need vshSaveLibvirtError to help us. However the error from virBitmap is not clearly enough, i chose use vshError to output error when parse failed. Signed-off-by: Luyao Huang <lhuang@xxxxxxxxxx> --- v2: Add the check in vshParseCPUList, because this will make get last cpu more easier when the cpulist is a bitmap. tools/virsh-domain.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 14e1e35..20f8c75 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -6348,7 +6348,7 @@ vshPrintPinInfo(unsigned char *cpumap, size_t cpumaplen) } static unsigned char * -vshParseCPUList(int *cpumaplen, const char *cpulist, int maxcpu) +vshParseCPUList(vshControl *ctl, int *cpumaplen, const char *cpulist, int maxcpu) { unsigned char *cpumap = NULL; virBitmapPtr map = NULL; @@ -6358,8 +6358,17 @@ vshParseCPUList(int *cpumaplen, const char *cpulist, int maxcpu) return NULL; virBitmapSetAll(map); } else { - if (virBitmapParse(cpulist, '\0', &map, maxcpu) < 0) - return NULL; + if ((virBitmapParse(cpulist, '\0', &map, 1024) < 0) || + virBitmapIsAllClear(map)) { + vshError(ctl, _("Invalid cpulist '%s'"), cpulist); + goto cleanup; + } + int lastcpu = virBitmapLastSetBit(map); + if (lastcpu >= maxcpu) { + vshError(ctl, _("CPU %d in cpulist '%s' exceed the maxcpu %d"), + lastcpu, cpulist, maxcpu); + goto cleanup; + } } if (virBitmapToData(map, &cpumap, cpumaplen) < 0) @@ -6458,7 +6467,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) } } else { /* Pin mode: pinning specified vcpu to specified physical cpus*/ - if (!(cpumap = vshParseCPUList(&cpumaplen, cpulist, maxcpu))) + if (!(cpumap = vshParseCPUList(ctl, &cpumaplen, cpulist, maxcpu))) goto cleanup; if (flags == -1) { @@ -6577,7 +6586,7 @@ cmdEmulatorPin(vshControl *ctl, const vshCmd *cmd) } /* Pin mode: pinning emulator threads to specified physical cpus*/ - if (!(cpumap = vshParseCPUList(&cpumaplen, cpulist, maxcpu))) + if (!(cpumap = vshParseCPUList(ctl, &cpumaplen, cpulist, maxcpu))) goto cleanup; if (flags == -1) @@ -6862,7 +6871,7 @@ cmdIOThreadPin(vshControl *ctl, const vshCmd *cmd) if ((maxcpu = vshNodeGetCPUCount(ctl->conn)) < 0) goto cleanup; - if (!(cpumap = vshParseCPUList(&cpumaplen, cpulist, maxcpu))) + if (!(cpumap = vshParseCPUList(ctl, &cpumaplen, cpulist, maxcpu))) goto cleanup; if (virDomainPinIOThread(dom, iothread_id, -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list