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 #include +#include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include @@ -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 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) -{ }