/* BubbleMon dockapp 1.2 - FreeBSD specific code * Copyright (C) 2001, oleg dashevskii * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "include/bubblemon.h" #include "include/sys_include.h" extern BubbleMonData bm; static kvm_t *kd = NULL; static struct nlist nlst[] = { {"_cp_time", 0}, {"_cnt", 0}, {"_bufspace", 0}, {0, 0} }; static int pageshift; #define pagetob(size) ((size) << pageshift) int init_stuff() { /* calculate page shift to convert pages into kilobytes */ int pagesize = getpagesize(); pageshift = 0; while (pagesize > 1) { pageshift++; pagesize >>= 1; } /* open kernel memory */ kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open"); if (kd == NULL) { puts("Could not open kernel virtual memory"); return 1; } kvm_nlist(kd, nlst); if (nlst[0].n_type == 0 || nlst[1].n_type == 0 || nlst[2].n_type == 0) { puts("Error extracting symbols"); return 2; } /* drop setgid & setuid (the latter should not be there really) */ seteuid(getuid()); setegid(getgid()); if (geteuid() != getuid() || getegid() != getgid()) { puts("Unable to drop privileges"); return 3; } return 0; } /* Returns the current CPU load in percent */ int system_cpu(void) { int loadPercentage; int previous_total, previous_load; int total, load; unsigned long int cpu_time[CPUSTATES]; int i; if (kvm_read(kd, nlst[0].n_value, &cpu_time, sizeof(cpu_time)) != sizeof(cpu_time)) return 0; load = cpu_time[CP_USER] + cpu_time[CP_SYS] + cpu_time[CP_NICE]; total = load + cpu_time[CP_IDLE]; i = bm.loadIndex; previous_load = bm.load[i]; previous_total = bm.total[i]; bm.load[i] = load; bm.total[i] = total; bm.loadIndex = (i + 1) % bm.samples; if (previous_total == 0) loadPercentage = 0; /* first time here */ else if (total == previous_total) loadPercentage = 100; else loadPercentage = (100 * (load - previous_load)) / (total - previous_total); return loadPercentage; } int system_memory(void) { u_int64_t my_mem_used, my_mem_max; u_int64_t my_swap_used, my_swap_max; struct vmmeter sum; int bufspace; static int swappgsin = -1; static int swappgsout = -1; static int swap_firsttime = 1; static int swapavail = 0, swapused = 0; static time_t last_time_swap = 0; time_t curr_time; if (kvm_read(kd, nlst[1].n_value, &sum, sizeof(sum)) != sizeof(sum)) return 0; /* _cnt */ if (kvm_read(kd, nlst[2].n_value, &bufspace, sizeof(bufspace)) != sizeof(bufspace)) return 0; /* _bufspace */ my_mem_max = pagetob((u_int64_t) sum.v_page_count); my_mem_used = pagetob((u_int64_t) sum.v_active_count); /* only calculate when first time or when changes took place */ /* do not call it more than 1 time per 2 seconds */ /* otherwise it can eat up to 50% of CPU time on heavy swap activity */ curr_time = time(NULL); if (swap_firsttime || (((sum.v_swappgsin > swappgsin) || (sum.v_swappgsout > swappgsout)) && curr_time > last_time_swap + 1)) { struct kvm_swap swap; int n; swapavail = 0; swapused = 0; n = kvm_getswapinfo(kd, &swap, 1, 0); if (n >= 0 && swap.ksw_total != 0) { swapavail = pagetob(swap.ksw_total); swapused = pagetob(swap.ksw_used); } swap_firsttime = 0; last_time_swap = curr_time; } my_swap_used = swapused; my_swap_max = swapavail; swappgsin = sum.v_swappgsin; swappgsout = sum.v_swappgsout; bm.mem_used = my_mem_used; bm.mem_max = my_mem_max; bm.swap_used = my_swap_used; bm.swap_max = my_swap_max; return 1; } #ifdef ENABLE_MEMSCREEN void system_loadavg(void) { static int avg_delay; if (avg_delay-- <= 0) { struct loadavg loadinfo; int i, mib[2]; size_t size; mib[0] = CTL_VM; mib[1] = VM_LOADAVG; size = sizeof (loadinfo); if (sysctl(mib, 2, &loadinfo, &size, NULL, 0) >= 0) for (i = 0; i < 3; i++) { bm.loadavg[i].i = loadinfo.ldavg[i] / loadinfo.fscale; bm.loadavg[i].f = ((loadinfo.ldavg[i] * 100 + loadinfo.fscale / 2) / loadinfo.fscale) % 100; } avg_delay = ROLLVALUE; } } #endif /* ENABLE_MEMSCREEN */ /* ex:set ts=8: */