mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
util: pull gnulib physmem impl into local code
We don't need all the platforms gnulib deals with, so this is a cut down version of GNULIB's physmem.c code. This also allows us to integrate libvirt's error reporting functions closer to the error cause. Reviewed-by: Pavel Hrdina <phrdina@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
210e19702e
commit
4f128bbbfb
@ -2320,7 +2320,7 @@ exclude_file_name_regexp--sc_prohibit_virXXXFree = \
|
|||||||
^(docs/|tests/|examples/|tools/|build-aux/syntax-check\.mk|src/test/test_driver.c|src/libvirt_public.syms|include/libvirt/libvirt-(domain|network|nodedev|storage|stream|secret|nwfilter|interface|domain-snapshot).h|src/libvirt-(domain|qemu|network|nodedev|storage|stream|secret|nwfilter|interface|domain-snapshot).c$$)
|
^(docs/|tests/|examples/|tools/|build-aux/syntax-check\.mk|src/test/test_driver.c|src/libvirt_public.syms|include/libvirt/libvirt-(domain|network|nodedev|storage|stream|secret|nwfilter|interface|domain-snapshot).h|src/libvirt-(domain|qemu|network|nodedev|storage|stream|secret|nwfilter|interface|domain-snapshot).c$$)
|
||||||
|
|
||||||
exclude_file_name_regexp--sc_prohibit_sysconf_pagesize = \
|
exclude_file_name_regexp--sc_prohibit_sysconf_pagesize = \
|
||||||
^(build-aux/syntax-check\.mk|src/util/virutil\.c)$$
|
^(build-aux/syntax-check\.mk|src/util/vir(hostmem|util)\.c)$$
|
||||||
|
|
||||||
exclude_file_name_regexp--sc_prohibit_pthread_create = \
|
exclude_file_name_regexp--sc_prohibit_pthread_create = \
|
||||||
^(build-aux/syntax-check\.mk|src/util/virthread\.c|tests/.*)$$
|
^(build-aux/syntax-check\.mk|src/util/virthread\.c|tests/.*)$$
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "capabilities.h"
|
#include "capabilities.h"
|
||||||
#include "cpu_conf.h"
|
#include "cpu_conf.h"
|
||||||
#include "domain_conf.h"
|
#include "domain_conf.h"
|
||||||
#include "physmem.h"
|
|
||||||
#include "storage_conf.h"
|
#include "storage_conf.h"
|
||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virarch.h"
|
#include "virarch.h"
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#define LIBVIRT_VIRHOSTCPUPRIV_H_ALLOW
|
#define LIBVIRT_VIRHOSTCPUPRIV_H_ALLOW
|
||||||
#include "virhostcpupriv.h"
|
#include "virhostcpupriv.h"
|
||||||
#include "physmem.h"
|
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
#include "virarch.h"
|
#include "virarch.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
|
@ -33,9 +33,13 @@
|
|||||||
# include <sys/resource.h>
|
# include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virhostmem.h"
|
#include "virhostmem.h"
|
||||||
#include "physmem.h"
|
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
#include "virarch.h"
|
#include "virarch.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
@ -577,13 +581,151 @@ virHostMemGetParameters(virTypedParameterPtr params G_GNUC_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* MEMORYSTATUSEX is missing from older windows headers, so define
|
||||||
|
a local replacement. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD dwLength;
|
||||||
|
DWORD dwMemoryLoad;
|
||||||
|
DWORDLONG ullTotalPhys;
|
||||||
|
DWORDLONG ullAvailPhys;
|
||||||
|
DWORDLONG ullTotalPageFile;
|
||||||
|
DWORDLONG ullAvailPageFile;
|
||||||
|
DWORDLONG ullTotalVirtual;
|
||||||
|
DWORDLONG ullAvailVirtual;
|
||||||
|
DWORDLONG ullAvailExtendedVirtual;
|
||||||
|
} lMEMORYSTATUSEX;
|
||||||
|
typedef WINBOOL(WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*);
|
||||||
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
|
static unsigned long long
|
||||||
|
virHostMemGetTotal(void)
|
||||||
|
{
|
||||||
|
#if defined HAVE_SYSCTLBYNAME
|
||||||
|
/* This works on freebsd & macOS. */
|
||||||
|
unsigned long long physmem = 0;
|
||||||
|
size_t len = sizeof(physmem);
|
||||||
|
|
||||||
|
if (sysctlbyname("hw.physmem", &physmem, &len, NULL, 0) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to query memory total"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return physmem;
|
||||||
|
#elif defined _SC_PHYS_PAGES && defined _SC_PAGESIZE
|
||||||
|
/* this works on linux */
|
||||||
|
long long pages;
|
||||||
|
long long pagesize;
|
||||||
|
if ((pages = sysconf(_SC_PHYS_PAGES)) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to query memory total"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to query memory page size"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (unsigned long long)pages * (unsigned long long)pagesize;
|
||||||
|
#elif defined WIN32
|
||||||
|
PFN_MS_EX pfnex;
|
||||||
|
HMODULE h = GetModuleHandle("kernel32.dll");
|
||||||
|
|
||||||
|
if (!h) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to access kernel32.dll"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use GlobalMemoryStatusEx if available. */
|
||||||
|
if ((pfnex = (PFN_MS_EX) GetProcAddress(h, "GlobalMemoryStatusEx"))) {
|
||||||
|
lMEMORYSTATUSEX lms_ex;
|
||||||
|
lms_ex.dwLength = sizeof(lms_ex);
|
||||||
|
if (!pfnex(&lms_ex)) {
|
||||||
|
virReportSystemError(EIO, "%s",
|
||||||
|
_("Unable to query memory total"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return lms_ex.ullTotalPhys;
|
||||||
|
} else {
|
||||||
|
/* Fall back to GlobalMemoryStatus which is always available.
|
||||||
|
but returns wrong results for physical memory > 4GB. */
|
||||||
|
MEMORYSTATUS ms;
|
||||||
|
GlobalMemoryStatus(&ms);
|
||||||
|
return ms.dwTotalPhys;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned long long
|
||||||
|
virHostMemGetAvailable(void)
|
||||||
|
{
|
||||||
|
#if defined HAVE_SYSCTLBYNAME
|
||||||
|
/* This works on freebsd and macOS */
|
||||||
|
unsigned long long usermem = 0;
|
||||||
|
size_t len = sizeof(usermem);
|
||||||
|
|
||||||
|
if (sysctlbyname("hw.usermem", &usermem, &len, NULL, 0) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to query memory available"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return usermem;
|
||||||
|
#elif defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE
|
||||||
|
/* this works on linux */
|
||||||
|
long long pages;
|
||||||
|
long long pagesize;
|
||||||
|
if ((pages = sysconf(_SC_AVPHYS_PAGES)) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to query memory available"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to query memory page size"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (unsigned long long)pages * (unsigned long long)pagesize;
|
||||||
|
#elif defined WIN32
|
||||||
|
PFN_MS_EX pfnex;
|
||||||
|
HMODULE h = GetModuleHandle("kernel32.dll");
|
||||||
|
|
||||||
|
if (!h) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to access kernel32.dll"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use GlobalMemoryStatusEx if available. */
|
||||||
|
if ((pfnex = (PFN_MS_EX) GetProcAddress(h, "GlobalMemoryStatusEx"))) {
|
||||||
|
lMEMORYSTATUSEX lms_ex;
|
||||||
|
lms_ex.dwLength = sizeof(lms_ex);
|
||||||
|
if (!pfnex(&lms_ex)) {
|
||||||
|
virReportSystemError(EIO, "%s",
|
||||||
|
_("Unable to query memory available"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return lms_ex.ullAvailPhys;
|
||||||
|
} else {
|
||||||
|
/* Fall back to GlobalMemoryStatus which is always available.
|
||||||
|
but returns wrong results for physical memory > 4GB */
|
||||||
|
MEMORYSTATUS ms;
|
||||||
|
GlobalMemoryStatus(&ms);
|
||||||
|
return ms.dwAvailPhys;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virHostMemGetCellsFreeFake(unsigned long long *freeMems,
|
virHostMemGetCellsFreeFake(unsigned long long *freeMems,
|
||||||
int startCell,
|
int startCell,
|
||||||
int maxCells G_GNUC_UNUSED)
|
int maxCells G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
double avail = physmem_available();
|
|
||||||
|
|
||||||
if (startCell != 0) {
|
if (startCell != 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("start cell %d out of range (0-%d)"),
|
_("start cell %d out of range (0-%d)"),
|
||||||
@ -591,13 +733,8 @@ virHostMemGetCellsFreeFake(unsigned long long *freeMems,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
freeMems[0] = (unsigned long long)avail;
|
if ((freeMems[0] = virHostMemGetAvailable()) == 0)
|
||||||
|
|
||||||
if (!freeMems[0]) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("Cannot determine free memory"));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -606,28 +743,13 @@ static int
|
|||||||
virHostMemGetInfoFake(unsigned long long *mem,
|
virHostMemGetInfoFake(unsigned long long *mem,
|
||||||
unsigned long long *freeMem)
|
unsigned long long *freeMem)
|
||||||
{
|
{
|
||||||
if (mem) {
|
if (mem &&
|
||||||
double total = physmem_total();
|
(*mem = virHostMemGetTotal()) == 0)
|
||||||
if (!total) {
|
return -1;
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("Cannot determine free memory"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*mem = (unsigned long long) total;
|
if (freeMem &&
|
||||||
}
|
(*freeMem = virHostMemGetAvailable()) == 0)
|
||||||
|
return -1;
|
||||||
if (freeMem) {
|
|
||||||
double avail = physmem_available();
|
|
||||||
|
|
||||||
if (!avail) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("Cannot determine free memory"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*freeMem = (unsigned long long) avail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user