util: virhostcpu: Fail when fetching CPU Stats for invalid cpu

virHostCPUGetStatsLinux walks through every cpu in /proc/stat until it
finds cpu%cpuNum that matches with the requested cpu.
If none is found it logs the error but it should return -1, instead of 0.
Otherwise virsh nodecpustats --cpu <invalid cpu number> and API bindings
don't fail properly, printing a blank line instead of an error message.

This patch also includes an additional test for virhostcputest to avoid
this regression to happen again in the future.

Fixes: 93af79fba3
Reported-by: Satheesh Rajendran <satheera@in.ibm.com>
Signed-off-by: Mauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
This commit is contained in:
Mauro S. M. Rodrigues 2020-02-21 15:10:45 -03:00 committed by Michal Privoznik
parent 223b370aaa
commit 75a4ec42f7
2 changed files with 19 additions and 4 deletions

View File

@ -852,7 +852,7 @@ virHostCPUGetStatsLinux(FILE *procstat,
_("Invalid cpuNum in %s"), _("Invalid cpuNum in %s"),
__FUNCTION__); __FUNCTION__);
return 0; return -1;
} }

View File

@ -196,6 +196,7 @@ linuxTestHostCPU(const void *opaque)
struct nodeCPUStatsData { struct nodeCPUStatsData {
const char *name; const char *name;
int ncpus; int ncpus;
bool shouldFail;
}; };
static int static int
@ -214,6 +215,19 @@ linuxTestNodeCPUStats(const void *data)
result = linuxCPUStatsCompareFiles(cpustatfile, result = linuxCPUStatsCompareFiles(cpustatfile,
testData->ncpus, testData->ncpus,
outfile); outfile);
if (result < 0) {
if (testData->shouldFail) {
/* Expected error */
result = 0;
}
} else {
if (testData->shouldFail) {
fprintf(stderr, "Expected a failure, got success");
result = -1;
}
}
VIR_FREE(cpustatfile); VIR_FREE(cpustatfile);
VIR_FREE(outfile); VIR_FREE(outfile);
return result; return result;
@ -258,14 +272,15 @@ mymain(void)
if (virTestRun(nodeData[i].testName, linuxTestHostCPU, &nodeData[i]) != 0) if (virTestRun(nodeData[i].testName, linuxTestHostCPU, &nodeData[i]) != 0)
ret = -1; ret = -1;
# define DO_TEST_CPU_STATS(name, ncpus) \ # define DO_TEST_CPU_STATS(name, ncpus, shouldFail) \
do { \ do { \
static struct nodeCPUStatsData data = { name, ncpus }; \ static struct nodeCPUStatsData data = { name, ncpus, shouldFail}; \
if (virTestRun("CPU stats " name, linuxTestNodeCPUStats, &data) < 0) \ if (virTestRun("CPU stats " name, linuxTestNodeCPUStats, &data) < 0) \
ret = -1; \ ret = -1; \
} while (0) } while (0)
DO_TEST_CPU_STATS("24cpu", 24); DO_TEST_CPU_STATS("24cpu", 24, false);
DO_TEST_CPU_STATS("24cpu", 25, true);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
} }