mirror of https://gitee.com/openkylin/libvirt.git
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$$)
|
||||
|
||||
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 = \
|
||||
^(build-aux/syntax-check\.mk|src/util/virthread\.c|tests/.*)$$
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "capabilities.h"
|
||||
#include "cpu_conf.h"
|
||||
#include "domain_conf.h"
|
||||
#include "physmem.h"
|
||||
#include "storage_conf.h"
|
||||
#include "viralloc.h"
|
||||
#include "virarch.h"
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "viralloc.h"
|
||||
#define LIBVIRT_VIRHOSTCPUPRIV_H_ALLOW
|
||||
#include "virhostcpupriv.h"
|
||||
#include "physmem.h"
|
||||
#include "virerror.h"
|
||||
#include "virarch.h"
|
||||
#include "virfile.h"
|
||||
|
|
|
@ -33,9 +33,13 @@
|
|||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "viralloc.h"
|
||||
#include "virhostmem.h"
|
||||
#include "physmem.h"
|
||||
#include "virerror.h"
|
||||
#include "virarch.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
|
||||
virHostMemGetCellsFreeFake(unsigned long long *freeMems,
|
||||
int startCell,
|
||||
int maxCells G_GNUC_UNUSED)
|
||||
{
|
||||
double avail = physmem_available();
|
||||
|
||||
if (startCell != 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("start cell %d out of range (0-%d)"),
|
||||
|
@ -591,13 +733,8 @@ virHostMemGetCellsFreeFake(unsigned long long *freeMems,
|
|||
return -1;
|
||||
}
|
||||
|
||||
freeMems[0] = (unsigned long long)avail;
|
||||
|
||||
if (!freeMems[0]) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot determine free memory"));
|
||||
if ((freeMems[0] = virHostMemGetAvailable()) == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -606,28 +743,13 @@ static int
|
|||
virHostMemGetInfoFake(unsigned long long *mem,
|
||||
unsigned long long *freeMem)
|
||||
{
|
||||
if (mem) {
|
||||
double total = physmem_total();
|
||||
if (!total) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot determine free memory"));
|
||||
return -1;
|
||||
}
|
||||
if (mem &&
|
||||
(*mem = virHostMemGetTotal()) == 0)
|
||||
return -1;
|
||||
|
||||
*mem = (unsigned long long) total;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (freeMem &&
|
||||
(*freeMem = virHostMemGetAvailable()) == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue