Instead of having platform specific code in nodeGetInfo to fetch CPU topology, split it all out into a new method nodeGetCPUInfo. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/nodeinfo.c | 172 +++++++++++++++++++++++++++++---------------------- src/nodeinfopriv.h | 7 ++- tests/nodeinfotest.c | 5 +- 3 files changed, 108 insertions(+), 76 deletions(-) diff --git a/src/nodeinfo.c b/src/nodeinfo.c index bc5400f..e6a9d3d 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -608,14 +608,19 @@ nodeHasValidSubcoreConfiguration(int threads_per_subcore) int linuxNodeInfoCPUPopulate(FILE *cpuinfo, virArch arch, - virNodeInfoPtr nodeinfo) + unsigned int *cpus, + unsigned int *mhz, + unsigned int *nodes, + unsigned int *sockets, + unsigned int *cores, + unsigned int *threads) { virBitmapPtr present_cpus_map = NULL; virBitmapPtr online_cpus_map = NULL; char line[1024]; DIR *nodedir = NULL; struct dirent *nodedirent = NULL; - int cpus, cores, socks, threads, offline = 0; + int nodecpus, nodecores, nodesockets, nodethreads, offline = 0; int threads_per_subcore = 0; unsigned int node; int ret = -1; @@ -623,6 +628,9 @@ linuxNodeInfoCPUPopulate(FILE *cpuinfo, char *sysfs_cpudir = NULL; int direrr; + *mhz = 0; + *cpus = *nodes = *sockets = *cores = *threads = 0; + /* Start with parsing CPU clock speed from /proc/cpuinfo */ while (fgets(line, sizeof(line), cpuinfo) != NULL) { if (ARCH_IS_X86(arch)) { @@ -644,9 +652,8 @@ linuxNodeInfoCPUPopulate(FILE *cpuinfo, if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 && /* Accept trailing fractional part. */ (*p == '\0' || *p == '.' || c_isspace(*p))) - nodeinfo->mhz = ui; + *mhz = ui; } - } else if (ARCH_IS_PPC(arch)) { char *buf = line; if (STRPREFIX(buf, "clock")) { @@ -666,7 +673,7 @@ linuxNodeInfoCPUPopulate(FILE *cpuinfo, if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 && /* Accept trailing fractional part. */ (*p == '\0' || *p == '.' || c_isspace(*p))) - nodeinfo->mhz = ui; + *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 @@ -692,12 +699,12 @@ linuxNodeInfoCPUPopulate(FILE *cpuinfo, if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 /* Accept trailing fractional part. */ && (*p == '\0' || *p == '.' || c_isspace(*p))) - nodeinfo->mhz = ui; + *mhz = ui; } } else if (ARCH_IS_S390(arch)) { /* s390x has no realistic value for CPU speed, * assign a value of zero to signify this */ - nodeinfo->mhz = 0; + *mhz = 0; } else { VIR_WARN("Parser for /proc/cpuinfo needs to be adapted for your architecture"); break; @@ -758,38 +765,38 @@ linuxNodeInfoCPUPopulate(FILE *cpuinfo, if (sscanf(nodedirent->d_name, "node%u", &node) != 1) continue; - nodeinfo->nodes++; + (*nodes)++; if (virAsprintf(&sysfs_cpudir, "%s/node/%s", sysfs_system_path, nodedirent->d_name) < 0) goto cleanup; - if ((cpus = virNodeParseNode(sysfs_cpudir, arch, - present_cpus_map, - online_cpus_map, - threads_per_subcore, - &socks, &cores, - &threads, &offline)) < 0) + if ((nodecpus = virNodeParseNode(sysfs_cpudir, arch, + present_cpus_map, + online_cpus_map, + threads_per_subcore, + &nodesockets, &nodecores, + &nodethreads, &offline)) < 0) goto cleanup; VIR_FREE(sysfs_cpudir); - nodeinfo->cpus += cpus; + *cpus += nodecpus; - if (socks > nodeinfo->sockets) - nodeinfo->sockets = socks; + if (nodesockets > *sockets) + *sockets = nodesockets; - if (cores > nodeinfo->cores) - nodeinfo->cores = cores; + if (nodecores > *cores) + *cores = nodecores; - if (threads > nodeinfo->threads) - nodeinfo->threads = threads; + if (nodethreads > *threads) + *threads = nodethreads; } if (direrr < 0) goto cleanup; - if (nodeinfo->cpus && nodeinfo->nodes) + if (*cpus && *nodes) goto done; fallback: @@ -798,33 +805,33 @@ linuxNodeInfoCPUPopulate(FILE *cpuinfo, if (virAsprintf(&sysfs_cpudir, "%s/cpu", sysfs_system_path) < 0) goto cleanup; - if ((cpus = virNodeParseNode(sysfs_cpudir, arch, - present_cpus_map, - online_cpus_map, - threads_per_subcore, - &socks, &cores, - &threads, &offline)) < 0) + if ((nodecpus = virNodeParseNode(sysfs_cpudir, arch, + present_cpus_map, + online_cpus_map, + threads_per_subcore, + &nodesockets, &nodecores, + &nodethreads, &offline)) < 0) goto cleanup; - nodeinfo->nodes = 1; - nodeinfo->cpus = cpus; - nodeinfo->sockets = socks; - nodeinfo->cores = cores; - nodeinfo->threads = threads; + *nodes = 1; + *cpus = nodecpus; + *sockets = nodesockets; + *cores = nodecores; + *threads = nodethreads; done: /* There should always be at least one cpu, socket, node, and thread. */ - if (nodeinfo->cpus == 0) { + if (*cpus == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no CPUs found")); goto cleanup; } - if (nodeinfo->sockets == 0) { + if (*sockets == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no sockets found")); goto cleanup; } - if (nodeinfo->threads == 0) { + if (*threads == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no threads found")); goto cleanup; } @@ -836,14 +843,14 @@ linuxNodeInfoCPUPopulate(FILE *cpuinfo, * the nodeinfo structure isn't designed to carry the full topology so * we're going to lie about the detected topology to notify the user * to check the host capabilities for the actual topology. */ - if ((nodeinfo->nodes * - nodeinfo->sockets * - nodeinfo->cores * - nodeinfo->threads) != (nodeinfo->cpus + offline)) { - nodeinfo->nodes = 1; - nodeinfo->sockets = 1; - nodeinfo->cores = nodeinfo->cpus + offline; - nodeinfo->threads = 1; + if ((*nodes * + *sockets * + *cores * + *threads) != (*cpus + offline)) { + *nodes = 1; + *sockets = 1; + *cores = *cpus + offline; + *threads = 1; } ret = 0; @@ -1161,23 +1168,17 @@ virNodeGetSiblingsList(const char *dir, int cpu_id) } #endif -int -nodeGetInfo(virNodeInfoPtr nodeinfo) -{ - virArch hostarch = virArchFromHost(); - unsigned long long memorybytes; - - memset(nodeinfo, 0, sizeof(*nodeinfo)); - - if (virStrcpyStatic(nodeinfo->model, virArchToString(hostarch)) == NULL) - return -1; - - if (nodeGetMemory(&memorybytes, NULL) < 0) - return -1; - nodeinfo->memory = memorybytes / 1024; +static int +nodeGetCPUInfo(virArch hostarch, + unsigned int *cpus, + unsigned int *mhz, + unsigned int *nodes, + unsigned int *sockets, + unsigned int *cores, + unsigned int *threads) +{ #ifdef __linux__ - { int ret = -1; FILE *cpuinfo = fopen(CPUINFO_PATH, "r"); @@ -1187,28 +1188,27 @@ nodeGetInfo(virNodeInfoPtr nodeinfo) return -1; } - ret = linuxNodeInfoCPUPopulate(cpuinfo, hostarch, nodeinfo); + ret = linuxNodeInfoCPUPopulate(cpuinfo, hostarch, + cpus, mhz, nodes, + sockets, cores, threads); if (ret < 0) goto cleanup; cleanup: VIR_FORCE_FCLOSE(cpuinfo); return ret; - } #elif defined(__FreeBSD__) || defined(__APPLE__) - { - nodeinfo->nodes = 1; - nodeinfo->sockets = 1; - nodeinfo->threads = 1; + unsigned long cpu_freq; + size_t cpu_freq_len = sizeof(cpu_freq); - nodeinfo->cpus = appleFreebsdNodeGetCPUCount(); - if (nodeinfo->cpus == -1) + *cpus = appleFreebsdNodeGetCPUCount(); + if (*cpus == -1) return -1; - nodeinfo->cores = nodeinfo->cpus; - - unsigned long cpu_freq; - size_t cpu_freq_len = sizeof(cpu_freq); + *nodes = 1; + *sockets = 1; + *cores = *cpus; + *threads = 1; # ifdef __FreeBSD__ if (sysctlbyname("dev.cpu.0.freq", &cpu_freq, &cpu_freq_len, NULL, 0) < 0) { @@ -1216,18 +1216,17 @@ nodeGetInfo(virNodeInfoPtr nodeinfo) return -1; } - nodeinfo->mhz = cpu_freq; + *mhz = cpu_freq; # else if (sysctlbyname("hw.cpufrequency", &cpu_freq, &cpu_freq_len, NULL, 0) < 0) { virReportSystemError(errno, "%s", _("cannot obtain CPU freq")); return -1; } - nodeinfo->mhz = cpu_freq / 1000000; + *mhz = cpu_freq / 1000000; # endif return 0; - } #else /* XXX Solaris will need an impl later if they port QEMU driver */ virReportError(VIR_ERR_NO_SUPPORT, "%s", @@ -1236,6 +1235,31 @@ nodeGetInfo(virNodeInfoPtr nodeinfo) #endif } + +int +nodeGetInfo(virNodeInfoPtr nodeinfo) +{ + virArch hostarch = virArchFromHost(); + unsigned long long memorybytes; + + memset(nodeinfo, 0, sizeof(*nodeinfo)); + + if (virStrcpyStatic(nodeinfo->model, virArchToString(hostarch)) == NULL) + return -1; + + if (nodeGetMemory(&memorybytes, NULL) < 0) + return -1; + nodeinfo->memory = memorybytes / 1024; + + if (nodeGetCPUInfo(hostarch, + &nodeinfo->cpus, &nodeinfo->mhz, + &nodeinfo->nodes, &nodeinfo->sockets, + &nodeinfo->cores, &nodeinfo->threads) < 0) + return -1; + + return 0; +} + int nodeGetCPUStats(int cpuNum ATTRIBUTE_UNUSED, virNodeCPUStatsPtr params ATTRIBUTE_UNUSED, diff --git a/src/nodeinfopriv.h b/src/nodeinfopriv.h index 4fe489a..01bcb8d 100644 --- a/src/nodeinfopriv.h +++ b/src/nodeinfopriv.h @@ -29,7 +29,12 @@ void linuxNodeInfoSetSysFSSystemPath(const char *path); int linuxNodeInfoCPUPopulate(FILE *cpuinfo, virArch arch, - virNodeInfoPtr nodeinfo); + unsigned int *cpus, + unsigned int *mhz, + unsigned int *nodes, + unsigned int *sockets, + unsigned int *cores, + unsigned int *threads); int linuxNodeGetCPUStats(FILE *procstat, int cpuNum, diff --git a/tests/nodeinfotest.c b/tests/nodeinfotest.c index 8d93024..951ae2f 100644 --- a/tests/nodeinfotest.c +++ b/tests/nodeinfotest.c @@ -41,7 +41,10 @@ linuxTestCompareFiles(const char *cpuinfofile, } memset(&nodeinfo, 0, sizeof(nodeinfo)); - if (linuxNodeInfoCPUPopulate(cpuinfo, arch, &nodeinfo) < 0) { + if (linuxNodeInfoCPUPopulate(cpuinfo, arch, + &nodeinfo.cpus, &nodeinfo.mhz, + &nodeinfo.nodes, &nodeinfo.sockets, + &nodeinfo.cores, &nodeinfo.threads) < 0) { if (virTestGetDebug()) { virErrorPtr error = virSaveLastError(); if (error && error->code != VIR_ERR_OK) -- 2.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list