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(a)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