virsh: forbid negative vcpu argument to vcpupin

The vcpupin command allowed specifying a negative number for the --vcpu
argument. This would the overflow when the underlying virDomainPinVcpu
API was called.

 $ virsh vcpupin r7 -1 0
 error: numerical overflow: input too large: 4294967295

Switch the vCPU variable to a unsigned int and parse it using the
corresponding function.

Also improve the vcpupin test to cover all the defects.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1101059

Signed-off-by: Jincheng Miao <jmiao@redhat.com>
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Jincheng Miao 2014-05-29 11:34:40 +08:00 committed by Peter Krempa
parent c62125395b
commit e430410480
2 changed files with 46 additions and 18 deletions

View File

@ -34,7 +34,7 @@ fail=0
$abs_top_builddir/tools/virsh --connect test:///default vcpupin test a 0,1 > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: vcpupin: Invalid or missing vCPU number.
error: vcpupin: Invalid vCPU number.
EOF
compare exp out || fail=1
@ -43,9 +43,36 @@ compare exp out || fail=1
$abs_top_builddir/tools/virsh --connect test:///default vcpupin test 100 0,1 > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: vcpupin: vCPU index out of range.
EOF
compare exp out || fail=1
# Negative number
$abs_top_builddir/tools/virsh --connect test:///default vcpupin test -100 0,1 > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: vcpupin: Invalid vCPU number.
EOF
compare exp out || fail=1
# missing argument
$abs_top_builddir/tools/virsh --connect test:///default vcpupin test --cpulist 0,1 > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: vcpupin: Missing vCPU number in pin mode.
EOF
compare exp out || fail=1
# without arguments. This should succeed but the backend function in the
# test driver isn't implemented
$abs_top_builddir/tools/virsh --connect test:///default vcpupin test > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: this function is not supported by the connection driver: virDomainGetVcpuPinInfo
EOF
compare exp out || fail=1
(exit $fail); exit $fail

View File

@ -5803,7 +5803,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
{
virDomainInfo info;
virDomainPtr dom;
int vcpu = -1;
unsigned int vcpu = 0;
const char *cpulist = NULL;
bool ret = false;
unsigned char *cpumap = NULL;
@ -5815,6 +5815,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
bool live = vshCommandOptBool(cmd, "live");
bool current = vshCommandOptBool(cmd, "current");
bool query = false; /* Query mode if no cpulist */
int got_vcpu;
unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
@ -5836,29 +5837,29 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
query = !cpulist;
/* 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;
if ((got_vcpu = vshCommandOptUInt(cmd, "vcpu", &vcpu)) < 0) {
vshError(ctl, "%s", _("vcpupin: Invalid vCPU number."));
goto cleanup;
}
if ((maxcpu = vshNodeGetCPUCount(ctl->conn)) < 0) {
virDomainFree(dom);
return false;
/* In pin mode, "vcpu" is necessary */
if (!query && got_vcpu == 0) {
vshError(ctl, "%s", _("vcpupin: Missing vCPU number in pin mode."));
goto cleanup;
}
if (virDomainGetInfo(dom, &info) != 0) {
vshError(ctl, "%s", _("vcpupin: failed to get domain information."));
virDomainFree(dom);
return false;
goto cleanup;
}
if (vcpu >= info.nrVirtCpu) {
vshError(ctl, "%s", _("vcpupin: Invalid vCPU number."));
virDomainFree(dom);
return false;
vshError(ctl, "%s", _("vcpupin: vCPU index out of range."));
goto cleanup;
}
if ((maxcpu = vshNodeGetCPUCount(ctl->conn)) < 0) {
goto cleanup;
}
cpumaplen = VIR_CPU_MAPLEN(maxcpu);
@ -5877,7 +5878,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
vshPrintExtra(ctl, "%s %s\n", _("VCPU:"), _("CPU Affinity"));
vshPrintExtra(ctl, "----------------------------------\n");
for (i = 0; i < ncpus; i++) {
if (vcpu != -1 && i != vcpu)
if (got_vcpu && i != vcpu)
continue;
vshPrint(ctl, "%4zu: ", i);
@ -5886,8 +5887,8 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
if (!ret)
break;
}
}
VIR_FREE(cpumaps);
goto cleanup;
}