mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-30 17:45:23 +00:00
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:
parent
ec48fd7d93
commit
ddf4a85db8
@ -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]);
|
||||||
|
Loading…
Reference in New Issue
Block a user