[libvirt] [PATCHv2] virsh: fix no error output when parse cpulist fail

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@redhat.com> --- 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

On 11.05.2015 10:25, Luyao Huang wrote:
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@redhat.com> --- 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(-)
Reworded the commit message a bit, ACKed and pushed. Michal

On 05/14/2015 08:33 PM, Michal Privoznik wrote:
On 11.05.2015 10:25, Luyao Huang wrote:
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@redhat.com> --- 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(-) Reworded the commit message a bit, ACKed and pushed.
Thanks for your review and help.
Michal
Luyao
participants (3)
-
lhuang
-
Luyao Huang
-
Michal Privoznik