2007-07-25 23:16:30 +00:00
|
|
|
/*
|
|
|
|
* nodeinfo.c: Helper routines for OS specific node information
|
|
|
|
*
|
2010-03-01 23:38:28 +00:00
|
|
|
* Copyright (C) 2006, 2007, 2008, 2010 Red Hat, Inc.
|
2007-07-25 23:16:30 +00:00
|
|
|
* Copyright (C) 2006 Daniel P. Berrange
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-12-05 21:40:15 +00:00
|
|
|
|
2007-07-25 23:16:30 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
#include <stdint.h>
|
2007-07-25 23:16:30 +00:00
|
|
|
#include <errno.h>
|
2010-03-04 22:28:40 +00:00
|
|
|
#include <dirent.h>
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
|
|
|
|
#if HAVE_NUMACTL
|
|
|
|
# define NUMA_VERSION1_COMPATIBILITY 1
|
|
|
|
# include <numa.h>
|
|
|
|
#endif
|
2007-07-25 23:16:30 +00:00
|
|
|
|
2007-12-07 14:45:39 +00:00
|
|
|
#ifdef HAVE_SYS_UTSNAME_H
|
2010-03-09 18:22:22 +00:00
|
|
|
# include <sys/utsname.h>
|
2007-12-07 14:45:39 +00:00
|
|
|
#endif
|
|
|
|
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
#include "c-ctype.h"
|
|
|
|
#include "memory.h"
|
2007-07-25 23:16:30 +00:00
|
|
|
#include "nodeinfo.h"
|
Use gnulib, starting with its physmem and getaddrinfo modules.
New files go into these directories:
gnulib/lib
gnulib/m4
gnulib/tests
* bootstrap: A wrapper around gnulib-tool.
* configure.in: Invoke gl_EARLY and gl_INIT, being careful to put gl_EARLY
before any macro that uses AC_COMPILE_IFELSE.
(AC_OUTPUT): Add lib/Makefile and gl-tests/Makefile. Remove m4/Makefile.
* Makefile.am (SUBDIRS): Add gnulib/lib and remove m4. Add gnulib/tests
early enough that those tests run before any libvirt unit tests.
* m4/Makefile.am: Remove file. Not needed.
* src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS, libvirt_la_LIBADD): Add ../gnulib/lib/libgnu.la.
* src/nodeinfo.c: Include "physmem.h".
* qemud/qemud.c, src/remote_internal.c: Include "getaddrinfo.h".
(MEMINFO_PATH, linuxNodeInfoMemPopulate): Remove definitions.
(virNodeInfoPopulate): Use physmem_total, not linuxNodeInfoMemPopulate.
* tests/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS): Add ../gnulib/lib/libgnu.la.
* qemud/Makefile.am (libvirtd_LDADD): Add ../gnulib/lib/libgnu.la.
* tests/nodeinfotest.c (linuxTestCompareFiles): No longer read total
memory from a file.
Update expected output not to include "Memory: NNNN"
* tests/nodeinfodata/linux-nodeinfo-1.txt:
* tests/nodeinfodata/linux-nodeinfo-2.txt:
* tests/nodeinfodata/linux-nodeinfo-3.txt:
* tests/nodeinfodata/linux-nodeinfo-4.txt:
* tests/nodeinfodata/linux-nodeinfo-5.txt:
* tests/nodeinfodata/linux-nodeinfo-6.txt:
* src/test.c [WITH_TEST]: Remove definition of _GNU_SOURCE that
would conflict with the one now in "config.h".
* autogen.sh: Add -I gnulib/m4.
* src/conf.c, src/sexpr.c: Don't define _GNU_SOURCE.
Instead, include "config.h".
* qemud/qemud.c: Remove definition of _GNU_SOURCE.
* src/openvz_driver.c: Likewise.
* src/qemu_driver.c: Likewise.
* src/remote_internal.c: Likewise.
* configure.in: Use AC_CONFIG_AUX_DIR(build-aux), so that a bunch
of gettextize-generated files go into build-aux/, rather than in
the top-level directory.
* .cvsignore: Adjust.
* build-aux/.cvsignore: New file.
Author: Jim Meyering <meyering@redhat.com>
2007-12-05 21:31:07 +00:00
|
|
|
#include "physmem.h"
|
2008-02-08 09:15:16 +00:00
|
|
|
#include "util.h"
|
2009-06-26 20:08:07 +00:00
|
|
|
#include "logging.h"
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
#include "virterror_internal.h"
|
2010-03-04 22:28:40 +00:00
|
|
|
#include "count-one-bits.h"
|
2007-07-25 23:16:30 +00:00
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
2010-03-01 23:38:28 +00:00
|
|
|
#define nodeReportError(conn, code, ...) \
|
2009-06-03 13:28:02 +00:00
|
|
|
virReportErrorHelper(conn, VIR_FROM_NONE, code, __FILE__, \
|
2010-03-01 23:38:28 +00:00
|
|
|
__FUNCTION__, __LINE__, __VA_ARGS__)
|
2009-06-03 13:28:02 +00:00
|
|
|
|
2007-07-25 23:16:30 +00:00
|
|
|
#ifdef __linux__
|
2010-03-09 18:22:22 +00:00
|
|
|
# define CPUINFO_PATH "/proc/cpuinfo"
|
|
|
|
# define CPU_SYS_PATH "/sys/devices/system/cpu"
|
2007-07-25 23:16:30 +00:00
|
|
|
|
2010-03-04 22:28:40 +00:00
|
|
|
/* NB, this is not static as we need to call it from the testsuite */
|
Use gnulib, starting with its physmem and getaddrinfo modules.
New files go into these directories:
gnulib/lib
gnulib/m4
gnulib/tests
* bootstrap: A wrapper around gnulib-tool.
* configure.in: Invoke gl_EARLY and gl_INIT, being careful to put gl_EARLY
before any macro that uses AC_COMPILE_IFELSE.
(AC_OUTPUT): Add lib/Makefile and gl-tests/Makefile. Remove m4/Makefile.
* Makefile.am (SUBDIRS): Add gnulib/lib and remove m4. Add gnulib/tests
early enough that those tests run before any libvirt unit tests.
* m4/Makefile.am: Remove file. Not needed.
* src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS, libvirt_la_LIBADD): Add ../gnulib/lib/libgnu.la.
* src/nodeinfo.c: Include "physmem.h".
* qemud/qemud.c, src/remote_internal.c: Include "getaddrinfo.h".
(MEMINFO_PATH, linuxNodeInfoMemPopulate): Remove definitions.
(virNodeInfoPopulate): Use physmem_total, not linuxNodeInfoMemPopulate.
* tests/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS): Add ../gnulib/lib/libgnu.la.
* qemud/Makefile.am (libvirtd_LDADD): Add ../gnulib/lib/libgnu.la.
* tests/nodeinfotest.c (linuxTestCompareFiles): No longer read total
memory from a file.
Update expected output not to include "Memory: NNNN"
* tests/nodeinfodata/linux-nodeinfo-1.txt:
* tests/nodeinfodata/linux-nodeinfo-2.txt:
* tests/nodeinfodata/linux-nodeinfo-3.txt:
* tests/nodeinfodata/linux-nodeinfo-4.txt:
* tests/nodeinfodata/linux-nodeinfo-5.txt:
* tests/nodeinfodata/linux-nodeinfo-6.txt:
* src/test.c [WITH_TEST]: Remove definition of _GNU_SOURCE that
would conflict with the one now in "config.h".
* autogen.sh: Add -I gnulib/m4.
* src/conf.c, src/sexpr.c: Don't define _GNU_SOURCE.
Instead, include "config.h".
* qemud/qemud.c: Remove definition of _GNU_SOURCE.
* src/openvz_driver.c: Likewise.
* src/qemu_driver.c: Likewise.
* src/remote_internal.c: Likewise.
* configure.in: Use AC_CONFIG_AUX_DIR(build-aux), so that a bunch
of gettextize-generated files go into build-aux/, rather than in
the top-level directory.
* .cvsignore: Adjust.
* build-aux/.cvsignore: New file.
Author: Jim Meyering <meyering@redhat.com>
2007-12-05 21:31:07 +00:00
|
|
|
int linuxNodeInfoCPUPopulate(virConnectPtr conn, FILE *cpuinfo,
|
|
|
|
virNodeInfoPtr nodeinfo);
|
2007-07-25 23:16:30 +00:00
|
|
|
|
2010-03-09 15:17:59 +00:00
|
|
|
static unsigned long count_thread_siblings(unsigned int cpu)
|
2010-03-04 22:28:40 +00:00
|
|
|
{
|
|
|
|
unsigned long ret = 0;
|
2010-03-09 15:17:59 +00:00
|
|
|
char *path;
|
|
|
|
FILE *pathfp;
|
2010-03-04 22:28:40 +00:00
|
|
|
char str[1024];
|
|
|
|
int i;
|
|
|
|
|
2010-03-09 15:17:59 +00:00
|
|
|
if (virAsprintf(&path, CPU_SYS_PATH "/cpu%u/topology/thread_siblings",
|
2010-03-04 22:28:40 +00:00
|
|
|
cpu) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
pathfp = fopen(path, "r");
|
|
|
|
if (pathfp == NULL) {
|
|
|
|
virReportSystemError(errno, _("cannot open %s"), path);
|
|
|
|
VIR_FREE(path);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fgets(str, sizeof(str), pathfp) == NULL) {
|
|
|
|
virReportSystemError(errno, _("cannot read from %s"), path);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (str[i] != '\0') {
|
2010-03-09 15:17:59 +00:00
|
|
|
if (c_isdigit(str[i]))
|
2010-03-04 22:28:40 +00:00
|
|
|
ret += count_one_bits(str[i] - '0');
|
2010-03-09 15:17:59 +00:00
|
|
|
else if (str[i] >= 'A' && str[i] <= 'F')
|
|
|
|
ret += count_one_bits(str[i] - 'A' + 10);
|
|
|
|
else if (str[i] >= 'a' && str[i] <= 'f')
|
|
|
|
ret += count_one_bits(str[i] - 'a' + 10);
|
2010-03-04 22:28:40 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
fclose(pathfp);
|
|
|
|
VIR_FREE(path);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-03-09 15:17:59 +00:00
|
|
|
static int parse_socket(unsigned int cpu)
|
2010-03-04 22:28:40 +00:00
|
|
|
{
|
2010-03-09 15:17:59 +00:00
|
|
|
char *path;
|
2010-03-04 22:28:40 +00:00
|
|
|
FILE *pathfp;
|
|
|
|
char socket_str[1024];
|
|
|
|
char *tmp;
|
2010-03-09 15:17:59 +00:00
|
|
|
int socket = -1;
|
2010-03-04 22:28:40 +00:00
|
|
|
|
2010-03-09 15:17:59 +00:00
|
|
|
if (virAsprintf(&path, CPU_SYS_PATH "/cpu%u/topology/physical_package_id",
|
|
|
|
cpu) < 0) {
|
2010-03-04 22:28:40 +00:00
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pathfp = fopen(path, "r");
|
|
|
|
if (pathfp == NULL) {
|
|
|
|
virReportSystemError(errno, _("cannot open %s"), path);
|
2010-03-09 15:17:59 +00:00
|
|
|
VIR_FREE(path);
|
|
|
|
return -1;
|
2010-03-04 22:28:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fgets(socket_str, sizeof(socket_str), pathfp) == NULL) {
|
|
|
|
virReportSystemError(errno, _("cannot read from %s"), path);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (virStrToLong_i(socket_str, &tmp, 10, &socket) < 0) {
|
|
|
|
nodeReportError(NULL, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not convert '%s' to an integer"),
|
|
|
|
socket_str);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
fclose(pathfp);
|
|
|
|
VIR_FREE(path);
|
|
|
|
|
|
|
|
return socket;
|
|
|
|
}
|
|
|
|
|
|
|
|
int linuxNodeInfoCPUPopulate(virConnectPtr conn, FILE *cpuinfo,
|
|
|
|
virNodeInfoPtr nodeinfo)
|
|
|
|
{
|
2007-07-25 23:16:30 +00:00
|
|
|
char line[1024];
|
2010-03-04 22:28:40 +00:00
|
|
|
DIR *cpudir = NULL;
|
|
|
|
struct dirent *cpudirent = NULL;
|
2010-03-09 15:17:59 +00:00
|
|
|
unsigned int cpu;
|
2010-03-04 22:28:40 +00:00
|
|
|
unsigned long cur_threads;
|
|
|
|
int socket;
|
|
|
|
unsigned long long socket_mask = 0;
|
2007-07-25 23:16:30 +00:00
|
|
|
|
|
|
|
nodeinfo->cpus = 0;
|
|
|
|
nodeinfo->mhz = 0;
|
2010-03-11 20:45:11 +00:00
|
|
|
nodeinfo->cores = 1;
|
2010-03-12 15:41:49 +00:00
|
|
|
|
|
|
|
nodeinfo->nodes = 1;
|
2010-03-15 13:14:06 +00:00
|
|
|
# if HAVE_NUMACTL
|
2010-03-12 15:41:49 +00:00
|
|
|
if (numa_available() >= 0)
|
2010-03-11 20:45:11 +00:00
|
|
|
nodeinfo->nodes = numa_max_node() + 1;
|
2010-03-15 13:14:06 +00:00
|
|
|
# endif
|
2007-07-25 23:16:30 +00:00
|
|
|
|
|
|
|
/* NB: It is impossible to fill our nodes, since cpuinfo
|
2010-03-09 15:17:59 +00:00
|
|
|
* has no knowledge of NUMA nodes */
|
2007-07-25 23:16:30 +00:00
|
|
|
|
2010-03-04 22:28:40 +00:00
|
|
|
/* NOTE: hyperthreads are ignored here; they are parsed out of /sys */
|
2007-07-25 23:16:30 +00:00
|
|
|
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
|
|
|
|
char *buf = line;
|
2008-05-15 14:21:34 +00:00
|
|
|
if (STRPREFIX(buf, "processor")) { /* aka a single logical CPU */
|
2007-07-25 23:16:30 +00:00
|
|
|
buf += 9;
|
2008-05-09 13:50:14 +00:00
|
|
|
while (*buf && c_isspace(*buf))
|
2007-07-25 23:16:30 +00:00
|
|
|
buf++;
|
|
|
|
if (*buf != ':') {
|
2009-06-03 13:28:02 +00:00
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("parsing cpuinfo processor"));
|
2007-07-25 23:16:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
nodeinfo->cpus++;
|
2008-05-15 14:21:34 +00:00
|
|
|
} else if (STRPREFIX(buf, "cpu MHz")) {
|
2007-11-14 10:53:05 +00:00
|
|
|
char *p;
|
|
|
|
unsigned int ui;
|
2007-07-25 23:16:30 +00:00
|
|
|
buf += 9;
|
2008-05-09 13:50:14 +00:00
|
|
|
while (*buf && c_isspace(*buf))
|
2007-07-25 23:16:30 +00:00
|
|
|
buf++;
|
|
|
|
if (*buf != ':' || !buf[1]) {
|
2009-06-03 13:28:02 +00:00
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("parsing cpuinfo cpu MHz"));
|
2007-07-25 23:16:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-02-08 09:15:16 +00:00
|
|
|
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0
|
2007-11-14 10:53:05 +00:00
|
|
|
/* Accept trailing fractional part. */
|
2008-05-09 13:50:14 +00:00
|
|
|
&& (*p == '\0' || *p == '.' || c_isspace(*p)))
|
2007-11-14 10:53:05 +00:00
|
|
|
nodeinfo->mhz = ui;
|
2008-05-15 14:21:34 +00:00
|
|
|
} else if (STRPREFIX(buf, "cpu cores")) { /* aka cores */
|
2007-11-14 10:53:05 +00:00
|
|
|
char *p;
|
2007-07-25 23:16:30 +00:00
|
|
|
unsigned int id;
|
|
|
|
buf += 9;
|
2008-05-09 13:50:14 +00:00
|
|
|
while (*buf && c_isspace(*buf))
|
2007-07-25 23:16:30 +00:00
|
|
|
buf++;
|
|
|
|
if (*buf != ':' || !buf[1]) {
|
2009-06-03 13:28:02 +00:00
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"parsing cpuinfo cpu cores %c", *buf);
|
2007-07-25 23:16:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-02-08 09:15:16 +00:00
|
|
|
if (virStrToLong_ui(buf+1, &p, 10, &id) == 0
|
2008-05-09 13:50:14 +00:00
|
|
|
&& (*p == '\0' || c_isspace(*p))
|
2007-11-14 10:53:05 +00:00
|
|
|
&& id > nodeinfo->cores)
|
2007-07-25 23:16:30 +00:00
|
|
|
nodeinfo->cores = id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nodeinfo->cpus) {
|
2009-06-03 13:28:02 +00:00
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("no cpus found"));
|
2007-07-25 23:16:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-03-04 22:28:40 +00:00
|
|
|
/* OK, we've parsed what we can out of /proc/cpuinfo. Get the socket
|
|
|
|
* and thread information from /sys
|
2007-07-25 23:16:30 +00:00
|
|
|
*/
|
2010-03-04 22:28:40 +00:00
|
|
|
cpudir = opendir(CPU_SYS_PATH);
|
|
|
|
if (cpudir == NULL) {
|
|
|
|
virReportSystemError(errno, _("cannot opendir %s"), CPU_SYS_PATH);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
while ((cpudirent = readdir(cpudir))) {
|
2010-03-09 15:17:59 +00:00
|
|
|
if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
|
2010-03-04 22:28:40 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
socket = parse_socket(cpu);
|
|
|
|
if (socket < 0) {
|
|
|
|
closedir(cpudir);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!(socket_mask & (1 << socket))) {
|
|
|
|
socket_mask |= (1 << socket);
|
|
|
|
nodeinfo->sockets++;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur_threads = count_thread_siblings(cpu);
|
|
|
|
if (cur_threads == 0) {
|
|
|
|
closedir(cpudir);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (cur_threads > nodeinfo->threads)
|
|
|
|
nodeinfo->threads = cur_threads;
|
|
|
|
}
|
|
|
|
|
|
|
|
closedir(cpudir);
|
2007-07-25 23:16:30 +00:00
|
|
|
|
2010-03-09 15:17:59 +00:00
|
|
|
/* there should always be at least one socket and one thread */
|
|
|
|
if (nodeinfo->sockets == 0) {
|
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("no sockets found"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (nodeinfo->threads == 0) {
|
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("no threads found"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-07-25 23:16:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-06-03 13:28:02 +00:00
|
|
|
int nodeGetInfo(virConnectPtr conn,
|
|
|
|
virNodeInfoPtr nodeinfo) {
|
2010-03-09 13:54:01 +00:00
|
|
|
memset(nodeinfo, 0, sizeof(*nodeinfo));
|
|
|
|
|
2007-12-07 14:45:39 +00:00
|
|
|
#ifdef HAVE_UNAME
|
2010-03-09 13:54:01 +00:00
|
|
|
{
|
2007-07-25 23:16:30 +00:00
|
|
|
struct utsname info;
|
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
uname(&info);
|
|
|
|
|
2009-08-03 12:37:44 +00:00
|
|
|
if (virStrcpyStatic(nodeinfo->model, info.machine) == NULL)
|
|
|
|
return -1;
|
2010-03-09 13:54:01 +00:00
|
|
|
}
|
2007-12-07 14:45:39 +00:00
|
|
|
#endif /* !HAVE_UNAME */
|
|
|
|
|
2007-07-25 23:16:30 +00:00
|
|
|
#ifdef __linux__
|
Use gnulib, starting with its physmem and getaddrinfo modules.
New files go into these directories:
gnulib/lib
gnulib/m4
gnulib/tests
* bootstrap: A wrapper around gnulib-tool.
* configure.in: Invoke gl_EARLY and gl_INIT, being careful to put gl_EARLY
before any macro that uses AC_COMPILE_IFELSE.
(AC_OUTPUT): Add lib/Makefile and gl-tests/Makefile. Remove m4/Makefile.
* Makefile.am (SUBDIRS): Add gnulib/lib and remove m4. Add gnulib/tests
early enough that those tests run before any libvirt unit tests.
* m4/Makefile.am: Remove file. Not needed.
* src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS, libvirt_la_LIBADD): Add ../gnulib/lib/libgnu.la.
* src/nodeinfo.c: Include "physmem.h".
* qemud/qemud.c, src/remote_internal.c: Include "getaddrinfo.h".
(MEMINFO_PATH, linuxNodeInfoMemPopulate): Remove definitions.
(virNodeInfoPopulate): Use physmem_total, not linuxNodeInfoMemPopulate.
* tests/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS): Add ../gnulib/lib/libgnu.la.
* qemud/Makefile.am (libvirtd_LDADD): Add ../gnulib/lib/libgnu.la.
* tests/nodeinfotest.c (linuxTestCompareFiles): No longer read total
memory from a file.
Update expected output not to include "Memory: NNNN"
* tests/nodeinfodata/linux-nodeinfo-1.txt:
* tests/nodeinfodata/linux-nodeinfo-2.txt:
* tests/nodeinfodata/linux-nodeinfo-3.txt:
* tests/nodeinfodata/linux-nodeinfo-4.txt:
* tests/nodeinfodata/linux-nodeinfo-5.txt:
* tests/nodeinfodata/linux-nodeinfo-6.txt:
* src/test.c [WITH_TEST]: Remove definition of _GNU_SOURCE that
would conflict with the one now in "config.h".
* autogen.sh: Add -I gnulib/m4.
* src/conf.c, src/sexpr.c: Don't define _GNU_SOURCE.
Instead, include "config.h".
* qemud/qemud.c: Remove definition of _GNU_SOURCE.
* src/openvz_driver.c: Likewise.
* src/qemu_driver.c: Likewise.
* src/remote_internal.c: Likewise.
* configure.in: Use AC_CONFIG_AUX_DIR(build-aux), so that a bunch
of gettextize-generated files go into build-aux/, rather than in
the top-level directory.
* .cvsignore: Adjust.
* build-aux/.cvsignore: New file.
Author: Jim Meyering <meyering@redhat.com>
2007-12-05 21:31:07 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
FILE *cpuinfo = fopen(CPUINFO_PATH, "r");
|
2007-07-25 23:16:30 +00:00
|
|
|
if (!cpuinfo) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("cannot open %s"), CPUINFO_PATH);
|
2007-07-25 23:16:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
ret = linuxNodeInfoCPUPopulate(conn, cpuinfo, nodeinfo);
|
|
|
|
fclose(cpuinfo);
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
Use gnulib, starting with its physmem and getaddrinfo modules.
New files go into these directories:
gnulib/lib
gnulib/m4
gnulib/tests
* bootstrap: A wrapper around gnulib-tool.
* configure.in: Invoke gl_EARLY and gl_INIT, being careful to put gl_EARLY
before any macro that uses AC_COMPILE_IFELSE.
(AC_OUTPUT): Add lib/Makefile and gl-tests/Makefile. Remove m4/Makefile.
* Makefile.am (SUBDIRS): Add gnulib/lib and remove m4. Add gnulib/tests
early enough that those tests run before any libvirt unit tests.
* m4/Makefile.am: Remove file. Not needed.
* src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS, libvirt_la_LIBADD): Add ../gnulib/lib/libgnu.la.
* src/nodeinfo.c: Include "physmem.h".
* qemud/qemud.c, src/remote_internal.c: Include "getaddrinfo.h".
(MEMINFO_PATH, linuxNodeInfoMemPopulate): Remove definitions.
(virNodeInfoPopulate): Use physmem_total, not linuxNodeInfoMemPopulate.
* tests/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS): Add ../gnulib/lib/libgnu.la.
* qemud/Makefile.am (libvirtd_LDADD): Add ../gnulib/lib/libgnu.la.
* tests/nodeinfotest.c (linuxTestCompareFiles): No longer read total
memory from a file.
Update expected output not to include "Memory: NNNN"
* tests/nodeinfodata/linux-nodeinfo-1.txt:
* tests/nodeinfodata/linux-nodeinfo-2.txt:
* tests/nodeinfodata/linux-nodeinfo-3.txt:
* tests/nodeinfodata/linux-nodeinfo-4.txt:
* tests/nodeinfodata/linux-nodeinfo-5.txt:
* tests/nodeinfodata/linux-nodeinfo-6.txt:
* src/test.c [WITH_TEST]: Remove definition of _GNU_SOURCE that
would conflict with the one now in "config.h".
* autogen.sh: Add -I gnulib/m4.
* src/conf.c, src/sexpr.c: Don't define _GNU_SOURCE.
Instead, include "config.h".
* qemud/qemud.c: Remove definition of _GNU_SOURCE.
* src/openvz_driver.c: Likewise.
* src/qemu_driver.c: Likewise.
* src/remote_internal.c: Likewise.
* configure.in: Use AC_CONFIG_AUX_DIR(build-aux), so that a bunch
of gettextize-generated files go into build-aux/, rather than in
the top-level directory.
* .cvsignore: Adjust.
* build-aux/.cvsignore: New file.
Author: Jim Meyering <meyering@redhat.com>
2007-12-05 21:31:07 +00:00
|
|
|
/* Convert to KB. */
|
|
|
|
nodeinfo->memory = physmem_total () / 1024;
|
2007-07-25 23:16:30 +00:00
|
|
|
|
|
|
|
return ret;
|
Use gnulib, starting with its physmem and getaddrinfo modules.
New files go into these directories:
gnulib/lib
gnulib/m4
gnulib/tests
* bootstrap: A wrapper around gnulib-tool.
* configure.in: Invoke gl_EARLY and gl_INIT, being careful to put gl_EARLY
before any macro that uses AC_COMPILE_IFELSE.
(AC_OUTPUT): Add lib/Makefile and gl-tests/Makefile. Remove m4/Makefile.
* Makefile.am (SUBDIRS): Add gnulib/lib and remove m4. Add gnulib/tests
early enough that those tests run before any libvirt unit tests.
* m4/Makefile.am: Remove file. Not needed.
* src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS, libvirt_la_LIBADD): Add ../gnulib/lib/libgnu.la.
* src/nodeinfo.c: Include "physmem.h".
* qemud/qemud.c, src/remote_internal.c: Include "getaddrinfo.h".
(MEMINFO_PATH, linuxNodeInfoMemPopulate): Remove definitions.
(virNodeInfoPopulate): Use physmem_total, not linuxNodeInfoMemPopulate.
* tests/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS): Add ../gnulib/lib/libgnu.la.
* qemud/Makefile.am (libvirtd_LDADD): Add ../gnulib/lib/libgnu.la.
* tests/nodeinfotest.c (linuxTestCompareFiles): No longer read total
memory from a file.
Update expected output not to include "Memory: NNNN"
* tests/nodeinfodata/linux-nodeinfo-1.txt:
* tests/nodeinfodata/linux-nodeinfo-2.txt:
* tests/nodeinfodata/linux-nodeinfo-3.txt:
* tests/nodeinfodata/linux-nodeinfo-4.txt:
* tests/nodeinfodata/linux-nodeinfo-5.txt:
* tests/nodeinfodata/linux-nodeinfo-6.txt:
* src/test.c [WITH_TEST]: Remove definition of _GNU_SOURCE that
would conflict with the one now in "config.h".
* autogen.sh: Add -I gnulib/m4.
* src/conf.c, src/sexpr.c: Don't define _GNU_SOURCE.
Instead, include "config.h".
* qemud/qemud.c: Remove definition of _GNU_SOURCE.
* src/openvz_driver.c: Likewise.
* src/qemu_driver.c: Likewise.
* src/remote_internal.c: Likewise.
* configure.in: Use AC_CONFIG_AUX_DIR(build-aux), so that a bunch
of gettextize-generated files go into build-aux/, rather than in
the top-level directory.
* .cvsignore: Adjust.
* build-aux/.cvsignore: New file.
Author: Jim Meyering <meyering@redhat.com>
2007-12-05 21:31:07 +00:00
|
|
|
}
|
2007-07-25 23:16:30 +00:00
|
|
|
#else
|
|
|
|
/* XXX Solaris will need an impl later if they port QEMU driver */
|
2009-06-15 17:15:54 +00:00
|
|
|
nodeReportError(conn, VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("node info not implemented on this platform"));
|
2007-07-25 23:16:30 +00:00
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
|
|
|
|
#if HAVE_NUMACTL
|
|
|
|
# if LIBNUMA_API_VERSION <= 1
|
|
|
|
# define NUMA_MAX_N_CPUS 4096
|
|
|
|
# else
|
|
|
|
# define NUMA_MAX_N_CPUS (numa_all_cpus_ptr->size)
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# define n_bits(var) (8 * sizeof(var))
|
|
|
|
# define MASK_CPU_ISSET(mask, cpu) \
|
|
|
|
(((mask)[((cpu) / n_bits(*(mask)))] >> ((cpu) % n_bits(*(mask)))) & 1)
|
|
|
|
|
|
|
|
int
|
2009-06-03 13:28:02 +00:00
|
|
|
nodeCapsInitNUMA(virCapsPtr caps)
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
{
|
|
|
|
int n;
|
2009-01-05 12:56:36 +00:00
|
|
|
unsigned long *mask = NULL;
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
int *cpus = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
int max_n_cpus = NUMA_MAX_N_CPUS;
|
|
|
|
|
|
|
|
if (numa_available() < 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
int mask_n_bytes = max_n_cpus / 8;
|
|
|
|
if (VIR_ALLOC_N(mask, mask_n_bytes / sizeof *mask) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (n = 0 ; n <= numa_max_node() ; n++) {
|
|
|
|
int i;
|
|
|
|
int ncpus;
|
2009-06-26 20:08:07 +00:00
|
|
|
if (numa_node_to_cpus(n, mask, mask_n_bytes) < 0) {
|
|
|
|
VIR_WARN("NUMA topology for cell %d of %d not available, ignoring",
|
|
|
|
n, numa_max_node());
|
|
|
|
continue;
|
|
|
|
}
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
|
|
|
|
for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++)
|
|
|
|
if (MASK_CPU_ISSET(mask, i))
|
|
|
|
ncpus++;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(cpus, ncpus) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++)
|
|
|
|
if (MASK_CPU_ISSET(mask, i))
|
|
|
|
cpus[ncpus++] = i;
|
|
|
|
|
|
|
|
if (virCapabilitiesAddHostNUMACell(caps,
|
|
|
|
n,
|
|
|
|
ncpus,
|
|
|
|
cpus) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
VIR_FREE(cpus);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(cpus);
|
|
|
|
VIR_FREE(mask);
|
|
|
|
return ret;
|
|
|
|
}
|
2009-06-03 13:28:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
nodeGetCellsFreeMemory(virConnectPtr conn,
|
|
|
|
unsigned long long *freeMems,
|
|
|
|
int startCell,
|
|
|
|
int maxCells)
|
|
|
|
{
|
|
|
|
int n, lastCell, numCells;
|
|
|
|
int ret = -1;
|
|
|
|
int maxCell;
|
|
|
|
|
|
|
|
if (numa_available() < 0) {
|
|
|
|
nodeReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("NUMA not supported on this host"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
maxCell = numa_max_node();
|
|
|
|
if (startCell > maxCell) {
|
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("start cell %d out of range (0-%d)"),
|
|
|
|
startCell, maxCell);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
lastCell = startCell + maxCells - 1;
|
|
|
|
if (lastCell > maxCell)
|
|
|
|
lastCell = maxCell;
|
|
|
|
|
|
|
|
for (numCells = 0, n = startCell ; n <= lastCell ; n++) {
|
|
|
|
long long mem;
|
|
|
|
if (numa_node_size64(n, &mem) < 0) {
|
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Failed to query NUMA free memory"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
freeMems[numCells++] = mem;
|
|
|
|
}
|
|
|
|
ret = numCells;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long long
|
|
|
|
nodeGetFreeMemory(virConnectPtr conn)
|
|
|
|
{
|
|
|
|
unsigned long long freeMem = 0;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
if (numa_available() < 0) {
|
|
|
|
nodeReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("NUMA not supported on this host"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (n = 0 ; n <= numa_max_node() ; n++) {
|
|
|
|
long long mem;
|
|
|
|
if (numa_node_size64(n, &mem) < 0) {
|
|
|
|
nodeReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Failed to query NUMA free memory"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
freeMem += mem;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return freeMem;
|
|
|
|
}
|
|
|
|
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
#else
|
2009-06-03 13:28:02 +00:00
|
|
|
int nodeCapsInitNUMA(virCapsPtr caps ATTRIBUTE_UNUSED) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int nodeGetCellsFreeMemory(virConnectPtr conn,
|
|
|
|
unsigned long long *freeMems ATTRIBUTE_UNUSED,
|
|
|
|
int startCell ATTRIBUTE_UNUSED,
|
|
|
|
int maxCells ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
nodeReportError(conn, VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("NUMA memory information not available on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long long nodeGetFreeMemory(virConnectPtr conn)
|
|
|
|
{
|
|
|
|
nodeReportError(conn, VIR_ERR_NO_SUPPORT, "%s",
|
|
|
|
_("NUMA memory information not available on this platform"));
|
|
|
|
return 0;
|
|
|
|
}
|
make NUMA-initialization code more portable and more robust
qemudCapsInitNUMA and umlCapsInitNUMA were identical, so this change
factors them into a new function, virCapsInitNUMA, and puts it in
nodeinfo.c.
In addition to factoring out the duplicates, this change also
adjusts that function definition (along with its macros) so
that it works with Fedora 9's numactl version 1, and makes it
so the code will work even if someone builds the kernel with
CONFIG_NR_CPUS > 4096.
Finally, also perform this NUMA initialization for the lxc
and openvz drivers.
* src/nodeinfo.c: Include <stdint.h>, <numa.h> and "memory.h".
(virCapsInitNUMA): Rename from qemudCapsInitNUMA and umlCapsInitNUMA.
(NUMA_MAX_N_CPUS): Define depending on NUMA API version.
(n_bits, MASK_CPU_ISSET): Define, adjust, use uint64 rather than long.
* src/nodeinfo.h: Include "capabilities.h".
(virCapsInitNUMA): Declare it.
* examples/domain-events/events-c/Makefile.am:
* src/Makefile.am: Add $(NUMACTL_CFLAGS) and $(NUMACTL_LIBS) to various
compile/link-related variables.
* src/qemu_conf.c: Include "nodeinfo.h".
(qemudCapsInitNUMA): Remove duplicate code. Adjust caller.
* src/uml_conf.c (umlCapsInitNUMA): Likewise.
Include "nodeinfo.h".
* src/lxc_conf.c: Include "nodeinfo.h".
(lxcCapsInit): Perform NUMA initialization here, too.
* src/openvz_conf.c (openvzCapsInit): And here.
Include "nodeinfo.h".
* src/libvirt_sym.version.in: Add virCapsInitNUMA so that libvirtd
can link to this function.
2008-12-21 18:55:09 +00:00
|
|
|
#endif
|