Add a BSD implementation of nodeGetMemoryStats based
on sysctl(3).
---
src/nodeinfo.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index 1838547..ecacfa4 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -55,6 +55,8 @@
#define VIR_FROM_THIS VIR_FROM_NONE
#if defined(__FreeBSD__) || defined(__APPLE__)
+# define BSD_MEMORY_STATS_ALL 4
+
static int
appleFreebsdNodeGetCPUCount(void)
{
@@ -96,6 +98,75 @@ appleFreebsdNodeGetMemorySize(unsigned long *memory)
return 0;
}
+
+static int
+appleFreebsdNodeGetMemoryStats(virNodeMemoryStatsPtr params,
+ int *nparams)
+{
+ size_t i, j = 0;
+ unsigned long pagesize = getpagesize() >> 10;
+ long bufpages;
+ size_t bufpages_size = sizeof(bufpages);
+ struct field_sysctl_map {
+ const char *field;
+ const char *sysctl_name;
+ } sysctl_map[] = {
+ {VIR_NODE_MEMORY_STATS_TOTAL, "vm.stats.vm.v_page_count"},
+ {VIR_NODE_MEMORY_STATS_FREE, "vm.stats.vm.v_free_count"},
+ {VIR_NODE_MEMORY_STATS_CACHED, "vm.stats.vm.v_cache_count"},
+ {NULL, NULL}
+ };
+
+ if ((*nparams) == 0) {
+ *nparams = BSD_MEMORY_STATS_ALL;
+ return 0;
+ }
+
+ if ((*nparams) != BSD_MEMORY_STATS_ALL) {
+ virReportInvalidArg(nparams,
+ _("nparams in %s must be %d"),
+ __FUNCTION__, BSD_MEMORY_STATS_ALL);
+ return -1;
+ }
+
+ for (i = 0; sysctl_map[i].field != NULL; i++) {
+ u_int value;
+ size_t value_size = sizeof(value);
+ virNodeMemoryStatsPtr param;
+
+ if (sysctlbyname(sysctl_map[i].sysctl_name, &value,
+ &value_size, NULL, 0) < 0) {
+ virReportSystemError(errno, "%s", _("sysctl failed"));
+ return -1;
+ }
+
+ param = ¶ms[j++];
+ if (virStrcpyStatic(param->field, sysctl_map[i].field) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field '%s' too long for destination"),
+ sysctl_map[i].field);
+ return -1;
+ }
+ param->value = (unsigned long long)value * pagesize;
+ }
+
+ {
+ virNodeMemoryStatsPtr param = ¶ms[j];
+
+ if (sysctlbyname("vfs.bufspace", &bufpages, &bufpages_size,
NULL, 0) < 0) {
+ return -1;
+ }
+ if (virStrcpyStatic(param->field, VIR_NODE_MEMORY_STATS_BUFFERS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field '%s' too long for destination"),
+ VIR_NODE_MEMORY_STATS_BUFFERS);
+ return -1;
+ }
+ param->value = (unsigned long long)bufpages >> 10;
+ }
+
+ return 0;
+}
#endif
#ifdef __linux__
@@ -1041,6 +1112,8 @@ int nodeGetMemoryStats(int cellNum ATTRIBUTE_UNUSED,
return ret;
}
+#elif defined(__FreeBSD__) || defined(__APPLE__)
+ return appleFreebsdNodeGetMemoryStats(params, nparams);
#else
virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("node memory stats not implemented on this platform"));
--
1.8.4.3