$OpenBSD: patch-src_openbsd_c,v 1.18 2017/04/19 20:37:42 sthen Exp $

declarations in common.h got changed, but upstream forgot to do the
corresponding changes into openbsd.c

Adapt to new OpenBSD kinfo_proc API.

Protect kvm_getprocs and global vars with mutexes.

dkstat.h is going away on OpenBSD, so use sys/sched.h instead for CP_*

Make "inline void proc_find_top" static to fix building with clang.

--- src/openbsd.c.orig	Thu May  3 23:08:27 2012
+++ src/openbsd.c	Wed Apr 19 22:14:41 2017
@@ -28,10 +28,11 @@
  *
  */
 
-#include <sys/dkstat.h>
 #include <sys/param.h>
+#include <sys/sched.h>
 #include <sys/resource.h>
 #include <sys/socket.h>
+#include <sys/proc.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -53,6 +54,7 @@
 #include <ifaddrs.h>
 #include <limits.h>
 #include <unistd.h>
+#include <pthread.h>
 #include <machine/apmvar.h>
 
 #include <net80211/ieee80211.h>
@@ -70,7 +72,7 @@
 #define LOG1024			10
 #define pagetok(size) ((size) << pageshift)
 
-inline void proc_find_top(struct process **cpu, struct process **mem);
+static inline void proc_find_top(struct process **cpu, struct process **mem);
 
 static short cpu_setup = 0;
 static kvm_t *kd = 0;
@@ -81,6 +83,8 @@ size_t len = 0;
 int init_kvm = 0;
 int init_sensors = 0;
 
+pthread_mutex_t kvm_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static int kvm_init()
 {
 	if (init_kvm) {
@@ -140,7 +144,7 @@ int check_mount(char *s)
 	return 0;
 }
 
-void update_uptime()
+int update_uptime()
 {
 	int mib[2] = { CTL_KERN, KERN_BOOTTIME };
 	struct timeval boottime;
@@ -155,9 +159,10 @@ void update_uptime()
 		NORM_ERR("Could not get uptime");
 		info.uptime = 0;
 	}
+	return 0;
 }
 
-void update_meminfo()
+int update_meminfo()
 {
 	static int mib[2] = { CTL_VM, VM_METER };
 	struct vmtotal vmtotal;
@@ -194,9 +199,10 @@ void update_meminfo()
 		info.swap = 0;
 		info.swapfree = 0;
 	}
+	return 0;
 }
 
-void update_net_stats()
+int update_net_stats()
 {
 	struct net_stat *ns;
 	double delta;
@@ -207,11 +213,11 @@ void update_net_stats()
 	/* get delta */
 	delta = current_update_time - last_update_time;
 	if (delta <= 0.0001) {
-		return;
+		return 0;
 	}
 
 	if (getifaddrs(&ifap) < 0) {
-		return;
+		return 0;
 	}
 
 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
@@ -266,28 +272,36 @@ void update_net_stats()
 	}
 
 	freeifaddrs(ifap);
+	return 0;
 }
 
-void update_total_processes()
+int update_total_processes()
 {
-	int n_processes;
+	int n_processes = 0;
 
+	int max_size = sizeof(struct kinfo_proc);
+
 	kvm_init();
-	kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes);
+	pthread_mutex_lock(&kvm_mutex);
+	kvm_getprocs(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
+	pthread_mutex_unlock(&kvm_mutex);
 
 	info.procs = n_processes;
+	return 0;
 }
 
