Hi Roman,
Unfortunately Mac OS X doesn't has the sysctl MIBs. So
ifdef __APPLE__ should be dropped.
I still don't know the correct API for that purpose though,
host_statistics seems to be used according to
.
ozaki-r
On Sat, Jan 4, 2014 at 12:13 AM, Roman Bogorodskiy
<bogorodskiy(a)gmail.com> wrote:
Add a BSD implementation of nodeGetMemoryStats based
on sysctl(3).
---
src/nodeinfo.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 79 insertions(+), 1 deletion(-)
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index 1838547..5e84e78 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,7 +98,81 @@ appleFreebsdNodeGetMemorySize(unsigned long *memory)
return 0;
}
-#endif
+
+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,
+ _("sysctl failed for '%s'"),
+ sysctl_map[i].sysctl_name);
+ 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) {
+ virReportSystemError(errno,
+ _("sysctl failed for '%s'"),
+ "vfs.bufspace");
+ 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 /* defined(__FreeBSD__) || defined(__APPLE__) */
#ifdef __linux__
# define CPUINFO_PATH "/proc/cpuinfo"
@@ -1041,6 +1117,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
--
libvir-list mailing list
libvir-list(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list