$OpenBSD: patch-agent_lib_libstatsinfo_c,v 1.3 2016/05/13 22:09:21 landry Exp $
--- agent/lib/libstatsinfo.c.orig	Fri Feb 12 10:49:13 2016
+++ agent/lib/libstatsinfo.c	Fri May 13 23:34:34 2016
@@ -1693,9 +1693,11 @@ statsinfo_restart(PG_FUNCTION_ARGS)
 #define NUM_STAT_FIELDS_MIN		6
 
 /* not support a kernel that does not have the required fields at "/proc/stat" */
+#if defined(__linux__)
 #if !LINUX_VERSION_AT_LEAST(2,5,41)
 #error kernel version 2.5.41 or later is required
 #endif
+#endif
 
 /*
  * statsinfo_cpustats - get cpu information
@@ -1734,6 +1736,7 @@ statsinfo_cpustats_noarg(PG_FUNCTION_ARGS)
 	PG_RETURN_DATUM(get_cpustats(fcinfo, 0, 0, 0, 0));
 }
 
+#ifdef __OpenBSD__
 static Datum
 get_cpustats(FunctionCallInfo fcinfo,
 			 int64 prev_cpu_user,
@@ -1746,6 +1749,59 @@ get_cpustats(FunctionCallInfo fcinfo,
 	int64			 cpu_system;
 	int64			 cpu_idle;
 	int64			 cpu_iowait;
+	HeapTuple		 tuple;
+	Datum			 values[NUM_CPUSTATS_COLS];
+	bool			 nulls[NUM_CPUSTATS_COLS];
+	long			 cp_time[CPUSTATES];
+	char			 errbuf[_POSIX2_LINE_MAX];
+	int			 mib[] = {CTL_KERN, KERN_CPTIME};
+	size_t			 size = sizeof( cp_time );
+
+	must_be_superuser();
+
+	/* Build a tuple descriptor for our result type */
+	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+		elog(ERROR, "return type must be a row type");
+
+	Assert(tupdesc->natts == lengthof(values));
+
+	if (sysctl(mib, 2, &cp_time, &size, NULL, 0) < 0)
+		elog(ERROR,"failed to get kern.cptime");
+
+	memset(nulls, 0, sizeof(nulls));
+	memset(values, 0, sizeof(values));
+
+	cpu_user = cp_time[CP_USER] + cp_time[CP_IDLE];
+	cpu_system = cp_time[CP_SYS];
+	cpu_idle = cp_time[CP_IDLE];
+	cpu_iowait = cp_time[CP_INTR];
+
+	values[0] = CStringGetTextDatum((char *)"cpu");
+	values[1] = Int64GetDatum(cpu_user);
+	values[2] = Int64GetDatum(cpu_system);
+	values[3] = Int64GetDatum(cpu_idle);
+	values[4] = Int64GetDatum(cpu_iowait);
+	values[5] = Int16GetDatum(cpu_user < prev_cpu_user ? 1 : 0);
+	values[6] = Int16GetDatum(cpu_system < prev_cpu_system ? 1 : 0);
+	values[7] = Int16GetDatum(cpu_idle < prev_cpu_idle ? 1 : 0);
+	values[8] = Int16GetDatum(cpu_iowait < prev_cpu_iowait ? 1 : 0);
+
+	tuple = heap_form_tuple(tupdesc, values, nulls);
+	return HeapTupleGetDatum(tuple);
+}
+#else
+static Datum
+get_cpustats(FunctionCallInfo fcinfo,
+			 int64 prev_cpu_user,
+			 int64 prev_cpu_system,
+			 int64 prev_cpu_idle,
+			 int64 prev_cpu_iowait)
+{
+	TupleDesc		 tupdesc;
+	int64			 cpu_user;
+	int64			 cpu_system;
+	int64			 cpu_idle;
+	int64			 cpu_iowait;
 	List			*records = NIL;
 	List			*fields = NIL;
 	HeapTuple		 tuple;
@@ -1818,6 +1874,7 @@ get_cpustats(FunctionCallInfo fcinfo,
 
 	return HeapTupleGetDatum(tuple);
 }
+#endif
 
 #define NUM_DEVICESTATS_COLS			17
 #define TYPE_DEVICE_TABLESPACES			TEXTOID
@@ -1991,10 +2048,46 @@ statsinfo_devicestats(PG_FUNCTION_ARGS)
 /*
  * statsinfo_loadavg - get loadavg information
  */
+#if defined(__OpenBSD__)
 Datum
 statsinfo_loadavg(PG_FUNCTION_ARGS)
 {
 	TupleDesc	tupdesc;
+	HeapTuple	tuple;
+	Datum		values[NUM_LOADAVG_COLS];
+	bool		nulls[NUM_LOADAVG_COLS];
+	char		errbuf[_POSIX2_LINE_MAX];
+	struct loadavg	load;
+	int		 mib[] = {CTL_VM, VM_LOADAVG};
+	size_t		 size = sizeof( load );
+
+	must_be_superuser();
+
+	/* Build a tuple descriptor for our result type */
+	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+		elog(ERROR, "return type must be a row type");
+
+	Assert(tupdesc->natts == lengthof(values));
+
+	if (sysctl(mib, 2, &load, &size, NULL, 0) < 0)
+		elog(ERROR,"failed to get vm.loadavg");
+
+	memset(nulls, 0, sizeof(nulls));
+	memset(values, 0, sizeof(values));
+
+	values[0] = Float4GetDatum(load.ldavg[0]);
+	values[1] = Float4GetDatum(load.ldavg[1]);
+	values[2] = Float4GetDatum(load.ldavg[2]);
+
+	tuple = heap_form_tuple(tupdesc, values, nulls);
+
+	return HeapTupleGetDatum(tuple);
+}
+#else
+Datum
+statsinfo_loadavg(PG_FUNCTION_ARGS)
+{
+	TupleDesc	tupdesc;
 	int			fd;
 	char		buffer[256];
 	int			nbytes;
@@ -2053,6 +2146,7 @@ statsinfo_loadavg(PG_FUNCTION_ARGS)
 
 	return HeapTupleGetDatum(tuple);
 }
+#endif
 
 #define FILE_MEMINFO		"/proc/meminfo"
 #define NUM_MEMORY_COLS		5
@@ -2072,6 +2166,7 @@ compare_meminfo_table(const void *a, const void *b)
 /*
  * statsinfo_memory - get memory information
  */
+#if defined(__OpenBSD__)
 Datum
 statsinfo_memory(PG_FUNCTION_ARGS)
 {
@@ -2079,6 +2174,36 @@ statsinfo_memory(PG_FUNCTION_ARGS)
 	HeapTuple		 tuple;
 	Datum			 values[NUM_MEMORY_COLS];
 	bool			 nulls[NUM_MEMORY_COLS];
+
+	must_be_superuser();
+
+	/* Build a tuple descriptor for our result type */
+	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+		elog(ERROR, "return type must be a row type");
+
+	Assert(tupdesc->natts == lengthof(values));
+
+	memset(nulls, 0, sizeof(nulls));
+	memset(values, 0, sizeof(values));
+
+	values[0] = Int64GetDatum(0);
+	values[1] = Int64GetDatum(0);
+	values[2] = Int64GetDatum(0);
+	values[3] = Int64GetDatum(0);
+	values[4] = Int64GetDatum(0);
+
+	tuple = heap_form_tuple(tupdesc, values, nulls);
+
+	return HeapTupleGetDatum(tuple);
+}
+#else
+Datum
+statsinfo_memory(PG_FUNCTION_ARGS)
+{
+	TupleDesc		 tupdesc;
+	HeapTuple		 tuple;
+	Datum			 values[NUM_MEMORY_COLS];
+	bool			 nulls[NUM_MEMORY_COLS];
 	int				 fd;
 	char			 buffer[2048];
 	int				 nbytes;
@@ -2177,6 +2302,7 @@ nextline:
 
 	return HeapTupleGetDatum(tuple);
 }
+#endif
 
 #define FILE_PROFILE		"/proc/systemtap/statsinfo_prof/profile"
 #define NUM_PROFILE_COLS	3
@@ -2185,9 +2311,16 @@ nextline:
 /*
  * statsinfo_profile - get profile information
  */
+#if defined(__OpenBSD__)
 Datum
 statsinfo_profile(PG_FUNCTION_ARGS)
 {
+	PG_RETURN_VOID();
+}
+#else
+Datum
+statsinfo_profile(PG_FUNCTION_ARGS)
+{
 	ReturnSetInfo	*rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
 	TupleDesc		 tupdesc;
 	Tuplestorestate	*tupstore;
@@ -2294,6 +2427,7 @@ statsinfo_profile(PG_FUNCTION_ARGS)
 
 	PG_RETURN_VOID();
 }
+#endif
 
 static bool
 checked_write(int fd, const void *buf, int size)
