$NetBSD: patch-ac,v 1.6 2004/06/07 17:01:50 cube Exp $ --- src/sysdeps/openbsd.c.orig 2004-05-01 19:46:38.000000000 +0200 +++ src/sysdeps/openbsd.c @@ -170,6 +170,95 @@ gkrellm_sys_proc_init(void) /* ===================================================================== */ +/* Memory/Swap monitor interface */ + +#include +#include +#include +#include + +static gulong swapin, + swapout; +static guint64 swap_total, + swap_used; + +void +gkrellm_sys_mem_read_data(void) +{ + static int mib[] = { CTL_VM, VM_METER }; + static int pgout, pgin; + unsigned long total, used, x_used, free, shared, buffers, cached; + struct vmtotal vmt; + struct uvmexp uvmexp; + size_t len; + static struct nlist nl[] = { +#define X_UVM_EXP 0 + { "_uvmexp" }, + { NULL } +}; + + + if (kvmd == NULL) return; + + /* get the name list if it's not done yet */ + if (nl[0].n_type == 0) kvm_nlist(kvmd, nl); + + if (nl[0].n_type != 0) + if (kvm_read(kvmd, nl[X_UVM_EXP].n_value, + &uvmexp, sizeof(uvmexp)) != sizeof(uvmexp)) + memset(&uvmexp, 0, sizeof(uvmexp)); + + if (sysctl(mib, 2, &vmt, &len, NULL, 0) < 0) + memset(&vmt, 0, sizeof(vmt)); + + total = (uvmexp.npages - uvmexp.wired) << uvmexp.pageshift; + + /* not sure of what must be computed */ + x_used = (uvmexp.active + uvmexp.inactive) << uvmexp.pageshift; + free = uvmexp.free << uvmexp.pageshift; + shared = vmt.t_rmshr << uvmexp.pageshift; + + /* want to see only this in the chat. this could be changed */ + used = uvmexp.active << uvmexp.pageshift; + + /* don't know how to get those values */ + buffers = 0; + cached = 0; + + gkrellm_mem_assign_data(total, used, free, shared, buffers, cached); + + /* 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; +} + +void +gkrellm_sys_swap_read_data(void) + { + gkrellm_swap_assign_data(swap_total, swap_used, swapin, swapout); + } + +gboolean +gkrellm_sys_mem_init(void) + { + return TRUE; + } + + +/* ===================================================================== */ /* Sensor monitor interface - not implemented */ gboolean @@ -199,3 +288,104 @@ gkrellm_sys_sensors_init(void) return FALSE; } + +/* ===================================================================== */ +/* Disk monitor interface */ + +#include +#include +#include + +static struct nlist nl_disk[] = { +#define X_DISK_COUNT 0 + { "_disk_count" }, /* number of disks */ +#define X_DISKLIST 1 + { "_disklist" }, /* TAILQ of disks */ + { NULL }, +}; + +static struct disk *dkdisks; /* kernel disk list head */ + +extern kvm_t *kvmd; + +static gint n_disks; + +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 */ + } + + +void +gkrellm_sys_disk_read_data(void) +{ + struct disk d, *p; + gint i; + char buf[20]; + guint64 rbytes, wbytes; + + if (kvmd == NULL) return; + if (n_disks <= 0) return; /* computed by register_disks() */ + if (nl_disk[0].n_type == 0) return; /* ditto. */ + + for (i = 0, p = dkdisks; i < n_disks; p = d.dk_link.tqe_next, ++i) + { + if (kvm_read(kvmd, (u_long)p, &d, sizeof(d)) == sizeof(d)) + { + if (kvm_read(kvmd, (u_long)d.dk_name, buf, sizeof(buf)) != sizeof(buf)) + /* fallback to default name if kvm_read failed */ + sprintf(buf, "%s%c", _("Disk"), 'A' + i); + + /* It seems impossible to get the read and write transfers + * separately. Its just a matter of choice to put the total in + * the rbytes member but I like the blue color so much. + */ + + /* Separate read/write stats were implemented in NetBSD 1.6K. + */ + +#if __NetBSD_Version__ >= 106110000 + rbytes = d.dk_rbytes; + wbytes = d.dk_wbytes; +#else + rbytes = d.dk_bytes; + wbytes = 0; +#endif + + gkrellm_disk_assign_data_by_name(buf, rbytes, wbytes); + } + } +} + +gboolean +gkrellm_sys_disk_init(void) +{ + struct disklist_head head; + + + if (kvmd == NULL) return FALSE; + + /* get disk count */ + if (kvm_nlist(kvmd, nl_disk) >= 0 && nl_disk[0].n_type != 0) + if (kvm_read(kvmd, nl_disk[X_DISK_COUNT].n_value, + (char *)&n_disks, sizeof(n_disks)) != sizeof(n_disks)) + n_disks = 0; + + /* get first disk */ + if (n_disks > 0) { + if (kvm_read(kvmd, nl_disk[X_DISKLIST].n_value, + &head, sizeof(head)) != sizeof(head)) + n_disks = 0; + + dkdisks = head.tqh_first; + } + return TRUE; +}