nodeinfo: support kernels that lack socket information

On RHEL 5, I was getting a segfault trying to start libvirtd,
because we were failing virNodeParseSocket but not checking
for errors, and then calling CPU_SET(-1, &sock_map) as a result.
But if you don't have a topology/physical_package_id file,
then you can just assume that the cpu belongs to socket 0.

* src/nodeinfo.c (virNodeGetCpuValue): Change bool into
default_value.
(virNodeParseSocket): Allow for default value when file is missing,
different from fatal error on reading file.
(virNodeParseNode): Update call sites to fail on error.
(cherry picked from commit 47976b484c)
This commit is contained in:
Eric Blake 2012-11-01 16:20:09 -06:00 committed by Cole Robinson
parent ec48fd7d93
commit ddf4a85db8

View File

@ -79,13 +79,14 @@ static int linuxNodeGetMemoryStats(FILE *meminfo,
int *nparams); int *nparams);
/* Return the positive decimal contents of the given /* Return the positive decimal contents of the given
* DIR/cpu%u/FILE, or -1 on error. If MISSING_OK and the * DIR/cpu%u/FILE, or -1 on error. If DEFAULT_VALUE is non-negative
* file could not be found, return 1 instead of an error; this is * and the file could not be found, return that instead of an error;
* because some machines cannot hot-unplug cpu0, or because * this is useful for machines that cannot hot-unplug cpu0, or where
* hot-unplugging is disabled. */ * hot-unplugging is disabled, or where the kernel is too old
* to support NUMA cells, etc. */
static int static int
virNodeGetCpuValue(const char *dir, unsigned int cpu, const char *file, virNodeGetCpuValue(const char *dir, unsigned int cpu, const char *file,
bool missing_ok) int default_value)
{ {
char *path; char *path;
FILE *pathfp; FILE *pathfp;
@ -100,8 +101,8 @@ virNodeGetCpuValue(const char *dir, unsigned int cpu, const char *file,
pathfp = fopen(path, "r"); pathfp = fopen(path, "r");
if (pathfp == NULL) { if (pathfp == NULL) {
if (missing_ok && errno == ENOENT) if (default_value >= 0 && errno == ENOENT)
value = 1; value = default_value;
else else
virReportSystemError(errno, _("cannot open %s"), path); virReportSystemError(errno, _("cannot open %s"), path);
goto cleanup; goto cleanup;
@ -174,7 +175,7 @@ static int
virNodeParseSocket(const char *dir, unsigned int cpu) virNodeParseSocket(const char *dir, unsigned int cpu)
{ {
int ret = virNodeGetCpuValue(dir, cpu, "topology/physical_package_id", int ret = virNodeGetCpuValue(dir, cpu, "topology/physical_package_id",
false); 0);
# if defined(__powerpc__) || \ # if defined(__powerpc__) || \
defined(__powerpc64__) || \ defined(__powerpc64__) || \
defined(__s390__) || \ defined(__s390__) || \
@ -236,14 +237,15 @@ virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1) if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
continue; continue;
if ((online = virNodeGetCpuValue(node, cpu, "online", true)) < 0) if ((online = virNodeGetCpuValue(node, cpu, "online", 1)) < 0)
goto cleanup; goto cleanup;
if (!online) if (!online)
continue; continue;
/* Parse socket */ /* Parse socket */
sock = virNodeParseSocket(node, cpu); if ((sock = virNodeParseSocket(node, cpu)) < 0)
goto cleanup;
CPU_SET(sock, &sock_map); CPU_SET(sock, &sock_map);
if (sock > sock_max) if (sock > sock_max)
@ -275,7 +277,7 @@ virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1) if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
continue; continue;
if ((online = virNodeGetCpuValue(node, cpu, "online", true)) < 0) if ((online = virNodeGetCpuValue(node, cpu, "online", 1)) < 0)
goto cleanup; goto cleanup;
if (!online) if (!online)
@ -284,7 +286,8 @@ virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
processors++; processors++;
/* Parse socket */ /* Parse socket */
sock = virNodeParseSocket(node, cpu); if ((sock = virNodeParseSocket(node, cpu)) < 0)
goto cleanup;
if (!CPU_ISSET(sock, &sock_map)) { if (!CPU_ISSET(sock, &sock_map)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("CPU socket topology has changed")); _("CPU socket topology has changed"));
@ -297,7 +300,7 @@ virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
/* logical cpu is equivalent to a core on s390 */ /* logical cpu is equivalent to a core on s390 */
core = cpu; core = cpu;
# else # else
core = virNodeGetCpuValue(node, cpu, "topology/core_id", false); core = virNodeGetCpuValue(node, cpu, "topology/core_id", 0);
# endif # endif
CPU_SET(core, &core_maps[sock]); CPU_SET(core, &core_maps[sock]);