-void update_running_processes()
+int update_running_processes()
 {
-	struct kinfo_proc2 *p;
-	int n_processes;
+	struct kinfo_proc *p;
+	int n_processes = 0;
 	int i, cnt = 0;
 
 	kvm_init();
-	int max_size = sizeof(struct kinfo_proc2);
+	int max_size = sizeof(struct kinfo_proc);
 
-	p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
+	pthread_mutex_lock(&kvm_mutex);
+	p = kvm_getprocs(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
+	pthread_mutex_unlock(&kvm_mutex);
 	for (i = 0; i < n_processes; i++) {
 		if (p[i].p_stat == SRUN) {
 			cnt++;
@@ -295,96 +309,64 @@ void update_running_processes()
 	}
 
 	info.run_procs = cnt;
+	return 0;
 }
 
-/* new SMP code can be enabled by commenting the following line */
-#define OLDCPU
-
-#ifdef OLDCPU
-struct cpu_load_struct {
-	unsigned long load[5];
-};
-
-struct cpu_load_struct fresh = { {0, 0, 0, 0, 0} };
-long cpu_used, oldtotal, oldused;
-#else
 #include <assert.h>
 int64_t *fresh = NULL;
 
 /* XXX is 8 enough? - What's the constant for MAXCPU? */
 /* allocate this with malloc would be better */
 int64_t oldtotal[8], oldused[8];
-#endif
 
 void get_cpu_count()
 {
 	int cpu_count = 1;	/* default to 1 cpu */
-#ifndef OLDCPU
+	static pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 	int mib[2] = { CTL_HW, HW_NCPU };
 	size_t len = sizeof(cpu_count);
 
 	if (sysctl(mib, 2, &cpu_count, &len, NULL, 0) != 0) {
 		NORM_ERR("error getting cpu count, defaulting to 1");
 	}
-#endif
+
+	pthread_mutex_lock(&count_mutex);
+
+	if (info.cpu_count == cpu_count) {
+		pthread_mutex_unlock(&count_mutex);
+		return;
+	}
+
 	info.cpu_count = cpu_count;
 
+	free(info.cpu_usage);
+
 	info.cpu_usage = malloc(info.cpu_count * sizeof(float));
 	if (info.cpu_usage == NULL) {
 		CRIT_ERR(NULL, NULL, "malloc");
 	}
 
-#ifndef OLDCPU
-	assert(fresh == NULL);	/* XXX Is this leaking memory? */
+	free(fresh);
 	/* XXX Where shall I free this? */
 	if (NULL == (fresh = calloc(cpu_count, sizeof(int64_t) * CPUSTATES))) {
 		CRIT_ERR(NULL, NULL, "calloc");
 	}
-#endif
+
+	pthread_mutex_unlock(&count_mutex);
 }
 
-void update_cpu_usage()
+int update_cpu_usage()
 {
-#ifdef OLDCPU
-	int mib[2] = { CTL_KERN, KERN_CPTIME };
-	long used, total;
-	long cp_time[CPUSTATES];
-	size_t len = sizeof(cp_time);
-#else
 	size_t size;
 	unsigned int i;
-#endif
 
 	/* add check for !info.cpu_usage since that mem is freed on a SIGUSR1 */
 	if ((cpu_setup == 0) || (!info.cpu_usage)) {
 		get_cpu_count();
 		cpu_setup = 1;
 	}
-
-#ifdef OLDCPU
-	if (sysctl(mib, 2, &cp_time, &len, NULL, 0) < 0) {
-		NORM_ERR("Cannot get kern.cp_time");
-	}
-
-	fresh.load[0] = cp_time[CP_USER];
-	fresh.load[1] = cp_time[CP_NICE];
-	fresh.load[2] = cp_time[CP_SYS];
-	fresh.load[3] = cp_time[CP_IDLE];
-	fresh.load[4] = cp_time[CP_IDLE];
-
-	used = fresh.load[0] + fresh.load[1] + fresh.load[2];
-	total = fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
-
-	if ((total - oldtotal) != 0) {
-		info.cpu_usage[0] = ((double) (used - oldused)) /
-			(double) (total - oldtotal);
-	} else {
-		info.cpu_usage[0] = 0;
-	}
-
-	oldused = used;
-	oldtotal = total;
-#else
+	
 	if (info.cpu_count > 1) {
 		size = CPUSTATES * sizeof(int64_t);
 		for (i = 0; i < info.cpu_count; i++) {
@@ -426,10 +408,11 @@ void update_cpu_usage()
 		oldused[i] = used;
 		oldtotal[i] = total;
 	}
-#endif
+
+	return 0;
 }
 
-void update_load_average()
+int update_load_average()
 {
 	double v[3];
 
@@ -438,6 +421,7 @@ void update_load_average()
 	info.loadavg[0] = (float) v[0];
 	info.loadavg[1] = (float) v[1];
 	info.loadavg[2] = (float) v[2];
+	return 0;
 }
 
 #define OBSD_MAX_SENSORS 256
@@ -606,10 +590,11 @@ char get_freq(char *p_client_buffer, size_t client_buf
 	return 1;
 }
 
-void update_top()
+int update_top()
 {
 	kvm_init();
 	proc_find_top(info.cpu, info.memu);
+	return 0;
 }
 
 #if 0
@@ -665,19 +650,11 @@ cleanup:
 }
 #endif
 
-void clear_diskio_stats()
+int update_diskio()
 {
+	return 0;	/* XXX: implement? hifi: not sure how */
 }
 
-struct diskio_stat *prepare_diskio_stat(const char *s)
-{
-}
-
-void update_diskio()
-{
-	return;	/* XXX: implement? hifi: not sure how */
-}
-
 /* While topless is obviously better, top is also not bad. */
 
 int comparecpu(const void *a, const void *b)
@@ -706,10 +683,10 @@ int comparemem(const void *a, const void *b)
 	return 0;
 }
 
-inline void proc_find_top(struct process **cpu, struct process **mem)
+static inline void proc_find_top(struct process **cpu, struct process **mem)
 {
-	struct kinfo_proc2 *p;
-	int n_processes;
+	struct kinfo_proc *p;
+	int n_processes = 0;
 	int i, j = 0;
 	struct process *processes;
 	int mib[2];
@@ -730,9 +707,11 @@ inline void proc_find_top(struct process **cpu, struct
 	/* translate bytes into page count */
 	total_pages = usermem / pagesize;
 
-	int max_size = sizeof(struct kinfo_proc2);
+	int max_size = sizeof(struct kinfo_proc);
 
-	p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
+
+	pthread_mutex_lock(&kvm_mutex);
+	p = kvm_getprocs(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
 	processes = malloc(n_processes * sizeof(struct process));
 
 	for (i = 0; i < n_processes; i++) {
@@ -740,9 +719,12 @@ inline void proc_find_top(struct process **cpu, struct
 			processes[j].pid = p[i].p_pid;
 			processes[j].name = strndup(p[i].p_comm, text_buffer_size);
 			processes[j].amount = 100.0 * p[i].p_pctcpu / FSCALE;
+			processes[j].vsize = p[i].p_vm_map_size;
+			processes[j].rss = p[i].p_vm_rssize * PAGE_SIZE;
 			j++;
 		}
 	}
+	pthread_mutex_unlock(&kvm_mutex);
 
 	qsort(processes, j - 1, sizeof(struct process), comparemem);
 	for (i = 0; i < 10; i++) {
@@ -752,6 +734,8 @@ inline void proc_find_top(struct process **cpu, struct
 		tmp->pid = processes[i].pid;
 		tmp->amount = processes[i].amount;
 		tmp->name = strndup(processes[i].name, text_buffer_size);
+		tmp->vsize = processes[i].vsize;
+		tmp->rss = processes[i].rss;
 
 		ttmp = mem[i];
 		mem[i] = tmp;
@@ -769,6 +753,8 @@ inline void proc_find_top(struct process **cpu, struct
 		tmp->pid = processes[i].pid;
 		tmp->amount = processes[i].amount;
 		tmp->name = strndup(processes[i].name, text_buffer_size);
+		tmp->vsize = processes[i].vsize;
+		tmp->rss = processes[i].rss;
 
 		ttmp = cpu[i];
 		cpu[i] = tmp;
@@ -784,7 +770,6 @@ inline void proc_find_top(struct process **cpu, struct
 	free(processes);
 }
 
-#if	defined(i386) || defined(__i386__)
 #define	APMDEV		"/dev/apm"
 #define	APM_UNKNOWN	255
 
@@ -908,7 +893,6 @@ char *get_apm_battery_time()
 	return out;
 }
 
-#endif
 
 /* empty stubs so conky links */
 void prepare_update()
@@ -923,8 +907,4 @@ int get_entropy_avail(unsigned int *val)
 int get_entropy_poolsize(unsigned int *val)
 {
 	return 1;
-}
-
-void free_all_processes(void)
-{
 }
