$NetBSD: patch-ab,v 1.15 2006/08/13 07:33:37 xtraeme Exp $ --- src/sysdeps/netbsd.c.orig 2006-03-30 00:23:37.000000000 +0200 +++ src/sysdeps/netbsd.c 2006-08-13 09:25:55.000000000 +0200 @@ -63,7 +63,8 @@ { static int mib[] = { CTL_KERN, KERN_CP_TIME }; u_int64_t cp_time[ncpus][CPUSTATES]; - int len, n; + int n; + size_t len; if (ncpus > 1) { len = sizeof(cp_time[0]); @@ -94,7 +95,7 @@ { static int mib[] = { CTL_HW, HW_NCPU }; int ncpus; - int len = sizeof(int); + size_t len = sizeof(int); if (sysctl(mib, 2, &ncpus, &len, NULL, 0) < 0) return 1; @@ -109,39 +110,33 @@ #include #include #include -#include #include -static struct nlist nl[] = { -#define X_UVM_EXP 0 - { "_uvmexp" }, - { NULL } -}; - -extern kvm_t *kvmd; - void gkrellm_sys_proc_read_data(void) { - static int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; + int mib[6]; double avenrun; guint n_forks = 0, n_processes = 0; - struct uvmexp *uvmexp; - int len, i; - - if (sysctl(mib, 3, NULL, &len, NULL, 0) >= 0) { - n_processes = len / sizeof(struct kinfo_proc); - } - - /* get name list if it is not done yet */ - if (kvmd == NULL) return; - if (nl[0].n_type == 0) kvm_nlist(kvmd, nl); + struct uvmexp_sysctl uvmexp; + size_t size; - if (nl[0].n_type != 0) { - uvmexp = (struct uvmexp *)nl[X_UVM_EXP].n_value; - if (kvm_read(kvmd, (u_long)&uvmexp->forks, &i, sizeof(i)) == sizeof(i)) - n_forks = i; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC2; + mib[2] = KERN_PROC_ALL; + mib[3] = 0; + mib[4] = sizeof(struct kinfo_proc2); + mib[5] = 0; + if (sysctl(mib, 6, NULL, &size, NULL, 0) >= 0) { + n_processes = size / sizeof(struct kinfo_proc2); + } + + mib[0] = CTL_VM; + mib[1] = VM_UVMEXP2; + size = sizeof(uvmexp); + if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) >= 0) { + n_forks = uvmexp.forks; } if (getloadavg(&avenrun, 1) <= 0) @@ -183,6 +178,96 @@ /* ===================================================================== */ +/* Memory/Swap monitor interface */ + +#include +#include +#include + + +void +gkrellm_sys_mem_read_data(void) +{ + int mib[2]; + guint64 total, used, free, shared, buffers, cached; + struct vmtotal vmt; + struct uvmexp_sysctl uvmexp; + size_t len; + + mib[0] = CTL_VM; + mib[1] = VM_METER; + len = sizeof(vmt); + if (sysctl(mib, 2, &vmt, &len, NULL, 0) < 0) + memset(&vmt, 0, sizeof(vmt)); + + mib[0] = CTL_VM; + mib[1] = VM_UVMEXP2; + len = sizeof(uvmexp); + if (sysctl(mib, 2, &uvmexp, &len, NULL, 0) < 0) + memset(&uvmexp, 0, sizeof(uvmexp)); + + total = uvmexp.npages << uvmexp.pageshift; + + /* not sure of what must be computed */ + free = (uvmexp.inactive + uvmexp.free) << uvmexp.pageshift; + shared = vmt.t_rmshr << uvmexp.pageshift; + + /* can't use "uvmexp.active << uvmexp.pageshift" here because the + * display for "free" uses "total - used" which is very wrong. */ + used = total - free; + + /* don't know how to get those values */ + buffers = 0; + cached = 0; + + gkrellm_mem_assign_data(total, used, free, shared, buffers, cached); + +} + +void +gkrellm_sys_swap_read_data(void) +{ + static int pgout, pgin; + int mib[2]; + struct uvmexp_sysctl uvmexp; + size_t len; + static gulong swapin = 0, swapout = 0; + guint64 swap_total, swap_used; + + mib[0] = CTL_VM; + mib[1] = VM_UVMEXP2; + len = sizeof(uvmexp); + if (sysctl(mib, 2, &uvmexp, &len, NULL, 0) < 0) + memset(&uvmexp, 0, sizeof(uvmexp)); + + /* show only the pages located on the disk and not in memory */ + swap_total = (guint64) (uvmexp.swpages << uvmexp.pageshift); + swap_used = (guint64) (uvmexp.swpgonly << uvmexp.pageshift); + + /* For page in/out operations, uvmexp struct doesn't seem to be reliable */ + + /* if the number of swapped pages that are in memory (inuse - only) is + * greater that the previous value (pgin), we count this a "page in" */ + if (uvmexp.swpginuse - uvmexp.swpgonly > pgin) + swapin += uvmexp.swpginuse - uvmexp.swpgonly - pgin; + pgin = uvmexp.swpginuse - uvmexp.swpgonly; + + /* same for page out */ + if (uvmexp.swpgonly > pgout) + swapout += uvmexp.swpgonly - pgout; + pgout = uvmexp.swpgonly; + + gkrellm_swap_assign_data(swap_total, swap_used, swapin, swapout); +} + +gboolean +gkrellm_sys_mem_init(void) + { + return TRUE; + } + + +/* ===================================================================== */ /* Sensor monitor interface */ /* Tables of voltage correction factors and offsets derived from the @@ -295,7 +380,7 @@ int fd; /* file desc. for /dev/sysmon */ int id = 0; /* incremented for each sensor */ int type; - char *s, base_name[32]; + char *s, base_name[33]; gboolean found_sensors = FALSE; /* check if some sensor is configured */ @@ -336,3 +421,158 @@ return found_sensors; } + +/* ===================================================================== */ +/* Disk monitor interface */ + +#include +#include +#include + +#ifdef HW_IOSTATS +#define HW_DISKSTATS HW_IOSTATS +#define disk_sysctl io_sysctl +#define dk_rbytes rbytes +#define dk_wbytes wbytes +#define dk_name name +#endif + +gboolean +gkrellm_sys_disk_init(void) +{ + int mib[3] = { CTL_HW, HW_DISKSTATS, sizeof(struct disk_sysctl) }; + size_t size; + + /* Just test if the sysctl call works */ + if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) + return (FALSE); + + return (TRUE); +} + +void +gkrellm_sys_disk_read_data(void) +{ + int i, n_disks, mib[3] = { CTL_HW, HW_DISKSTATS, sizeof(struct disk_sysctl) }; + size_t size; + guint64 rbytes, wbytes; + struct disk_sysctl *dk_drives; + + if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) + return; + dk_drives = malloc(size); + if (dk_drives == NULL) + return; + n_disks = size / sizeof(struct disk_sysctl); + + if (sysctl(mib, 3, dk_drives, &size, NULL, 0) == -1) + return; + + for (i = 0; i < n_disks; i++) { +#if __NetBSD_Version__ >= 106110000 + rbytes = dk_drives[i].dk_rbytes; + wbytes = dk_drives[i].dk_wbytes; +#else + rbytes = dk_drives[i].dk_bytes; + wbytes = 0; +#endif + + gkrellm_disk_assign_data_by_name(dk_drives[i].dk_name, rbytes, wbytes, FALSE); + } + + free(dk_drives); +} + +gchar * +gkrellm_sys_disk_name_from_device(gint device_number, gint unit_number, + gint *order) + { + return NULL; /* disk data by device not implemented */ + } + +gint +gkrellm_sys_disk_order_from_name(gchar *name) + { + return -1; /* append disk charts as added */ + } + +#if __NetBSD_Version__ >= 399000100 + +#include "../inet.h" + +#include +#include +#include +#include + +static const struct gkrellm_inet_fam { + sa_family_t family; + const char *mib; +} families[] = { {AF_INET, "net.inet.tcp.pcblist"}, +#ifdef INET6 + {AF_INET6, "net.inet6.tcp6.pcblist"}, +#endif + {0, NULL} }; + +void +gkrellm_sys_inet_read_tcp_data() +{ + ActiveTCP tcp; + int mib[CTL_MAXNAME], i; + size_t sz; + u_int namelen; + struct kinfo_pcb *pcbt = NULL; + const struct gkrellm_inet_fam *pf = families; + + while (pf->mib != NULL) { + sz = CTL_MAXNAME; + if (sysctlnametomib(pf->mib, mib, &sz) == -1) + return; + namelen = sz; + + mib[namelen++] = PCB_ALL; + mib[namelen++] = 0; + mib[namelen++] = sizeof(struct kinfo_pcb); + mib[namelen++] = INT_MAX; + + sz = 0; + pcbt = NULL; + if (sysctl(&mib[0], namelen, pcbt, &sz, NULL, 0) == -1) + return; + pcbt = malloc(sz); + if (pcbt == NULL) + return; + if (sysctl(&mib[0], namelen, pcbt, &sz, NULL, 0) == -1) + return; + + sz /= sizeof(struct kinfo_pcb); + for (i = 0; i < sz; i++) { + tcp.family = pf->family; + if (pf->family == AF_INET) { + struct sockaddr_in *sin = + (struct sockaddr_in *)&pcbt[i].ki_dst; + tcp.remote_addr.s_addr = sin->sin_addr.s_addr; + tcp.remote_port = sin->sin_port; + + sin = (struct sockaddr_in *)&pcbt[i].ki_src; + tcp.local_port = sin->sin_port; +#ifdef INET6 + } else { /* AF_INET6 */ + struct sockaddr_in6 *sin = + (struct sockaddr_in6 *)&pcbt[i].ki_dst; + memcpy(&tcp.remote_addr6, &sin->sin6_addr, + sizeof(struct in6_addr)); + tcp.remote_port = sin->sin6_port; + + sin = (struct sockaddr_in6 *)&pcbt[i].ki_src; + tcp.local_port = sin->sin6_port; +#endif + } + if (pcbt[i].ki_tstate == TCPS_ESTABLISHED) + gkrellm_inet_log_tcp_port_data(&tcp); + } + free(pcbt); + pf++; + } +} +#endif