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. --- src/nodeinfo.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 4589b77..d5f2c00 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -79,13 +79,14 @@ static int linuxNodeGetMemoryStats(FILE *meminfo, int *nparams); /* Return the positive decimal contents of the given - * DIR/cpu%u/FILE, or -1 on error. If MISSING_OK and the - * file could not be found, return 1 instead of an error; this is - * because some machines cannot hot-unplug cpu0, or because - * hot-unplugging is disabled. */ + * DIR/cpu%u/FILE, or -1 on error. If DEFAULT_VALUE is non-negative + * and the file could not be found, return that instead of an error; + * this is useful for machines that cannot hot-unplug cpu0, or where + * hot-unplugging is disabled, or where the kernel is too old + * to support NUMA cells, etc. */ static int virNodeGetCpuValue(const char *dir, unsigned int cpu, const char *file, - bool missing_ok) + int default_value) { char *path; FILE *pathfp; @@ -100,8 +101,8 @@ virNodeGetCpuValue(const char *dir, unsigned int cpu, const char *file, pathfp = fopen(path, "r"); if (pathfp == NULL) { - if (missing_ok && errno == ENOENT) - value = 1; + if (default_value >= 0 && errno == ENOENT) + value = default_value; else virReportSystemError(errno, _("cannot open %s"), path); goto cleanup; @@ -174,7 +175,7 @@ static int virNodeParseSocket(const char *dir, unsigned int cpu) { int ret = virNodeGetCpuValue(dir, cpu, "topology/physical_package_id", - false); + 0); # if defined(__powerpc__) || \ defined(__powerpc64__) || \ defined(__s390__) || \ @@ -241,14 +242,15 @@ virNodeParseNode(const char *node, if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1) continue; - if ((online = virNodeGetCpuValue(node, cpu, "online", true)) < 0) + if ((online = virNodeGetCpuValue(node, cpu, "online", 1)) < 0) goto cleanup; if (!online) continue; /* Parse socket */ - sock = virNodeParseSocket(node, cpu); + if ((sock = virNodeParseSocket(node, cpu)) < 0) + goto cleanup; CPU_SET(sock, &sock_map); if (sock > sock_max) @@ -280,7 +282,7 @@ virNodeParseNode(const char *node, if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1) continue; - if ((online = virNodeGetCpuValue(node, cpu, "online", true)) < 0) + if ((online = virNodeGetCpuValue(node, cpu, "online", 1)) < 0) goto cleanup; if (!online) { @@ -291,7 +293,8 @@ virNodeParseNode(const char *node, processors++; /* Parse socket */ - sock = virNodeParseSocket(node, cpu); + if ((sock = virNodeParseSocket(node, cpu)) < 0) + goto cleanup; if (!CPU_ISSET(sock, &sock_map)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("CPU socket topology has changed")); @@ -304,7 +307,7 @@ virNodeParseNode(const char *node, /* logical cpu is equivalent to a core on s390 */ core = cpu; # else - core = virNodeGetCpuValue(node, cpu, "topology/core_id", false); + core = virNodeGetCpuValue(node, cpu, "topology/core_id", 0); # endif CPU_SET(core, &core_maps[sock]); -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list