mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-01 20:05:46 +00:00
Implement NUMA info/apis in QEMU driver
This commit is contained in:
parent
ab5be538f3
commit
508c4226e1
@ -1,3 +1,12 @@
|
|||||||
|
Thu May 22 11:24:29 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
Support for NUMA info in the QEMU driver
|
||||||
|
* configure.in: check for libnuma
|
||||||
|
* libvirt.spec.in: add requirement on libnuma-devel at build
|
||||||
|
* src/Makefile.am: add NUMA compiler / linker flags
|
||||||
|
* src/qemu_conf.c: populate capabilities data with NUMA topology
|
||||||
|
* src/qemu_driver.c: implement free memory APIs
|
||||||
|
|
||||||
Thu May 22 11:15:29 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
Thu May 22 11:15:29 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
Support the free memory API calls in the remote driver/daemon
|
Support the free memory API calls in the remote driver/daemon
|
||||||
|
39
configure.in
39
configure.in
@ -534,6 +534,40 @@ AM_CONDITIONAL(HAVE_SELINUX, [test "$with_selinux" != "no"])
|
|||||||
AC_SUBST(SELINUX_CFLAGS)
|
AC_SUBST(SELINUX_CFLAGS)
|
||||||
AC_SUBST(SELINUX_LIBS)
|
AC_SUBST(SELINUX_LIBS)
|
||||||
|
|
||||||
|
dnl NUMA lib
|
||||||
|
AC_ARG_WITH(numactl,
|
||||||
|
[ --with-numactl use numactl for host topology info],
|
||||||
|
[],
|
||||||
|
[with_numactl=check])
|
||||||
|
|
||||||
|
NUMACTL_CFLAGS=
|
||||||
|
NUMACTL_LIBS=
|
||||||
|
if test "$with_qemu" = "yes" -a "$with_numactl" != "no"; then
|
||||||
|
old_cflags="$CFLAGS"
|
||||||
|
old_libs="$LIBS"
|
||||||
|
if test "$with_numactl" = "check"; then
|
||||||
|
AC_CHECK_HEADER([numa.h],[],[with_numactl=no])
|
||||||
|
AC_CHECK_LIB(numa, numa_available,[],[with_numactl=no])
|
||||||
|
if test "$with_numactl" != "no"; then
|
||||||
|
with_numactl="yes"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_CHECK_HEADER([numa.h],[],
|
||||||
|
[AC_MSG_ERROR([You must install the numactl development package in order to compile libvirt])])
|
||||||
|
AC_CHECK_LIB(numa, numa_available,[],
|
||||||
|
[AC_MSG_ERROR([You must install the numactl development package in order to compile and run libvirt])])
|
||||||
|
fi
|
||||||
|
CFLAGS="$old_cflags"
|
||||||
|
LIBS="$old_libs"
|
||||||
|
fi
|
||||||
|
if test "$with_numactl" = "yes"; then
|
||||||
|
NUMACTL_LIBS="-lnuma"
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_NUMACTL, 1, [whether Numactl is available for security])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(HAVE_NUMACTL, [test "$with_numactl" != "no"])
|
||||||
|
AC_SUBST(NUMACTL_CFLAGS)
|
||||||
|
AC_SUBST(NUMACTL_LIBS)
|
||||||
|
|
||||||
dnl virsh libraries
|
dnl virsh libraries
|
||||||
AC_CHECK_HEADERS([readline/readline.h])
|
AC_CHECK_HEADERS([readline/readline.h])
|
||||||
|
|
||||||
@ -1001,6 +1035,11 @@ AC_MSG_NOTICE([ selinux: $SELINUX_CFLAGS $SELINUX_LIBS])
|
|||||||
else
|
else
|
||||||
AC_MSG_NOTICE([ selinux: no])
|
AC_MSG_NOTICE([ selinux: no])
|
||||||
fi
|
fi
|
||||||
|
if test "$with_numactl" = "yes" ; then
|
||||||
|
AC_MSG_NOTICE([ numactl: $NUMACTL_CFLAGS $NUMACTL_LIBS])
|
||||||
|
else
|
||||||
|
AC_MSG_NOTICE([ numactl: no])
|
||||||
|
fi
|
||||||
AC_MSG_NOTICE([])
|
AC_MSG_NOTICE([])
|
||||||
AC_MSG_NOTICE([Miscellaneous])
|
AC_MSG_NOTICE([Miscellaneous])
|
||||||
AC_MSG_NOTICE([])
|
AC_MSG_NOTICE([])
|
||||||
|
@ -67,6 +67,9 @@ BuildRequires: dnsmasq
|
|||||||
BuildRequires: bridge-utils
|
BuildRequires: bridge-utils
|
||||||
BuildRequires: qemu
|
BuildRequires: qemu
|
||||||
BuildRequires: cyrus-sasl-devel
|
BuildRequires: cyrus-sasl-devel
|
||||||
|
%if %{with_qemu}
|
||||||
|
BuildRequires: numactl-devel
|
||||||
|
%endif
|
||||||
%if %{with_polkit}
|
%if %{with_polkit}
|
||||||
BuildRequires: PolicyKit-devel >= 0.6
|
BuildRequires: PolicyKit-devel >= 0.6
|
||||||
%endif
|
%endif
|
||||||
|
@ -9,6 +9,7 @@ INCLUDES = \
|
|||||||
$(GNUTLS_CFLAGS) \
|
$(GNUTLS_CFLAGS) \
|
||||||
$(SASL_CFLAGS) \
|
$(SASL_CFLAGS) \
|
||||||
$(SELINUX_CFLAGS) \
|
$(SELINUX_CFLAGS) \
|
||||||
|
$(NUMACTL_CFLAGS) \
|
||||||
-DBINDIR=\""$(libexecdir)"\" \
|
-DBINDIR=\""$(libexecdir)"\" \
|
||||||
-DSBINDIR=\""$(sbindir)"\" \
|
-DSBINDIR=\""$(sbindir)"\" \
|
||||||
-DSYSCONF_DIR="\"$(sysconfdir)\"" \
|
-DSYSCONF_DIR="\"$(sysconfdir)\"" \
|
||||||
@ -100,6 +101,7 @@ endif
|
|||||||
|
|
||||||
libvirt_la_SOURCES = $(CLIENT_SOURCES) $(SERVER_SOURCES)
|
libvirt_la_SOURCES = $(CLIENT_SOURCES) $(SERVER_SOURCES)
|
||||||
libvirt_la_LIBADD = $(LIBXML_LIBS) $(GNUTLS_LIBS) $(SASL_LIBS) $(SELINUX_LIBS) \
|
libvirt_la_LIBADD = $(LIBXML_LIBS) $(GNUTLS_LIBS) $(SASL_LIBS) $(SELINUX_LIBS) \
|
||||||
|
$(NUMACTL_LIBS) \
|
||||||
@CYGWIN_EXTRA_LIBADD@ ../gnulib/lib/libgnu.la
|
@CYGWIN_EXTRA_LIBADD@ ../gnulib/lib/libgnu.la
|
||||||
libvirt_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvirt_sym.version \
|
libvirt_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvirt_sym.version \
|
||||||
-version-info @LIBVIRT_VERSION_INFO@ \
|
-version-info @LIBVIRT_VERSION_INFO@ \
|
||||||
|
@ -42,6 +42,10 @@
|
|||||||
#include <libxml/xpath.h>
|
#include <libxml/xpath.h>
|
||||||
#include <libxml/uri.h>
|
#include <libxml/uri.h>
|
||||||
|
|
||||||
|
#if HAVE_NUMACTL
|
||||||
|
#include <numa.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libvirt/virterror.h"
|
#include "libvirt/virterror.h"
|
||||||
|
|
||||||
#include "qemu_conf.h"
|
#include "qemu_conf.h"
|
||||||
@ -49,6 +53,7 @@
|
|||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "memory.h"
|
||||||
#include "verify.h"
|
#include "verify.h"
|
||||||
#include "c-ctype.h"
|
#include "c-ctype.h"
|
||||||
|
|
||||||
@ -390,6 +395,65 @@ qemudCapsInitGuest(virCapsPtr caps,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_NUMACTL
|
||||||
|
#define MAX_CPUS 4096
|
||||||
|
#define MAX_CPUS_MASK_SIZE (sizeof(unsigned long))
|
||||||
|
#define MAX_CPUS_MASK_LEN (MAX_CPUS / MAX_CPUS_MASK_SIZE)
|
||||||
|
#define MAX_CPUS_MASK_BYTES (MAX_CPUS / 8)
|
||||||
|
|
||||||
|
#define MASK_CPU_ISSET(mask, cpu) \
|
||||||
|
(((mask)[((cpu) / MAX_CPUS_MASK_SIZE)] >> ((cpu) % MAX_CPUS_MASK_SIZE)) & 1)
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemudCapsInitNUMA(virCapsPtr caps)
|
||||||
|
{
|
||||||
|
int n, i;
|
||||||
|
unsigned long *mask = NULL;
|
||||||
|
int ncpus;
|
||||||
|
int *cpus = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (numa_available() < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(mask, MAX_CPUS_MASK_LEN) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (n = 0 ; n <= numa_max_node() ; n++) {
|
||||||
|
if (numa_node_to_cpus(n, mask, MAX_CPUS_MASK_BYTES) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (ncpus = 0, i = 0 ; i < MAX_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_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;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int qemudCapsInitNUMA(virCapsPtr caps ATTRIBUTE_UNUSED) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
virCapsPtr qemudCapsInit(void) {
|
virCapsPtr qemudCapsInit(void) {
|
||||||
struct utsname utsname;
|
struct utsname utsname;
|
||||||
virCapsPtr caps;
|
virCapsPtr caps;
|
||||||
@ -402,6 +466,9 @@ virCapsPtr qemudCapsInit(void) {
|
|||||||
0, 0)) == NULL)
|
0, 0)) == NULL)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
if (qemudCapsInitNUMA(caps) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
for (i = 0 ; i < (sizeof(arch_info_hvm)/sizeof(arch_info_hvm[0])) ; i++)
|
for (i = 0 ; i < (sizeof(arch_info_hvm)/sizeof(arch_info_hvm[0])) ; i++)
|
||||||
if (qemudCapsInitGuest(caps,
|
if (qemudCapsInitGuest(caps,
|
||||||
utsname.machine,
|
utsname.machine,
|
||||||
|
@ -46,6 +46,10 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <libxml/uri.h>
|
#include <libxml/uri.h>
|
||||||
|
|
||||||
|
#if HAVE_NUMACTL
|
||||||
|
#include <numa.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libvirt/virterror.h"
|
#include "libvirt/virterror.h"
|
||||||
|
|
||||||
#include "c-ctype.h"
|
#include "c-ctype.h"
|
||||||
@ -1619,6 +1623,61 @@ static char *qemudGetCapabilities(virConnectPtr conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if HAVE_NUMACTL
|
||||||
|
static int
|
||||||
|
qemudNodeGetCellsFreeMemory(virConnectPtr conn,
|
||||||
|
unsigned long long *freeMems,
|
||||||
|
int startCell,
|
||||||
|
int maxCells)
|
||||||
|
{
|
||||||
|
int n, lastCell, numCells;
|
||||||
|
|
||||||
|
if (numa_available() < 0) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
|
||||||
|
"%s", _("NUMA not supported on this host"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
lastCell = startCell + maxCells - 1;
|
||||||
|
if (lastCell > numa_max_node())
|
||||||
|
lastCell = numa_max_node();
|
||||||
|
|
||||||
|
for (numCells = 0, n = startCell ; n <= lastCell ; n++) {
|
||||||
|
long long mem;
|
||||||
|
if (numa_node_size64(n, &mem) < 0) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("Failed to query NUMA free memory"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
freeMems[numCells++] = mem;
|
||||||
|
}
|
||||||
|
return numCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long long
|
||||||
|
qemudNodeGetFreeMemory (virConnectPtr conn)
|
||||||
|
{
|
||||||
|
unsigned long long freeMem = 0;
|
||||||
|
int n;
|
||||||
|
if (numa_available() < 0) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
|
||||||
|
"%s", _("NUMA not supported on this host"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0 ; n <= numa_max_node() ; n++) {
|
||||||
|
long long mem;
|
||||||
|
if (numa_node_size64(n, &mem) < 0) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("Failed to query NUMA free memory"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
freeMem += mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return freeMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
|
static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
|
||||||
char proc[PATH_MAX];
|
char proc[PATH_MAX];
|
||||||
@ -3182,8 +3241,13 @@ static virDriver qemuDriver = {
|
|||||||
NULL, /* domainMigrateFinish */
|
NULL, /* domainMigrateFinish */
|
||||||
qemudDomainBlockStats, /* domainBlockStats */
|
qemudDomainBlockStats, /* domainBlockStats */
|
||||||
qemudDomainInterfaceStats, /* domainInterfaceStats */
|
qemudDomainInterfaceStats, /* domainInterfaceStats */
|
||||||
|
#if HAVE_NUMACTL
|
||||||
|
qemudNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
|
||||||
|
qemudNodeGetFreeMemory, /* getFreeMemory */
|
||||||
|
#else
|
||||||
NULL, /* nodeGetCellsFreeMemory */
|
NULL, /* nodeGetCellsFreeMemory */
|
||||||
NULL, /* getFreeMemory */
|
NULL, /* getFreeMemory */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static virNetworkDriver qemuNetworkDriver = {
|
static virNetworkDriver qemuNetworkDriver = {
|
||||||
|
Loading…
Reference in New Issue
Block a user