mirror of https://gitee.com/openkylin/libvirt.git
nodeinfo: Introduce @arch to linuxNodeInfoCPUPopulate
So far, we are doing compile time decisions on which architecture is used. However, for testing purposes it's much easier if we pass host architecture as parameter and then let the function decide which code snippet for extracting host CPU info will be used. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
0b33d7c921
commit
e808357528
138
src/nodeinfo.c
138
src/nodeinfo.c
|
@ -52,9 +52,12 @@
|
||||||
#include "virtypedparam.h"
|
#include "virtypedparam.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "virnuma.h"
|
#include "virnuma.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
VIR_LOG_INIT("nodeinfo");
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
static int
|
static int
|
||||||
appleFreebsdNodeGetCPUCount(void)
|
appleFreebsdNodeGetCPUCount(void)
|
||||||
|
@ -557,6 +560,7 @@ virNodeParseNode(const char *node,
|
||||||
|
|
||||||
int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
|
int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
|
||||||
const char *sysfs_dir,
|
const char *sysfs_dir,
|
||||||
|
virArch arch,
|
||||||
virNodeInfoPtr nodeinfo)
|
virNodeInfoPtr nodeinfo)
|
||||||
{
|
{
|
||||||
char line[1024];
|
char line[1024];
|
||||||
|
@ -571,86 +575,83 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
|
||||||
|
|
||||||
/* Start with parsing CPU clock speed from /proc/cpuinfo */
|
/* Start with parsing CPU clock speed from /proc/cpuinfo */
|
||||||
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
|
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
|
||||||
# if defined(__x86_64__) || \
|
if (ARCH_IS_X86(arch)) {
|
||||||
defined(__amd64__) || \
|
char *buf = line;
|
||||||
defined(__i386__)
|
if (STRPREFIX(buf, "cpu MHz")) {
|
||||||
char *buf = line;
|
char *p;
|
||||||
if (STRPREFIX(buf, "cpu MHz")) {
|
unsigned int ui;
|
||||||
char *p;
|
|
||||||
unsigned int ui;
|
|
||||||
|
|
||||||
buf += 7;
|
buf += 7;
|
||||||
while (*buf && c_isspace(*buf))
|
while (*buf && c_isspace(*buf))
|
||||||
buf++;
|
buf++;
|
||||||
|
|
||||||
if (*buf != ':' || !buf[1]) {
|
if (*buf != ':' || !buf[1]) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("parsing cpu MHz from cpuinfo"));
|
_("parsing cpu MHz from cpuinfo"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 &&
|
||||||
|
/* Accept trailing fractional part. */
|
||||||
|
(*p == '\0' || *p == '.' || c_isspace(*p)))
|
||||||
|
nodeinfo->mhz = ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 &&
|
} else if (ARCH_IS_PPC(arch)) {
|
||||||
/* Accept trailing fractional part. */
|
char *buf = line;
|
||||||
(*p == '\0' || *p == '.' || c_isspace(*p)))
|
if (STRPREFIX(buf, "clock")) {
|
||||||
nodeinfo->mhz = ui;
|
char *p;
|
||||||
}
|
unsigned int ui;
|
||||||
|
|
||||||
# elif defined(__powerpc__) || \
|
buf += 5;
|
||||||
defined(__powerpc64__)
|
while (*buf && c_isspace(*buf))
|
||||||
char *buf = line;
|
buf++;
|
||||||
if (STRPREFIX(buf, "clock")) {
|
|
||||||
char *p;
|
|
||||||
unsigned int ui;
|
|
||||||
|
|
||||||
buf += 5;
|
if (*buf != ':' || !buf[1]) {
|
||||||
while (*buf && c_isspace(*buf))
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
buf++;
|
_("parsing cpu MHz from cpuinfo"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buf != ':' || !buf[1]) {
|
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 &&
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
/* Accept trailing fractional part. */
|
||||||
_("parsing cpu MHz from cpuinfo"));
|
(*p == '\0' || *p == '.' || c_isspace(*p)))
|
||||||
goto cleanup;
|
nodeinfo->mhz = ui;
|
||||||
|
/* No other interesting infos are available in /proc/cpuinfo.
|
||||||
|
* However, there is a line identifying processor's version,
|
||||||
|
* identification and machine, but we don't want it to be caught
|
||||||
|
* and parsed in next iteration, because it is not in expected
|
||||||
|
* format and thus lead to error. */
|
||||||
}
|
}
|
||||||
|
} else if (ARCH_IS_ARM(arch)) {
|
||||||
|
char *buf = line;
|
||||||
|
if (STRPREFIX(buf, "BogoMIPS")) {
|
||||||
|
char *p;
|
||||||
|
unsigned int ui;
|
||||||
|
|
||||||
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 &&
|
buf += 8;
|
||||||
/* Accept trailing fractional part. */
|
while (*buf && c_isspace(*buf))
|
||||||
(*p == '\0' || *p == '.' || c_isspace(*p)))
|
buf++;
|
||||||
nodeinfo->mhz = ui;
|
|
||||||
/* No other interesting infos are available in /proc/cpuinfo.
|
|
||||||
* However, there is a line identifying processor's version,
|
|
||||||
* identification and machine, but we don't want it to be caught
|
|
||||||
* and parsed in next iteration, because it is not in expected
|
|
||||||
* format and thus lead to error. */
|
|
||||||
}
|
|
||||||
# elif defined(__arm__) || defined(__aarch64__)
|
|
||||||
char *buf = line;
|
|
||||||
if (STRPREFIX(buf, "BogoMIPS")) {
|
|
||||||
char *p;
|
|
||||||
unsigned int ui;
|
|
||||||
|
|
||||||
buf += 8;
|
if (*buf != ':' || !buf[1]) {
|
||||||
while (*buf && c_isspace(*buf))
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
buf++;
|
"%s", _("parsing cpu MHz from cpuinfo"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buf != ':' || !buf[1]) {
|
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
/* Accept trailing fractional part. */
|
||||||
"%s", _("parsing cpu MHz from cpuinfo"));
|
&& (*p == '\0' || *p == '.' || c_isspace(*p)))
|
||||||
goto cleanup;
|
nodeinfo->mhz = ui;
|
||||||
}
|
}
|
||||||
|
} else if (ARCH_IS_S390(arch)) {
|
||||||
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0
|
/* s390x has no realistic value for CPU speed,
|
||||||
/* Accept trailing fractional part. */
|
* assign a value of zero to signify this */
|
||||||
&& (*p == '\0' || *p == '.' || c_isspace(*p)))
|
nodeinfo->mhz = 0;
|
||||||
nodeinfo->mhz = ui;
|
} else {
|
||||||
|
VIR_WARN("Parser for /proc/cpuinfo needs to be adapted for your architecture");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
# elif defined(__s390__) || \
|
|
||||||
defined(__s390x__)
|
|
||||||
/* s390x has no realistic value for CPU speed,
|
|
||||||
* assign a value of zero to signify this */
|
|
||||||
nodeinfo->mhz = 0;
|
|
||||||
# else
|
|
||||||
# warning Parser for /proc/cpuinfo needs to be adapted for your architecture
|
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK, we've parsed clock speed out of /proc/cpuinfo. Get the
|
/* OK, we've parsed clock speed out of /proc/cpuinfo. Get the
|
||||||
|
@ -1057,7 +1058,8 @@ int nodeGetInfo(virNodeInfoPtr nodeinfo)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = linuxNodeInfoCPUPopulate(cpuinfo, SYSFS_SYSTEM_PATH, nodeinfo);
|
ret = linuxNodeInfoCPUPopulate(cpuinfo, SYSFS_SYSTEM_PATH,
|
||||||
|
hostarch, nodeinfo);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
# ifdef __linux__
|
# ifdef __linux__
|
||||||
int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
|
int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
|
||||||
const char *sysfs_dir,
|
const char *sysfs_dir,
|
||||||
|
virArch arch,
|
||||||
virNodeInfoPtr nodeinfo);
|
virNodeInfoPtr nodeinfo);
|
||||||
|
|
||||||
int linuxNodeGetCPUStats(FILE *procstat,
|
int linuxNodeGetCPUStats(FILE *procstat,
|
||||||
|
|
|
@ -73,6 +73,20 @@ typedef enum {
|
||||||
# define ARCH_IS_X86(arch) ((arch) == VIR_ARCH_X86_64 ||\
|
# define ARCH_IS_X86(arch) ((arch) == VIR_ARCH_X86_64 ||\
|
||||||
(arch) == VIR_ARCH_I686)
|
(arch) == VIR_ARCH_I686)
|
||||||
|
|
||||||
|
# define ARCH_IS_PPC(arch) ((arch) == VIR_ARCH_PPC ||\
|
||||||
|
(arch) == VIR_ARCH_PPCLE ||\
|
||||||
|
(arch) == VIR_ARCH_PPC64 ||\
|
||||||
|
(arch) == VIR_ARCH_PPC64LE ||\
|
||||||
|
(arch) == VIR_ARCH_PPCEMB)
|
||||||
|
|
||||||
|
# define ARCH_IS_ARM(arch) ((arch) == VIR_ARCH_ARMV6L ||\
|
||||||
|
(arch) == VIR_ARCH_ARMV7L ||\
|
||||||
|
(arch) == VIR_ARCH_ARMV7B ||\
|
||||||
|
(arch) == VIR_ARCH_AARCH64)
|
||||||
|
|
||||||
|
# define ARCH_IS_S390(arch) ((arch) == VIR_ARCH_S390 ||\
|
||||||
|
(arch) == VIR_ARCH_S390X)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_ARCH_LITTLE_ENDIAN,
|
VIR_ARCH_LITTLE_ENDIAN,
|
||||||
VIR_ARCH_BIG_ENDIAN,
|
VIR_ARCH_BIG_ENDIAN,
|
||||||
|
|
|
@ -13,11 +13,7 @@
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
#if ! (defined __linux__ && (defined(__x86_64__) || \
|
#if !(defined __linux__)
|
||||||
defined(__amd64__) || \
|
|
||||||
defined(__i386__) || \
|
|
||||||
defined(__powerpc__) || \
|
|
||||||
defined(__powerpc64__)))
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
|
@ -30,6 +26,7 @@ main(void)
|
||||||
static int
|
static int
|
||||||
linuxTestCompareFiles(const char *cpuinfofile,
|
linuxTestCompareFiles(const char *cpuinfofile,
|
||||||
char *sysfs_dir,
|
char *sysfs_dir,
|
||||||
|
virArch arch,
|
||||||
const char *outputfile)
|
const char *outputfile)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
@ -46,7 +43,7 @@ linuxTestCompareFiles(const char *cpuinfofile,
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
memset(&nodeinfo, 0, sizeof(nodeinfo));
|
memset(&nodeinfo, 0, sizeof(nodeinfo));
|
||||||
if (linuxNodeInfoCPUPopulate(cpuinfo, sysfs_dir, &nodeinfo) < 0) {
|
if (linuxNodeInfoCPUPopulate(cpuinfo, sysfs_dir, arch, &nodeinfo) < 0) {
|
||||||
if (virTestGetDebug()) {
|
if (virTestGetDebug()) {
|
||||||
virErrorPtr error = virSaveLastError();
|
virErrorPtr error = virSaveLastError();
|
||||||
if (error && error->code != VIR_ERR_OK)
|
if (error && error->code != VIR_ERR_OK)
|
||||||
|
@ -167,31 +164,31 @@ linuxCPUStatsCompareFiles(const char *cpustatfile,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct linuxTestNodeInfoData {
|
||||||
|
const char *testName;
|
||||||
|
virArch arch;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
linuxTestNodeInfo(const void *data)
|
linuxTestNodeInfo(const void *opaque)
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
char *cpuinfo = NULL;
|
char *cpuinfo = NULL;
|
||||||
char *sysfs_dir = NULL;
|
char *sysfs_dir = NULL;
|
||||||
char *output = NULL;
|
char *output = NULL;
|
||||||
const char *test = data;
|
struct linuxTestNodeInfoData *data = (struct linuxTestNodeInfoData *) opaque;
|
||||||
const char *arch = "x86";
|
const char *archStr = virArchToString(data->arch);
|
||||||
|
|
||||||
# if defined(__powerpc__) || \
|
|
||||||
defined(__powerpc64__)
|
|
||||||
arch = "ppc";
|
|
||||||
# endif
|
|
||||||
|
|
||||||
if (virAsprintf(&sysfs_dir, "%s/nodeinfodata/linux-%s",
|
if (virAsprintf(&sysfs_dir, "%s/nodeinfodata/linux-%s",
|
||||||
abs_srcdir, test) < 0 ||
|
abs_srcdir, data->testName) < 0 ||
|
||||||
virAsprintf(&cpuinfo, "%s/nodeinfodata/linux-%s-%s.cpuinfo",
|
virAsprintf(&cpuinfo, "%s/nodeinfodata/linux-%s-%s.cpuinfo",
|
||||||
abs_srcdir, arch, test) < 0 ||
|
abs_srcdir, archStr, data->testName) < 0 ||
|
||||||
virAsprintf(&output, "%s/nodeinfodata/linux-%s-%s.expected",
|
virAsprintf(&output, "%s/nodeinfodata/linux-%s-%s.expected",
|
||||||
abs_srcdir, arch, test) < 0) {
|
abs_srcdir, archStr, data->testName) < 0) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = linuxTestCompareFiles(cpuinfo, sysfs_dir, output);
|
result = linuxTestCompareFiles(cpuinfo, sysfs_dir, data->arch, output);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(cpuinfo);
|
VIR_FREE(cpuinfo);
|
||||||
|
@ -235,25 +232,23 @@ mymain(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
const char *nodeData[] = {
|
const struct linuxTestNodeInfoData nodeData[] = {
|
||||||
"test1",
|
{"test1", VIR_ARCH_X86_64},
|
||||||
# if !(defined(__powerpc__) || \
|
{"test1", VIR_ARCH_PPC},
|
||||||
defined(__powerpc64__))
|
{"test2", VIR_ARCH_X86_64},
|
||||||
"test2",
|
{"test3", VIR_ARCH_X86_64},
|
||||||
"test3",
|
{"test4", VIR_ARCH_X86_64},
|
||||||
"test4",
|
{"test5", VIR_ARCH_X86_64},
|
||||||
"test5",
|
{"test6", VIR_ARCH_X86_64},
|
||||||
"test6",
|
{"test7", VIR_ARCH_X86_64},
|
||||||
"test7",
|
{"test8", VIR_ARCH_X86_64},
|
||||||
"test8",
|
|
||||||
# endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (virInitialize() < 0)
|
if (virInitialize() < 0)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_CARDINALITY(nodeData); i++)
|
for (i = 0; i < ARRAY_CARDINALITY(nodeData); i++)
|
||||||
if (virtTestRun(nodeData[i], linuxTestNodeInfo, nodeData[i]) != 0)
|
if (virtTestRun(nodeData[i].testName, linuxTestNodeInfo, &nodeData[i]) != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
# define DO_TEST_CPU_STATS(name, ncpus) \
|
# define DO_TEST_CPU_STATS(name, ncpus) \
|
||||||
|
|
Loading…
Reference in New Issue