diff options
69 files changed, 5851 insertions, 1998 deletions
@@ -1,3 +1,18 @@ +2007-02-18 Benoît Dejean <benoit@placenet.org> + + * configure.in: + * libgtop-sysdeps.m4: + * sysdeps/Makefile.am: + + Huge (k)FreeBSD update. + (k)FreeBSD support is freebsd/ + Other BSD are in bsd/ + + Patch by Joe Marcus Clarke <marcus@freebsd.org> + Alexander Nedotsukov <bland@FreeBSD.org> + + Closes #407693. + 2007-02-14 Benoît Dejean <benoit@placenet.org> * lib/read.c: (glibtop_read_l): diff --git a/configure.in b/configure.in index 5540f952..a7ac30b7 100644 --- a/configure.in +++ b/configure.in @@ -410,6 +410,7 @@ sysdeps/linux/Makefile sysdeps/freebsd/Makefile sysdeps/solaris/Makefile sysdeps/aix/Makefile +sysdeps/bsd/Makefile src/Makefile src/daemon/Makefile src/inodedb/Makefile diff --git a/libgtop-sysdeps.m4 b/libgtop-sysdeps.m4 index 0ae3b8c1..0bcb01e1 100644 --- a/libgtop-sysdeps.m4 +++ b/libgtop-sysdeps.m4 @@ -67,11 +67,17 @@ AC_DEFUN([GNOME_LIBGTOP_SYSDEPS],[ libgtop_have_sysinfo=yes libgtop_need_server=no ;; - freebsd*|netbsd*|openbsd*|bsdi*|kfreebsd*) + netbsd*|openbsd*|bsdi*) + libgtop_sysdeps_dir=bsd + libgtop_use_machine_h=yes + libgtop_need_server=yes + libgtop_postinstall='chgrp kmem $(bindir)/libgtop_server2 && chmod 2755 $(bindir)/libgtop_server2' + ;; + freebsd*|kfreebsd*) libgtop_sysdeps_dir=freebsd libgtop_use_machine_h=yes libgtop_need_server=yes - libgtop_postinstall='chgrp kmem $(bindir)/libgtop_server && chmod 2755 $(bindir)/libgtop_server' + libgtop_postinstall='chgrp kmem $(bindir)/libgtop_server2 && chmod 2755 $(bindir)/libgtop_server2' ;; solaris*) libgtop_sysdeps_dir=solaris @@ -134,6 +140,20 @@ AC_DEFUN([GNOME_LIBGTOP_SYSDEPS],[ AC_SUBST(KVM_LIBS) + case "$host_os" in + kfreebsd*) + EXTRA_SYSDEPS_LIBS="-lgeom -ldevstat" + ;; + freebsd*) + osreldate=`sysctl -n kern.osreldate 2>/dev/null` + if test -n "${osreldate}" && test ${osreldate} -ge 600000 ; then + EXTRA_SYSDEPS_LIBS="-lgeom -ldevstat" + fi + ;; + esac + + AC_SUBST(EXTRA_SYSDEPS_LIBS) + AC_CHECK_HEADERS(net/if_var.h) AC_MSG_CHECKING([for I4B]) AC_TRY_COMPILE([ diff --git a/sysdeps/Makefile.am b/sysdeps/Makefile.am index 8fa96437..bcdca880 100644 --- a/sysdeps/Makefile.am +++ b/sysdeps/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS = common @sysdeps_dir@ -DIST_SUBDIRS = common linux osf1 \ +DIST_SUBDIRS = bsd common linux osf1 \ stub stub_suid sun4 freebsd solaris aix diff --git a/sysdeps/bsd/AUTHORS b/sysdeps/bsd/AUTHORS new file mode 100644 index 00000000..9da8aceb --- /dev/null +++ b/sysdeps/bsd/AUTHORS @@ -0,0 +1,2 @@ +Martin Baulig (martin@home-of-linux.org) +Josh Sled (jsled@scam.XCF.Berkeley.EDU) diff --git a/sysdeps/bsd/ChangeLog b/sysdeps/bsd/ChangeLog new file mode 100644 index 00000000..9b92d189 --- /dev/null +++ b/sysdeps/bsd/ChangeLog @@ -0,0 +1,477 @@ +2007-02-18 Benoît Dejean <benoit@placenet.org> + + * AUTHORS: + * Makefile.am: + * NOTES: + * close.c: (glibtop_close_p): + * cpu.c: (glibtop_init_cpu_p), (glibtop_get_cpu_p): + * fsusage.c: (_glibtop_bsd_get_fsusage_read_write): + * glibtop_machine.h: + * glibtop_server.h: + * glibtop_suid.h: + * init.c: (glibtop_init_r): + * loadavg.c: (glibtop_init_loadavg_p), (glibtop_get_loadavg_p): + * mem.c: (glibtop_init_mem_p), (glibtop_get_mem_p): + * msg_limits.c: (glibtop_init_msg_limits_p), + (glibtop_get_msg_limits_p): + * netlist.c: (glibtop_init_netlist_s), (glibtop_get_netlist_s): + * netload.c: (glibtop_init_netload_p), (glibtop_get_netload_p): + * nosuid.c: (glibtop_open_s), (glibtop_close_s): + * open.c: (glibtop_init_p), (glibtop_open_p): + * ppp.c: (glibtop_init_ppp_p), (glibtop_get_ppp_p): + * procargs.c: (glibtop_init_proc_args_p), + (glibtop_get_proc_args_p): + * procdata.c: (glibtop_get_procdata_s): + * prockernel.c: (glibtop_init_proc_kernel_p), + (glibtop_get_proc_kernel_p): + * proclist.c: (glibtop_init_proclist_p), (glibtop_get_proclist_p): + * procmap.c: (glibtop_init_proc_map_p), (glibtop_get_proc_map_p): + * procmem.c: (glibtop_init_proc_mem_p), (glibtop_get_proc_mem_p): + * procopenfiles.c: (glibtop_init_proc_open_files_s), + (glibtop_get_proc_open_files_s): + * procsegment.c: (glibtop_init_proc_segment_p), + (glibtop_get_proc_segment_p): + * procsignal.c: (glibtop_init_proc_signal_p), + (glibtop_get_proc_signal_p): + * procstate.c: (glibtop_init_proc_state_p), + (glibtop_get_proc_state_p): + * proctime.c: (glibtop_init_proc_time_p): + * procuid.c: (glibtop_init_proc_uid_p), (glibtop_get_proc_uid_p): + * sem_limits.c: (glibtop_init_sem_limits_p), + (glibtop_get_sem_limits_p): + * shm_limits.c: (glibtop_init_shm_limits_p), + (glibtop_get_shm_limits_p): + * siglist.c: + * swap.c: (glibtop_init_swap_p), (glibtop_get_swap_p): + * sysinfo.c: (init_sysinfo), (glibtop_get_sysinfo_s): + * uptime.c: (glibtop_init_uptime_p), (glibtop_get_uptime_p): + + Huge (k)FreeBSD update. + (k)FreeBSD support is freebsd/ + Other BSD are in bsd/ + + Patch by Joe Marcus Clarke <marcus@freebsd.org> + Alexander Nedotsukov <bland@FreeBSD.org> + + Closes #407693. + +2007-01-31 Benoît Dejean <benoit@placenet.org> + + * fsusage.c: (_glibtop_freebsd_get_fsusage_read_write): + * netload.c: (glibtop_get_netload_p): + * prockernel.c: (glibtop_get_proc_kernel_p): + * procmap.c: (glibtop_get_proc_map_p): + * proctime.c: + * siglist.c: + * /libgtop-sysdeps.m4: + + Various FreeBSD and kFreeBSD updates. + Patch by Roy Marples <uberlord@gentoo.org>. + Reviewed by Petr Salinger <Petr.Salinger@seznam.cz>. + Closes #387200. + +2006-11-27 Benoît Dejean <benoit@placenet.org> + + * fsusage.c: (_glibtop_freebsd_get_fsusage_read_write): + * mem.c: (glibtop_get_mem_p): + * prockernel.c: (glibtop_get_proc_kernel_p): + * proclist.c: (glibtop_get_proclist_p): + * procmap.c: (glibtop_get_proc_map_p): + * procmem.c: (glibtop_get_proc_mem_p): + * procsignal.c: (glibtop_get_proc_signal_p): + * procstate.c: (glibtop_get_proc_state_p): + * proctime.c: + * procuid.c: (glibtop_get_proc_uid_p): + * swap.c: (glibtop_init_swap_p), (glibtop_get_swap_p): + + Added kfreebsd support. + Patch by Petr Salinger <Petr.Salinger@seznam.cz>. + +2006-04-09 Benoît Dejean <benoit@placenet.org> + + * fsusage.c: (_glibtop_freebsd_get_fsusage_read_write): + + Fixed typo. + +2006-04-04 Julio M. Merino Vidal <jmmv@NetBSD.org> + + * sysdeps/freebsd/fsusage.c: + + Use statvfs(2) if available instead of statfs(2). The latter was + replaced by the former and is no longer available under, e.g. NetBSD. + + Fixes bug #337235. + +2006-04-04 Benoît Dejean <benoit@placenet.org> + + * sysinfo.c: (init_sysinfo): + + Store only strings in values' values. g_strdup these strings. + Even if values is never destroyed, set key_destroy_func to NULL. + + Leave description to NULL. + +2006-04-04 Julio M. Merino Vidal <jmmv@NetBSD.org> + + * sysdeps/freebsd/Makefile.am: + * sysdeps/freebsd/sysinfo.c: + + Bring back to life (from the 1.x versions) the sysinfo.c file for + the freebsd sysdeps. The new file comes from the FreeBSD ports + repository and has some minor style changes by me. This is required + to get the glibtop_get_sysinfo_s function used by the sysdeps common + code. + + Fixes bug #337251. + +2006-04-04 Julio M. Merino Vidal <jmmv@NetBSD.org> + + * sysdeps/freebsd/proctime.c: + + Remove obsolete and non-functional code that breaks the build under + NetBSD. It was guarded by a conditional but could not compile + anyway because it referred to an undefined variable. + + Fixes bug #337234. + +2005-02-28 Benoît Dejean <TazForEver@dlfp.org> + + * fsusage.c: (_glibtop_freebsd_get_fsusage_read_write): Forgot to add + this file :) + +2005-02-28 Benoît Dejean <TazForEver@dlfp.org> + + * Makefile.am: + * cpu.c: (glibtop_get_cpu_p): + * netlist.c: (glibtop_get_netlist_s): + * netload.c: (glibtop_get_netload_p): + * procmem.c: (glibtop_get_proc_mem_p): + + Fix a bug in netlist where glibtop_netlist.number was never initialized to 0 + (this resulted in a NULL pointer dereference in the network load feature + of the multiload applet) + + * Add support for getting interface flags and packet counts even on interfaces + without IP addresses (needed for the network load feature of the multiload applet) + + * Restore per-process limits in the !FreeBSD or __FreeBSD_version < 500013 + case + + * Add CPU interrupt time as IOWAIT to get support for the cpu load feature of + the multiload applet. + + Patch from marcus@freebsd.org (Joe Marcus Clarke). + Closes #168704. + +2005-02-23 Benoît Dejean <TazForEver@dlfp.org> + + * Makefile.am: + * netlist.c: (glibtop_get_netlist_s): + * procmap.c: (glibtop_get_proc_map_p): + * procmem.c: (glibtop_get_proc_mem_p): + * procopenfiles.c: (glibtop_init_proc_open_files_s), + (glibtop_get_proc_open_files_s): + * proctime.c: + + Add support for FreeBSD 6-CURRENT. + Use the more portable getrlimit to obtain process memory limits. + Correctly determine process time. + Stub out the procopenfiles() function (this is not yet implemented, however). + Fix a nasty infinite loop and memory leak due to a forgot pointer increment. + + Patch from marcus@freebsd.org (Joe Marcus Clarke). + Closes #168232. + +2004-12-05 Benoît Dejean <tazforever@dlfp.org> + + * Makefile.am: + * netlist.c: (glibtop_init_netlist_s), (glibtop_get_netlist_s): + Added glibtop_get_netlist. Patch from marcus@freebsd.org (Joe Marcus Clarke). + +2004-08-28 Benoît Dejean <tazforever@dlfp.org> + + * mem.c: (glibtop_get_mem_p): + * ppp.c: + * swap.c: (glibtop_init_swap_p), (glibtop_get_swap_p): + * uptime.c: (glibtop_get_uptime_p): Merge a bunch of trivial OpenBSD + patchs. To *BSD maintainers : please report bugs ! don't be selfish, share + your patchs. + +2004-08-22 Benoît Dejean <tazforever@dlfp.org> + + * procstate.c: + * uptime.c: (glibtop_get_uptime_p): Merged Marcus' patches. + +2004-07-15 Benoît Dejean <tazforever@dlfp.org> + + * procstate.c: (glibtop_get_proc_state_p): Fixed copy/paste error + while setting buf->state. + +2004-06-07 Benoît Dejean <tazforever@dlfp.org> + + * netload.c: (glibtop_get_netload_p): + * procstate.c: (glibtop_get_proc_state_p): + * prockernel.c: (glibtop_get_proc_kernel_p): s/strncpy/g_strlcpy/. + + * procargs.c: (glibtop_get_proc_args_p): + * procmap.c: (glibtop_get_proc_map_p): Cleaned. + + +2004-05-26 Benoît Dejean <tazforever@dlfp.org> + + * procdata.c: (glibtop_get_procdata_s): Removed Linux related code. + +2004-04-07 Bastien Nocera <hadess@hadess.net> + + * prockernel.c: (glibtop_get_proc_kernel_p): patch for NetBSD/AMD64 + support (Julio M. Merino Vidal <jmmv@menta.net>) + +2004-03-09 Bastien Nocera <hadess@hadess.net> + + * Makefile.am: + * cpu.c: (glibtop_init_cpu_p), (glibtop_get_cpu_p): + * glibtop_machine.h: + * mem.c: + * netload.c: (glibtop_get_netload_p): + * prockernel.c: (glibtop_get_proc_kernel_p): + * proclist.c: (glibtop_get_proclist_p): + * procmap.c: (glibtop_get_proc_map_p): + * procmem.c: (glibtop_get_proc_mem_p): + * procsignal.c: (glibtop_get_proc_signal_p): + * procstate.c: (glibtop_get_proc_state_p): + * proctime.c: + * procuid.c: (glibtop_get_proc_uid_p): + * uptime.c: (glibtop_get_uptime_p): implement NetBSD support, and + some build problems on FreeBSD (Closes: #135674) + +2004-03-09 Bastien Nocera <hadess@hadess.net> + + * procargs.c: (glibtop_get_proc_args_p): + * procmap.c: (glibtop_get_proc_map_p): + * swap.c: (glibtop_get_swap_p): fix g_malloc usage on non-Linux + platforms (patch by Benoît Dejean <bnet@ifrance.com>) + +2003-10-21 Bastien Nocera <hadess@hadess.net> + + * Makefile.am: install only one library, libgtop-2.0 + Fix build-time warnings due to the redefinition of guint64 + +2003-10-20 Bastien Nocera <hadess@hadess.net> + + * mem.c: (glibtop_get_mem_p): + * prockernel.c: (glibtop_get_proc_kernel_p): + * procmem.c: (glibtop_get_proc_mem_p): + * proctime.c: (glibtop_get_proc_time_p): s/u_int64_t/guint64/ + +2003-10-20 Bastien Nocera <hadess@hadess.net> + + * swap.c: (glibtop_get_swap_p): fix swap sizes in FreeBSD, + patch by edwin@mavetju.org + +2003-10-20 Bastien Nocera <hadess@hadess.net> + + * glibtop_machine.h: + * glibtop_server.h: + * glibtop_suid.h: + * open.c: + * procargs.c: + * proclist.c: + * procmap.c: + * swap.c: fixed compilation + +2003-10-20 Bastien Nocera <hadess@hadess.net> + + * procargs.c: (glibtop_get_proc_args_p): + * proclist.c: (glibtop_get_proclist_p): + * procmap.c: (glibtop_get_proc_map_p): + * swap.c: (glibtop_get_swap_p): replace all the xmalloc crap by glib + memory management functions + +2001-10-17 Abel Cheung <maddog@linux.org.hk> + + * Makefile.am: move header to $(includedir)/libgtop-1.0/glibtop. + +2001-02-27 Martin Baulig <baulig@suse.de> + + * netload.c: Comment out the `subnet' field on BSDI; this should + make it compile. Bug #13345. + + * shm_limits.c, msg_limits.c, sem_limits.c: Applied a patch + from Rolf Grossmann (grossman@securitas.net) for FreeBSD 4.2. + Fixes #51334. + +2001-02-14 Martin Baulig <baulig@suse.de> + + * proctime.c (glibtop_get_proc_time_p): Make things work on + OpenBSD 2.6; this is basically the same than on NetBSD. + +2000-02-13 Martin Baulig <martin@home-of-linux.org> + + * *.c: kvm_nlist () returns -1 on error, but a positive return value + does not necessarily mean failure. Fixes #3302 which was reported by + Matthias Scheler some time ago. + +1999-10-16 Martin Baulig <martin@home-of-linux.org> + + Applied all patches from the FreeBSD 3.3 ports collection. + + * swap.c: Only #include <rlist.h> for __FreeBSD_version < 400005. + + * prockernel.c: Make it compile on FreeBSD / alpha. + + * procsignal.c: Some fixes for FreeBSD-current. + +1999-10-16 Martin Baulig <martin@home-of-linux.org> + + * procstate.c (glibtop_get_proc_state_p): Don't use the + `GLIBTOP_PROCESS_*' constants for process states for + LibGTop 1.0.x. + +1999-07-29 Martin Baulig <martin@home-of-linux.org> + + * proctime.c (glibtop_get_proc_time_p): Fix bug reported by + Takis Psarogiannakopoulos: `start_time' are seconds since the + epoch as it is stated in the manual. + +Tue Jun 15 16:04:10 1999 Timur Bakeyev <mc@bat.ru> + + * procuid.c: A fix to a ommitted case, when nor NetBSD, nor + LibGTop >= 1.1.0. This should be investigated closely to cover + more cases.... + +1999-05-26 Martin Baulig <martin@home-of-linux.org> + + More NetBSD 1.4 fixes. + + * mem.c, procmap.c, procmem.c: Make this work with the new UVM code. + + [FIXME: This following most likely works on all BSD systems, but + this needs to be tested; I made it conditional to NetBSD 1.4 at + the moment. Please extend the conditionals to any other systems + where this works ...] + + * procstate.c: Added `ruid' and `rgid' for LibGTop >= 1.1.0. + * procuid.c: Added `ngroups' and `groups' for LibGTop >= 1.1.0. + +1999-05-25 Martin Baulig <martin@home-of-linux.org> + + * ppp.c: Make this work on NetBSD. + +Thu Apr 8 23:47:29 1999 Timur Bakeyev <timur@gnu.org> + + * cpu.c, mem.c, netload.c, procargs.c, procstate.c, proctime.c, + sem_limits.c, shm_limits.c, swap.c: Added initial port for BSD/OS + (aka BSDI) 2.x and 3.x. 4.x should also(?) work. + + Still, this port require more close look and extended check. + +1999-03-19 Martin Baulig <martin@home-of-linux.org> + + Added basic support for BSDI. It compiles without problems on + BSDI 2.1 and 3.1, but it is *untested* - I'm neither root on + the machine nor have I access to /dev/kmem, so I don't know + whether it will work. + + You need to give configure the `--enable-hacker-mode' parameter + to use the code. + + If someone can verify whether it actually works, please let me + know. + +1999-03-18 Martin Baulig <martin@home-of-linux.org> + + * ppp.c: Don't use `sppp.pp_phase' if we don't HAVE_I4B_ACCT. + This is an ugly hack until someone tells me which versions have + this field and which not. + +1999-02-25 Martin Baulig <martin@home-of-linux.org> + + * prockernel.c, proctime.c: Applied patch Stanislav Grozev for + OpenBSD: only include <osreldate.h> for FreeBSD. + +1999-02-24 Martin Baulig <martin@home-of-linux.org> + + * swap.c: Applied another patch from Jeremy Lea to + make it work with FreeBSD-current. + +1999-02-21 Martin Baulig <martin@home-of-linux.org> + + * procmap.c, procmem.c: Applied patch from Jeremy Lea. + + * prockernel.c, proctime.c: Applied patch from the FreeBSD 2.2.8 + ports collection. + + * procsignal.c: Applied patch from the NetBSD-current ports + collection. + +1998-12-06 Martin Baulig <martin@home-of-linux.org> + + * Make it work with OpenBSD 2.4. + +1998-12-05 Martin Baulig <martin@home-of-linux.org> + + * Make it work with NetBSD 1.3.2. + +1998-11-17 Martin Baulig <martin@home-of-linux.org> + + * Make it work with FreeBSD 3.0. + +1998-11-11 Martin Baulig <martin@home-of-linux.org> + + * *.c: It does not work to get information about the swapper task + on FreeBSD 2.2.6, so we simple return if pid == 0. + +1998-10-31 Martin Baulig <martin@home-of-linux.org> + + * *.c: Use glibtop_warn_io_r () instead of glibtop_error_io_r (). + + * proctime.c, prockernel.c, procargs.c: Don't call kvm_uread () if + the /proc filesystem is not mounted. + +1998-10-26 Martin Baulig <martin@home-of-linux.org> + + * netload.c: New file to get network load. + +1998-10-26 Martin Baulig <martin@home-of-linux.org> + + * procargs.c: New file to get command line arguments. + +1998-10-25 Martin Baulig <martin@home-of-linux.org> + + * ppp.c: New file to get PPP/ISDN statistics. Currently this only + get ISDN statistics if you have the I4B package. + + To get the number of bytes transferred in/out you need to read the + file `misc/i4b_acct.txt' in the LibGTop source directory to see + how to enable this. + +1998-10-03 Martin Baulig <martin@home-of-linux.org> + + * procstate.c (glibtop_get_procstate_s): Use correct values for + the `state' field. + + * proclist.c (glibtop_get_proclist_p): Honor the GLIBTOP_EXCLUDE_IDLE + and GLIBTOP_EXCLUDE_SYSTEM flags of the `which' parameter. + +1998-08-24 Martin Baulig <martin@home-of-linux.org> + + * *.c (glibtop_init_p): Using correct `(1 << GLIBTOP_SYSDPES_*)'. + * cpu.c, mem.c: Removed `const' from sysctl () constants to keep + compiler happy. + + * procmem.c: Added missing call to `glibtop_init_p'. + + * prockernel.c: Casting `nwchan' to `unsigned long' since this + normally has the same size than a pointer. Well, is there a + FreeBSD for 64bit architectures ? + +1998-08-08 Martin Baulig <martin@home-of-linux.org> + + * swap.c: Added swap usage based upton the source code + of `pinfo'. + +1998-08-07 Martin Baulig <martin@home-of-linux.org> + + * *: Imported FreeBSD port of libgtop from Josh Sled. + + * ChangeLog: New file. diff --git a/sysdeps/bsd/Makefile.am b/sysdeps/bsd/Makefile.am new file mode 100644 index 00000000..9ec00a3c --- /dev/null +++ b/sysdeps/bsd/Makefile.am @@ -0,0 +1,23 @@ + +INCLUDES = @INCLUDES@ + +noinst_LTLIBRARIES = libgtop_sysdeps-2.0.la libgtop_sysdeps_suid-2.0.la + +libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c + +libgtop_sysdeps_2_0_la_LDFLAGS = $(LT_VERSION_INFO) + +libgtop_sysdeps_suid_2_0_la_LIBADD = $(KVM_LIBS) +libgtop_sysdeps_suid_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \ + uptime.c loadavg.c shm_limits.c msg_limits.c \ + sem_limits.c proclist.c procstate.c procuid.c \ + proctime.c procmem.c procsignal.c prockernel.c \ + procsegment.c procargs.c procmap.c netlist.c \ + netload.c ppp.c procopenfiles.c fsusage.c + +libgtop_sysdeps_suid_2_0_la_LDFLAGS = $(LT_VERSION_INFO) + +libgtopinclude_HEADERS = glibtop_server.h glibtop_machine.h \ + glibtop_suid.h + +libgtopincludedir = $(includedir)/libgtop-2.0 diff --git a/sysdeps/freebsd/NOTES b/sysdeps/bsd/NOTES index 82bbbc4b..82bbbc4b 100644 --- a/sysdeps/freebsd/NOTES +++ b/sysdeps/bsd/NOTES diff --git a/sysdeps/bsd/close.c b/sysdeps/bsd/close.c new file mode 100644 index 00000000..208c6244 --- /dev/null +++ b/sysdeps/bsd/close.c @@ -0,0 +1,32 @@ +/* $Id: close.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/close.h> + +/* Closes pipe to gtop server. */ + +void +glibtop_close_p (glibtop *server) +{ } diff --git a/sysdeps/bsd/cpu.c b/sysdeps/bsd/cpu.c new file mode 100644 index 00000000..9334529d --- /dev/null +++ b/sysdeps/bsd/cpu.c @@ -0,0 +1,144 @@ +/* $Id: cpu.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/cpu.h> + +#include <glibtop_suid.h> + +#ifdef __NetBSD__ +#include <sys/sched.h> +#endif + +static const unsigned long _glibtop_sysdeps_cpu = +(1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_USER) + +(1L << GLIBTOP_CPU_NICE) + (1L << GLIBTOP_CPU_SYS) + +(1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_CPU_FREQUENCY) + +(1L << GLIBTOP_CPU_IOWAIT); + +#ifndef KERN_CP_TIME +/* nlist structure for kernel access */ +static struct nlist nlst [] = { +#ifdef __bsdi__ + { "_cpustats" }, +#else + { "_cp_time" }, +#endif + { 0 } +}; +#endif + +/* MIB array for sysctl */ +static int mib_length=2; +static int mib [] = { CTL_KERN, KERN_CLOCKRATE }; +#ifdef KERN_CP_TIME +static int mib2 [] = { CTL_KERN, KERN_CP_TIME }; +#endif + +/* Init function. */ + +void +glibtop_init_cpu_p (glibtop *server) +{ +#ifndef KERN_CP_TIME + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (cpu)"); + return; + } +#endif + + /* Set this only if kvm_nlist () succeeded. */ + server->sysdeps.cpu = _glibtop_sysdeps_cpu; +} + +/* Provides information about cpu usage. */ + +void +glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf) +{ +#ifdef KERN_CP_TIME + guint64 cpts [CPUSTATES]; +#else + long cpts [CPUSTATES]; +#endif + /* sysctl vars*/ + struct clockinfo ci; + size_t length; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_CPU), 0); + + memset (buf, 0, sizeof (glibtop_cpu)); + + /* If this fails, the nlist may not be valid. */ + if (server->sysdeps.cpu == 0) + return; + +#ifdef KERN_CP_TIME + length = sizeof (cpts); + if (sysctl (mib2, mib_length, cpts, &length, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl"); + return; + } +#else + if (kvm_read (server->machine.kd, nlst [0].n_value, + &cpts, sizeof (cpts)) != sizeof (cpts)) { + glibtop_warn_io_r (server, "kvm_read (cp_time)"); + return; + } +#endif + + /* Get the clockrate data */ + length = sizeof (struct clockinfo); + if (sysctl (mib, mib_length, &ci, &length, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl"); + return; + } + + /* set user time */ + buf->user = cpts [CP_USER]; + /* set nice time */ + buf->nice = cpts [CP_NICE]; + /* set sys time */ + buf->sys = cpts [CP_SYS]; + /* set idle time */ + buf->idle = cpts [CP_IDLE]; + /* set iowait (really just interrupt) time */ + buf->iowait = cpts [CP_INTR]; + + /* set frequency */ + /* + FIXME -- is hz, tick, profhz or stathz wanted? + buf->frequency = sysctl("kern.clockrate", ...); + + struct clockinfo + */ + buf->frequency = ci.hz; + /* set total */ + buf->total = cpts [CP_USER] + cpts [CP_NICE] + + cpts [CP_SYS] + cpts [CP_IDLE]; + + /* Set the flags last. */ + buf->flags = _glibtop_sysdeps_cpu; +} diff --git a/sysdeps/bsd/fsusage.c b/sysdeps/bsd/fsusage.c new file mode 100644 index 00000000..5f592b5d --- /dev/null +++ b/sysdeps/bsd/fsusage.c @@ -0,0 +1,60 @@ +#include <config.h> + +/* Although FreeBSD ships with statvfs it seems incomplete, so prefer statfs */ +#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) +#undef HAVE_SYS_STATVFS_H +#undef STAT_STATVFS +#endif + +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/fsusage.h> + +#include <glibtop_suid.h> + +#include <glib.h> + +#include <unistd.h> +#include <sys/param.h> +#if defined (HAVE_SYS_STATVFS_H) +#include <sys/statvfs.h> +#else +#include <sys/mount.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +void +G_GNUC_INTERNAL +_glibtop_bsd_get_fsusage_read_write(glibtop *server, + glibtop_fsusage *buf, + const char *path); + +void G_GNUC_INTERNAL +_glibtop_bsd_get_fsusage_read_write(glibtop *server, + glibtop_fsusage *buf, + const char *path) +{ + int result; +#if defined (STAT_STATVFS) + struct statvfs sfs; +#else + struct statfs sfs; +#endif + +#if defined (STAT_STATVFS) + result = statvfs (path, &sfs); +#else + result = statfs (path, &sfs); +#endif + + if (result == -1) { + return; + } + + buf->read = sfs.f_syncreads + sfs.f_asyncreads; + buf->write = sfs.f_syncwrites + sfs.f_asyncwrites; + buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE); +} diff --git a/sysdeps/bsd/glibtop_machine.h b/sysdeps/bsd/glibtop_machine.h new file mode 100644 index 00000000..a40a2ad7 --- /dev/null +++ b/sysdeps/bsd/glibtop_machine.h @@ -0,0 +1,67 @@ +/* $Id: glibtop_machine.h 2003 2004-06-09 18:52:22Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_MACHINE_H__ +#define __GLIBTOP_MACHINE_H__ + +#include <sys/param.h> +#include <nlist.h> +#include <kvm.h> +#include <sys/dkstat.h> +#include <time.h> +#include <sys/user.h> +#include <sys/types.h> +#include <sys/sysctl.h> + +#include <fcntl.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +#ifdef __NetBSD__ +#include <sys/proc.h> + +#ifndef SRUN +#define SRUN SACTIVE +#endif +#endif + +G_BEGIN_DECLS + +typedef struct _glibtop_machine glibtop_machine; + +struct _glibtop_machine +{ + uid_t uid, euid; + gid_t gid, egid; + + /* The kernel descriptor, used by kvm_* calls. We keep and re-use + * it rather than re-getting it for almost all function + * invocations. */ + kvm_t *kd; +}; + +G_END_DECLS + +#endif /* __GLIBTOP_MACHINE_H__ */ diff --git a/sysdeps/bsd/glibtop_server.h b/sysdeps/bsd/glibtop_server.h new file mode 100644 index 00000000..c107055f --- /dev/null +++ b/sysdeps/bsd/glibtop_server.h @@ -0,0 +1,53 @@ +/* $Id: glibtop_server.h 2469 2006-04-04 20:06:14Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_SERVER_H__ +#define __GLIBTOP_SERVER_H__ + +G_BEGIN_DECLS + +#define GLIBTOP_SUID_CPU (1 << GLIBTOP_SYSDEPS_CPU) +#define GLIBTOP_SUID_MEM (1 << GLIBTOP_SYSDEPS_MEM) +#define GLIBTOP_SUID_SWAP (1 << GLIBTOP_SYSDEPS_SWAP) +#define GLIBTOP_SUID_UPTIME (1 << GLIBTOP_SYSDEPS_UPTIME) +#define GLIBTOP_SUID_LOADAVG (1 << GLIBTOP_SYSDEPS_LOADAVG) +#define GLIBTOP_SUID_SHM_LIMITS (1 << GLIBTOP_SYSDEPS_SHM_LIMITS) +#define GLIBTOP_SUID_MSG_LIMITS (1 << GLIBTOP_SYSDEPS_MSG_LIMITS) +#define GLIBTOP_SUID_SEM_LIMITS (1 << GLIBTOP_SYSDEPS_SEM_LIMITS) +#define GLIBTOP_SUID_PROCLIST (1 << GLIBTOP_SYSDEPS_PROCLIST) +#define GLIBTOP_SUID_PROC_STATE (1 << GLIBTOP_SYSDEPS_PROC_STATE) +#define GLIBTOP_SUID_PROC_UID (1 << GLIBTOP_SYSDEPS_PROC_UID) +#define GLIBTOP_SUID_PROC_MEM (1 << GLIBTOP_SYSDEPS_PROC_MEM) +#define GLIBTOP_SUID_PROC_TIME (1 << GLIBTOP_SYSDEPS_PROC_TIME) +#define GLIBTOP_SUID_PROC_SIGNAL (1 << GLIBTOP_SYSDEPS_PROC_SIGNAL) +#define GLIBTOP_SUID_PROC_KERNEL (1 << GLIBTOP_SYSDEPS_PROC_KERNEL) +#define GLIBTOP_SUID_PROC_SEGMENT (1 << GLIBTOP_SYSDEPS_PROC_SEGMENT) +#define GLIBTOP_SUID_PROC_ARGS (1 << GLIBTOP_SYSDEPS_PROC_ARGS) +#define GLIBTOP_SUID_PROC_MAP (1 << GLIBTOP_SYSDEPS_PROC_MAP) +#define GLIBTOP_SUID_NETLOAD (1 << GLIBTOP_SYSDEPS_NETLOAD) +#define GLIBTOP_SUID_NETLIST 0 +#define GLIBTOP_SUID_PPP (1 << GLIBTOP_SYSDEPS_PPP) + +G_END_DECLS + +#endif diff --git a/sysdeps/bsd/glibtop_suid.h b/sysdeps/bsd/glibtop_suid.h new file mode 100644 index 00000000..371e3a80 --- /dev/null +++ b/sysdeps/bsd/glibtop_suid.h @@ -0,0 +1,58 @@ +/* $Id: glibtop_suid.h 1862 2003-10-20 15:20:16Z hadess $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_SUID_H__ +#define __GLIBTOP_SUID_H__ + +G_BEGIN_DECLS + +#if _IN_LIBGTOP +#include <sys/param.h> +#endif + +#define KI_PROC(ki) (&(ki))->kp_proc) +#define KI_EPROC(ki) (&(ki))->kp_eproc) + +#define FORCEUREAD 1 +#define UREADOK(ki) (FORCEUREAD || (KI_PROC(ki)->p_flag & P_INMEM)) + +static inline void glibtop_suid_enter (glibtop *server) { + setregid (server->machine.gid, server->machine.egid); +}; + +static inline void glibtop_suid_leave (glibtop *server) { + if (setregid (server->machine.egid, server->machine.gid)) + _exit (1); +}; + +void +glibtop_init_p (glibtop *server, const unsigned long features, + const unsigned flags); +void +glibtop_open_p (glibtop *server, const char *program_name, + const unsigned long features, + const unsigned flags); + +G_END_DECLS + +#endif diff --git a/sysdeps/freebsd/init.c b/sysdeps/bsd/init.c index d43b71f8..27998cc7 100644 --- a/sysdeps/freebsd/init.c +++ b/sysdeps/bsd/init.c @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id: init.c 2422 2005-12-12 09:38:15Z jamesh $ */ /* Copyright (C) 1998 Joshua Sled This file is part of LibGTop 1.0. diff --git a/sysdeps/bsd/loadavg.c b/sysdeps/bsd/loadavg.c new file mode 100644 index 00000000..d633d8d9 --- /dev/null +++ b/sysdeps/bsd/loadavg.c @@ -0,0 +1,61 @@ +/* $Id: loadavg.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/loadavg.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_loadavg = +(1L << GLIBTOP_LOADAVG_LOADAVG); + +/* Init function. */ + +void +glibtop_init_loadavg_p (glibtop *server) +{ + server->sysdeps.loadavg = _glibtop_sysdeps_loadavg; +} + +/* Provides load averange. */ + +void +glibtop_get_loadavg_p (glibtop *server, glibtop_loadavg *buf) +{ + double ldavg[3]; + int i; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_LOADAVG), 0); + + memset (buf, 0, sizeof (glibtop_loadavg)); + + getloadavg (ldavg, 3); + + /* fill in the struct */ + buf->flags = _glibtop_sysdeps_loadavg; + for (i = 0; i < 3; i++) { + buf->loadavg [i] = ldavg [i]; + } /* end for */ +} diff --git a/sysdeps/bsd/mem.c b/sysdeps/bsd/mem.c new file mode 100644 index 00000000..55aeaadf --- /dev/null +++ b/sysdeps/bsd/mem.c @@ -0,0 +1,224 @@ +/* $Id: mem.c 2536 2006-11-27 19:22:45Z bdejean $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/mem.h> + +#include <glibtop_suid.h> + +#include <sys/sysctl.h> +#include <sys/vmmeter.h> +#if defined(__NetBSD__) && (__NetBSD_Version__ < 105020000) +#include <vm/vm_param.h> +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) +#include <uvm/uvm_extern.h> +#endif + +static const unsigned long _glibtop_sysdeps_mem = +(1L << GLIBTOP_MEM_TOTAL) + (1L << GLIBTOP_MEM_USED) + +(1L << GLIBTOP_MEM_FREE) + +(1L << GLIBTOP_MEM_SHARED) + +(1L << GLIBTOP_MEM_BUFFER) + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +(1L << GLIBTOP_MEM_CACHED) + +#endif +(1L << GLIBTOP_MEM_USER) + (1L << GLIBTOP_MEM_LOCKED); + +#ifndef LOG1024 +#define LOG1024 10 +#endif + +/* these are for getting the memory statistics */ +static int pageshift; /* log base 2 of the pagesize */ + +/* define pagetok in terms of pageshift */ +#define pagetok(size) ((size) << pageshift) + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + { "_bufpages" }, + { 0 } +#else +#if defined(__bsdi__) + { "_bufcachemem" }, +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + { "_bufspace" }, +#else + { "_bufpages" }, +#endif + { "_cnt" }, + { 0 } +#endif +}; + +/* MIB array for sysctl */ +#ifdef __bsdi__ +static int mib [] = { CTL_VM, VM_TOTAL }; +#else +static int mib [] = { CTL_VM, VM_METER }; +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) +static int mib_uvmexp [] = { CTL_VM, VM_UVMEXP }; +#endif + +/* Init function. */ + +void +glibtop_init_mem_p (glibtop *server) +{ + register int pagesize; + + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (mem)"); + return; + } + + /* get the page size with "getpagesize" and calculate pageshift + * from it */ + pagesize = getpagesize (); + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= LOG1024; + + server->sysdeps.mem = _glibtop_sysdeps_mem; +} + +void +glibtop_get_mem_p (glibtop *server, glibtop_mem *buf) +{ + struct vmtotal vmt; + size_t length_vmt; +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + struct uvmexp uvmexp; + size_t length_uvmexp; +#else + struct vmmeter vmm; +#endif + u_int v_used_count; + u_int v_total_count; + u_int v_free_count; + int bufspace; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MEM), 0); + + memset (buf, 0, sizeof (glibtop_mem)); + + if (server->sysdeps.mem == 0) + return; + + /* [FIXME: On FreeBSD 2.2.6, sysctl () returns an incorrect + * value for `vmt.vm'. We use some code from Unix top + * here.] */ + + /* Get the data from sysctl */ + length_vmt = sizeof (vmt); + if (sysctl (mib, 2, &vmt, &length_vmt, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (vmt)"); + return; + } + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + length_uvmexp = sizeof (uvmexp); + if (sysctl (mib_uvmexp, 2, &uvmexp, &length_uvmexp, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (uvmexp)"); + return; + } +#else + /* Get the data from kvm_* */ + if (kvm_read (server->machine.kd, nlst[1].n_value, + &vmm, sizeof (vmm)) != sizeof (vmm)) { + glibtop_warn_io_r (server, "kvm_read (cnt)"); + return; + } +#endif + + if (kvm_read (server->machine.kd, nlst[0].n_value, + &bufspace, sizeof (bufspace)) != sizeof (bufspace)) { + glibtop_warn_io_r (server, "kvm_read (bufspace)"); + return; + } + + /* convert memory stats to Kbytes */ + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + v_total_count = vmm.v_page_count; +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + v_total_count = uvmexp.reserve_kernel + + uvmexp.reserve_pagedaemon + + uvmexp.free + uvmexp.wired + uvmexp.active + + uvmexp.inactive; +#else + v_total_count = vmm.v_kernel_pages + + vmm.v_free_count + vmm.v_wire_count + + vmm.v_active_count + vmm.v_inactive_count; +#endif +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + v_used_count = uvmexp.active + uvmexp.inactive; + v_free_count = uvmexp.free; +#else + v_used_count = vmm.v_active_count + vmm.v_inactive_count; + v_free_count = vmm.v_free_count; +#endif + + buf->total = (guint64) pagetok (v_total_count) << LOG1024; + buf->used = (guint64) pagetok (v_used_count) << LOG1024; + buf->free = (guint64) pagetok (v_free_count) << LOG1024; + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + buf->cached = (guint64) pagetok (vmm.v_cache_count) << LOG1024; +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + buf->locked = (guint64) pagetok (uvmexp.wired) << LOG1024; +#else + buf->locked = (guint64) pagetok (vmm.v_wire_count) << LOG1024; +#endif + + buf->shared = (guint64) pagetok (vmt.t_rmshr) << LOG1024; + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + buf->buffer = (guint64) bufspace; +#else + buf->buffer = (guint64) pagetok (bufspace) << LOG1024; +#endif + + /* user */ + buf->user = buf->total - buf->free - buf->shared - buf->buffer; + + /* Set the values to return */ + buf->flags = _glibtop_sysdeps_mem; +} diff --git a/sysdeps/bsd/msg_limits.c b/sysdeps/bsd/msg_limits.c new file mode 100644 index 00000000..6daf5f17 --- /dev/null +++ b/sysdeps/bsd/msg_limits.c @@ -0,0 +1,116 @@ +/* $Id: msg_limits.c 2475 2006-04-09 10:50:43Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, August 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/msg_limits.h> + +#include <glibtop_suid.h> + +#if (defined __bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_msg_limits_p (glibtop *server) +{ } + +void +glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MSG_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_msg_limits)); +} + +#else + +/* Define the appropriate macro (if any) to get declaration of `struct + * msginfo'. Needed on, at least, FreeBSD. */ +#if defined (STRUCT_MSGINFO_NEEDS_KERNEL) +#define KERNEL 1 +#elif defined (STRUCT_MSGINFO_NEEDS__KERNEL) +#define _KERNEL 1 +#endif + +#include <sys/ipc.h> +#include <sys/msg.h> + +static const unsigned long _glibtop_sysdeps_msg_limits = +(1L << GLIBTOP_IPC_MSGMAX) + (1L << GLIBTOP_IPC_MSGMNI) + +(1L << GLIBTOP_IPC_MSGMNB) + (1L << GLIBTOP_IPC_MSGTQL) + +(1L << GLIBTOP_IPC_MSGSSZ); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_msginfo' + * since `msginfo' is already declared external in <sys/msg.h>. */ +static struct msginfo _msginfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_msginfo" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_msg_limits_p (glibtop *server) +{ + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (msg_limits)"); + return; + } + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_msginfo, sizeof (_msginfo)) != sizeof (_msginfo)) { + glibtop_warn_io_r (server, "kvm_read (msginfo)"); + return; + } + + server->sysdeps.msg_limits = _glibtop_sysdeps_msg_limits; +} + +/* Provides information about sysv ipc limits. */ + +void +glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MSG_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_msg_limits)); + + if (server->sysdeps.msg_limits == 0) + return; + + buf->msgmax = _msginfo.msgmax; + buf->msgmni = _msginfo.msgmni; + buf->msgmnb = _msginfo.msgmnb; + buf->msgtql = _msginfo.msgtql; + buf->msgssz = _msginfo.msgtql; + + buf->flags = _glibtop_sysdeps_msg_limits; +} + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/bsd/netlist.c b/sysdeps/bsd/netlist.c new file mode 100644 index 00000000..d20a204a --- /dev/null +++ b/sysdeps/bsd/netlist.c @@ -0,0 +1,68 @@ +/* $Id: netlist.c 2303 2005-02-28 08:15:59Z bdejean $ */ + +/* + This file is part of LibGTop 2.0. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop/netlist.h> +#include <glibtop/error.h> + +#include <net/if.h> + + +static const unsigned long _glibtop_sysdeps_netlist = (1 << GLIBTOP_NETLIST_NUMBER); + +/* Init function. */ + +void +glibtop_init_netlist_s (glibtop *server) +{ + server->sysdeps.netlist = _glibtop_sysdeps_netlist; +} + + +char** +glibtop_get_netlist_s (glibtop *server, glibtop_netlist *buf) +{ + struct if_nameindex *ifstart, *ifs; + GPtrArray *devices; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_NETLIST, 0); + + memset (buf, 0, sizeof (glibtop_netlist)); + + ifs = ifstart = if_nameindex(); + + devices = g_ptr_array_new(); + + while(ifs && ifs->if_name) { + g_ptr_array_add(devices, g_strdup(ifs->if_name)); + buf->number++; + ifs++; + } + + if_freenameindex(ifstart); + + buf->flags = _glibtop_sysdeps_netlist; + + g_ptr_array_add(devices, NULL); + + return (char **) g_ptr_array_free(devices, FALSE); +} + diff --git a/sysdeps/bsd/netload.c b/sysdeps/bsd/netload.c new file mode 100644 index 00000000..a66b57e0 --- /dev/null +++ b/sysdeps/bsd/netload.c @@ -0,0 +1,242 @@ +/* $Id: netload.c 2550 2007-01-31 21:23:21Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, October 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/netload.h> + +#include <glibtop_suid.h> + +#include <string.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> + +#ifdef HAVE_NET_IF_VAR_H +#include <net/if_var.h> +#endif + +#include <netinet/in.h> +#include <netinet/in_var.h> + +static const unsigned long _glibtop_sysdeps_netload = +(1L << GLIBTOP_NETLOAD_IF_FLAGS) + +(1L << GLIBTOP_NETLOAD_PACKETS_IN) + +(1L << GLIBTOP_NETLOAD_PACKETS_OUT) + +(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) + +(1L << GLIBTOP_NETLOAD_BYTES_IN) + +(1L << GLIBTOP_NETLOAD_BYTES_OUT) + +(1L << GLIBTOP_NETLOAD_BYTES_TOTAL) + +(1L << GLIBTOP_NETLOAD_ERRORS_IN) + +(1L << GLIBTOP_NETLOAD_ERRORS_OUT) + +(1L << GLIBTOP_NETLOAD_ERRORS_TOTAL) + +(1L << GLIBTOP_NETLOAD_COLLISIONS); + +static const unsigned _glibtop_sysdeps_netload_data = +(1L << GLIBTOP_NETLOAD_ADDRESS) + +#if !defined(__bsdi__) +(1L << GLIBTOP_NETLOAD_SUBNET) + +#endif +(1L << GLIBTOP_NETLOAD_MTU); + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_ifnet" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_netload_p (glibtop *server) +{ + server->sysdeps.netload = _glibtop_sysdeps_netload; + + if (kvm_nlist (server->machine.kd, nlst) < 0) + glibtop_error_io_r (server, "kvm_nlist"); +} + +/* Provides Network statistics. */ + +void +glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, + const char *interface) +{ + struct ifnet ifnet; + u_long ifnetaddr, ifnetfound; + struct sockaddr *sa = NULL; +#if (defined(__FreeBSD__) && (__FreeBSD_version < 501113)) || defined(__bsdi__) + char tname [16]; +#endif + char name [32]; + + union { + struct ifaddr ifa; + struct in_ifaddr in; + } ifaddr; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_NETLOAD), 0); + + memset (buf, 0, sizeof (glibtop_netload)); + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &ifnetaddr, sizeof (ifnetaddr)) != sizeof (ifnetaddr)) + glibtop_error_io_r (server, "kvm_read (ifnet)"); + + while (ifnetaddr) { + struct sockaddr_in *sin; + register char *cp; + u_long ifaddraddr; + + { + ifnetfound = ifnetaddr; + + if (kvm_read (server->machine.kd, ifnetaddr, &ifnet, + sizeof (ifnet)) != sizeof (ifnet)) + glibtop_error_io_r (server, "kvm_read (ifnetaddr)"); + +#if (defined(__FreeBSD__) && (__FreeBSD_version < 501113)) || defined(__bsdi__) + if (kvm_read (server->machine.kd, (u_long) ifnet.if_name, + tname, 16) != 16) + glibtop_error_io_r (server, "kvm_read (if_name)"); + tname[15] = '\0'; + snprintf (name, 32, "%s%d", tname, ifnet.if_unit); +#else + g_strlcpy (name, ifnet.if_xname, sizeof(name)); +#endif +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) + ifnetaddr = (u_long) ifnet.if_link.tqe_next; +#elif defined(__FreeBSD__) || defined(__bsdi__) + ifnetaddr = (u_long) ifnet.if_next; +#else + ifnetaddr = (u_long) ifnet.if_list.tqe_next; +#endif + + if (strcmp (name, interface) != 0) + continue; + +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) + ifaddraddr = (u_long) ifnet.if_addrhead.tqh_first; +#elif defined(__FreeBSD__) || defined(__bsdi__) + ifaddraddr = (u_long) ifnet.if_addrlist; +#else + ifaddraddr = (u_long) ifnet.if_addrlist.tqh_first; +#endif + } + if (ifnet.if_flags & IFF_UP) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP); + if (ifnet.if_flags & IFF_BROADCAST) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST); + if (ifnet.if_flags & IFF_DEBUG) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG); + if (ifnet.if_flags & IFF_LOOPBACK) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK); + if (ifnet.if_flags & IFF_POINTOPOINT) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT); +#ifdef IFF_DRV_RUNNING + if (ifnet.if_drv_flags & IFF_DRV_RUNNING) +#else + if (ifnet.if_flags & IFF_RUNNING) +#endif + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING); + if (ifnet.if_flags & IFF_NOARP) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP); + if (ifnet.if_flags & IFF_PROMISC) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC); + if (ifnet.if_flags & IFF_ALLMULTI) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI); +#ifdef IFF_DRV_OACTIVE + if (ifnet.if_drv_flags & IFF_DRV_OACTIVE) +#else + if (ifnet.if_flags & IFF_OACTIVE) +#endif + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_OACTIVE); + if (ifnet.if_flags & IFF_SIMPLEX) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_SIMPLEX); + if (ifnet.if_flags & IFF_LINK0) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK0); + if (ifnet.if_flags & IFF_LINK1) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK1); + if (ifnet.if_flags & IFF_LINK2) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK2); +#ifdef __FreeBSD__ + if (ifnet.if_flags & IFF_ALTPHYS) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALTPHYS); +#endif + if (ifnet.if_flags & IFF_MULTICAST) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST); + + buf->packets_in = ifnet.if_ipackets; + buf->packets_out = ifnet.if_opackets; + buf->packets_total = buf->packets_in + buf->packets_out; + + buf->bytes_in = ifnet.if_ibytes; + buf->bytes_out = ifnet.if_obytes; + buf->bytes_total = buf->bytes_in + buf->bytes_out; + + buf->errors_in = ifnet.if_ierrors; + buf->errors_out = ifnet.if_oerrors; + buf->errors_total = buf->errors_in + buf->errors_out; + + buf->collisions = ifnet.if_collisions; + buf->flags = _glibtop_sysdeps_netload; + + while (ifaddraddr) { + if ((kvm_read (server->machine.kd, ifaddraddr, &ifaddr, + sizeof (ifaddr)) != sizeof (ifaddr))) + glibtop_error_io_r (server, "kvm_read (ifaddraddr)"); + +#define CP(x) ((char *)(x)) + cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + + CP(&ifaddr); + sa = (struct sockaddr *)cp; + + if (sa->sa_family == AF_LINK) { + struct sockaddr_dl *dl = (struct sockaddr_dl *) sa; + + memcpy (buf->hwaddress, LLADDR (dl), sizeof (buf->hwaddress)); + buf->flags |= GLIBTOP_NETLOAD_HWADDRESS; + } else if (sa->sa_family == AF_INET) { + sin = (struct sockaddr_in *)sa; +#if !defined(__bsdi__) + /* Commenting out to "fix" #13345. */ + buf->subnet = htonl (ifaddr.in.ia_subnet); +#endif + buf->address = sin->sin_addr.s_addr; + buf->mtu = ifnet.if_mtu; + + buf->flags |= _glibtop_sysdeps_netload_data; + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + + memcpy (buf->address6, &sin6->sin6_addr, sizeof (buf->address6)); + buf->flags |= GLIBTOP_NETLOAD_ADDRESS6; + } + /* FIXME prefix6, scope6 */ + ifaddraddr = (u_long) ifaddr.ifa.ifa_link.tqe_next; + } + return; + } +} diff --git a/sysdeps/bsd/nosuid.c b/sysdeps/bsd/nosuid.c new file mode 100644 index 00000000..2dcac5b5 --- /dev/null +++ b/sysdeps/bsd/nosuid.c @@ -0,0 +1,38 @@ +/* $Id: nosuid.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/open.h> +#include <glibtop/close.h> + +void +glibtop_open_s (glibtop *server, + const char *program_name, + const unsigned long features, + const unsigned flags) +{ } + +void +glibtop_close_s (glibtop *server) +{ } diff --git a/sysdeps/bsd/open.c b/sysdeps/bsd/open.c new file mode 100644 index 00000000..41d82c44 --- /dev/null +++ b/sysdeps/bsd/open.c @@ -0,0 +1,96 @@ +/* $Id: open.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/open.h> +#include <glibtop/init_hooks.h> + +/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */ + +void +glibtop_init_p (glibtop *server, const unsigned long features, + const unsigned flags) +{ + const glibtop_init_func_t *init_fkt; + + if (server == NULL) + glibtop_error_r (NULL, "glibtop_init_p (server == NULL)"); + + /* Do the initialization, but only if not already initialized. */ + + if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) { + glibtop_open_p (server, "glibtop", features, flags); + + for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++) + (*init_fkt) (server); + + server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS; + } +} + +void +glibtop_open_p (glibtop *server, const char *program_name, + const unsigned long features, + const unsigned flags) +{ +#ifdef DEBUG + fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ()); +#endif + + /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */ + + server->machine.uid = getuid (); + server->machine.euid = geteuid (); + server->machine.gid = getgid (); + server->machine.egid = getegid (); + +#ifdef __FreeBSD__ + server->os_version_code = __FreeBSD_version; +#endif + + /* Setup machine-specific data */ + server->machine.kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "kvm_open"); + + if (server->machine.kd == NULL) + glibtop_error_io_r (server, "kvm_open"); + + /* Drop priviledges. */ + + if (setreuid (server->machine.euid, server->machine.uid)) + _exit (1); + + if (setregid (server->machine.egid, server->machine.gid)) + _exit (1); + + /* !!! END OF SUID ROOT PART !!! */ + + /* Our effective uid is now those of the user invoking the server, + * so we do no longer have any priviledges. */ + + /* NOTE: On FreeBSD, we do not need to be suid root, we just need to + * be sgid kmem. + * + * The server will only use setegid() to get back it's priviledges, + * so it will fail if it is suid root and not sgid kmem. */ +} diff --git a/sysdeps/bsd/ppp.c b/sysdeps/bsd/ppp.c new file mode 100644 index 00000000..e0a2fed6 --- /dev/null +++ b/sysdeps/bsd/ppp.c @@ -0,0 +1,145 @@ +/* $Id: ppp.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, October 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/ppp.h> + +#include <glibtop_suid.h> + +#ifdef HAVE_I4B + +#include <net/if.h> +#include <net/if_types.h> + +#ifdef HAVE_NET_IF_VAR_H +#include <net/if_var.h> +#endif + +#include <net/netisr.h> +#include <net/route.h> + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include <net/if_sppp.h> +#else +#include <i4b/sppp/if_sppp.h> +#endif + +/* Read `misc/i4b_acct.txt' for details ... */ +#ifdef HAVE_I4B_ACCT +#include <machine/i4b_acct.h> +#endif + +static const unsigned long _glibtop_sysdeps_ppp = +(1L << GLIBTOP_PPP_STATE); + +#ifdef HAVE_I4B_ACCT +static const unsigned long _glibtop_sysdeps_ppp_acct = +(1L << GLIBTOP_PPP_BYTES_IN) + (1L << GLIBTOP_PPP_BYTES_OUT); +#endif + +#endif /* HAVE_I4B */ + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { +#ifdef HAVE_I4B + { "_i4bisppp_softc" }, +#endif + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_ppp_p (glibtop *server) +{ +#ifdef HAVE_I4B +#ifdef HAVE_I4B_ACCT + server->sysdeps.ppp = _glibtop_sysdeps_ppp | + _glibtop_sysdeps_ppp_acct; +#else + server->sysdeps.ppp = _glibtop_sysdeps_ppp; +#endif +#endif /* HAVE_I4B */ + + if (kvm_nlist (server->machine.kd, nlst) < 0) + glibtop_error_io_r (server, "kvm_nlist"); +} + +/* Provides information about ppp usage. */ + +void +glibtop_get_ppp_p (glibtop *server, glibtop_ppp *buf, unsigned short device) +{ +#ifdef HAVE_I4B +#ifdef HAVE_I4B_ACCT + struct i4bisppp_softc data; +#else + struct sppp data; +#endif + int phase; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PPP), 0); + + memset (buf, 0, sizeof (glibtop_ppp)); + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &data, sizeof (data)) != sizeof (data)) + glibtop_error_io_r (server, "kvm_read (i4bisppp_softc)"); + +#ifdef HAVE_I4B_ACCT + phase = data.sc_if_un.scu_sp.pp_phase; +#else + /* FIXME: Which FreeBSD version have this field and + * which not. */ +#if 0 + phase = data.pp_phase; +#endif +#endif + + switch (phase) { +#ifdef HAVE_I4B_ACCT + case PHASE_DEAD: + case PHASE_TERMINATE: + buf->state = GLIBTOP_PPP_STATE_HANGUP; + break; + case PHASE_ESTABLISH: + case PHASE_NETWORK: + buf->state = GLIBTOP_PPP_STATE_ONLINE; + break; +#endif + default: + buf->state = GLIBTOP_PPP_STATE_UNKNOWN; + break; + } + + buf->flags = _glibtop_sysdeps_ppp; + +#ifdef HAVE_I4B_ACCT + buf->bytes_in = data.sc_inb; + buf->bytes_out = data.sc_outb; + buf->flags |= _glibtop_sysdeps_ppp_acct; +#endif +#endif /* HAVE_I4B */ +} diff --git a/sysdeps/bsd/procargs.c b/sysdeps/bsd/procargs.c new file mode 100644 index 00000000..4550fbc6 --- /dev/null +++ b/sysdeps/bsd/procargs.c @@ -0,0 +1,110 @@ +/* $Id: procargs.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procargs.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/proc.h> + +static const unsigned long _glibtop_sysdeps_proc_args = +(1L << GLIBTOP_PROC_ARGS_SIZE); + +/* Init function. */ + +void +glibtop_init_proc_args_p (glibtop *server) +{ + server->sysdeps.proc_args = _glibtop_sysdeps_proc_args; +} + +/* Provides detailed information about a process. */ + +char * +glibtop_get_proc_args_p (glibtop *server, glibtop_proc_args *buf, + pid_t pid, unsigned max_len) +{ + struct kinfo_proc *pinfo; + char *retval, **args, **ptr; + size_t size = 0, pos = 0; + int count; + +#ifndef __bsdi__ + char filename [BUFSIZ]; + struct stat statb; +#endif + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_ARGS), 0); + + memset (buf, 0, sizeof (glibtop_proc_args)); + + /* swapper, init, pagedaemon, vmdaemon, update - this doen't work. */ + if (pid < 5) return NULL; + +#ifndef __bsdi__ + sprintf (filename, "/proc/%d/mem", pid); + if (stat (filename, &statb)) return NULL; +#endif + + glibtop_suid_enter (server); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_suid_leave (server); + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return NULL; + } + + args = kvm_getargv (server->machine.kd, pinfo, max_len); + if (args == NULL) { + glibtop_suid_leave (server); + glibtop_warn_io_r (server, "kvm_getargv (%d)", pid); + return NULL; + } + + glibtop_suid_leave (server); + + for (ptr = args; *ptr; ptr++) + size += strlen (*ptr)+1; + + size += 2; + retval = g_malloc0 (size); + + for (ptr = args; *ptr; ptr++) { + const size_t len = strlen (*ptr)+1; + memcpy (retval+pos, *ptr, len); + pos += len; + } + + buf->size = pos ? pos-1 : 0; + + buf->flags = _glibtop_sysdeps_proc_args; + + return retval; +} diff --git a/sysdeps/freebsd/procdata.c b/sysdeps/bsd/procdata.c index e8503cbf..c4d1862a 100644 --- a/sysdeps/freebsd/procdata.c +++ b/sysdeps/bsd/procdata.c @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id: procdata.c 2003 2004-06-09 18:52:22Z bdejean $ */ /* Copyright (C) 1998 Joshua Sled This file is part of LibGTop 1.0. diff --git a/sysdeps/bsd/prockernel.c b/sysdeps/bsd/prockernel.c new file mode 100644 index 00000000..49003f33 --- /dev/null +++ b/sysdeps/bsd/prockernel.c @@ -0,0 +1,272 @@ +/* $Id: prockernel.c 2550 2007-01-31 21:23:21Z bdejean $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/prockernel.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/proc.h> +#if (!defined __OpenBSD__) && (!defined __bsdi__) +#include <sys/user.h> +#endif +#if !defined(__bsdi__) && !(defined(__FreeBSD__) && defined(__alpha__)) && \ + !defined(__NetBSD__) +#include <machine/pcb.h> +#endif + +#include <unistd.h> +#include <fcntl.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +#ifdef __NetBSD__ +#include <machine/vmparam.h> +#include <machine/pmap.h> +#ifdef __arm32__ +#define KERNBASE KERNEL_BASE +#endif +#endif + +#ifdef __NetBSD__ +#include <machine/vmparam.h> +#include <machine/pmap.h> +#ifdef __arm32__ +#define KERNBASE KERNEL_BASE +#endif +#endif + + +static const unsigned long _glibtop_sysdeps_proc_kernel_pstats = +(1L << GLIBTOP_PROC_KERNEL_MIN_FLT) + +(1L << GLIBTOP_PROC_KERNEL_MAJ_FLT) + +(1L << GLIBTOP_PROC_KERNEL_CMIN_FLT) + +(1L << GLIBTOP_PROC_KERNEL_CMAJ_FLT); + +static const unsigned long _glibtop_sysdeps_proc_kernel_pcb = +(1L << GLIBTOP_PROC_KERNEL_KSTK_EIP) + +(1L << GLIBTOP_PROC_KERNEL_KSTK_ESP); + +static const unsigned long _glibtop_sysdeps_proc_kernel_wchan = +(1L << GLIBTOP_PROC_KERNEL_NWCHAN) + +(1L << GLIBTOP_PROC_KERNEL_WCHAN); + +/* Init function. */ + +void +glibtop_init_proc_kernel_p (glibtop *server) +{ + server->sysdeps.proc_kernel = _glibtop_sysdeps_proc_kernel_pstats | + _glibtop_sysdeps_proc_kernel_pcb | + _glibtop_sysdeps_proc_kernel_wchan; +} + +void +glibtop_get_proc_kernel_p (glibtop *server, + glibtop_proc_kernel *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; +#if !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) + struct user *u_addr = (struct user *)USRSTACK; + struct pstats pstats; + struct pcb pcb; +#endif + int count; + + char filename [BUFSIZ]; + struct stat statb; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_KERNEL), 0); + + memset (buf, 0, sizeof (glibtop_proc_kernel)); + + if (server->sysdeps.proc_time == 0) + return; + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) + +#define PROC_WCHAN ki_wchan +#define PROC_WMESG ki_wmesg +#define PROC_WMESG ki_wmesg + +#else + +#define PROC_WCHAN kp_proc.p_wchan +#define PROC_WMESG kp_proc.p_wmesg +#define PROC_WMESG kp_eproc.e_wmesg + +#endif + +#if !defined(__NetBSD__) || !defined(SACTIVE) + buf->nwchan = (unsigned long) pinfo [0].PROC_WCHAN &~ KERNBASE; + + buf->flags |= (1L << GLIBTOP_PROC_KERNEL_NWCHAN); + + if (pinfo [0].PROC_WCHAN && pinfo [0].PROC_WMESG) { + g_strlcpy (buf->wchan, pinfo [0].PROC_WMESG, + sizeof buf->wchan); + buf->flags |= (1L << GLIBTOP_PROC_KERNEL_WCHAN); + } else { + buf->wchan [0] = 0; + } +#endif + +#if !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) + + /* Taken from `saveuser ()' in `/usr/src/bin/ps/ps.c'. */ + + /* [FIXME]: /usr/include/sys/user.h tells me that the user area + * may or may not be at the same kernel address in all + * processes, but I don't see any way to get that address. + * Since `ps' simply uses its own address, I think it's + * safe to do this here, too. */ + + /* NOTE: You need to mount the /proc filesystem to make + * `kvm_uread' work. */ + + sprintf (filename, "/proc/%d/mem", (int) pid); + if (stat (filename, &statb)) return; + + glibtop_suid_enter (server); + +#if !defined(__NetBSD__) || !defined(SACTIVE) +#ifdef __NetBSD__ + /* On NetBSD, there is no kvm_uread(), and kvm_read() always reads + * from kernel memory. */ + + if (kvm_read (server->machine.kd, +#else + + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, +#endif + (unsigned long) &u_addr->u_stats, + (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) + { + /* + * The u-area might be swapped out, and we can't get + * at it because we have a crashdump and no swap. + * If it's here fill in these fields, otherwise, just + * leave them 0. + */ + + buf->min_flt = (guint64) pstats.p_ru.ru_minflt; + buf->maj_flt = (guint64) pstats.p_ru.ru_majflt; + buf->cmin_flt = (guint64) pstats.p_cru.ru_minflt; + buf->cmaj_flt = (guint64) pstats.p_cru.ru_majflt; + + buf->flags |= _glibtop_sysdeps_proc_kernel_pstats; + } + +#ifdef __NetBSD__ + if (kvm_read (server->machine.kd, +#else + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, +#endif + (unsigned long) &u_addr->u_pcb, + (char *) &pcb, sizeof (pcb)) == sizeof (pcb)) + { +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#ifndef __alpha__ +#if (__FreeBSD_version >= 300003) || defined(__FreeBSD_kernel__) + buf->kstk_esp = (guint64) pcb.pcb_esp; + buf->kstk_eip = (guint64) pcb.pcb_eip; +#else + buf->kstk_esp = (guint64) pcb.pcb_ksp; + buf->kstk_eip = (guint64) pcb.pcb_pc; +#endif +#else + /*xxx FreeBSD/Alpha? */ +#endif +#else +#ifdef __i386__ + buf->kstk_esp = (guint64) pcb.pcb_tss.tss_esp0; +#ifdef __bsdi__ + buf->kstk_eip = (guint64) pcb.pcb_tss.tss_eip; +#else + buf->kstk_eip = (guint64) pcb.pcb_tss.__tss_eip; +#endif +#else +#if defined(__NetBSD__) +#if defined(__m68k__) + buf->kstk_esp = (guint64) pcb.pcb_usp; + buf->kstk_eip = (guint64) 0; +#elif defined(__x86_64__) + buf->kstk_esp = (guint64) pcb.pcb_usersp; + buf->kstk_eip = (guint64) 0; +#elif (defined(__arm32__) || defined(__powerpc__)) + buf->kstk_esp = (guint64) pcb.pcb_sp; + buf->kstk_eip = (guint64) 0; +#elif defined(__mipsel__) + buf->kstk_esp = (guint64) pcb.pcb_context[8]; + buf->kstk_eip = (guint64) 0; +#elif defined(__sparc__) + buf->kstk_esp = (guint64) pcb.pcb_sp; + buf->kstk_eip = (guint64) pcb.pcb_pc; +#elif defined(__alpha__) + buf->kstk_esp = (guint64) pcb.pcb_context[9]; + buf->kstk_eip = (guint64) pcb.pcb_context[8]; +#else + /* provide some defaults for other platforms */ + buf->kstk_esp = (guint64) 0; + buf->kstk_eip = (guint64) 0; +#endif /* ${MACHINE_ARCH} */ +#endif /* __NetBSD__ */ + buf->flags |= _glibtop_sysdeps_proc_kernel_pcb; +#endif +#endif + } +#endif + + /* Taken from `wchan ()' in `/usr/src/bin/ps/print.c'. */ + + glibtop_suid_leave (server); + +#else + /* XXX: the code here was, quite frankly, junk, and almost + * certainly wrong - remove it all, leave these fields + * unpopulated, and give up until such time as the right + * code is produced for both FreeBSD 4.x and 5.x + */ + return; +#endif /* __FreeBSD__ */ +} diff --git a/sysdeps/bsd/proclist.c b/sysdeps/bsd/proclist.c new file mode 100644 index 00000000..d83399c7 --- /dev/null +++ b/sysdeps/bsd/proclist.c @@ -0,0 +1,115 @@ +/* $Id: proclist.c 2536 2006-11-27 19:22:45Z bdejean $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/proclist.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_proclist = +(1L << GLIBTOP_PROCLIST_TOTAL) + (1L << GLIBTOP_PROCLIST_NUMBER) + +(1L << GLIBTOP_PROCLIST_SIZE); + +/* Fetch list of currently running processes. + * The interface of this function is a little bit different from the others: + * buf->flags is only set if the call succeeded, in this case pids_chain, + * a list of the pids of all currently running processes is returned, + * buf->number is the number of elements of this list and buf->size is + * the size of one single element (sizeof (unsigned)). The total size is + * stored in buf->total. + * + * The calling function has to free the memory to which a pointer is returned. + * + * IMPORTANT NOTE: + * On error, this function MUST return NULL and set buf->flags to zero ! + * On success, it returnes a pointer to a list of buf->number elements + * each buf->size big. The total size is stored in buf->total. + * The calling function has to free the memory to which a pointer is returned. + * + * On error, NULL is returned and buf->flags is zero. */ + +/* Init function. */ + +void +glibtop_init_proclist_p (glibtop *server) +{ + server->sysdeps.proclist = _glibtop_sysdeps_proclist; +} + +unsigned * +glibtop_get_proclist_p (glibtop *server, glibtop_proclist *buf, + gint64 real_which, gint64 arg) +{ + struct kinfo_proc *pinfo; + unsigned *pids = NULL; + int which, count; + int i,j; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROCLIST), 0); + + memset (buf, 0, sizeof (glibtop_proclist)); + + which = (int)(real_which & GLIBTOP_KERN_PROC_MASK); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, which, arg, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (proclist)"); + return NULL; + } + count--; + + /* Allocate count objects in the pids_chain array + * Same as malloc is pids is NULL, which it is. */ + pids = g_realloc (pids, count * sizeof (unsigned)); + /* Copy the pids over to this chain */ + for (i=j=0; i < count; i++) { +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) +#define PROC_STAT ki_stat +#define PROC_RUID ki_ruid +#define PROC_PID ki_pid + +#else +#define PROC_STAT kp_proc.p_stat +#define PROC_RUID kp_eproc.e_pcred.p_ruid +#define PROC_PID kp_proc.p_pid + +#endif + + if ((real_which & GLIBTOP_EXCLUDE_IDLE) && + (pinfo[i].PROC_STAT != SRUN)) + continue; + else if ((real_which & GLIBTOP_EXCLUDE_SYSTEM) && + (pinfo[i].PROC_RUID == 0)) + continue; + pids [j++] = (unsigned) pinfo[i].PROC_PID; + } /* end for */ + /* Set the fields in buf */ + buf->number = j; + buf->size = sizeof (unsigned); + buf->total = j * sizeof (unsigned); + buf->flags = _glibtop_sysdeps_proclist; + return pids; +} diff --git a/sysdeps/bsd/procmap.c b/sysdeps/bsd/procmap.c new file mode 100644 index 00000000..d70353fa --- /dev/null +++ b/sysdeps/bsd/procmap.c @@ -0,0 +1,313 @@ +/* $Id: procmap.c 2550 2007-01-31 21:23:21Z bdejean $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procmap.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/resource.h> +#if defined(__NetBSD__) && (__NetBSD_Version__ < 105020000) +#include <vm/vm_object.h> +#include <vm/vm_prot.h> +#include <vm/vm_map.h> +#elif defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) +#include <uvm/uvm_extern.h> +#else +#include <vm/vm_object.h> +#include <vm/vm_map.h> +#if (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__) +#include <vm/vm.h> +#else +#include <vm/vm_prot.h> +#endif +#endif + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#define _KVM_VNODE +#endif +#include <sys/vnode.h> +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#undef _KVM_VNODE +#endif +#include <sys/mount.h> +#include <ufs/ufs/quota.h> +#include <ufs/ufs/inode.h> + +#include <sys/ucred.h> +#if (!defined __OpenBSD__) && (!defined __bsdi__) +#include <sys/user.h> +#endif +#include <sys/sysctl.h> +#if !defined(__NetBSD__) || (__NetBSD_Version__ < 105020000) +#include <vm/vm.h> +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +/* Fixme ... */ +#undef _KERNEL +#define _UVM_UVM_AMAP_I_H_ 1 +#define _UVM_UVM_MAP_I_H_ 1 +#include <uvm/uvm.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_map = +(1L << GLIBTOP_PROC_MAP_TOTAL) + (1L << GLIBTOP_PROC_MAP_NUMBER) + +(1L << GLIBTOP_PROC_MAP_SIZE); + +static const unsigned long _glibtop_sysdeps_map_entry = +(1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) + +(1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM) + +(1L << GLIBTOP_MAP_ENTRY_INODE) + (1L << GLIBTOP_MAP_ENTRY_DEVICE); + +/* Init function. */ + +void +glibtop_init_proc_map_p (glibtop *server) +{ + server->sysdeps.proc_map = _glibtop_sysdeps_proc_map; +} + +/* Provides detailed information about a process. */ + +glibtop_map_entry * +glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + struct vm_map_entry entry, *first; + struct vmspace vmspace; +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct vnode vnode; + struct inode inode; +#else + struct vm_object object; +#endif + GArray *maps = g_array_sized_new(FALSE, FALSE, + sizeof(glibtop_map_entry), + 100); +#if (defined __FreeBSD__) || defined(__FreeBSD_kernel__) + struct vnode vnode; +#if (__FreeBSD_version < 500039) && !defined(__FreeBSD_kernel__) + struct inode inode; +#endif +#endif + int count, i = 0; + int update = 0; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MAP), 0); + + memset (buf, 0, sizeof (glibtop_proc_map)); + + /* It does not work for the swapper task. */ + if (pid == 0) return (glibtop_map_entry*) g_array_free(maps, TRUE); + + glibtop_suid_enter (server); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return (glibtop_map_entry*) g_array_free(maps, TRUE); + } + + /* Now we get the memory maps. */ + + if (kvm_read (server->machine.kd, +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) + (unsigned long) pinfo [0].ki_vmspace, +#else + (unsigned long) pinfo [0].kp_proc.p_vmspace, +#endif + (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) + glibtop_error_io_r (server, "kvm_read (vmspace)"); + + first = vmspace.vm_map.header.next; + + if (kvm_read (server->machine.kd, + (unsigned long) vmspace.vm_map.header.next, + (char *) &entry, sizeof (entry)) != sizeof (entry)) + glibtop_error_io_r (server, "kvm_read (entry)"); + + /* Allocate space. */ + + buf->number = vmspace.vm_map.nentries; + buf->size = sizeof (glibtop_map_entry); + + buf->total = buf->number * buf->size; + + buf->flags = _glibtop_sysdeps_proc_map; + + /* Walk through the `vm_map_entry' list ... */ + + /* I tested this a few times with `mmap'; as soon as you write + * to the mmap'ed area, the object type changes from OBJT_VNODE + * to OBJT_DEFAULT so if seems this really works. */ + + do { + glibtop_map_entry *mentry; + unsigned long inum, dev; + guint len; + + if (update) { + if (kvm_read (server->machine.kd, + (unsigned long) entry.next, + &entry, sizeof (entry)) != sizeof (entry)) + glibtop_error_io_r (server, "kvm_read (entry)"); + } else { + update = 1; + } + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if (__FreeBSD__ >= 4) || defined(__FreeBSD_kernel__) + if (entry.eflags & (MAP_ENTRY_IS_SUB_MAP)) + continue; +#else + if (entry.eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) + continue; +#endif +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (UVM_ET_ISSUBMAP (&entry)) + continue; +#else + if (entry.is_a_map || entry.is_sub_map) + continue; +#endif +#endif + + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (!entry.object.uvm_obj) + continue; + + /* We're only interested in vnodes */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.uvm_obj, + &vnode, sizeof (vnode)) != sizeof (vnode)) { + glibtop_warn_io_r (server, "kvm_read (vnode)"); + return (glibtop_map_entry*) g_array_free(maps, TRUE); + } +#else + if (!entry.object.vm_object) + continue; + + /* We're only interested in `vm_object's */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.vm_object, + &object, sizeof (object)) != sizeof (object)) + glibtop_error_io_r (server, "kvm_read (object)"); +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +#if defined(UVM_VNODE_VALID) + if (!vnode.v_uvm.u_flags & UVM_VNODE_VALID) + continue; +#endif + if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || + !vnode.v_data) continue; + + if (kvm_read (server->machine.kd, + (unsigned long) vnode.v_data, + &inode, sizeof (inode)) != sizeof (inode)) + glibtop_error_io_r (server, "kvm_read (inode)"); + + inum = inode.i_number; + dev = inode.i_dev; +#endif + + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + /* If the object is of type vnode, add its size */ + + if (object.type != OBJT_VNODE) + continue; + + if (!object.handle) + continue; + + if (kvm_read (server->machine.kd, + (unsigned long) object.handle, + &vnode, sizeof (vnode)) != sizeof (vnode)) + glibtop_error_io_r (server, "kvm_read (vnode)"); + +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500039)) || defined(__FreeBSD_kernel__) + switch (vnode.v_type) { + case VREG: +#if (__FreeBSD_version < 600006) && !defined(__FreeBSD_kernel__) + inum = vnode.v_cachedid; + dev = vnode.v_cachedfs; +#endif + default: + continue; + } +#else + if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || + !vnode.v_data) continue; + + if (kvm_read (server->machine.kd, + (unsigned long) vnode.v_data, + &inode, sizeof (inode)) != sizeof (inode)) + glibtop_error_io_r (server, "kvm_read (inode)"); + + inum = inode.i_number; + dev = inode.i_dev; +#endif +#endif + len = maps->len; + g_array_set_size(maps, len + 1); + mentry = &g_array_index(maps, glibtop_map_entry, len); + + mentry->flags = _glibtop_sysdeps_map_entry; + + mentry->start = (guint64) entry.start; + mentry->end = (guint64) entry.end; + mentry->offset = (guint64) entry.offset; + mentry->device = (guint64) dev; + mentry->inode = (guint64) inum; + + mentry->perm = (guint64) 0; + + if (entry.protection & VM_PROT_READ) + mentry->perm |= GLIBTOP_MAP_PERM_READ; + if (entry.protection & VM_PROT_WRITE) + mentry->perm |= GLIBTOP_MAP_PERM_WRITE; + if (entry.protection & VM_PROT_EXECUTE) + mentry->perm |= GLIBTOP_MAP_PERM_EXECUTE; + } while (entry.next != first); + + buf->flags = _glibtop_sysdeps_proc_map; + + buf->number = maps->len; + buf->size = sizeof (glibtop_map_entry); + buf->total = buf->number * buf->size; + + return (glibtop_map_entry*) g_array_free(maps, FALSE); +} diff --git a/sysdeps/bsd/procmem.c b/sysdeps/bsd/procmem.c new file mode 100644 index 00000000..904715e1 --- /dev/null +++ b/sysdeps/bsd/procmem.c @@ -0,0 +1,295 @@ +/* $Id: procmem.c 2536 2006-11-27 19:22:45Z bdejean $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procmem.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/resource.h> +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) +#include <uvm/uvm_extern.h> +#else +#include <vm/vm_object.h> +#include <vm/vm_map.h> +#endif + +#include <sys/vnode.h> +#include <ufs/ufs/quota.h> +#include <ufs/ufs/inode.h> + +#include <sys/ucred.h> +#if (!defined __OpenBSD__) && (!defined __bsdi__) +#include <sys/user.h> +#endif +#include <sys/sysctl.h> +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) +#include <uvm/uvm.h> +#else +#include <vm/vm.h> +#endif + +#if defined(__NetBSD__) && \ + (__NetBSD_Version__ >= 104000000) && (__NetBSD_Version__ < 105020000) +/* Fixme ... */ +#undef _KERNEL +#define _UVM_UVM_AMAP_I_H_ 1 +#define _UVM_UVM_MAP_I_H_ 1 +#include <uvm/uvm.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_mem = +(1L << GLIBTOP_PROC_MEM_SIZE) + +(1L << GLIBTOP_PROC_MEM_VSIZE) + +(1L << GLIBTOP_PROC_MEM_RESIDENT) + +(1L << GLIBTOP_PROC_MEM_RSS) + +(1L << GLIBTOP_PROC_MEM_RSS_RLIM); + +static const unsigned long _glibtop_sysdeps_proc_mem_share = +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +(1L << GLIBTOP_PROC_MEM_SHARE); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +(1L << GLIBTOP_PROC_MEM_SHARE); +#else +0; +#endif + +#ifndef LOG1024 +#define LOG1024 10 +#endif + +/* these are for getting the memory statistics */ +static int pageshift; /* log base 2 of the pagesize */ + +/* define pagetok in terms of pageshift */ +#define pagetok(size) ((size) << pageshift) + +/* Init function. */ + +void +glibtop_init_proc_mem_p (glibtop *server) +{ + register int pagesize; + + /* get the page size with "getpagesize" and calculate pageshift + * from it */ + pagesize = getpagesize (); + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= LOG1024; + + server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem | + _glibtop_sysdeps_proc_mem_share; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + struct vm_map_entry entry, *first; + struct vmspace *vms, vmspace; +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct vnode vnode; +#else + struct vm_object object; +#endif +#if (!defined(__FreeBSD__) || (__FreeBSD_version < 500013)) && !defined(__FreeBSD_kernel__) + struct plimit plimit; +#endif + int count; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MEM), 0); + + memset (buf, 0, sizeof (glibtop_proc_mem)); + + if (server->sysdeps.proc_mem == 0) + return; + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) + +#define PROC_VMSPACE ki_vmspace + + buf->rss_rlim = pinfo [0].ki_rssize; + + buf->vsize = buf->size = (guint64) pagetok + (pinfo [0].ki_tsize + pinfo [0].ki_dsize + pinfo[0].ki_ssize) + << LOG1024; + buf->resident = buf->rss = (guint64) pagetok + (pinfo [0].ki_rssize) << LOG1024; + +#else + +#define PROC_VMSPACE kp_proc.p_vmspace + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].PROC_VMSPACE, + (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) { + glibtop_warn_io_r (server, "kvm_read (plimit)"); + return; + } + + buf->rss_rlim = (guint64) + (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur); + + vms = &pinfo [0].kp_eproc.e_vm; + + buf->vsize = buf->size = (guint64) pagetok + (vms->vm_tsize + vms->vm_dsize + vms->vm_ssize) << LOG1024; + + buf->resident = buf->rss = (guint64) pagetok + (vms->vm_rssize) << LOG1024; +#endif + + /* Now we get the shared memory. */ + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].PROC_VMSPACE, + (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) { + glibtop_warn_io_r (server, "kvm_read (vmspace)"); + return; + } + + first = vmspace.vm_map.header.next; + + if (kvm_read (server->machine.kd, + (unsigned long) vmspace.vm_map.header.next, + (char *) &entry, sizeof (entry)) != sizeof (entry)) { + glibtop_warn_io_r (server, "kvm_read (entry)"); + return; + } + + /* Walk through the `vm_map_entry' list ... */ + + /* I tested this a few times with `mmap'; as soon as you write + * to the mmap'ed area, the object type changes from OBJT_VNODE + * to OBJT_DEFAULT so if seems this really works. */ + + while (entry.next != first) { + if (kvm_read (server->machine.kd, + (unsigned long) entry.next, + &entry, sizeof (entry)) != sizeof (entry)) { + glibtop_warn_io_r (server, "kvm_read (entry)"); + return; + } + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if (__FreeBSD__ >= 4) || defined(__FreeBSD_kernel__) + if (entry.eflags & (MAP_ENTRY_IS_SUB_MAP)) + continue; +#else + if (entry.eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) + continue; +#endif +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (UVM_ET_ISSUBMAP (&entry)) + continue; +#else + if (entry.is_a_map || entry.is_sub_map) + continue; +#endif +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (!entry.object.uvm_obj) + continue; + + /* We're only interested in vnodes */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.uvm_obj, + &vnode, sizeof (vnode)) != sizeof (vnode)) { + glibtop_warn_io_r (server, "kvm_read (vnode)"); + return; + } +#else + if (!entry.object.vm_object) + continue; + + /* We're only interested in `vm_object's */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.vm_object, + &object, sizeof (object)) != sizeof (object)) { + glibtop_warn_io_r (server, "kvm_read (object)"); + return; + } +#endif + /* If the object is of type vnode, add its size */ + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +#if defined(UVM_VNODE_VALID) + if (!vnode.v_uvm.u_flags & UVM_VNODE_VALID) + continue; +#endif + if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || + !vnode.v_data) continue; +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105250000) + /* Reference count must be at least two. */ + if (vnode.v_usecount <= 1) + continue; + + buf->share += pagetok (vnode.v_uobj.uo_npages) << LOG1024; +#else + + /* Reference count must be at least two. */ + if (vnode.v_uvm.u_obj.uo_refs <= 1) + continue; + + buf->share += pagetok (vnode.v_uvm.u_obj.uo_npages) << LOG1024; +#endif /* __NetBSD_Version__ >= 105250000 */ +#endif + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + if (object.type != OBJT_VNODE) + continue; + + buf->share += object.un_pager.vnp.vnp_size; +#endif + } + + buf->flags = _glibtop_sysdeps_proc_mem | + _glibtop_sysdeps_proc_mem_share; +} diff --git a/sysdeps/bsd/procopenfiles.c b/sysdeps/bsd/procopenfiles.c new file mode 100644 index 00000000..3b1d2bd6 --- /dev/null +++ b/sysdeps/bsd/procopenfiles.c @@ -0,0 +1,53 @@ +/* $Id: procopenfiles.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998-99 Martin Baulig + Copyright (C) 2004 Nicol�s Lichtmaier + This file is part of LibGTop 1.0. + + Modified by Nicol�s Lichtmaier to give a process open files. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procopenfiles.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_proc_open_files = +(1L << GLIBTOP_PROC_OPEN_FILES_NUMBER)| +(1L << GLIBTOP_PROC_OPEN_FILES_TOTAL)| +(1L << GLIBTOP_PROC_OPEN_FILES_SIZE); + +/* Init function. */ + +void +glibtop_init_proc_open_files_s (glibtop *server) +{ + server->sysdeps.proc_open_files = _glibtop_sysdeps_proc_open_files; +} + + +/* XXX Unimplemented on FreeBSD */ +glibtop_open_files_entry * +glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pid_t pid) +{ + return NULL; +} diff --git a/sysdeps/bsd/procsegment.c b/sysdeps/bsd/procsegment.c new file mode 100644 index 00000000..a0de0ff5 --- /dev/null +++ b/sysdeps/bsd/procsegment.c @@ -0,0 +1,83 @@ +/* $Id: procsegment.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procsegment.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/sysctl.h> + +static const unsigned long _glibtop_sysdeps_proc_segment = 0; + +/* Init function. */ + +void +glibtop_init_proc_segment_p (glibtop *server) +{ + server->sysdeps.proc_segment = _glibtop_sysdeps_proc_segment; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_segment_p (glibtop *server, + glibtop_proc_segment *buf, + pid_t pid) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_SEGMENT), 0); + + memset (buf, 0, sizeof (glibtop_proc_segment)); + +#if 0 + /* Get the process info from the kernel */ + kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, count); + if (*count != 1) { + return; /* the zeroed-out buffer indicating no data */ + } + + /* trs: text resident set size + pinfo[0]->kp_eproc.e_xrssize; + */ + /* buf->trs = pinfo[0]->kp_eproc.e_xrssize; */ + /* lrs: shared-lib resident set size + ? */ + /* drs: data resident set size + pinfo[0]->kp_eproc.e_vm.vm_map.vm_dsize; + */ + /* dt: dirty pages + */ + /* start_code: address of beginning of code segment + + */ + /* end_code: address of end of code segment + */ + /* start_stack: address of the bottom of stack segment + */ +#endif +} + diff --git a/sysdeps/bsd/procsignal.c b/sysdeps/bsd/procsignal.c new file mode 100644 index 00000000..a9a1e570 --- /dev/null +++ b/sysdeps/bsd/procsignal.c @@ -0,0 +1,138 @@ +/* $Id: procsignal.c 2536 2006-11-27 19:22:45Z bdejean $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procsignal.h> + +#include <glibtop_suid.h> + +#include <sys/param.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_signal = +(1L << GLIBTOP_PROC_SIGNAL_SIGNAL) + +(1L << GLIBTOP_PROC_SIGNAL_BLOCKED) + +(1L << GLIBTOP_PROC_SIGNAL_SIGIGNORE) + +(1L << GLIBTOP_PROC_SIGNAL_SIGCATCH); + +/* Init function. */ + +void +glibtop_init_proc_signal_p (glibtop *server) +{ + server->sysdeps.proc_signal = _glibtop_sysdeps_proc_signal; +} + +void +glibtop_get_proc_signal_p (glibtop *server, + glibtop_proc_signal *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + int count = 0; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_SIGNAL), 0); + + memset (buf, 0, sizeof (glibtop_proc_signal)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) + +#define PROC_SIGLIST ki_siglist +#define PROC_SIGMASK ki_sigmask +#define PROC_SIGIGNORE ki_sigignore +#define PROC_SIGCATCH ki_sigcatch + +#else + +#define PROC_SIGLIST kp_proc.p_siglist +#define PROC_SIGMASK kp_proc.p_sigmask +#define PROC_SIGIGNORE kp_proc.p_sigignore +#define PROC_SIGCATCH kp_proc.p_sigcatch + +#endif + + /* signal: mask of pending signals. + * pinfo [0].kp_proc.p_siglist + */ +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) + buf->signal [0] = pinfo [0].kp_proc.p_sigctx.ps_siglist.__bits[0]; +#elif (defined(__NetBSD__) && (NSIG > 32)) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) + buf->signal [0] = pinfo [0].PROC_SIGLIST.__bits[0]; +#else + buf->signal [0] = pinfo [0].kp_proc.p_siglist; +#endif + + /* blocked: mask of blocked signals. + * pinfo [0].kp_proc.p_sigmask + */ +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) + buf->blocked [0] = pinfo [0].kp_proc.p_sigctx.ps_sigmask.__bits[0]; +#elif (defined(__NetBSD__) && (NSIG > 32)) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) + buf->blocked [0] = pinfo [0].PROC_SIGMASK.__bits[0]; +#else + buf->blocked [0] = pinfo [0].kp_proc.p_sigmask; +#endif + + /* sigignore: mask of ignored signals. + * pinfo [0].kp_proc.p_sigignore + */ +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) + buf->sigignore [0] = pinfo [0].kp_proc.p_sigctx.ps_sigignore.__bits[0]; +#elif (defined(__NetBSD__) && (NSIG > 32)) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) + buf->sigignore [0] = pinfo [0].PROC_SIGIGNORE.__bits[0]; +#else + buf->sigignore [0] = pinfo [0].kp_proc.p_sigignore; +#endif + + /* sigcatch: mask of caught signals. + * pinfo [0].kp_proc.p_sigcatch + */ +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) + buf->sigcatch [0] = pinfo [0].kp_proc.p_sigctx.ps_sigcatch.__bits[0]; +#elif (defined(__NetBSD__) && (NSIG > 32)) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) + buf->sigcatch [0] = pinfo [0].PROC_SIGCATCH.__bits[0]; +#else + buf->sigcatch [0] = pinfo [0].kp_proc.p_sigcatch; +#endif + + buf->flags = _glibtop_sysdeps_proc_signal; +} diff --git a/sysdeps/bsd/procstate.c b/sysdeps/bsd/procstate.c new file mode 100644 index 00000000..006832e8 --- /dev/null +++ b/sysdeps/bsd/procstate.c @@ -0,0 +1,150 @@ +/* $Id: procstate.c 2536 2006-11-27 19:22:45Z bdejean $ */ + +/* Copyright (C) 1998 Joshua Sled + This file is part of LibGTop 1.0. + + Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procstate.h> + +#include <glibtop_suid.h> + +#if !defined(__OpenBSD__) +/* && (!defined __bsdi__) */ +#include <sys/user.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_state = +(1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_UID) + +(1L << GLIBTOP_PROC_STATE_GID); + +static const unsigned long _glibtop_sysdeps_proc_state_new = +0; + +/* Init function. */ + +void +glibtop_init_proc_state_p (glibtop *server) +{ + server->sysdeps.proc_state = _glibtop_sysdeps_proc_state | + _glibtop_sysdeps_proc_state_new; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_state_p (glibtop *server, + glibtop_proc_state *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + int count = 0; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_STATE), 0); + + memset (buf, 0, sizeof (glibtop_proc_state)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) +#define PROC_COMM ki_comm +#define PROC_SVUID ki_svuid +#define PROC_SVGID ki_svgid +#define PROC_RUID ki_ruid +#define PROC_RGID ki_rgid +#define PROC_STAT ki_stat + +#else +#define PROC_COMM kp_proc.p_comm +#define PROC_SVUID kp_eproc.e_pcred.p_svuid +#define PROC_SVGID kp_eproc.e_pcred.p_svgid +#define PROC_RUID kp_eproc.e_pcred.p_ruid +#define PROC_RGID kp_eproc.e_pcred.p_rgid +#define PROC_STAT kp_proc.p_stat + +#endif + + g_strlcpy (buf->cmd, pinfo [0].PROC_COMM, sizeof buf->cmd); + + buf->uid = pinfo [0].PROC_SVUID; + buf->gid = pinfo [0].PROC_SVGID; + + /* Set the flags for the data we're about to return*/ + buf->flags = _glibtop_sysdeps_proc_state | + _glibtop_sysdeps_proc_state_new; + +#if LIBGTOP_VERSION_CODE >= 1001000 + switch (pinfo [0].PROC_STAT) { + case SIDL: + buf->state = 0; + break; + case SRUN: + buf->state = GLIBTOP_PROCESS_RUNNING; + break; +#ifdef SSLEEP + case SSLEEP: + buf->state = GLIBTOP_PROCESS_INTERRUPTIBLE; + break; +#endif + case SSTOP: + buf->state = GLIBTOP_PROCESS_STOPPED; + break; + case SZOMB: + buf->state = GLIBTOP_PROCESS_ZOMBIE; + break; + default: + return; + } +#else + switch (pinfo [0].PROC_STAT) { + case SIDL: + buf->state = 'D'; + break; + case SRUN: + buf->state = 'R'; + break; +#ifdef SSLEEP + case SSLEEP: + buf->state = 'S'; + break; +#endif + case SSTOP: + buf->state = 'T'; + break; + case SZOMB: + buf->state = 'Z'; + break; + default: + return; + } +#endif + + buf->flags |= (1L << GLIBTOP_PROC_STATE_STATE); +} diff --git a/sysdeps/bsd/proctime.c b/sysdeps/bsd/proctime.c new file mode 100644 index 00000000..b7f394e8 --- /dev/null +++ b/sysdeps/bsd/proctime.c @@ -0,0 +1,254 @@ +/* $Id: proctime.c 2550 2007-01-31 21:23:21Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/proctime.h> + +#include <glibtop_suid.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_time = +(1L << GLIBTOP_PROC_TIME_RTIME) + (1L << GLIBTOP_PROC_TIME_FREQUENCY); + +static const unsigned long _glibtop_sysdeps_proc_time_user = +(1L << GLIBTOP_PROC_TIME_UTIME) + (1L << GLIBTOP_PROC_TIME_STIME) + +(1L << GLIBTOP_PROC_TIME_CUTIME) + (1L << GLIBTOP_PROC_TIME_CSTIME) + +(1L << GLIBTOP_PROC_TIME_START_TIME); + +#define tv2sec(tv) (((guint64) tv.tv_sec * 1000000) + (guint64) tv.tv_usec) + +/* Init function. */ + +void +glibtop_init_proc_time_p (glibtop *server) +{ + server->sysdeps.proc_time = _glibtop_sysdeps_proc_time | + _glibtop_sysdeps_proc_time_user; +} + +/* Taken from /usr/src/sys/kern/kern_resource.c */ + +/* + * Transform the running time and tick information in proc p into user, + * system, and interrupt time usage. + */ + +#if !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) + +static void +calcru(p, up, sp, ip) + struct proc *p; + struct timeval *up; + struct timeval *sp; + struct timeval *ip; +{ + quad_t totusec; + u_quad_t u, st, ut, it, tot; + long sec, usec; + struct timeval tv; + + st = p->p_sticks; + ut = p->p_uticks; + it = p->p_iticks; + + tot = st + ut + it; + if (tot == 0) { + st = 1; + tot = 1; + } + + sec = p->p_rtime.tv_sec; + usec = p->p_rtime.tv_usec; + + totusec = (quad_t)sec * 1000000 + usec; + + if (totusec < 0) { + /* XXX no %qd in kernel. Truncate. */ + fprintf (stderr, "calcru: negative time: %ld usec\n", + (long)totusec); + totusec = 0; + } + + + u = totusec; + st = (u * st) / tot; + sp->tv_sec = st / 1000000; + sp->tv_usec = st % 1000000; + ut = (u * ut) / tot; + up->tv_sec = ut / 1000000; + up->tv_usec = ut % 1000000; + if (ip != NULL) { + it = (u * it) / tot; + ip->tv_sec = it / 1000000; + ip->tv_usec = it % 1000000; + } +} +#endif /* !__FreeBSD__ */ + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; +#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) || (defined(OpenBSD) && (OpenBSD >= 199912)) + register struct rusage *rup; +#else + struct user *u_addr = (struct user *)USRSTACK; +#endif + struct pstats pstats; + int count; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_TIME), 0); + + memset (buf, 0, sizeof (glibtop_proc_time)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + +#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) + if (server->sysdeps.proc_time == 0) + return; +#endif + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) + buf->rtime = pinfo [0].ki_runtime; +#elif (defined __FreeBSD__) && (__FreeBSD_version <= 500013) + buf->rtime = pinfo [0].kp_proc.p_runtime; +#else + buf->rtime = tv2sec (pinfo [0].kp_proc.p_rtime); +#endif + + buf->frequency = 1000000; + buf->flags = _glibtop_sysdeps_proc_time; + +#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) || (defined(OpenBSD) && (OpenBSD >= 199912)) + glibtop_suid_enter (server); + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].kp_proc.p_stats, + &pstats, sizeof (pstats)) != sizeof (pstats)) { + glibtop_warn_io_r (server, "kvm_read (pstats)"); + return; + } + + glibtop_suid_leave (server); + + rup = &pstats.p_ru; + calcru(&(pinfo [0]).kp_proc, + &rup->ru_utime, &rup->ru_stime, NULL); + + buf->utime = tv2sec (pstats.p_ru.ru_utime); + buf->stime = tv2sec (pstats.p_ru.ru_stime); + + buf->cutime = tv2sec (pstats.p_cru.ru_utime); + buf->cstime = tv2sec (pstats.p_cru.ru_stime); + + buf->start_time = (guint64) pstats.p_start.tv_sec; + + buf->flags |= _glibtop_sysdeps_proc_time_user; +#else +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) +#if (__FreeBSD_version >= 500016) || defined(__FreeBSD_kernel__) + if ((pinfo [0].ki_flag & PS_INMEM)) { +#else + if ((pinfo [0].ki_flag & P_INMEM)) { +#endif + buf->utime = pinfo [0].ki_runtime; + buf->stime = tv2sec (pinfo [0].ki_rusage.ru_stime); + buf->cutime = tv2sec (pinfo [0].ki_childtime); +#if (__FreeBSD_version >= 600000) || (__FreeBSD_kernel_version >= 600000) + buf->cstime = tv2sec (pinfo [0].ki_rusage_ch.ru_stime); +#else + buf->cstime = 0; +#endif + buf->start_time = tv2sec (pinfo [0].ki_start); + buf->flags = _glibtop_sysdeps_proc_time_user; + } + + glibtop_suid_enter (server); + +#elif (__FreeBSD_version <= 500013) + + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, + (unsigned long) &u_addr->u_stats, + (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) + { + + buf->utime = tv2sec (pinfo[0].kp_eproc.e_stats.p_ru.ru_utime); + buf->stime = tv2sec (pinfo[0].kp_eproc.e_stats.p_ru.ru_stime); + buf->cutime = tv2sec (pinfo[0].kp_eproc.e_stats.p_cru.ru_utime); + buf->cstime = tv2sec (pinfo[0].kp_eproc.e_stats.p_cru.ru_stime); + buf->start_time = tv2sec (pinfo[0].kp_eproc.e_stats.p_start); + buf->flags = _glibtop_sysdeps_proc_time_user; + glibtop_suid_leave (server); + } +#else + + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, + (unsigned long) &u_addr->u_stats, + (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) + { + /* This is taken form the kernel source code of + * FreeBSD 2.2.6. */ + + /* Well, we just do the same getrusage () does ... */ + + register struct rusage *rup; + + glibtop_suid_leave (server); + + rup = &pstats.p_ru; + calcru(&(pinfo [0]).kp_proc, + &rup->ru_utime, &rup->ru_stime, NULL); + + buf->utime = tv2sec (pstats.p_ru.ru_utime); + buf->stime = tv2sec (pstats.p_ru.ru_stime); + + buf->cutime = tv2sec (pstats.p_cru.ru_utime); + buf->cstime = tv2sec (pstats.p_cru.ru_stime); + + buf->start_time = tv2sec (pstats.p_start); + + buf->flags = _glibtop_sysdeps_proc_time_user; + } +#endif + glibtop_suid_leave (server); +#endif +} + diff --git a/sysdeps/bsd/procuid.c b/sysdeps/bsd/procuid.c new file mode 100644 index 00000000..2d78bf3a --- /dev/null +++ b/sysdeps/bsd/procuid.c @@ -0,0 +1,150 @@ +/* $Id: procuid.c 2536 2006-11-27 19:22:45Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procuid.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_proc_uid = +(1L << GLIBTOP_PROC_UID_UID) + (1L << GLIBTOP_PROC_UID_EUID) + +(1L << GLIBTOP_PROC_UID_EGID) + (1L << GLIBTOP_PROC_UID_PID) + +(1L << GLIBTOP_PROC_UID_PPID) + (1L << GLIBTOP_PROC_UID_PGRP) + +(1L << GLIBTOP_PROC_UID_TPGID) + (1L << GLIBTOP_PROC_UID_PRIORITY) + +(1L << GLIBTOP_PROC_UID_NICE); + +static const unsigned long _glibtop_sysdeps_proc_uid_groups = +0L; + +/* Init function. */ + +void +glibtop_init_proc_uid_p (glibtop *server) +{ + server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid | + _glibtop_sysdeps_proc_uid_groups; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_uid_p (glibtop *server, glibtop_proc_uid *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + int count = 0; + +#if LIBGTOP_VERSION_CODE >= 1001000 +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct ucred ucred; + void *ucred_ptr; +#endif +#endif + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_UID), 0); + + memset (buf, 0, sizeof (glibtop_proc_uid)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + +#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) + +#define PROC_RUID ki_ruid +#define PROC_SVUID ki_svuid +#define PROC_RGID ki_rgid +#define PROC_SVGID ki_svgid +#define PROC_PPID ki_ppid +#define PROC_PGID ki_pgid +#define PROC_TPGID ki_tpgid +#define PROC_NICE ki_nice +#define PROC_PRIORITY ki_pri.pri_user +#else + +#define PROC_RUID kp_eproc.e_pcred.p_ruid +#define PROC_SVUID kp_eproc.e_pcred.p_svuid +#define PROC_RGID kp_eproc.e_pcred.p_rgid +#define PROC_SVGID kp_eproc.e_pcred.p_svgid +#define PROC_PPID kp_eproc.e_ppid +#define PROC_PGID kp_eproc.e_pgid +#define PROC_TPGID kp_eproc.e_tpgid +#define PROC_NICE kp_proc.p_nice +#define PROC_PRIORITY kp_proc.p_priority + +#endif + + buf->uid = pinfo [0].PROC_RUID; + buf->euid = pinfo [0].PROC_SVUID; + buf->gid = pinfo [0].PROC_RGID; + buf->egid = pinfo [0].PROC_SVGID; + + buf->ppid = pinfo [0].PROC_PPID; + buf->pgrp = pinfo [0].PROC_PGID; + buf->tpgid = pinfo [0].PROC_TPGID; + + buf->nice = pinfo [0].PROC_NICE; +#if defined(__NetBSD__) && defined(SACTIVE) + buf->priority = 0; +#else + buf->priority = pinfo [0].PROC_PRIORITY; +#endif + + /* Set the flags for the data we're about to return*/ + buf->flags = _glibtop_sysdeps_proc_uid; + + /* Use LibGTop conditionals here so we can more easily merge this + * code into the LIBGTOP_STABLE_1_0 branch. */ +#if 0 + /* This probably also works with other versions, but not yet + * tested. Please remove the conditional if this is true. */ +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + ucred_ptr = (void *) pinfo [0].kp_eproc.e_pcred.pc_ucred; + + if (ucred_ptr) { + if (kvm_read (server->machine.kd, (unsigned long) ucred_ptr, + &ucred, sizeof (ucred)) != sizeof (ucred)) { + glibtop_warn_io_r (server, "kvm_read (ucred)"); + } else { + int count = (ucred.cr_ngroups < GLIBTOP_MAX_GROUPS) ? + ucred.cr_ngroups : GLIBTOP_MAX_GROUPS; + int i; + + for (i = 0; i < count; i++) + buf->groups [i] = ucred.cr_groups [i]; + buf->ngroups = count; + + buf->flags |= _glibtop_sysdeps_proc_uid_groups; + } + } +#endif +#endif +} diff --git a/sysdeps/bsd/sem_limits.c b/sysdeps/bsd/sem_limits.c new file mode 100644 index 00000000..d27d774f --- /dev/null +++ b/sysdeps/bsd/sem_limits.c @@ -0,0 +1,121 @@ +/* $Id: sem_limits.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, August 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/sem_limits.h> + +#include <glibtop_suid.h> + +#if defined(__bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_sem_limits_p (glibtop *server) +{ } + +void +glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SEM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_sem_limits)); +} + +#else + +/* #define KERNEL to get declaration of `struct seminfo'. */ + +#if (defined(__FreeBSD__) && (__FreeBSD_version < 410000)) || defined(__bsdi__) +#define KERNEL 1 +#else +#define _KERNEL 1 +#endif + +#include <sys/ipc.h> +#include <sys/sem.h> + +static unsigned long _glibtop_sysdeps_sem_limits = +(1L << GLIBTOP_IPC_SEMMAP) + (1L << GLIBTOP_IPC_SEMMNI) + +(1L << GLIBTOP_IPC_SEMMNS) + (1L << GLIBTOP_IPC_SEMMNU) + +(1L << GLIBTOP_IPC_SEMMSL) + (1L << GLIBTOP_IPC_SEMOPM) + +(1L << GLIBTOP_IPC_SEMUME) + (1L << GLIBTOP_IPC_SEMUSZ) + +(1L << GLIBTOP_IPC_SEMVMX) + (1L << GLIBTOP_IPC_SEMAEM); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_seminfo' + * since `seminfo' is already declared external in <sys/sem.h>. */ +static struct seminfo _seminfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_seminfo" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_sem_limits_p (glibtop *server) +{ + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (sem_limits)"); + return; + } + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_seminfo, sizeof (_seminfo)) != sizeof (_seminfo)) { + glibtop_warn_io_r (server, "kvm_read (seminfo)"); + return; + } + + server->sysdeps.sem_limits = _glibtop_sysdeps_sem_limits; +} + +/* Provides information about sysv sem limits. */ + +void +glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SEM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_sem_limits)); + + if (server->sysdeps.sem_limits == 0) + return; + + buf->semmap = _seminfo.semmap; + buf->semmni = _seminfo.semmni; + buf->semmns = _seminfo.semmns; + buf->semmnu = _seminfo.semmnu; + buf->semmsl = _seminfo.semmsl; + buf->semopm = _seminfo.semopm; + buf->semvmx = _seminfo.semvmx; + buf->semaem = _seminfo.semaem; + + buf->flags = _glibtop_sysdeps_sem_limits; +} + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/bsd/shm_limits.c b/sysdeps/bsd/shm_limits.c new file mode 100644 index 00000000..a3059c65 --- /dev/null +++ b/sysdeps/bsd/shm_limits.c @@ -0,0 +1,116 @@ +/* $Id: shm_limits.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, August 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/shm_limits.h> + +#include <glibtop_suid.h> + +#if defined(__bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_shm_limits_p (glibtop *server) +{ } + +void +glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SHM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_shm_limits)); +} + +#else + +/* #define KERNEL to get declaration of `struct shminfo'. */ + +#if (defined(__FreeBSD__) && (__FreeBSD_version < 410000)) || defined(__bsdi__) +#define KERNEL 1 +#else +#define _KERNEL 1 +#endif + +#include <sys/ipc.h> +#include <sys/shm.h> + +static unsigned long _glibtop_sysdeps_shm_limits = +(1L << GLIBTOP_IPC_SHMMAX) + (1L << GLIBTOP_IPC_SHMMIN) + +(1L << GLIBTOP_IPC_SHMMNI) + (1L << GLIBTOP_IPC_SHMSEG) + +(1L << GLIBTOP_IPC_SHMALL); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_shminfo' + * since `shminfo' is already declared external in <sys/shm.h>. */ +static struct shminfo _shminfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_shminfo" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_shm_limits_p (glibtop *server) +{ + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (shm_limits)"); + return; + } + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_shminfo, sizeof (_shminfo)) != sizeof (_shminfo)) { + glibtop_warn_io_r (server, "kvm_read (shminfo)"); + return; + } + + server->sysdeps.shm_limits = _glibtop_sysdeps_shm_limits; +} + +/* Provides information about sysv ipc limits. */ + +void +glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SHM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_shm_limits)); + + if (server->sysdeps.shm_limits == 0) + return; + + buf->shmmax = _shminfo.shmmax; + buf->shmmin = _shminfo.shmmin; + buf->shmmni = _shminfo.shmmni; + buf->shmseg = _shminfo.shmseg; + buf->shmall = _shminfo.shmall; + + buf->flags = _glibtop_sysdeps_shm_limits; +} + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/bsd/siglist.c b/sysdeps/bsd/siglist.c new file mode 100644 index 00000000..ce3e8841 --- /dev/null +++ b/sysdeps/bsd/siglist.c @@ -0,0 +1,62 @@ +/* $Id: siglist.c 2550 2007-01-31 21:23:21Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/signal.h> + +const glibtop_signame glibtop_sys_siglist [] = +{ { 1, "SIGHUP", "Hangup" }, + { 2, "SIGINT", "Interrupt" }, + { 3, "SIGQUIT", "Quit" }, + { 4, "SIGILL", "Illegal Instruction" }, + { 5, "SIGTRAP", "Trace/Breakpoint Trap" }, + { 6, "SIGABRT", "Abort" }, + { 7, "SIGEMT", "Emulation Trap" }, + { 8, "SIGFPE", "Arithmetic Exception" }, + { 9, "SIGKILL", "Killed" }, + { 10, "SIGBUS", "Bus Error" }, + { 11, "SIGSEGV", "Segmentation Fault" }, + { 12, "SIGSYS", "Bad System Call" }, + { 13, "SIGPIPE", "Broken Pipe" }, + { 14, "SIGALRM", "Alarm Clock" }, + { 15, "SIGTERM", "Terminated" }, + { 16, "SIGURG", "Urgent Condition Present On Socket" }, + { 17, "SIGSTOP", "Stop (cannot be caught or ignored)" }, + { 18, "SIGTSTP", "Stop Signal Generated From Keyboard" }, + { 19, "SIGCONT", "Continue After Stop" }, + { 20, "SIGCHLD", "Child Status Has Changed" }, + { 21, "SIGTTIN", "Background Read Attempted From Control Terminal" }, + { 22, "SIGTTOU", "Background Write Attempted To Control Terminal" }, + { 23, "SIGIO", "I/O Is Possible On A Descriptor" }, + { 24, "SIGXCPU", "CPU Time Limit Exceeded" }, + { 25, "SIGXFSZ", "File Size Limit Exceeded" }, + { 26, "SIGVTALRM","Virtual Time Alarm" }, + { 27, "SIGPROF", "Profiling Timer Alarm" }, + { 28, "SIGWINCH","Window Size Change" }, + { 29, "SIGINFO", "Status Request From Keyboard" }, + { 30, "SIGUSR1", "User Defined Signal 1" }, + { 31, "SIGUSR2", "User Defined Signal 2" }, + { 32, "SIGTHR", "Thread Interrupt" }, + { 0, NULL, NULL } +}; diff --git a/sysdeps/bsd/swap.c b/sysdeps/bsd/swap.c new file mode 100644 index 00000000..8347490f --- /dev/null +++ b/sysdeps/bsd/swap.c @@ -0,0 +1,425 @@ +/* $Id: swap.c 2536 2006-11-27 19:22:45Z bdejean $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/swap.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_swap = +(1L << GLIBTOP_SWAP_TOTAL) + (1L << GLIBTOP_SWAP_USED) + +(1L << GLIBTOP_SWAP_FREE) + (1L << GLIBTOP_SWAP_PAGEIN) + +(1L << GLIBTOP_SWAP_PAGEOUT); + +#if defined(__FreeBSD__) || defined(__bsdi__) || defined(__FreeBSD_kernel__) + +#include <sys/conf.h> +#ifdef __bsdi__ +#include <vm/swap_pager.h> +#else +#if (__FreeBSD_version < 400005) && !defined(__FreeBSD_kernel__) +#include <sys/rlist.h> +#endif +#endif +#include <sys/vmmeter.h> + +/* nlist structure for kernel access */ + +#if defined(__bsdi__) +static struct nlist nlst [] = { + { "_swapstats" }, /* general swap info */ + { 0 } +}; +#elif __FreeBSD__ < 4 +static struct nlist nlst [] = { +#define VM_SWAPLIST 0 + { "_swaplist" },/* list of free swap areas */ +#define VM_SWDEVT 1 + { "_swdevt" }, /* list of swap devices and sizes */ +#define VM_NSWAP 2 + { "_nswap" }, /* size of largest swap device */ +#define VM_NSWDEV 3 + { "_nswdev" }, /* number of swap devices */ +#define VM_DMMAX 4 + { "_dmmax" }, /* maximum size of a swap block */ + { 0 } +}; +#endif + +#elif defined(__NetBSD__) || defined(__OpenBSD__) + +#if (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) +#include <uvm/uvm_extern.h> +#include <sys/swap.h> +#else +#include <vm/vm_swap.h> +#endif + +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) +static int mib_uvmexp [] = { CTL_VM, VM_UVMEXP }; +#else +/* nlist structure for kernel access */ +static struct nlist nlst2 [] = { + { "_cnt" }, + { 0 } +}; +#endif + +/* Init function. */ + +void +glibtop_init_swap_p (glibtop *server) +{ +#if defined(__FreeBSD__) || defined(__bsdi__) || defined(__FreeBSD_kernel__) +#if __FreeBSD__ < 4 || defined(__bsdi__) + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (swap)"); + return; + } +#else + struct kvm_swap dummy; + + if (kvm_getswapinfo (server->machine.kd, &dummy, 1, 0) != 0) { + glibtop_warn_io_r (server, "kvm_swap (swap)"); + return; + } +#endif +#endif + +#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) && !defined(__OpenBSD__) + if (kvm_nlist (server->machine.kd, nlst2) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (cnt)"); + return; + } +#endif + + server->sysdeps.swap = _glibtop_sysdeps_swap; +} + +/* Provides information about swap usage. */ + +/* + * This function is based on a program called swapinfo written + * by Kevin Lahey <kml@rokkaku.atl.ga.us>. + */ + +void +glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) +{ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + +# if (__FreeBSD__ < 4) && !defined(__FreeBSD_kernel__) + char *header; + int hlen, nswdev, dmmax; + int div, nfree, npfree; + struct swdevt *sw; + long blocksize, *perdev; + struct rlist head; + struct rlisthdr swaplist; + struct rlist *swapptr; + size_t sw_size; + u_long ptr; +# else + int nswdev; + struct kvm_swap kvmsw[16]; +# endif + +#elif defined(__bsdi__) + struct swapstats swap; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + struct swapent *swaplist; +#endif + + int nswap, i; + int avail = 0, inuse = 0; + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + struct uvmexp uvmexp; + size_t length_uvmexp; +#else + /* To get `pagein' and `pageout'. */ + struct vmmeter vmm; +#endif + static int swappgsin = -1; + static int swappgsout = -1; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SWAP), 0); + + memset (buf, 0, sizeof (glibtop_swap)); + + if (server->sysdeps.swap == 0) + return; + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + length_uvmexp = sizeof (uvmexp); + if (sysctl (mib_uvmexp, 2, &uvmexp, &length_uvmexp, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (uvmexp)"); + return; + } +#else + /* This is used to get the `pagein' and `pageout' members. */ + + if (kvm_read (server->machine.kd, nlst2[0].n_value, + &vmm, sizeof (vmm)) != sizeof (vmm)) { + glibtop_warn_io_r (server, "kvm_read (cnt)"); + return; + } +#endif + + if (swappgsin < 0) { + buf->pagein = 0; + buf->pageout = 0; + } else { +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + buf->pagein = vmm.v_swappgsin - swappgsin; + buf->pageout = vmm.v_swappgsout - swappgsout; +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + buf->pagein = uvmexp.swapins - swappgsin; + buf->pageout = uvmexp.swapouts - swappgsout; +#else + buf->pagein = vmm.v_swpin - swappgsin; + buf->pageout = vmm.v_swpout - swappgsout; +#endif +#endif + } + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + swappgsin = vmm.v_swappgsin; + swappgsout = vmm.v_swappgsout; +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) + swappgsin = uvmexp.swapins; + swappgsout = uvmexp.swapouts; +#else + swappgsin = vmm.v_swpin; + swappgsout = vmm.v_swpout; +#endif +#endif + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + +#if (__FreeBSD__ < 4) && !defined(__FreeBSD_kernel__) + + /* Size of largest swap device. */ + + if (kvm_read (server->machine.kd, nlst[VM_NSWAP].n_value, + &nswap, sizeof (nswap)) != sizeof (nswap)) { + glibtop_warn_io_r (server, "kvm_read (nswap)"); + return; + } + + /* Number of swap devices. */ + + if (kvm_read (server->machine.kd, nlst[VM_NSWDEV].n_value, + &nswdev, sizeof (nswdev)) != sizeof (nswdev)) { + glibtop_warn_io_r (server, "kvm_read (nswdev)"); + return; + } + + /* Maximum size of a swap block. */ + + if (kvm_read (server->machine.kd, nlst[VM_DMMAX].n_value, + &dmmax, sizeof (dmmax)) != sizeof (dmmax)) { + glibtop_warn_io_r (server, "kvm_read (dmmax)"); + return; + } + + /* List of free swap areas. */ + + if (kvm_read (server->machine.kd, nlst[VM_SWAPLIST].n_value, + &swaplist, sizeof (swaplist)) != sizeof (swaplist)) { + glibtop_warn_io_r (server, "kvm_read (swaplist)"); + return; + } + + /* Kernel offset of list of swap devices and sizes. */ + + if (kvm_read (server->machine.kd, nlst[VM_SWDEVT].n_value, + &ptr, sizeof (ptr)) != sizeof (ptr)) { + glibtop_warn_io_r (server, "kvm_read (swdevt)"); + return; + } + + /* List of swap devices and sizes. */ + + sw_size = nswdev * sizeof (*sw); + sw = g_malloc (sw_size); + + if (kvm_read (server->machine.kd, ptr, sw, sw_size) != (ssize_t)sw_size) { + glibtop_warn_io_r (server, "kvm_read (*swdevt)"); + return; + } + + perdev = g_malloc (nswdev * sizeof (*perdev)); + + /* Count up swap space. */ + + nfree = 0; + memset (perdev, 0, nswdev * sizeof(*perdev)); + + swapptr = swaplist.rlh_list; + + while (swapptr) { + int top, bottom, next_block; + + if (kvm_read (server->machine.kd, (int) swapptr, &head, + sizeof (struct rlist)) != sizeof (struct rlist)) { + glibtop_warn_io_r (server, "kvm_read (swapptr)"); + return; + } + + top = head.rl_end; + bottom = head.rl_start; + + nfree += top - bottom + 1; + + /* + * Swap space is split up among the configured disks. + * + * For interleaved swap devices, the first dmmax blocks + * of swap space some from the first disk, the next dmmax + * blocks from the next, and so on up to nswap blocks. + * + * The list of free space joins adjacent free blocks, + * ignoring device boundries. If we want to keep track + * of this information per device, we'll just have to + * extract it ourselves. + */ + while (top / dmmax != bottom / dmmax) { + next_block = ((bottom + dmmax) / dmmax); + perdev[(bottom / dmmax) % nswdev] += + next_block * dmmax - bottom; + bottom = next_block * dmmax; + } + perdev[(bottom / dmmax) % nswdev] += + top - bottom + 1; + + swapptr = head.rl_next; + } + + header = getbsize (&hlen, &blocksize); + + div = blocksize / 512; + avail = npfree = 0; + for (i = 0; i < nswdev; i++) { + int xsize, xfree; + + /* + * Don't report statistics for partitions which have not + * yet been activated via swapon(8). + */ + if (!(sw[i].sw_flags & SW_FREED)) + continue; + + /* The first dmmax is never allocated to avoid trashing of + * disklabels + */ + xsize = sw[i].sw_nblks - dmmax; + xfree = perdev[i]; + inuse = xsize - xfree; + npfree++; + avail += xsize; + } + + /* + * If only one partition has been set up via swapon(8), we don't + * need to bother with totals. + */ + inuse = avail - nfree; + + g_free (sw); + g_free (perdev); + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = inuse; + buf->free = avail; + + buf->total = inuse + avail; + +#else + + nswdev = kvm_getswapinfo(server->machine.kd, kvmsw, 16, 0); + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = kvmsw[nswdev].ksw_used * getpagesize(); + buf->total = kvmsw[nswdev].ksw_total * getpagesize(); + + buf->free = buf->total - buf->used; + +#endif + +#elif defined(__bsdi__) + + /* General info about swap devices. */ + + if (kvm_read (server->machine.kd, nlst[0].n_value, + &swap, sizeof (swap)) != sizeof (swap)) { + glibtop_warn_io_r (server, "kvm_read (swap)"); + return; + } + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = swap.swap_total - swap.swap_free; + buf->free = swap.swap_free; + + buf->total = swap.swap_total; + +#elif defined(__NetBSD__) || defined(__OpenBSD__) + + nswap = swapctl (SWAP_NSWAP, NULL, 0); + if (nswap < 0) { + glibtop_warn_io_r (server, "swapctl (SWAP_NSWAP)"); + return; + } + + swaplist = g_malloc (nswap * sizeof (struct swapent)); + + if (swapctl (SWAP_STATS, swaplist, nswap) != nswap) { + glibtop_warn_io_r (server, "swapctl (SWAP_STATS)"); + g_free (swaplist); + return; + } + + for (i = 0; i < nswap; i++) { + avail += swaplist[i].se_nblks; + inuse += swaplist[i].se_inuse; + } + + g_free (swaplist); + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = inuse; + buf->free = avail; + + buf->total = inuse + avail; +#endif +} diff --git a/sysdeps/bsd/sysinfo.c b/sysdeps/bsd/sysinfo.c new file mode 100644 index 00000000..10cbd6f3 --- /dev/null +++ b/sysdeps/bsd/sysinfo.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/sysctl.h> +#include <glibtop/error.h> +#include <glibtop/cpu.h> +#include <glibtop/sysinfo.h> + +static const unsigned long _glibtop_sysdeps_sysinfo = +(1L << GLIBTOP_SYSINFO_CPUINFO); + +static glibtop_sysinfo sysinfo = { .flags = 0 }; + +static void +init_sysinfo (glibtop *server) +{ + char *model; + guint64 ncpus = 1; + int mhz = 0; + size_t len; + + if (G_LIKELY (sysinfo.flags)) + return; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_CPU, 0); + + len = sizeof (ncpus); + sysctlbyname ("hw.ncpu", &ncpus, &len, NULL, 0); + len = 0; + sysctlbyname ("hw.model", NULL, &len, NULL, 0); + model = g_malloc (len); + sysctlbyname ("hw.model", model, &len, NULL, 0); + len = sizeof (mhz); + sysctlbyname ("hw.clockrate", &mhz, &len, NULL, 0); + + for (sysinfo.ncpu = 0; + sysinfo.ncpu < GLIBTOP_NCPU && sysinfo.ncpu < ncpus; + sysinfo.ncpu++) { + glibtop_entry * const cpuinfo = &sysinfo.cpuinfo[sysinfo.ncpu]; + + cpuinfo->labels = g_ptr_array_new (); + + cpuinfo->values = g_hash_table_new_full(g_str_hash, + g_str_equal, + NULL, g_free); + + g_ptr_array_add (cpuinfo->labels, "processor"); + g_hash_table_insert (cpuinfo->values, "processor", + g_strdup_printf("%u", (guint)sysinfo.ncpu)); + + g_ptr_array_add (cpuinfo->labels, "vendor_id"); + g_hash_table_insert (cpuinfo->values, "vendor_id", + g_strdup(model)); + + g_ptr_array_add (cpuinfo->labels, "cpu MHz"); + g_hash_table_insert (cpuinfo->values, "cpu MHz", + g_strdup_printf("%d", mhz)); + } + + g_free (model); + + sysinfo.flags = _glibtop_sysdeps_sysinfo; +} + +const glibtop_sysinfo * +glibtop_get_sysinfo_s (glibtop *server) +{ + init_sysinfo (server); + return &sysinfo; +} diff --git a/sysdeps/bsd/uptime.c b/sysdeps/bsd/uptime.c new file mode 100644 index 00000000..4da70244 --- /dev/null +++ b/sysdeps/bsd/uptime.c @@ -0,0 +1,94 @@ +/* $Id: uptime.c 2422 2005-12-12 09:38:15Z jamesh $ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/uptime.h> + +#include <glibtop/cpu.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_uptime = +(1L << GLIBTOP_UPTIME_UPTIME) + (1L << GLIBTOP_UPTIME_IDLETIME); + +static const unsigned long _required_cpu_flags = +(1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_IDLE) + +(1L << GLIBTOP_CPU_FREQUENCY); + +/* Init function. */ + +void +glibtop_init_uptime_p (glibtop *server) +{ + server->sysdeps.uptime = _glibtop_sysdeps_uptime; +} + +/* Provides uptime and idle time. */ + +void +glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf) +{ +#if defined(__NetBSD__) || defined(__OpenBSD__) + time_t now; + time_t uptime; + int mib[2]; + struct timeval boottime; + size_t size; + + mib[0] = CTL_KERN; + mib[1] = KERN_BOOTTIME; + size = sizeof(boottime); + if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && + boottime.tv_sec != 0) { + time(&now); + buf->uptime = now - boottime.tv_sec; + /* XXX: don't know a useful value to put here. */ + buf->idletime = 0; + buf->flags = _glibtop_sysdeps_uptime; + } +#else + glibtop_cpu cpu; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_UPTIME), 0); + + memset (buf, 0, sizeof (glibtop_uptime)); + + /* We simply calculate it from the CPU usage. */ + + glibtop_get_cpu_p (server, &cpu); + + /* Make sure all required fields are present. */ + + if ((cpu.flags & _required_cpu_flags) != _required_cpu_flags) + return; + + /* Calculate values. */ + + buf->uptime = (double) cpu.total / (double) cpu.frequency; + buf->idletime = (double) cpu.idle / (double) cpu.frequency; + + buf->flags = _glibtop_sysdeps_uptime; +#endif +} diff --git a/sysdeps/freebsd/AUTHORS b/sysdeps/freebsd/AUTHORS index 9da8aceb..e274ce59 100644 --- a/sysdeps/freebsd/AUTHORS +++ b/sysdeps/freebsd/AUTHORS @@ -1,2 +1,3 @@ Martin Baulig (martin@home-of-linux.org) Josh Sled (jsled@scam.XCF.Berkeley.EDU) +Joe Marcus Clarke (marcus@FreeBSD.org) diff --git a/sysdeps/freebsd/ChangeLog b/sysdeps/freebsd/ChangeLog index b3876d89..dcff7cc5 100644 --- a/sysdeps/freebsd/ChangeLog +++ b/sysdeps/freebsd/ChangeLog @@ -1,3 +1,52 @@ +2007-02-18 Benoît Dejean <benoit@placenet.org> + + * AUTHORS: + * Makefile.am: + * NOTES: + * cpu.c: (glibtop_init_cpu_s), (glibtop_get_cpu_s): + * fsusage.c: (_glibtop_freebsd_get_fsusage_read_write): + * glibtop_machine.h: + * glibtop_server.h: + * init.c: + * loadavg.c: (glibtop_init_loadavg_s), (glibtop_get_loadavg_s): + * mem.c: (glibtop_init_mem_s), (glibtop_get_mem_s): + * msg_limits.c: (glibtop_init_msg_limits_s), + (glibtop_get_msg_limits_s): + * netload.c: (glibtop_init_netload_p), (glibtop_get_netload_p): + * open.c: (glibtop_open_p): + * ppp.c: (glibtop_init_ppp_p), (glibtop_get_ppp_p): + * procargs.c: (glibtop_get_proc_args_p): + * procdata.c: + * prockernel.c: (glibtop_init_proc_kernel_p), + (glibtop_get_proc_kernel_p): + * proclist.c: (glibtop_get_proclist_p): + * procmap.c: (_glibtop_sysdeps_freebsd_dev_inode), + (glibtop_get_proc_map_p): + * procmem.c: (glibtop_init_proc_mem_p), (glibtop_get_proc_mem_p): + * procsegment.c: (glibtop_init_proc_segment_p), + (glibtop_get_proc_segment_p): + * procsignal.c: (glibtop_get_proc_signal_p): + * procstate.c: (glibtop_init_proc_state_p), + (glibtop_get_proc_state_p): + * proctime.c: (glibtop_get_proc_time_p): + * procuid.c: (glibtop_init_proc_uid_p), (glibtop_get_proc_uid_p): + * sem_limits.c: (glibtop_init_sem_limits_s), + (glibtop_get_sem_limits_s): + * shm_limits.c: (glibtop_init_shm_limits_s), + (glibtop_get_shm_limits_s): + * swap.c: (glibtop_init_swap_p), (glibtop_get_swap_p): + * sysinfo.c: (init_sysinfo): + * uptime.c: (glibtop_init_uptime_s), (glibtop_get_uptime_s): + + Huge (k)FreeBSD update. + (k)FreeBSD support is freebsd/ + Other BSD are in bsd/ + + Patch by Joe Marcus Clarke <marcus@freebsd.org> + Alexander Nedotsukov <bland@FreeBSD.org> + + Closes #407693. + 2007-01-31 Benoît Dejean <benoit@placenet.org> * fsusage.c: (_glibtop_freebsd_get_fsusage_read_write): diff --git a/sysdeps/freebsd/Makefile.am b/sysdeps/freebsd/Makefile.am index 9ec00a3c..ee18d5c8 100644 --- a/sysdeps/freebsd/Makefile.am +++ b/sysdeps/freebsd/Makefile.am @@ -3,17 +3,18 @@ INCLUDES = @INCLUDES@ noinst_LTLIBRARIES = libgtop_sysdeps-2.0.la libgtop_sysdeps_suid-2.0.la -libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c +libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c shm_limits.c \ + cpu.c msg_limits.c sem_limits.c loadavg.c \ + uptime.c netlist.c fsusage.c mem.c libgtop_sysdeps_2_0_la_LDFLAGS = $(LT_VERSION_INFO) -libgtop_sysdeps_suid_2_0_la_LIBADD = $(KVM_LIBS) -libgtop_sysdeps_suid_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \ - uptime.c loadavg.c shm_limits.c msg_limits.c \ - sem_limits.c proclist.c procstate.c procuid.c \ - proctime.c procmem.c procsignal.c prockernel.c \ - procsegment.c procargs.c procmap.c netlist.c \ - netload.c ppp.c procopenfiles.c fsusage.c +libgtop_sysdeps_suid_2_0_la_LIBADD = $(KVM_LIBS) $(EXTRA_SYSDEPS_LIBS) +libgtop_sysdeps_suid_2_0_la_SOURCES = open.c close.c swap.c \ + proclist.c procstate.c procuid.c \ + proctime.c procmem.c procsignal.c \ + prockernel.c procsegment.c procargs.c \ + procmap.c netload.c ppp.c procopenfiles.c libgtop_sysdeps_suid_2_0_la_LDFLAGS = $(LT_VERSION_INFO) diff --git a/sysdeps/freebsd/cpu.c b/sysdeps/freebsd/cpu.c index 3d4098b3..7c8f807e 100644 --- a/sysdeps/freebsd/cpu.c +++ b/sysdeps/freebsd/cpu.c @@ -28,91 +28,52 @@ #include <glibtop_suid.h> -#ifdef __NetBSD__ -#include <sys/sched.h> -#endif - static const unsigned long _glibtop_sysdeps_cpu = (1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_USER) + (1L << GLIBTOP_CPU_NICE) + (1L << GLIBTOP_CPU_SYS) + (1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_CPU_FREQUENCY) + -(1L << GLIBTOP_CPU_IOWAIT); - -#ifndef KERN_CP_TIME -/* nlist structure for kernel access */ -static struct nlist nlst [] = { -#ifdef __bsdi__ - { "_cpustats" }, -#else - { "_cp_time" }, -#endif - { 0 } -}; -#endif - -/* MIB array for sysctl */ -static int mib_length=2; -static int mib [] = { CTL_KERN, KERN_CLOCKRATE }; -#ifdef KERN_CP_TIME -static int mib2 [] = { CTL_KERN, KERN_CP_TIME }; -#endif +(1L << GLIBTOP_CPU_IRQ); + +static const unsigned long _glibtop_sysdeps_cpu_smp = +(1L << GLIBTOP_XCPU_TOTAL) + (1L << GLIBTOP_XCPU_USER) + +(1L << GLIBTOP_XCPU_NICE) + (1L << GLIBTOP_XCPU_SYS) + +(1L << GLIBTOP_XCPU_IDLE) + (1L << GLIBTOP_XCPU_IRQ); /* Init function. */ void -glibtop_init_cpu_p (glibtop *server) +glibtop_init_cpu_s (glibtop *server) { -#ifndef KERN_CP_TIME - if (kvm_nlist (server->machine.kd, nlst) < 0) { - glibtop_warn_io_r (server, "kvm_nlist (cpu)"); - return; - } -#endif - - /* Set this only if kvm_nlist () succeeded. */ server->sysdeps.cpu = _glibtop_sysdeps_cpu; + + if (server->ncpu) + server->sysdeps.cpu |= _glibtop_sysdeps_cpu_smp; } /* Provides information about cpu usage. */ void -glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf) +glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf) { -#ifdef KERN_CP_TIME - guint64 cpts [CPUSTATES]; -#else long cpts [CPUSTATES]; -#endif - /* sysctl vars*/ struct clockinfo ci; size_t length; + int ncpu, i; - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_CPU), 0); + glibtop_init_s (&server, GLIBTOP_SYSDEPS_CPU, 0); memset (buf, 0, sizeof (glibtop_cpu)); - /* If this fails, the nlist may not be valid. */ - if (server->sysdeps.cpu == 0) - return; - -#ifdef KERN_CP_TIME length = sizeof (cpts); - if (sysctl (mib2, mib_length, cpts, &length, NULL, 0)) { - glibtop_warn_io_r (server, "sysctl"); - return; - } -#else - if (kvm_read (server->machine.kd, nlst [0].n_value, - &cpts, sizeof (cpts)) != sizeof (cpts)) { - glibtop_warn_io_r (server, "kvm_read (cp_time)"); + if (sysctlbyname ("kern.cp_time", cpts, &length, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.cp_time)"); return; } -#endif /* Get the clockrate data */ - length = sizeof (struct clockinfo); - if (sysctl (mib, mib_length, &ci, &length, NULL, 0)) { - glibtop_warn_io_r (server, "sysctl"); + length = sizeof (ci); + if (sysctlbyname ("kern.clockrate", &ci, &length, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.cockrate)"); return; } @@ -124,21 +85,32 @@ glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf) buf->sys = cpts [CP_SYS]; /* set idle time */ buf->idle = cpts [CP_IDLE]; - /* set iowait (really just interrupt) time */ - buf->iowait = cpts [CP_INTR]; + /* set irq */ + buf->irq = cpts [CP_INTR]; /* set frequency */ - /* - FIXME -- is hz, tick, profhz or stathz wanted? - buf->frequency = sysctl("kern.clockrate", ...); - - struct clockinfo - */ - buf->frequency = ci.hz; + buf->frequency = (ci.stathz ? ci.stathz : ci.hz); /* set total */ buf->total = cpts [CP_USER] + cpts [CP_NICE] - + cpts [CP_SYS] + cpts [CP_IDLE]; + + cpts [CP_SYS] + cpts [CP_IDLE] + cpts [CP_INTR]; + + ncpu = server->ncpu + 1; + + for (i = 0; i < ncpu; i++) { + buf->xcpu_user[i] = cpts [CP_USER] / ncpu; + buf->xcpu_nice[i] = cpts [CP_NICE] / ncpu; + buf->xcpu_sys[i] = cpts [CP_SYS] / ncpu; + buf->xcpu_idle[i] = cpts [CP_IDLE] / ncpu; + buf->xcpu_irq[i] = cpts [CP_INTR] / ncpu; + buf->xcpu_total[i] = buf->xcpu_user[i] + buf->xcpu_nice[i] \ + + buf->xcpu_sys[i] + buf->xcpu_idle[i] \ + + buf->xcpu_irq[i]; + } /* Set the flags last. */ buf->flags = _glibtop_sysdeps_cpu; + + if (ncpu > 1) { + buf->flags |= _glibtop_sysdeps_cpu_smp; + } } diff --git a/sysdeps/freebsd/fsusage.c b/sysdeps/freebsd/fsusage.c index 3103e22c..8b12edac 100644 --- a/sysdeps/freebsd/fsusage.c +++ b/sysdeps/freebsd/fsusage.c @@ -1,11 +1,4 @@ #include <config.h> - -/* Although FreeBSD ships with statvfs it seems incomplete, so prefer statfs */ -#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) -#undef HAVE_SYS_STATVFS_H -#undef STAT_STATVFS -#endif - #include <glibtop.h> #include <glibtop/error.h> #include <glibtop/fsusage.h> @@ -16,10 +9,12 @@ #include <unistd.h> #include <sys/param.h> -#if defined (HAVE_SYS_STATVFS_H) -#include <sys/statvfs.h> -#else #include <sys/mount.h> +#if __FreeBSD_version >= 600000 || defined(__FreeBSD_kernel__) +#include <libgeom.h> +#include <sys/resource.h> +#include <devstat.h> +#include <sys/devicestat.h> #endif #include <stdio.h> @@ -29,32 +24,115 @@ void G_GNUC_INTERNAL _glibtop_freebsd_get_fsusage_read_write(glibtop *server, - glibtop_fsusage *buf, - const char *path); + glibtop_fsusage *buf, + const char *path); void G_GNUC_INTERNAL _glibtop_freebsd_get_fsusage_read_write(glibtop *server, - glibtop_fsusage *buf, - const char *path) + glibtop_fsusage *buf, + const char *path) { - int result; -#if defined (STAT_STATVFS) - struct statvfs sfs; -#else - struct statfs sfs; + int result; + struct statfs sfs; +#if __FreeBSD_version >= 600000 || defined(__FreeBSD_kernel__) + struct devstat *ds; + void *sc; + struct timespec ts; + struct gprovider *gp; + struct gident *gid; + struct gmesh gmp; + double etime; + uint64_t ld[2]; #endif -#if defined (STAT_STATVFS) - result = statvfs (path, &sfs); -#else - result = statfs (path, &sfs); -#endif + result = statfs (path, &sfs); + + if (result == -1) { + glibtop_warn_io_r (server, "statfs"); + return; + } +#if __FreeBSD_version >= 600000 || defined(__FreeBSD_kernel__) + ld[0] = 0; + ld[1] = 0; + result = geom_gettree (&gmp); + if (result != 0) { + glibtop_warn_io_r (server, "geom_gettree = %d", result); + return; + } + + result = geom_stats_open (); + if (result != 0) { + glibtop_warn_io_r (server, "geom_stats_open()"); + geom_deletetree (&gmp); + return; + } - if (result == -1) { - return; - } + sc = NULL; + sc = geom_stats_snapshot_get (); + if (sc == NULL) { + glibtop_warn_io_r (server, "geom_stats_snapshot_get()"); + geom_stats_close (); + geom_deletetree (&gmp); + return; + } + geom_stats_snapshot_timestamp (sc, &ts); + etime = ts.tv_sec + (ts.tv_nsec * 1e-9); + geom_stats_snapshot_reset (sc); - buf->read = sfs.f_syncreads + sfs.f_asyncreads; - buf->write = sfs.f_syncwrites + sfs.f_asyncwrites; - buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE); + for (;;) { + ds = geom_stats_snapshot_next (sc); + if (ds == NULL) { + break; + } + if (ds->id == NULL) { + continue; + } + + gid = geom_lookupid (&gmp, ds->id); + if (gid == NULL) { + geom_deletetree (&gmp); + result = geom_gettree (&gmp); + gid = geom_lookupid (&gmp, ds->id); + } + + if (gid == NULL) { + continue; + } + if (gid->lg_what == ISCONSUMER) { + continue; + } + + gp = gid->lg_ptr; + + if (!g_str_has_suffix (sfs.f_mntfromname, gp->lg_name)) { + continue; + } else { + result = devstat_compute_statistics (ds, NULL, etime, + DSM_TOTAL_TRANSFERS_READ, + &ld[0], + DSM_TOTAL_TRANSFERS_WRITE, + &ld[1], DSM_NONE); + if (result != 0) { + glibtop_warn_io_r (server, + "devstat_compute_statistics()"); + geom_stats_snapshot_free (sc); + geom_stats_close (); + geom_deletetree (&gmp); + return; + } + break; + } + } + + geom_stats_snapshot_free (sc); + geom_stats_close (); + geom_deletetree (&gmp); + + buf->read = ld[0]; + buf->write = ld[1]; +#else + buf->read = sfs.f_syncreads + sfs.f_asyncreads; + buf->write = sfs.f_syncwrites + sfs.f_asyncwrites; +#endif + buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE); } diff --git a/sysdeps/freebsd/glibtop_machine.h b/sysdeps/freebsd/glibtop_machine.h index 7c1cb920..a1ca2e82 100644 --- a/sysdeps/freebsd/glibtop_machine.h +++ b/sysdeps/freebsd/glibtop_machine.h @@ -35,17 +35,7 @@ #include <fcntl.h> -#ifdef __FreeBSD__ #include <osreldate.h> -#endif - -#ifdef __NetBSD__ -#include <sys/proc.h> - -#ifndef SRUN -#define SRUN SACTIVE -#endif -#endif G_BEGIN_DECLS diff --git a/sysdeps/freebsd/glibtop_server.h b/sysdeps/freebsd/glibtop_server.h index 087e2a35..c82fbd4e 100644 --- a/sysdeps/freebsd/glibtop_server.h +++ b/sysdeps/freebsd/glibtop_server.h @@ -21,19 +21,12 @@ Boston, MA 02111-1307, USA. */ -#ifndef __GLIBTOP_SERVER_H__ -#define __GLIBTOP_SERVER_H__ +#ifndef __FREEBSD__GLIBTOP_SERVER_H__ +#define __FREEBSD__GLIBTOP_SERVER_H__ G_BEGIN_DECLS -#define GLIBTOP_SUID_CPU (1 << GLIBTOP_SYSDEPS_CPU) -#define GLIBTOP_SUID_MEM (1 << GLIBTOP_SYSDEPS_MEM) #define GLIBTOP_SUID_SWAP (1 << GLIBTOP_SYSDEPS_SWAP) -#define GLIBTOP_SUID_UPTIME (1 << GLIBTOP_SYSDEPS_UPTIME) -#define GLIBTOP_SUID_LOADAVG (1 << GLIBTOP_SYSDEPS_LOADAVG) -#define GLIBTOP_SUID_SHM_LIMITS (1 << GLIBTOP_SYSDEPS_SHM_LIMITS) -#define GLIBTOP_SUID_MSG_LIMITS (1 << GLIBTOP_SYSDEPS_MSG_LIMITS) -#define GLIBTOP_SUID_SEM_LIMITS (1 << GLIBTOP_SYSDEPS_SEM_LIMITS) #define GLIBTOP_SUID_PROCLIST (1 << GLIBTOP_SYSDEPS_PROCLIST) #define GLIBTOP_SUID_PROC_STATE (1 << GLIBTOP_SYSDEPS_PROC_STATE) #define GLIBTOP_SUID_PROC_UID (1 << GLIBTOP_SYSDEPS_PROC_UID) @@ -45,8 +38,15 @@ G_BEGIN_DECLS #define GLIBTOP_SUID_PROC_ARGS (1 << GLIBTOP_SYSDEPS_PROC_ARGS) #define GLIBTOP_SUID_PROC_MAP (1 << GLIBTOP_SYSDEPS_PROC_MAP) #define GLIBTOP_SUID_NETLOAD (1 << GLIBTOP_SYSDEPS_NETLOAD) -#define GLIBTOP_SUID_NETLIST 0 #define GLIBTOP_SUID_PPP (1 << GLIBTOP_SYSDEPS_PPP) +#define GLIBTOP_SUID_CPU 0 +#define GLIBTOP_SUID_MEM 0 +#define GLIBTOP_SUID_UPTIME 0 +#define GLIBTOP_SUID_LOADAVG 0 +#define GLIBTOP_SUID_SHM_LIMITS 0 +#define GLIBTOP_SUID_MSG_LIMITS 0 +#define GLIBTOP_SUID_SEM_LIMITS 0 +#define GLIBTOP_SUID_NETLIST 0 G_END_DECLS diff --git a/sysdeps/freebsd/loadavg.c b/sysdeps/freebsd/loadavg.c index 5764e475..5c7ee050 100644 --- a/sysdeps/freebsd/loadavg.c +++ b/sysdeps/freebsd/loadavg.c @@ -22,32 +22,40 @@ */ #include <config.h> +#include <stdlib.h> #include <glibtop.h> #include <glibtop/error.h> #include <glibtop/loadavg.h> -#include <glibtop_suid.h> +#include <sys/types.h> +#include <sys/sysctl.h> static const unsigned long _glibtop_sysdeps_loadavg = (1L << GLIBTOP_LOADAVG_LOADAVG); +static const unsigned long _glibtop_sysdeps_last_pid = +(1L << GLIBTOP_LOADAVG_LAST_PID); + /* Init function. */ void -glibtop_init_loadavg_p (glibtop *server) +glibtop_init_loadavg_s (glibtop *server) { - server->sysdeps.loadavg = _glibtop_sysdeps_loadavg; + server->sysdeps.loadavg = _glibtop_sysdeps_loadavg | + _glibtop_sysdeps_last_pid; } /* Provides load averange. */ void -glibtop_get_loadavg_p (glibtop *server, glibtop_loadavg *buf) +glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf) { double ldavg[3]; + pid_t last_pid; + size_t len; int i; - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_LOADAVG), 0); + glibtop_init_s (&server, GLIBTOP_SYSDEPS_LOADAVG, 0); memset (buf, 0, sizeof (glibtop_loadavg)); @@ -58,4 +66,14 @@ glibtop_get_loadavg_p (glibtop *server, glibtop_loadavg *buf) for (i = 0; i < 3; i++) { buf->loadavg [i] = ldavg [i]; } /* end for */ + + len = sizeof (last_pid); + if (sysctlbyname ("kern.lastpid", &last_pid, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.lastpid)"); + return; + } + + buf->last_pid = last_pid; + + buf->flags |= _glibtop_sysdeps_last_pid; } diff --git a/sysdeps/freebsd/mem.c b/sysdeps/freebsd/mem.c index 95266163..1b7bf3d7 100644 --- a/sysdeps/freebsd/mem.c +++ b/sysdeps/freebsd/mem.c @@ -26,199 +26,67 @@ #include <glibtop/error.h> #include <glibtop/mem.h> -#include <glibtop_suid.h> - +#include <sys/types.h> #include <sys/sysctl.h> -#include <sys/vmmeter.h> -#if defined(__NetBSD__) && (__NetBSD_Version__ < 105020000) -#include <vm/vm_param.h> -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) -#include <uvm/uvm_extern.h> -#endif static const unsigned long _glibtop_sysdeps_mem = (1L << GLIBTOP_MEM_TOTAL) + (1L << GLIBTOP_MEM_USED) + -(1L << GLIBTOP_MEM_FREE) + -(1L << GLIBTOP_MEM_SHARED) + -(1L << GLIBTOP_MEM_BUFFER) + -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -(1L << GLIBTOP_MEM_CACHED) + -#endif -(1L << GLIBTOP_MEM_USER) + (1L << GLIBTOP_MEM_LOCKED); - -#ifndef LOG1024 -#define LOG1024 10 -#endif +(1L << GLIBTOP_MEM_FREE) + (1L << GLIBTOP_MEM_SHARED) + +(1L << GLIBTOP_MEM_BUFFER) + (1L << GLIBTOP_MEM_CACHED) + +(1L << GLIBTOP_MEM_USER); /* these are for getting the memory statistics */ -static int pageshift; /* log base 2 of the pagesize */ - -/* define pagetok in terms of pageshift */ -#define pagetok(size) ((size) << pageshift) - -/* nlist structure for kernel access */ -static struct nlist nlst [] = { -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - { "_bufpages" }, - { 0 } -#else -#if defined(__bsdi__) - { "_bufcachemem" }, -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - { "_bufspace" }, -#else - { "_bufpages" }, -#endif - { "_cnt" }, - { 0 } -#endif -}; - -/* MIB array for sysctl */ -#ifdef __bsdi__ -static int mib [] = { CTL_VM, VM_TOTAL }; -#else -static int mib [] = { CTL_VM, VM_METER }; -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) -static int mib_uvmexp [] = { CTL_VM, VM_UVMEXP }; -#endif +static int pagesize; /* Init function. */ - void -glibtop_init_mem_p (glibtop *server) +glibtop_init_mem_s (glibtop *server) { - register int pagesize; - - if (kvm_nlist (server->machine.kd, nlst) < 0) { - glibtop_warn_io_r (server, "kvm_nlist (mem)"); - return; - } - - /* get the page size with "getpagesize" and calculate pageshift - * from it */ pagesize = getpagesize (); - pageshift = 0; - while (pagesize > 1) { - pageshift++; - pagesize >>= 1; - } - - /* we only need the amount of log(2)1024 for our conversion */ - pageshift -= LOG1024; server->sysdeps.mem = _glibtop_sysdeps_mem; } void -glibtop_get_mem_p (glibtop *server, glibtop_mem *buf) +glibtop_get_mem_s (glibtop *server, glibtop_mem *buf) { - struct vmtotal vmt; - size_t length_vmt; -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - struct uvmexp uvmexp; - size_t length_uvmexp; -#else - struct vmmeter vmm; -#endif - u_int v_used_count; - u_int v_total_count; - u_int v_free_count; - int bufspace; - - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MEM), 0); - - memset (buf, 0, sizeof (glibtop_mem)); - - if (server->sysdeps.mem == 0) - return; + gulong memtotal; + guint memused; + gulong buffers; + guint cached; + size_t len; - /* [FIXME: On FreeBSD 2.2.6, sysctl () returns an incorrect - * value for `vmt.vm'. We use some code from Unix top - * here.] */ + glibtop_init_s (&server, GLIBTOP_SYSDEPS_MEM, 0); - /* Get the data from sysctl */ - length_vmt = sizeof (vmt); - if (sysctl (mib, 2, &vmt, &length_vmt, NULL, 0)) { - glibtop_warn_io_r (server, "sysctl (vmt)"); - return; - } + memset (buf, 0, sizeof *buf); -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - length_uvmexp = sizeof (uvmexp); - if (sysctl (mib_uvmexp, 2, &uvmexp, &length_uvmexp, NULL, 0)) { - glibtop_warn_io_r (server, "sysctl (uvmexp)"); + len = sizeof (memtotal); + if (sysctlbyname ("hw.physmem", &memtotal, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (hw.physmem)"); return; } -#else - /* Get the data from kvm_* */ - if (kvm_read (server->machine.kd, nlst[1].n_value, - &vmm, sizeof (vmm)) != sizeof (vmm)) { - glibtop_warn_io_r (server, "kvm_read (cnt)"); + + len = sizeof (memused); + if (sysctlbyname ("vm.stats.vm.v_wire_count", &memused, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (vm.stats.vm.v_wire_count)"); return; } -#endif - if (kvm_read (server->machine.kd, nlst[0].n_value, - &bufspace, sizeof (bufspace)) != sizeof (bufspace)) { - glibtop_warn_io_r (server, "kvm_read (bufspace)"); + len = sizeof (cached); + if (sysctlbyname ("vm.stats.vm.v_cache_count", &cached, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (vm.stats.vm.v_cache_count)"); return; } - /* convert memory stats to Kbytes */ - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - v_total_count = vmm.v_page_count; -#else -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - v_total_count = uvmexp.reserve_kernel + - uvmexp.reserve_pagedaemon + - uvmexp.free + uvmexp.wired + uvmexp.active + - uvmexp.inactive; -#else - v_total_count = vmm.v_kernel_pages + - vmm.v_free_count + vmm.v_wire_count + - vmm.v_active_count + vmm.v_inactive_count; -#endif -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - v_used_count = uvmexp.active + uvmexp.inactive; - v_free_count = uvmexp.free; -#else - v_used_count = vmm.v_active_count + vmm.v_inactive_count; - v_free_count = vmm.v_free_count; -#endif - - buf->total = (guint64) pagetok (v_total_count) << LOG1024; - buf->used = (guint64) pagetok (v_used_count) << LOG1024; - buf->free = (guint64) pagetok (v_free_count) << LOG1024; - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - buf->cached = (guint64) pagetok (vmm.v_cache_count) << LOG1024; -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - buf->locked = (guint64) pagetok (uvmexp.wired) << LOG1024; -#else - buf->locked = (guint64) pagetok (vmm.v_wire_count) << LOG1024; -#endif - - buf->shared = (guint64) pagetok (vmt.t_rmshr) << LOG1024; - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - buf->buffer = (guint64) bufspace; -#else - buf->buffer = (guint64) pagetok (bufspace) << LOG1024; -#endif - - /* user */ - buf->user = buf->total - buf->free - buf->shared - buf->buffer; - - /* Set the values to return */ + buffers = 0; + + buf->total = memtotal; + buf->used = (memused * pagesize); + buf->free = (buf->total - buf->used); + buf->shared = 0; + buf->cached = (cached * pagesize); + buf->buffer = buffers; + + buf->user = buf->total - buf->free - buf->cached - buf->buffer; buf->flags = _glibtop_sysdeps_mem; } diff --git a/sysdeps/freebsd/msg_limits.c b/sysdeps/freebsd/msg_limits.c index 4d40dc69..a718db64 100644 --- a/sysdeps/freebsd/msg_limits.c +++ b/sysdeps/freebsd/msg_limits.c @@ -26,91 +26,79 @@ #include <glibtop/error.h> #include <glibtop/msg_limits.h> -#include <glibtop_suid.h> +#include <sys/types.h> +#include <sys/sysctl.h> -#if (defined __bsdi__) && (_BSDI_VERSION < 199700) -/* Older versions of BSDI don't seem to have this. */ +static const unsigned long _glibtop_sysdeps_msg_limits = +(1L << GLIBTOP_IPC_MSGMAX) + (1L << GLIBTOP_IPC_MSGMNI) + +(1L << GLIBTOP_IPC_MSGMNB) + (1L << GLIBTOP_IPC_MSGTQL) + +(1L << GLIBTOP_IPC_MSGSSZ) + (1L << GLIBTOP_IPC_MSGPOOL); -void -glibtop_init_msg_limits_p (glibtop *server) -{ } +/* Init function. */ void -glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) +glibtop_init_msg_limits_s (glibtop *server) { - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MSG_LIMITS), 0); - - memset (buf, 0, sizeof (glibtop_msg_limits)); + server->sysdeps.msg_limits = _glibtop_sysdeps_msg_limits; } -#else - -/* Define the appropriate macro (if any) to get declaration of `struct - * msginfo'. Needed on, at least, FreeBSD. */ -#if defined (STRUCT_MSGINFO_NEEDS_KERNEL) -#define KERNEL 1 -#elif defined (STRUCT_MSGINFO_NEEDS__KERNEL) -#define _KERNEL 1 -#endif - -#include <sys/ipc.h> -#include <sys/msg.h> +/* Provides information about sysv ipc limits. */ -static const unsigned long _glibtop_sysdeps_msg_limits = -(1L << GLIBTOP_IPC_MSGMAX) + (1L << GLIBTOP_IPC_MSGMNI) + -(1L << GLIBTOP_IPC_MSGMNB) + (1L << GLIBTOP_IPC_MSGTQL) + -(1L << GLIBTOP_IPC_MSGSSZ); +void +glibtop_get_msg_limits_s (glibtop *server, glibtop_msg_limits *buf) +{ + size_t len; + int msgmax, msgmni, msgmnb, msgtql, msgssz, msgseg; -/* The values in this structure never change at runtime, so we only - * read it once during initialization. We have to use the name `_msginfo' - * since `msginfo' is already declared external in <sys/msg.h>. */ -static struct msginfo _msginfo; + glibtop_init_s (&server, GLIBTOP_SYSDEPS_MSG_LIMITS, 0); -/* nlist structure for kernel access */ -static struct nlist nlst [] = { - { "_msginfo" }, - { 0 } -}; + memset (buf, 0, sizeof (glibtop_msg_limits)); -/* Init function. */ + if (server->sysdeps.msg_limits == 0) + return; -void -glibtop_init_msg_limits_p (glibtop *server) -{ - if (kvm_nlist (server->machine.kd, nlst) < 0) { - glibtop_warn_io_r (server, "kvm_nlist (msg_limits)"); + len = sizeof (msgseg); + if (sysctlbyname ("kern.ipc.msgseg", &msgseg, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.msgseg)"); return; } - if (kvm_read (server->machine.kd, nlst [0].n_value, - &_msginfo, sizeof (_msginfo)) != sizeof (_msginfo)) { - glibtop_warn_io_r (server, "kvm_read (msginfo)"); + len = sizeof (msgssz); + if (sysctlbyname ("kern.ipc.msgssz", &msgssz, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.msgssz)"); return; } - server->sysdeps.msg_limits = _glibtop_sysdeps_msg_limits; -} - -/* Provides information about sysv ipc limits. */ + len = sizeof (msgtql); + if (sysctlbyname ("kern.ipc.msgtql", &msgtql, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.msgtql)"); + return; + } -void -glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) -{ - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MSG_LIMITS), 0); + len = sizeof (msgmnb); + if (sysctlbyname ("kern.ipc.msgmnb", &msgmnb, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.msgmnb)"); + return; + } - memset (buf, 0, sizeof (glibtop_msg_limits)); + len = sizeof (msgmni); + if (sysctlbyname ("kern.ipc.msgmni", &msgmni, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.msgmni)"); + return; + } - if (server->sysdeps.msg_limits == 0) + len = sizeof (msgmax); + if (sysctlbyname ("kern.ipc.msgmax", &msgmax, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.msgmax)"); return; + } - buf->msgmax = _msginfo.msgmax; - buf->msgmni = _msginfo.msgmni; - buf->msgmnb = _msginfo.msgmnb; - buf->msgtql = _msginfo.msgtql; - buf->msgssz = _msginfo.msgtql; + buf->msgmax = msgmax; + buf->msgmni = msgmni; + buf->msgmnb = msgmnb; + buf->msgtql = msgtql; + buf->msgssz = msgssz; + buf->msgpool = msgseg; buf->flags = _glibtop_sysdeps_msg_limits; } - -#endif /* either a newer BSDI or no BSDI at all. */ - diff --git a/sysdeps/freebsd/netload.c b/sysdeps/freebsd/netload.c index 4451dd9c..596230c6 100644 --- a/sysdeps/freebsd/netload.c +++ b/sysdeps/freebsd/netload.c @@ -30,6 +30,10 @@ #include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> + #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> @@ -54,189 +58,199 @@ static const unsigned long _glibtop_sysdeps_netload = (1L << GLIBTOP_NETLOAD_ERRORS_TOTAL) + (1L << GLIBTOP_NETLOAD_COLLISIONS); -static const unsigned _glibtop_sysdeps_netload_data = +static const unsigned long _glibtop_sysdeps_netload_data = (1L << GLIBTOP_NETLOAD_ADDRESS) + -#if !defined(__bsdi__) -(1L << GLIBTOP_NETLOAD_SUBNET) + -#endif (1L << GLIBTOP_NETLOAD_MTU); +static const unsigned long _glibtop_sysdeps_netload6 = +(1L << GLIBTOP_NETLOAD_ADDRESS6) + +(1L << GLIBTOP_NETLOAD_SCOPE6); + /* nlist structure for kernel access */ -static struct nlist nlst [] = { - { "_ifnet" }, - { 0 } -}; +static struct nlist nlst [] = + { + { "_ifnet" + }, + { 0 } + }; /* Init function. */ void glibtop_init_netload_p (glibtop *server) { - server->sysdeps.netload = _glibtop_sysdeps_netload; + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist"); + return; + } - if (kvm_nlist (server->machine.kd, nlst) < 0) - glibtop_error_io_r (server, "kvm_nlist"); + server->sysdeps.netload = _glibtop_sysdeps_netload; } /* Provides Network statistics. */ void glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, - const char *interface) + const char *interface) { - struct ifnet ifnet; - u_long ifnetaddr, ifnetfound; - struct sockaddr *sa = NULL; -#if (defined(__FreeBSD__) && (__FreeBSD_version < 501113)) || defined(__bsdi__) - char tname [16]; -#endif - char name [32]; - - union { - struct ifaddr ifa; - struct in_ifaddr in; - } ifaddr; - - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_NETLOAD), 0); + struct ifnet ifnet; + u_long ifnetaddr, ifnetfound; + struct sockaddr *sa = NULL; + char name [32]; - memset (buf, 0, sizeof (glibtop_netload)); + union { + struct ifaddr ifa; + struct in_ifaddr in; + } ifaddr; - if (kvm_read (server->machine.kd, nlst [0].n_value, - &ifnetaddr, sizeof (ifnetaddr)) != sizeof (ifnetaddr)) - glibtop_error_io_r (server, "kvm_read (ifnet)"); + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_NETLOAD), 0); - while (ifnetaddr) { - struct sockaddr_in *sin; - register char *cp; - u_long ifaddraddr; + memset (buf, 0, sizeof (glibtop_netload)); - { - ifnetfound = ifnetaddr; - - if (kvm_read (server->machine.kd, ifnetaddr, &ifnet, - sizeof (ifnet)) != sizeof (ifnet)) - glibtop_error_io_r (server, "kvm_read (ifnetaddr)"); - -#if (defined(__FreeBSD__) && (__FreeBSD_version < 501113)) || defined(__bsdi__) - if (kvm_read (server->machine.kd, (u_long) ifnet.if_name, - tname, 16) != 16) - glibtop_error_io_r (server, "kvm_read (if_name)"); - tname[15] = '\0'; - snprintf (name, 32, "%s%d", tname, ifnet.if_unit); -#else - g_strlcpy (name, ifnet.if_xname, sizeof(name)); -#endif -#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) - ifnetaddr = (u_long) ifnet.if_link.tqe_next; -#elif defined(__FreeBSD__) || defined(__bsdi__) - ifnetaddr = (u_long) ifnet.if_next; -#else - ifnetaddr = (u_long) ifnet.if_list.tqe_next; -#endif + if (server->sysdeps.netload == 0) return; - if (strcmp (name, interface) != 0) - continue; - -#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) - ifaddraddr = (u_long) ifnet.if_addrhead.tqh_first; -#elif defined(__FreeBSD__) || defined(__bsdi__) - ifaddraddr = (u_long) ifnet.if_addrlist; -#else - ifaddraddr = (u_long) ifnet.if_addrlist.tqh_first; -#endif + if (kvm_read (server->machine.kd, nlst [0].n_value, + &ifnetaddr, sizeof (ifnetaddr)) != sizeof (ifnetaddr)) { + glibtop_warn_io_r (server, "kvm_read (ifnet)"); + return; } - if (ifnet.if_flags & IFF_UP) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP); - if (ifnet.if_flags & IFF_BROADCAST) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST); - if (ifnet.if_flags & IFF_DEBUG) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG); - if (ifnet.if_flags & IFF_LOOPBACK) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK); - if (ifnet.if_flags & IFF_POINTOPOINT) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT); + + while (ifnetaddr) + { + struct sockaddr_in *sin; + register char *cp; + u_long ifaddraddr; + + { + ifnetfound = ifnetaddr; + + if (kvm_read (server->machine.kd, ifnetaddr, &ifnet, + sizeof (ifnet)) != sizeof (ifnet)) { + glibtop_warn_io_r (server, + "kvm_read (ifnetaddr)"); + continue; + } + + g_strlcpy (name, ifnet.if_xname, sizeof(name)); + ifnetaddr = (u_long) ifnet.if_link.tqe_next; + + if (strcmp (name, interface) != 0) + continue; + + ifaddraddr = (u_long) ifnet.if_addrhead.tqh_first; + } + if (ifnet.if_flags & IFF_UP) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP); + if (ifnet.if_flags & IFF_BROADCAST) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST); + if (ifnet.if_flags & IFF_DEBUG) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG); + if (ifnet.if_flags & IFF_LOOPBACK) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK); + if (ifnet.if_flags & IFF_POINTOPOINT) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT); #ifdef IFF_DRV_RUNNING - if (ifnet.if_drv_flags & IFF_DRV_RUNNING) + if (ifnet.if_drv_flags & IFF_DRV_RUNNING) #else - if (ifnet.if_flags & IFF_RUNNING) + if (ifnet.if_flags & IFF_RUNNING) #endif - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING); - if (ifnet.if_flags & IFF_NOARP) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP); - if (ifnet.if_flags & IFF_PROMISC) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC); - if (ifnet.if_flags & IFF_ALLMULTI) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI); + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING); + if (ifnet.if_flags & IFF_NOARP) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP); + if (ifnet.if_flags & IFF_PROMISC) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC); + if (ifnet.if_flags & IFF_ALLMULTI) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI); #ifdef IFF_DRV_OACTIVE - if (ifnet.if_drv_flags & IFF_DRV_OACTIVE) + if (ifnet.if_drv_flags & IFF_DRV_OACTIVE) #else - if (ifnet.if_flags & IFF_OACTIVE) -#endif - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_OACTIVE); - if (ifnet.if_flags & IFF_SIMPLEX) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_SIMPLEX); - if (ifnet.if_flags & IFF_LINK0) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK0); - if (ifnet.if_flags & IFF_LINK1) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK1); - if (ifnet.if_flags & IFF_LINK2) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK2); -#ifdef __FreeBSD__ - if (ifnet.if_flags & IFF_ALTPHYS) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALTPHYS); + if (ifnet.if_flags & IFF_OACTIVE) #endif - if (ifnet.if_flags & IFF_MULTICAST) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST); - - buf->packets_in = ifnet.if_ipackets; - buf->packets_out = ifnet.if_opackets; - buf->packets_total = buf->packets_in + buf->packets_out; - - buf->bytes_in = ifnet.if_ibytes; - buf->bytes_out = ifnet.if_obytes; - buf->bytes_total = buf->bytes_in + buf->bytes_out; - - buf->errors_in = ifnet.if_ierrors; - buf->errors_out = ifnet.if_oerrors; - buf->errors_total = buf->errors_in + buf->errors_out; - - buf->collisions = ifnet.if_collisions; - buf->flags = _glibtop_sysdeps_netload; - - while (ifaddraddr) { - if ((kvm_read (server->machine.kd, ifaddraddr, &ifaddr, - sizeof (ifaddr)) != sizeof (ifaddr))) - glibtop_error_io_r (server, "kvm_read (ifaddraddr)"); + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_OACTIVE); + if (ifnet.if_flags & IFF_SIMPLEX) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_SIMPLEX); + if (ifnet.if_flags & IFF_LINK0) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK0); + if (ifnet.if_flags & IFF_LINK1) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK1); + if (ifnet.if_flags & IFF_LINK2) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK2); + if (ifnet.if_flags & IFF_ALTPHYS) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALTPHYS); + if (ifnet.if_flags & IFF_MULTICAST) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST); + + buf->packets_in = ifnet.if_ipackets; + buf->packets_out = ifnet.if_opackets; + buf->packets_total = buf->packets_in + buf->packets_out; + + buf->bytes_in = ifnet.if_ibytes; + buf->bytes_out = ifnet.if_obytes; + buf->bytes_total = buf->bytes_in + buf->bytes_out; + + buf->errors_in = ifnet.if_ierrors; + buf->errors_out = ifnet.if_oerrors; + buf->errors_total = buf->errors_in + buf->errors_out; + + buf->collisions = ifnet.if_collisions; + buf->flags = _glibtop_sysdeps_netload; + + while (ifaddraddr) { + if ((kvm_read (server->machine.kd, ifaddraddr, &ifaddr, + sizeof (ifaddr)) != sizeof (ifaddr))) { + glibtop_warn_io_r (server, + "kvm_read (ifaddraddr)"); + continue; + } #define CP(x) ((char *)(x)) - cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + - CP(&ifaddr); - sa = (struct sockaddr *)cp; - - if (sa->sa_family == AF_LINK) { - struct sockaddr_dl *dl = (struct sockaddr_dl *) sa; - - memcpy (buf->hwaddress, LLADDR (dl), sizeof (buf->hwaddress)); - buf->flags |= GLIBTOP_NETLOAD_HWADDRESS; - } else if (sa->sa_family == AF_INET) { - sin = (struct sockaddr_in *)sa; -#if !defined(__bsdi__) - /* Commenting out to "fix" #13345. */ - buf->subnet = htonl (ifaddr.in.ia_subnet); -#endif - buf->address = sin->sin_addr.s_addr; - buf->mtu = ifnet.if_mtu; - - buf->flags |= _glibtop_sysdeps_netload_data; - } else if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; - - memcpy (buf->address6, &sin6->sin6_addr, sizeof (buf->address6)); - buf->flags |= GLIBTOP_NETLOAD_ADDRESS6; - } - /* FIXME prefix6, scope6 */ - ifaddraddr = (u_long) ifaddr.ifa.ifa_link.tqe_next; - } - return; - } + cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + + CP(&ifaddr); + sa = (struct sockaddr *)cp; + + if (sa->sa_family == AF_LINK) { + struct sockaddr_dl *dl = (struct sockaddr_dl *) sa; + + memcpy (buf->hwaddress, LLADDR (dl), + sizeof (buf->hwaddress)); + buf->flags |= GLIBTOP_NETLOAD_HWADDRESS; + } else if (sa->sa_family == AF_INET) { + sin = (struct sockaddr_in *)sa; + /* Commenting out to "fix" #13345. */ + buf->subnet = htonl (ifaddr.in.ia_subnet); + buf->address = sin->sin_addr.s_addr; + buf->mtu = ifnet.if_mtu; + + buf->flags |= _glibtop_sysdeps_netload_data; + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + int in6fd; + + memcpy (buf->address6, &sin6->sin6_addr, + sizeof (buf->address6)); + buf->scope6 = (guint8) sin6->sin6_scope_id; + buf->flags |= _glibtop_sysdeps_netload6; + + in6fd = socket (AF_INET6, SOCK_DGRAM, 0); + if (in6fd >= 0) { + struct in6_ifreq ifr; + + memset (&ifr, 0, sizeof (ifr)); + ifr.ifr_addr = *sin6; + g_strlcpy (ifr.ifr_name, interface, + sizeof (ifr.ifr_name)); + if (ioctl (in6fd, SIOCGIFNETMASK_IN6, + (char *) &ifr) >= 0) { + memcpy (buf->prefix6, + &ifr.ifr_addr.sin6_addr, + sizeof (buf->prefix6)); + buf->flags |= GLIBTOP_NETLOAD_PREFIX6; + } + close (in6fd); + } + } + ifaddraddr = (u_long) ifaddr.ifa.ifa_link.tqe_next; + } + return; + } } diff --git a/sysdeps/freebsd/open.c b/sysdeps/freebsd/open.c index 4703eb70..fdf4bc85 100644 --- a/sysdeps/freebsd/open.c +++ b/sysdeps/freebsd/open.c @@ -23,6 +23,7 @@ #include <config.h> #include <glibtop.h> +#include <glibtop/error.h> #include <glibtop/open.h> #include <glibtop/init_hooks.h> @@ -65,9 +66,7 @@ glibtop_open_p (glibtop *server, const char *program_name, server->machine.gid = getgid (); server->machine.egid = getegid (); -#ifdef __FreeBSD__ server->os_version_code = __FreeBSD_version; -#endif /* Setup machine-specific data */ server->machine.kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "kvm_open"); diff --git a/sysdeps/freebsd/ppp.c b/sysdeps/freebsd/ppp.c index 1c97bdca..9ad4afa1 100644 --- a/sysdeps/freebsd/ppp.c +++ b/sysdeps/freebsd/ppp.c @@ -40,11 +40,7 @@ #include <net/netisr.h> #include <net/route.h> -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include <net/if_sppp.h> -#else -#include <i4b/sppp/if_sppp.h> -#endif /* Read `misc/i4b_acct.txt' for details ... */ #ifdef HAVE_I4B_ACCT @@ -83,8 +79,10 @@ glibtop_init_ppp_p (glibtop *server) #endif #endif /* HAVE_I4B */ - if (kvm_nlist (server->machine.kd, nlst) < 0) - glibtop_error_io_r (server, "kvm_nlist"); + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist"); + server->sysdeps.ppp = 0; + } } /* Provides information about ppp usage. */ @@ -104,9 +102,13 @@ glibtop_get_ppp_p (glibtop *server, glibtop_ppp *buf, unsigned short device) memset (buf, 0, sizeof (glibtop_ppp)); + if (server->sysdeps.ppp == 0) return; + if (kvm_read (server->machine.kd, nlst [0].n_value, - &data, sizeof (data)) != sizeof (data)) - glibtop_error_io_r (server, "kvm_read (i4bisppp_softc)"); + &data, sizeof (data)) != sizeof (data)) { + glibtop_warn_io_r (server, "kvm_read (i4bisppp_softc)"); + return; + } #ifdef HAVE_I4B_ACCT phase = data.sc_if_un.scu_sp.pp_phase; diff --git a/sysdeps/freebsd/procargs.c b/sysdeps/freebsd/procargs.c index 9b7357ee..ec4671bf 100644 --- a/sysdeps/freebsd/procargs.c +++ b/sysdeps/freebsd/procargs.c @@ -54,11 +54,6 @@ glibtop_get_proc_args_p (glibtop *server, glibtop_proc_args *buf, size_t size = 0, pos = 0; int count; -#ifndef __bsdi__ - char filename [BUFSIZ]; - struct stat statb; -#endif - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_ARGS), 0); memset (buf, 0, sizeof (glibtop_proc_args)); @@ -66,25 +61,20 @@ glibtop_get_proc_args_p (glibtop *server, glibtop_proc_args *buf, /* swapper, init, pagedaemon, vmdaemon, update - this doen't work. */ if (pid < 5) return NULL; -#ifndef __bsdi__ - sprintf (filename, "/proc/%d/mem", pid); - if (stat (filename, &statb)) return NULL; -#endif - glibtop_suid_enter (server); /* Get the process data */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count < 1)) { - glibtop_suid_leave (server); glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + glibtop_suid_leave (server); return NULL; } args = kvm_getargv (server->machine.kd, pinfo, max_len); if (args == NULL) { - glibtop_suid_leave (server); glibtop_warn_io_r (server, "kvm_getargv (%d)", pid); + glibtop_suid_leave (server); return NULL; } diff --git a/sysdeps/freebsd/prockernel.c b/sysdeps/freebsd/prockernel.c index 08a8511b..759ab5d5 100644 --- a/sysdeps/freebsd/prockernel.c +++ b/sysdeps/freebsd/prockernel.c @@ -32,51 +32,27 @@ #include <sys/param.h> #include <sys/sysctl.h> #include <sys/proc.h> -#if (!defined __OpenBSD__) && (!defined __bsdi__) #include <sys/user.h> -#endif -#if !defined(__bsdi__) && !(defined(__FreeBSD__) && defined(__alpha__)) && \ - !defined(__NetBSD__) -#include <machine/pcb.h> -#endif #include <unistd.h> #include <fcntl.h> -#ifdef __FreeBSD__ #include <osreldate.h> -#endif - -#ifdef __NetBSD__ -#include <machine/vmparam.h> -#include <machine/pmap.h> -#ifdef __arm32__ -#define KERNBASE KERNEL_BASE -#endif -#endif - -#ifdef __NetBSD__ -#include <machine/vmparam.h> -#include <machine/pmap.h> -#ifdef __arm32__ -#define KERNBASE KERNEL_BASE -#endif -#endif - static const unsigned long _glibtop_sysdeps_proc_kernel_pstats = +(1L << GLIBTOP_PROC_KERNEL_K_FLAGS) + (1L << GLIBTOP_PROC_KERNEL_MIN_FLT) + (1L << GLIBTOP_PROC_KERNEL_MAJ_FLT) + +#if (__FreeBSD_version >= 600006) || defined(__FreeBSD_kernel__) (1L << GLIBTOP_PROC_KERNEL_CMIN_FLT) + (1L << GLIBTOP_PROC_KERNEL_CMAJ_FLT); - -static const unsigned long _glibtop_sysdeps_proc_kernel_pcb = -(1L << GLIBTOP_PROC_KERNEL_KSTK_EIP) + -(1L << GLIBTOP_PROC_KERNEL_KSTK_ESP); +#else +0; +#endif static const unsigned long _glibtop_sysdeps_proc_kernel_wchan = -(1L << GLIBTOP_PROC_KERNEL_NWCHAN) + -(1L << GLIBTOP_PROC_KERNEL_WCHAN); +(1L << GLIBTOP_PROC_KERNEL_WCHAN) + +(1L << GLIBTOP_PROC_KERNEL_NWCHAN); /* Init function. */ @@ -84,7 +60,6 @@ void glibtop_init_proc_kernel_p (glibtop *server) { server->sysdeps.proc_kernel = _glibtop_sysdeps_proc_kernel_pstats | - _glibtop_sysdeps_proc_kernel_pcb | _glibtop_sysdeps_proc_kernel_wchan; } @@ -94,16 +69,8 @@ glibtop_get_proc_kernel_p (glibtop *server, pid_t pid) { struct kinfo_proc *pinfo; -#if !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) - struct user *u_addr = (struct user *)USRSTACK; - struct pstats pstats; - struct pcb pcb; -#endif int count; - char filename [BUFSIZ]; - struct stat statb; - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_KERNEL), 0); memset (buf, 0, sizeof (glibtop_proc_kernel)); @@ -114,159 +81,43 @@ glibtop_get_proc_kernel_p (glibtop *server, /* It does not work for the swapper task. */ if (pid == 0) return; + glibtop_suid_enter (server); + /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count != 1)) { glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + glibtop_suid_leave (server); return; } -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) + glibtop_suid_leave (server); #define PROC_WCHAN ki_wchan #define PROC_WMESG ki_wmesg #define PROC_WMESG ki_wmesg -#else - -#define PROC_WCHAN kp_proc.p_wchan -#define PROC_WMESG kp_proc.p_wmesg -#define PROC_WMESG kp_eproc.e_wmesg - -#endif - -#if !defined(__NetBSD__) || !defined(SACTIVE) - buf->nwchan = (unsigned long) pinfo [0].PROC_WCHAN &~ KERNBASE; + buf->nwchan = (unsigned long) pinfo [0].PROC_WCHAN; buf->flags |= (1L << GLIBTOP_PROC_KERNEL_NWCHAN); - if (pinfo [0].PROC_WCHAN && pinfo [0].PROC_WMESG) { + if (pinfo [0].PROC_WCHAN && pinfo [0].PROC_WMESG[0] != 0) { g_strlcpy (buf->wchan, pinfo [0].PROC_WMESG, sizeof buf->wchan); buf->flags |= (1L << GLIBTOP_PROC_KERNEL_WCHAN); } else { buf->wchan [0] = 0; } -#endif - -#if !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) - - /* Taken from `saveuser ()' in `/usr/src/bin/ps/ps.c'. */ - - /* [FIXME]: /usr/include/sys/user.h tells me that the user area - * may or may not be at the same kernel address in all - * processes, but I don't see any way to get that address. - * Since `ps' simply uses its own address, I think it's - * safe to do this here, too. */ - /* NOTE: You need to mount the /proc filesystem to make - * `kvm_uread' work. */ - - sprintf (filename, "/proc/%d/mem", (int) pid); - if (stat (filename, &statb)) return; - - glibtop_suid_enter (server); - -#if !defined(__NetBSD__) || !defined(SACTIVE) -#ifdef __NetBSD__ - /* On NetBSD, there is no kvm_uread(), and kvm_read() always reads - * from kernel memory. */ - - if (kvm_read (server->machine.kd, -#else - - if ((pinfo [0].kp_proc.p_flag & P_INMEM) && - kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, + buf->k_flags = (unsigned long) pinfo [0].ki_flag; + buf->min_flt = (unsigned long) pinfo [0].ki_rusage.ru_minflt; + buf->maj_flt = (unsigned long) pinfo [0].ki_rusage.ru_majflt; +#if (__FreeBSD_version >= 600006) || defined(__FreeBSD_kernel__) + buf->cmin_flt = (unsigned long) buf->min_flt + pinfo [0].ki_rusage_ch.ru_minflt; + buf->cmaj_flt = (unsigned long) buf->maj_flt + pinfo [0].ki_rusage_ch.ru_majflt; #endif - (unsigned long) &u_addr->u_stats, - (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) - { - /* - * The u-area might be swapped out, and we can't get - * at it because we have a crashdump and no swap. - * If it's here fill in these fields, otherwise, just - * leave them 0. - */ - buf->min_flt = (guint64) pstats.p_ru.ru_minflt; - buf->maj_flt = (guint64) pstats.p_ru.ru_majflt; - buf->cmin_flt = (guint64) pstats.p_cru.ru_minflt; - buf->cmaj_flt = (guint64) pstats.p_cru.ru_majflt; + buf->flags |= _glibtop_sysdeps_proc_kernel_pstats; - buf->flags |= _glibtop_sysdeps_proc_kernel_pstats; - } - -#ifdef __NetBSD__ - if (kvm_read (server->machine.kd, -#else - if ((pinfo [0].kp_proc.p_flag & P_INMEM) && - kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, -#endif - (unsigned long) &u_addr->u_pcb, - (char *) &pcb, sizeof (pcb)) == sizeof (pcb)) - { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#ifndef __alpha__ -#if (__FreeBSD_version >= 300003) || defined(__FreeBSD_kernel__) - buf->kstk_esp = (guint64) pcb.pcb_esp; - buf->kstk_eip = (guint64) pcb.pcb_eip; -#else - buf->kstk_esp = (guint64) pcb.pcb_ksp; - buf->kstk_eip = (guint64) pcb.pcb_pc; -#endif -#else - /*xxx FreeBSD/Alpha? */ -#endif -#else -#ifdef __i386__ - buf->kstk_esp = (guint64) pcb.pcb_tss.tss_esp0; -#ifdef __bsdi__ - buf->kstk_eip = (guint64) pcb.pcb_tss.tss_eip; -#else - buf->kstk_eip = (guint64) pcb.pcb_tss.__tss_eip; -#endif -#else -#if defined(__NetBSD__) -#if defined(__m68k__) - buf->kstk_esp = (guint64) pcb.pcb_usp; - buf->kstk_eip = (guint64) 0; -#elif defined(__x86_64__) - buf->kstk_esp = (guint64) pcb.pcb_usersp; - buf->kstk_eip = (guint64) 0; -#elif (defined(__arm32__) || defined(__powerpc__)) - buf->kstk_esp = (guint64) pcb.pcb_sp; - buf->kstk_eip = (guint64) 0; -#elif defined(__mipsel__) - buf->kstk_esp = (guint64) pcb.pcb_context[8]; - buf->kstk_eip = (guint64) 0; -#elif defined(__sparc__) - buf->kstk_esp = (guint64) pcb.pcb_sp; - buf->kstk_eip = (guint64) pcb.pcb_pc; -#elif defined(__alpha__) - buf->kstk_esp = (guint64) pcb.pcb_context[9]; - buf->kstk_eip = (guint64) pcb.pcb_context[8]; -#else - /* provide some defaults for other platforms */ - buf->kstk_esp = (guint64) 0; - buf->kstk_eip = (guint64) 0; -#endif /* ${MACHINE_ARCH} */ -#endif /* __NetBSD__ */ - buf->flags |= _glibtop_sysdeps_proc_kernel_pcb; -#endif -#endif - } -#endif - - /* Taken from `wchan ()' in `/usr/src/bin/ps/print.c'. */ - - glibtop_suid_leave (server); - -#else - /* XXX: the code here was, quite frankly, junk, and almost - * certainly wrong - remove it all, leave these fields - * unpopulated, and give up until such time as the right - * code is produced for both FreeBSD 4.x and 5.x - */ return; -#endif /* __FreeBSD__ */ } diff --git a/sysdeps/freebsd/proclist.c b/sysdeps/freebsd/proclist.c index 9a866550..665ac4c1 100644 --- a/sysdeps/freebsd/proclist.c +++ b/sysdeps/freebsd/proclist.c @@ -25,9 +25,14 @@ #include <glibtop.h> #include <glibtop/error.h> #include <glibtop/proclist.h> +#include <glibtop/procstate.h> #include <glibtop_suid.h> +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/user.h> + static const unsigned long _glibtop_sysdeps_proclist = (1L << GLIBTOP_PROCLIST_TOTAL) + (1L << GLIBTOP_PROCLIST_NUMBER) + (1L << GLIBTOP_PROCLIST_SIZE); @@ -60,56 +65,90 @@ glibtop_init_proclist_p (glibtop *server) unsigned * glibtop_get_proclist_p (glibtop *server, glibtop_proclist *buf, - gint64 real_which, gint64 arg) + gint64 which, gint64 arg) { struct kinfo_proc *pinfo; - unsigned *pids = NULL; - int which, count; - int i,j; + GArray *pids; + glibtop_proc_state procstate; + size_t len; + unsigned int i; glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROCLIST), 0); memset (buf, 0, sizeof (glibtop_proclist)); - which = (int)(real_which & GLIBTOP_KERN_PROC_MASK); + if (sysctlbyname ("kern.proc.all", NULL, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.proc.all)"); + return NULL; + } + + pinfo = (struct kinfo_proc *) g_malloc0 (len); - /* Get the process data */ - pinfo = kvm_getprocs (server->machine.kd, which, arg, &count); - if ((pinfo == NULL) || (count < 1)) { - glibtop_warn_io_r (server, "kvm_getprocs (proclist)"); + if (sysctlbyname ("kern.proc.all", pinfo, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.proc.all)"); + g_free (pinfo); return NULL; } - count--; - - /* Allocate count objects in the pids_chain array - * Same as malloc is pids is NULL, which it is. */ - pids = g_realloc (pids, count * sizeof (unsigned)); - /* Copy the pids over to this chain */ - for (i=j=0; i < count; i++) { -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) -#define PROC_STAT ki_stat -#define PROC_RUID ki_ruid -#define PROC_PID ki_pid - -#else -#define PROC_STAT kp_proc.p_stat -#define PROC_RUID kp_eproc.e_pcred.p_ruid -#define PROC_PID kp_proc.p_pid - -#endif - - if ((real_which & GLIBTOP_EXCLUDE_IDLE) && - (pinfo[i].PROC_STAT != SRUN)) - continue; - else if ((real_which & GLIBTOP_EXCLUDE_SYSTEM) && - (pinfo[i].PROC_RUID == 0)) - continue; - pids [j++] = (unsigned) pinfo[i].PROC_PID; - } /* end for */ - /* Set the fields in buf */ - buf->number = j; - buf->size = sizeof (unsigned); - buf->total = j * sizeof (unsigned); + + len /= sizeof (struct kinfo_proc); + + pids = g_array_sized_new (FALSE, FALSE, sizeof (unsigned), len); + + for (i = 0; i < len; i++) { + unsigned pid; + + pid = (unsigned) pinfo[i].ki_pid; + + switch (which & GLIBTOP_KERN_PROC_MASK) { + case GLIBTOP_KERN_PROC_ALL: + break; + case GLIBTOP_KERN_PROC_PID: + if ((unsigned) arg != pid) + continue; + break; + case GLIBTOP_KERN_PROC_UID: + if ((uid_t) arg != pinfo[i].ki_ruid) + continue; + break; + case GLIBTOP_KERN_PROC_PGRP: + if ((pid_t) arg != pinfo[i].ki_pgid) + continue; + break; + case GLIBTOP_KERN_PROC_SESSION: + if ((pid_t) arg != pinfo[i].ki_sid) + continue; + break; + case GLIBTOP_KERN_PROC_TTY: + if ((dev_t) arg != pinfo[i].ki_tdev) + continue; + break; + case GLIBTOP_KERN_PROC_RUID: + if ((uid_t) arg != pinfo[i].ki_ruid) + continue; + break; + } + + if (which & GLIBTOP_EXCLUDE_NOTTY) + if (pinfo[i].ki_tdev == (dev_t) -1) continue; + + if (which & GLIBTOP_EXCLUDE_IDLE) { + glibtop_get_proc_state_p (server, &procstate, pid); + if (procstate.flags & (1L << GLIBTOP_PROC_STATE_STATE)) + if (procstate.state != GLIBTOP_PROCESS_RUNNING) continue; + } + + if (which & GLIBTOP_EXCLUDE_SYSTEM) + if (pinfo[i].ki_ruid == (uid_t) 0) continue; + + g_array_append_val (pids, pid); + } + + g_free (pinfo); + buf->flags = _glibtop_sysdeps_proclist; - return pids; + buf->size = sizeof (unsigned); + buf->number = pids->len; + buf->total = buf->number * buf->size; + + return (unsigned *) g_array_free (pids, FALSE); } diff --git a/sysdeps/freebsd/procmap.c b/sysdeps/freebsd/procmap.c index 8c2c0f89..0b60d096 100644 --- a/sysdeps/freebsd/procmap.c +++ b/sysdeps/freebsd/procmap.c @@ -32,282 +32,256 @@ #include <sys/param.h> #include <sys/proc.h> #include <sys/resource.h> -#if defined(__NetBSD__) && (__NetBSD_Version__ < 105020000) #include <vm/vm_object.h> -#include <vm/vm_prot.h> #include <vm/vm_map.h> -#elif defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) -#include <uvm/uvm_extern.h> -#else -#include <vm/vm_object.h> -#include <vm/vm_map.h> -#if (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__) #include <vm/vm.h> -#else -#include <vm/vm_prot.h> -#endif -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #define _KVM_VNODE -#endif #include <sys/vnode.h> -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #undef _KVM_VNODE -#endif + +#define _KERNEL +#include <sys/pipe.h> +#include <sys/conf.h> +#include <sys/file.h> #include <sys/mount.h> #include <ufs/ufs/quota.h> #include <ufs/ufs/inode.h> +#include <fs/devfs/devfs.h> +#if (__FreeBSD_version >= 600006) || defined(__FreeBSD_kernel__) +#include <fs/devfs/devfs_int.h> +#endif +#undef _KERNEL #include <sys/ucred.h> -#if (!defined __OpenBSD__) && (!defined __bsdi__) -#include <sys/user.h> -#endif #include <sys/sysctl.h> -#if !defined(__NetBSD__) || (__NetBSD_Version__ < 105020000) -#include <vm/vm.h> -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) -/* Fixme ... */ -#undef _KERNEL -#define _UVM_UVM_AMAP_I_H_ 1 -#define _UVM_UVM_MAP_I_H_ 1 -#include <uvm/uvm.h> -#endif static const unsigned long _glibtop_sysdeps_proc_map = -(1L << GLIBTOP_PROC_MAP_TOTAL) + (1L << GLIBTOP_PROC_MAP_NUMBER) + -(1L << GLIBTOP_PROC_MAP_SIZE); + (1L << GLIBTOP_PROC_MAP_TOTAL) + (1L << GLIBTOP_PROC_MAP_NUMBER) + + (1L << GLIBTOP_PROC_MAP_SIZE); static const unsigned long _glibtop_sysdeps_map_entry = -(1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) + -(1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM) + -(1L << GLIBTOP_MAP_ENTRY_INODE) + (1L << GLIBTOP_MAP_ENTRY_DEVICE); + (1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) + + (1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM) + + (1L << GLIBTOP_MAP_ENTRY_INODE) + (1L << GLIBTOP_MAP_ENTRY_DEVICE); + +#if (__FreeBSD_version >= 600006) || defined(__FreeBSD_kernel__) +void _glibtop_sysdeps_freebsd_dev_inode (glibtop *server, struct vnode *vnode, struct vnode *vn, guint64 *inum, guint64 *dev); + +void +_glibtop_sysdeps_freebsd_dev_inode (glibtop *server, struct vnode *vnode, + struct vnode *vn, guint64 *inum, + guint64 *dev) +{ + char *tagptr; + char tagstr[12]; + struct inode inode; + struct cdev_priv priv; + struct cdev si; + + *inum = 0; + *dev = 0; + + if (kvm_read (server->machine.kd, (gulong) &vnode->v_tag, + (char *) &tagptr, sizeof (tagptr)) != sizeof (tagptr) || + kvm_read (server->machine.kd, (gulong) tagptr, + (char *) tagstr, sizeof (tagstr)) != sizeof (tagstr)) + { + glibtop_warn_io_r (server, "kvm_read (tagptr)"); + return; + } + + tagstr[sizeof(tagstr) - 1] = '\0'; + + if (strcmp (tagstr, "ufs")) + return; + + if (kvm_read (server->machine.kd, (gulong) VTOI(vn), (char *) &inode, + sizeof (inode)) != sizeof (inode)) + { + glibtop_warn_io_r (server, "kvm_read (inode)"); + return; + } + + if (kvm_read (server->machine.kd, (gulong) inode.i_dev, (char *) &si, + sizeof (si)) != sizeof (si) || + kvm_read (server->machine.kd, (gulong) si.si_priv, (char *) &priv, + sizeof (priv)) != sizeof (priv)) + { + glibtop_warn_io_r (server, "kvm_read (si)"); + return; + } + + *inum = (guint64) inode.i_number; + *dev = (guint64) priv.cdp_inode; +} +#endif /* Init function. */ void glibtop_init_proc_map_p (glibtop *server) { - server->sysdeps.proc_map = _glibtop_sysdeps_proc_map; + server->sysdeps.proc_map = _glibtop_sysdeps_proc_map; } /* Provides detailed information about a process. */ glibtop_map_entry * glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf, - pid_t pid) + pid_t pid) { - struct kinfo_proc *pinfo; - struct vm_map_entry entry, *first; - struct vmspace vmspace; -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - struct vnode vnode; - struct inode inode; -#else - struct vm_object object; -#endif - GArray *maps = g_array_sized_new(FALSE, FALSE, - sizeof(glibtop_map_entry), - 100); -#if (defined __FreeBSD__) || defined(__FreeBSD_kernel__) - struct vnode vnode; -#if (__FreeBSD_version < 500039) && !defined(__FreeBSD_kernel__) - struct inode inode; -#endif -#endif - int count, i = 0; - int update = 0; - - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MAP), 0); - - memset (buf, 0, sizeof (glibtop_proc_map)); - - /* It does not work for the swapper task. */ - if (pid == 0) return (glibtop_map_entry*) g_array_free(maps, TRUE); - - glibtop_suid_enter (server); - - /* Get the process data */ - pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); - if ((pinfo == NULL) || (count < 1)) { - glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); - return (glibtop_map_entry*) g_array_free(maps, TRUE); - } - - /* Now we get the memory maps. */ - - if (kvm_read (server->machine.kd, -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) - (unsigned long) pinfo [0].ki_vmspace, -#else - (unsigned long) pinfo [0].kp_proc.p_vmspace, -#endif - (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) - glibtop_error_io_r (server, "kvm_read (vmspace)"); - - first = vmspace.vm_map.header.next; - - if (kvm_read (server->machine.kd, - (unsigned long) vmspace.vm_map.header.next, - (char *) &entry, sizeof (entry)) != sizeof (entry)) - glibtop_error_io_r (server, "kvm_read (entry)"); - - /* Allocate space. */ - - buf->number = vmspace.vm_map.nentries; - buf->size = sizeof (glibtop_map_entry); - - buf->total = buf->number * buf->size; - - buf->flags = _glibtop_sysdeps_proc_map; - - /* Walk through the `vm_map_entry' list ... */ - - /* I tested this a few times with `mmap'; as soon as you write - * to the mmap'ed area, the object type changes from OBJT_VNODE - * to OBJT_DEFAULT so if seems this really works. */ - - do { - glibtop_map_entry *mentry; - unsigned long inum, dev; - guint len; - - if (update) { - if (kvm_read (server->machine.kd, - (unsigned long) entry.next, - &entry, sizeof (entry)) != sizeof (entry)) - glibtop_error_io_r (server, "kvm_read (entry)"); - } else { - update = 1; - } - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#if (__FreeBSD__ >= 4) || defined(__FreeBSD_kernel__) - if (entry.eflags & (MAP_ENTRY_IS_SUB_MAP)) - continue; -#else - if (entry.eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) - continue; -#endif -#else -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - if (UVM_ET_ISSUBMAP (&entry)) - continue; -#else - if (entry.is_a_map || entry.is_sub_map) - continue; -#endif -#endif - - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - if (!entry.object.uvm_obj) - continue; - - /* We're only interested in vnodes */ + struct kinfo_proc *pinfo; + struct vm_map_entry entry, *first; + struct vmspace vmspace; + struct vm_object object; + GArray *maps; + struct vnode vnode; + int count; + int update = 0; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MAP), 0); + + memset (buf, 0, sizeof (glibtop_proc_map)); + + /* It does not work for the swapper task. */ + if (pid == 0) return NULL; + + /*return (glibtop_map_entry*) g_array_free(maps, TRUE);*/ + + glibtop_suid_enter (server); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + glibtop_suid_leave (server); + return NULL; + } + + /* Now we get the memory maps. */ + + if (kvm_read (server->machine.kd, + (gulong) pinfo [0].ki_vmspace, + (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) { + glibtop_warn_io_r (server, "kvm_read (vmspace)"); + glibtop_suid_leave (server); + return NULL; + } + + first = vmspace.vm_map.header.next; + + if (kvm_read (server->machine.kd, + (gulong) vmspace.vm_map.header.next, + (char *) &entry, sizeof (entry)) != sizeof (entry)) { + glibtop_warn_io_r (server, "kvm_read (entry)"); + glibtop_suid_leave (server); + return NULL; + } + + /* Walk through the `vm_map_entry' list ... */ + + /* I tested this a few times with `mmap'; as soon as you write + * to the mmap'ed area, the object type changes from OBJT_VNODE + * to OBJT_DEFAULT so if seems this really works. */ + + maps = g_array_sized_new(FALSE, FALSE, sizeof(glibtop_map_entry), + vmspace.vm_map.nentries); + + do { + glibtop_map_entry *mentry; + guint64 inum, dev; + guint len; + + if (update) { + if (kvm_read (server->machine.kd, + (gulong) entry.next, + (char *) &entry, sizeof (entry)) != sizeof (entry)) { + glibtop_warn_io_r (server, "kvm_read (entry)"); + continue; + } + } else { + update = 1; + } + + if (entry.eflags & (MAP_ENTRY_IS_SUB_MAP)) + continue; + + if (!entry.object.vm_object) + continue; + + /* We're only interested in `vm_object's */ + + if (kvm_read (server->machine.kd, + (gulong) entry.object.vm_object, + (char *) &object, sizeof (object)) != sizeof (object)) { + glibtop_warn_io_r (server, "kvm_read (object)"); + continue; + } + + /* If the object is of type vnode, add its size */ + + if (object.type != OBJT_VNODE) + continue; + + if (!object.handle) + continue; + + if (kvm_read (server->machine.kd, + (gulong) object.handle, + (char *) &vnode, sizeof (vnode)) != sizeof (vnode)) { + glibtop_warn_io_r (server, "kvm_read (vnode)"); + continue; + } + + switch (vnode.v_type) { + case VNON: + case VBAD: + continue; + default: +#if (__FreeBSD_version < 600006) && !defined(__FreeBSD_kernel__) + inum = vnode.v_cachedid; + dev = vnode.v_cachedfs; - if (kvm_read (server->machine.kd, - (unsigned long) entry.object.uvm_obj, - &vnode, sizeof (vnode)) != sizeof (vnode)) { - glibtop_warn_io_r (server, "kvm_read (vnode)"); - return (glibtop_map_entry*) g_array_free(maps, TRUE); - } #else - if (!entry.object.vm_object) - continue; - - /* We're only interested in `vm_object's */ - - if (kvm_read (server->machine.kd, - (unsigned long) entry.object.vm_object, - &object, sizeof (object)) != sizeof (object)) - glibtop_error_io_r (server, "kvm_read (object)"); -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) -#if defined(UVM_VNODE_VALID) - if (!vnode.v_uvm.u_flags & UVM_VNODE_VALID) - continue; + _glibtop_sysdeps_freebsd_dev_inode (server, + (struct vnode *) object.handle, + &vnode, &inum, &dev); #endif - if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || - !vnode.v_data) continue; - - if (kvm_read (server->machine.kd, - (unsigned long) vnode.v_data, - &inode, sizeof (inode)) != sizeof (inode)) - glibtop_error_io_r (server, "kvm_read (inode)"); - - inum = inode.i_number; - dev = inode.i_dev; -#endif - + break; + } -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - /* If the object is of type vnode, add its size */ + len = maps->len; + g_array_set_size(maps, len + 1); + mentry = &g_array_index(maps, glibtop_map_entry, len); - if (object.type != OBJT_VNODE) - continue; + memset (mentry, 0, sizeof (glibtop_map_entry)); - if (!object.handle) - continue; - - if (kvm_read (server->machine.kd, - (unsigned long) object.handle, - &vnode, sizeof (vnode)) != sizeof (vnode)) - glibtop_error_io_r (server, "kvm_read (vnode)"); - -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500039)) || defined(__FreeBSD_kernel__) - switch (vnode.v_type) { - case VREG: -#if (__FreeBSD_version < 600006) && !defined(__FreeBSD_kernel__) - inum = vnode.v_cachedid; - dev = vnode.v_cachedfs; -#endif - default: - continue; - } -#else - if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || - !vnode.v_data) continue; - - if (kvm_read (server->machine.kd, - (unsigned long) vnode.v_data, - &inode, sizeof (inode)) != sizeof (inode)) - glibtop_error_io_r (server, "kvm_read (inode)"); - - inum = inode.i_number; - dev = inode.i_dev; -#endif -#endif - len = maps->len; - g_array_set_size(maps, len + 1); - mentry = &g_array_index(maps, glibtop_map_entry, len); + mentry->flags = _glibtop_sysdeps_map_entry; + mentry->start = (guint64) entry.start; + mentry->end = (guint64) entry.end; + mentry->offset = (guint64) entry.offset; + mentry->device = (guint64) dev; + mentry->inode = (guint64) inum; - mentry->flags = _glibtop_sysdeps_map_entry; + mentry->perm = (guint64) 0; - mentry->start = (guint64) entry.start; - mentry->end = (guint64) entry.end; - mentry->offset = (guint64) entry.offset; - mentry->device = (guint64) dev; - mentry->inode = (guint64) inum; + if (entry.protection & VM_PROT_READ) + mentry->perm |= GLIBTOP_MAP_PERM_READ; + if (entry.protection & VM_PROT_WRITE) + mentry->perm |= GLIBTOP_MAP_PERM_WRITE; + if (entry.protection & VM_PROT_EXECUTE) + mentry->perm |= GLIBTOP_MAP_PERM_EXECUTE; - mentry->perm = (guint64) 0; + } while (entry.next != first); - if (entry.protection & VM_PROT_READ) - mentry->perm |= GLIBTOP_MAP_PERM_READ; - if (entry.protection & VM_PROT_WRITE) - mentry->perm |= GLIBTOP_MAP_PERM_WRITE; - if (entry.protection & VM_PROT_EXECUTE) - mentry->perm |= GLIBTOP_MAP_PERM_EXECUTE; - } while (entry.next != first); + glibtop_suid_leave (server); - buf->flags = _glibtop_sysdeps_proc_map; + buf->flags = _glibtop_sysdeps_proc_map; - buf->number = maps->len; - buf->size = sizeof (glibtop_map_entry); - buf->total = buf->number * buf->size; + buf->number = (guint64) maps->len; + buf->size = (guint64) sizeof (glibtop_map_entry); + buf->total = (guint64) (buf->number * buf->size); - return (glibtop_map_entry*) g_array_free(maps, FALSE); + return (glibtop_map_entry*) g_array_free(maps, FALSE); } diff --git a/sysdeps/freebsd/procmem.c b/sysdeps/freebsd/procmem.c index 864ff344..d18df8a4 100644 --- a/sysdeps/freebsd/procmem.c +++ b/sysdeps/freebsd/procmem.c @@ -32,36 +32,17 @@ #include <sys/param.h> #include <sys/proc.h> #include <sys/resource.h> -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) -#include <uvm/uvm_extern.h> -#else #include <vm/vm_object.h> #include <vm/vm_map.h> -#endif #include <sys/vnode.h> #include <ufs/ufs/quota.h> #include <ufs/ufs/inode.h> #include <sys/ucred.h> -#if (!defined __OpenBSD__) && (!defined __bsdi__) #include <sys/user.h> -#endif #include <sys/sysctl.h> -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) -#include <uvm/uvm.h> -#else #include <vm/vm.h> -#endif - -#if defined(__NetBSD__) && \ - (__NetBSD_Version__ >= 104000000) && (__NetBSD_Version__ < 105020000) -/* Fixme ... */ -#undef _KERNEL -#define _UVM_UVM_AMAP_I_H_ 1 -#define _UVM_UVM_MAP_I_H_ 1 -#include <uvm/uvm.h> -#endif static const unsigned long _glibtop_sysdeps_proc_mem = (1L << GLIBTOP_PROC_MEM_SIZE) + @@ -71,43 +52,16 @@ static const unsigned long _glibtop_sysdeps_proc_mem = (1L << GLIBTOP_PROC_MEM_RSS_RLIM); static const unsigned long _glibtop_sysdeps_proc_mem_share = -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) -(1L << GLIBTOP_PROC_MEM_SHARE); -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) (1L << GLIBTOP_PROC_MEM_SHARE); -#else -0; -#endif - -#ifndef LOG1024 -#define LOG1024 10 -#endif - -/* these are for getting the memory statistics */ -static int pageshift; /* log base 2 of the pagesize */ /* define pagetok in terms of pageshift */ -#define pagetok(size) ((size) << pageshift) +#define ps_pgtok(a) (((a) * getpagesize()) / 1024) /* Init function. */ void glibtop_init_proc_mem_p (glibtop *server) { - register int pagesize; - - /* get the page size with "getpagesize" and calculate pageshift - * from it */ - pagesize = getpagesize (); - pageshift = 0; - while (pagesize > 1) { - pageshift++; - pagesize >>= 1; - } - - /* we only need the amount of log(2)1024 for our conversion */ - pageshift -= LOG1024; - server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem | _glibtop_sysdeps_proc_mem_share; } @@ -120,15 +74,8 @@ glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, { struct kinfo_proc *pinfo; struct vm_map_entry entry, *first; - struct vmspace *vms, vmspace; -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - struct vnode vnode; -#else + struct vmspace vmspace; struct vm_object object; -#endif -#if (!defined(__FreeBSD__) || (__FreeBSD_version < 500013)) && !defined(__FreeBSD_kernel__) - struct plimit plimit; -#endif int count; glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MEM), 0); @@ -147,40 +94,15 @@ glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); return; } -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) #define PROC_VMSPACE ki_vmspace buf->rss_rlim = pinfo [0].ki_rssize; - buf->vsize = buf->size = (guint64) pagetok - (pinfo [0].ki_tsize + pinfo [0].ki_dsize + pinfo[0].ki_ssize) - << LOG1024; - buf->resident = buf->rss = (guint64) pagetok - (pinfo [0].ki_rssize) << LOG1024; - -#else - -#define PROC_VMSPACE kp_proc.p_vmspace - - if (kvm_read (server->machine.kd, - (unsigned long) pinfo [0].PROC_VMSPACE, - (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) { - glibtop_warn_io_r (server, "kvm_read (plimit)"); - return; - } - - buf->rss_rlim = (guint64) - (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur); - - vms = &pinfo [0].kp_eproc.e_vm; - - buf->vsize = buf->size = (guint64) pagetok - (vms->vm_tsize + vms->vm_dsize + vms->vm_ssize) << LOG1024; - - buf->resident = buf->rss = (guint64) pagetok - (vms->vm_rssize) << LOG1024; -#endif + buf->vsize = buf->size = (guint64) + (pinfo [0].ki_size / 1024); + buf->resident = buf->rss = (guint64) + ps_pgtok (pinfo [0].ki_rssize); /* Now we get the shared memory. */ @@ -209,42 +131,14 @@ glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, while (entry.next != first) { if (kvm_read (server->machine.kd, (unsigned long) entry.next, - &entry, sizeof (entry)) != sizeof (entry)) { + (char *) &entry, sizeof (entry)) != sizeof (entry)) { glibtop_warn_io_r (server, "kvm_read (entry)"); return; } -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#if (__FreeBSD__ >= 4) || defined(__FreeBSD_kernel__) if (entry.eflags & (MAP_ENTRY_IS_SUB_MAP)) continue; -#else - if (entry.eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) - continue; -#endif -#else -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - if (UVM_ET_ISSUBMAP (&entry)) - continue; -#else - if (entry.is_a_map || entry.is_sub_map) - continue; -#endif -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - if (!entry.object.uvm_obj) - continue; - - /* We're only interested in vnodes */ - if (kvm_read (server->machine.kd, - (unsigned long) entry.object.uvm_obj, - &vnode, sizeof (vnode)) != sizeof (vnode)) { - glibtop_warn_io_r (server, "kvm_read (vnode)"); - return; - } -#else if (!entry.object.vm_object) continue; @@ -252,42 +146,15 @@ glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, if (kvm_read (server->machine.kd, (unsigned long) entry.object.vm_object, - &object, sizeof (object)) != sizeof (object)) { + (char *) &object, sizeof (object)) != sizeof (object)) { glibtop_warn_io_r (server, "kvm_read (object)"); return; } -#endif - /* If the object is of type vnode, add its size */ - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) -#if defined(UVM_VNODE_VALID) - if (!vnode.v_uvm.u_flags & UVM_VNODE_VALID) - continue; -#endif - if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || - !vnode.v_data) continue; -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105250000) - /* Reference count must be at least two. */ - if (vnode.v_usecount <= 1) - continue; - - buf->share += pagetok (vnode.v_uobj.uo_npages) << LOG1024; -#else - - /* Reference count must be at least two. */ - if (vnode.v_uvm.u_obj.uo_refs <= 1) - continue; - - buf->share += pagetok (vnode.v_uvm.u_obj.uo_npages) << LOG1024; -#endif /* __NetBSD_Version__ >= 105250000 */ -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (object.type != OBJT_VNODE) continue; buf->share += object.un_pager.vnp.vnp_size; -#endif } buf->flags = _glibtop_sysdeps_proc_mem | diff --git a/sysdeps/freebsd/procsegment.c b/sysdeps/freebsd/procsegment.c index 460f96ad..5790062f 100644 --- a/sysdeps/freebsd/procsegment.c +++ b/sysdeps/freebsd/procsegment.c @@ -32,13 +32,18 @@ #include <sys/param.h> #include <sys/sysctl.h> -static const unsigned long _glibtop_sysdeps_proc_segment = 0; +static const unsigned long _glibtop_sysdeps_proc_segment = +(1L << GLIBTOP_PROC_SEGMENT_TEXT_RSS) + +(1L << GLIBTOP_PROC_SEGMENT_DATA_RSS); + +static int pagesize; /* Init function. */ void glibtop_init_proc_segment_p (glibtop *server) { + pagesize = getpagesize (); server->sysdeps.proc_segment = _glibtop_sysdeps_proc_segment; } @@ -49,35 +54,25 @@ glibtop_get_proc_segment_p (glibtop *server, glibtop_proc_segment *buf, pid_t pid) { + struct kinfo_proc *pinfo; + int count = 0; + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_SEGMENT), 0); memset (buf, 0, sizeof (glibtop_proc_segment)); -#if 0 + /* It does not work for the swapper task. */ + if (pid == 0) return; + /* Get the process info from the kernel */ - kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, count); - if (*count != 1) { - return; /* the zeroed-out buffer indicating no data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; } - /* trs: text resident set size - pinfo[0]->kp_eproc.e_xrssize; - */ - /* buf->trs = pinfo[0]->kp_eproc.e_xrssize; */ - /* lrs: shared-lib resident set size - ? */ - /* drs: data resident set size - pinfo[0]->kp_eproc.e_vm.vm_map.vm_dsize; - */ - /* dt: dirty pages - */ - /* start_code: address of beginning of code segment - - */ - /* end_code: address of end of code segment - */ - /* start_stack: address of the bottom of stack segment - */ -#endif -} + buf->text_rss = pinfo[0].ki_tsize * pagesize; + buf->data_rss = pinfo[0].ki_dsize * pagesize; + buf->flags = _glibtop_sysdeps_proc_segment; +} diff --git a/sysdeps/freebsd/procsignal.c b/sysdeps/freebsd/procsignal.c index 41d9b00a..9ae966b7 100644 --- a/sysdeps/freebsd/procsignal.c +++ b/sysdeps/freebsd/procsignal.c @@ -30,9 +30,7 @@ #include <sys/param.h> -#ifdef __FreeBSD__ #include <osreldate.h> -#endif static const unsigned long _glibtop_sysdeps_proc_signal = (1L << GLIBTOP_PROC_SIGNAL_SIGNAL) + @@ -70,69 +68,30 @@ glibtop_get_proc_signal_p (glibtop *server, return; } -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) - #define PROC_SIGLIST ki_siglist #define PROC_SIGMASK ki_sigmask #define PROC_SIGIGNORE ki_sigignore #define PROC_SIGCATCH ki_sigcatch -#else - -#define PROC_SIGLIST kp_proc.p_siglist -#define PROC_SIGMASK kp_proc.p_sigmask -#define PROC_SIGIGNORE kp_proc.p_sigignore -#define PROC_SIGCATCH kp_proc.p_sigcatch - -#endif - /* signal: mask of pending signals. * pinfo [0].kp_proc.p_siglist */ -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) - buf->signal [0] = pinfo [0].kp_proc.p_sigctx.ps_siglist.__bits[0]; -#elif (defined(__NetBSD__) && (NSIG > 32)) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) buf->signal [0] = pinfo [0].PROC_SIGLIST.__bits[0]; -#else - buf->signal [0] = pinfo [0].kp_proc.p_siglist; -#endif /* blocked: mask of blocked signals. * pinfo [0].kp_proc.p_sigmask */ -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) - buf->blocked [0] = pinfo [0].kp_proc.p_sigctx.ps_sigmask.__bits[0]; -#elif (defined(__NetBSD__) && (NSIG > 32)) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) buf->blocked [0] = pinfo [0].PROC_SIGMASK.__bits[0]; -#else - buf->blocked [0] = pinfo [0].kp_proc.p_sigmask; -#endif /* sigignore: mask of ignored signals. * pinfo [0].kp_proc.p_sigignore */ -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) - buf->sigignore [0] = pinfo [0].kp_proc.p_sigctx.ps_sigignore.__bits[0]; -#elif (defined(__NetBSD__) && (NSIG > 32)) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) buf->sigignore [0] = pinfo [0].PROC_SIGIGNORE.__bits[0]; -#else - buf->sigignore [0] = pinfo [0].kp_proc.p_sigignore; -#endif /* sigcatch: mask of caught signals. * pinfo [0].kp_proc.p_sigcatch */ -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105150000) - buf->sigcatch [0] = pinfo [0].kp_proc.p_sigctx.ps_sigcatch.__bits[0]; -#elif (defined(__NetBSD__) && (NSIG > 32)) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 400011) || defined(__FreeBSD_kernel__)) buf->sigcatch [0] = pinfo [0].PROC_SIGCATCH.__bits[0]; -#else - buf->sigcatch [0] = pinfo [0].kp_proc.p_sigcatch; -#endif buf->flags = _glibtop_sysdeps_proc_signal; } diff --git a/sysdeps/freebsd/procstate.c b/sysdeps/freebsd/procstate.c index 723a0c10..e5eee22b 100644 --- a/sysdeps/freebsd/procstate.c +++ b/sysdeps/freebsd/procstate.c @@ -28,25 +28,18 @@ #include <glibtop_suid.h> -#if !defined(__OpenBSD__) -/* && (!defined __bsdi__) */ #include <sys/user.h> -#endif static const unsigned long _glibtop_sysdeps_proc_state = -(1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_UID) + -(1L << GLIBTOP_PROC_STATE_GID); - -static const unsigned long _glibtop_sysdeps_proc_state_new = -0; +(1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_STATE) + +(1L << GLIBTOP_PROC_STATE_UID) + (1L << GLIBTOP_PROC_STATE_GID); /* Init function. */ void glibtop_init_proc_state_p (glibtop *server) { - server->sysdeps.proc_state = _glibtop_sysdeps_proc_state | - _glibtop_sysdeps_proc_state_new; + server->sysdeps.proc_state = _glibtop_sysdeps_proc_state; } /* Provides detailed information about a process. */ @@ -73,78 +66,33 @@ glibtop_get_proc_state_p (glibtop *server, return; } -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) -#define PROC_COMM ki_comm -#define PROC_SVUID ki_svuid -#define PROC_SVGID ki_svgid -#define PROC_RUID ki_ruid -#define PROC_RGID ki_rgid -#define PROC_STAT ki_stat - -#else -#define PROC_COMM kp_proc.p_comm -#define PROC_SVUID kp_eproc.e_pcred.p_svuid -#define PROC_SVGID kp_eproc.e_pcred.p_svgid -#define PROC_RUID kp_eproc.e_pcred.p_ruid -#define PROC_RGID kp_eproc.e_pcred.p_rgid -#define PROC_STAT kp_proc.p_stat - -#endif - - g_strlcpy (buf->cmd, pinfo [0].PROC_COMM, sizeof buf->cmd); - - buf->uid = pinfo [0].PROC_SVUID; - buf->gid = pinfo [0].PROC_SVGID; - - /* Set the flags for the data we're about to return*/ - buf->flags = _glibtop_sysdeps_proc_state | - _glibtop_sysdeps_proc_state_new; - -#if LIBGTOP_VERSION_CODE >= 1001000 - switch (pinfo [0].PROC_STAT) { - case SIDL: - buf->state = 0; - break; - case SRUN: - buf->state = GLIBTOP_PROCESS_RUNNING; - break; -#ifdef SSLEEP - case SSLEEP: - buf->state = GLIBTOP_PROCESS_INTERRUPTIBLE; - break; -#endif - case SSTOP: - buf->state = GLIBTOP_PROCESS_STOPPED; - break; - case SZOMB: - buf->state = GLIBTOP_PROCESS_ZOMBIE; - break; - default: - return; - } -#else - switch (pinfo [0].PROC_STAT) { - case SIDL: - buf->state = 'D'; - break; - case SRUN: - buf->state = 'R'; - break; -#ifdef SSLEEP - case SSLEEP: - buf->state = 'S'; - break; -#endif - case SSTOP: - buf->state = 'T'; - break; - case SZOMB: - buf->state = 'Z'; - break; - default: - return; + buf->uid = pinfo[0].ki_ruid; + buf->gid = pinfo[0].ki_rgid; + + g_strlcpy (buf->cmd, pinfo[0].ki_comm, sizeof (buf->cmd)); + + switch (pinfo[0].ki_stat) { + case SRUN: + buf->state = GLIBTOP_PROCESS_RUNNING; + break; + case SSLEEP: + buf->state = GLIBTOP_PROCESS_INTERRUPTIBLE; + break; + case SSTOP: + buf->state = GLIBTOP_PROCESS_STOPPED; + break; + case SZOMB: + buf->state = GLIBTOP_PROCESS_ZOMBIE; + break; + case SWAIT: + case SLOCK: + buf->state = GLIBTOP_PROCESS_UNINTERRUPTIBLE; + break; + case SIDL: + default: + buf->state = 0; + break; } -#endif - buf->flags |= (1L << GLIBTOP_PROC_STATE_STATE); + buf->flags = _glibtop_sysdeps_proc_state; } diff --git a/sysdeps/freebsd/proctime.c b/sysdeps/freebsd/proctime.c index b7bd595c..25239910 100644 --- a/sysdeps/freebsd/proctime.c +++ b/sysdeps/freebsd/proctime.c @@ -28,9 +28,8 @@ #include <glibtop_suid.h> -#ifdef __FreeBSD__ +#include <sys/time.h> #include <osreldate.h> -#endif static const unsigned long _glibtop_sysdeps_proc_time = (1L << GLIBTOP_PROC_TIME_RTIME) + (1L << GLIBTOP_PROC_TIME_FREQUENCY); @@ -53,63 +52,6 @@ glibtop_init_proc_time_p (glibtop *server) /* Taken from /usr/src/sys/kern/kern_resource.c */ -/* - * Transform the running time and tick information in proc p into user, - * system, and interrupt time usage. - */ - -#if !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) - -static void -calcru(p, up, sp, ip) - struct proc *p; - struct timeval *up; - struct timeval *sp; - struct timeval *ip; -{ - quad_t totusec; - u_quad_t u, st, ut, it, tot; - long sec, usec; - struct timeval tv; - - st = p->p_sticks; - ut = p->p_uticks; - it = p->p_iticks; - - tot = st + ut + it; - if (tot == 0) { - st = 1; - tot = 1; - } - - sec = p->p_rtime.tv_sec; - usec = p->p_rtime.tv_usec; - - totusec = (quad_t)sec * 1000000 + usec; - - if (totusec < 0) { - /* XXX no %qd in kernel. Truncate. */ - fprintf (stderr, "calcru: negative time: %ld usec\n", - (long)totusec); - totusec = 0; - } - - - u = totusec; - st = (u * st) / tot; - sp->tv_sec = st / 1000000; - sp->tv_usec = st % 1000000; - ut = (u * ut) / tot; - up->tv_sec = ut / 1000000; - up->tv_usec = ut % 1000000; - if (ip != NULL) { - it = (u * it) / tot; - ip->tv_sec = it / 1000000; - ip->tv_usec = it % 1000000; - } -} -#endif /* !__FreeBSD__ */ - /* Provides detailed information about a process. */ void @@ -117,13 +59,9 @@ glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, pid_t pid) { struct kinfo_proc *pinfo; -#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) || (defined(OpenBSD) && (OpenBSD >= 199912)) - register struct rusage *rup; -#else - struct user *u_addr = (struct user *)USRSTACK; -#endif - struct pstats pstats; + struct clockinfo ci; int count; + size_t len; glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_TIME), 0); @@ -132,123 +70,42 @@ glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, /* It does not work for the swapper task. */ if (pid == 0) return; -#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) - if (server->sysdeps.proc_time == 0) - return; -#endif + glibtop_suid_enter (server); /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count != 1)) { glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + glibtop_suid_leave (server); return; } -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) - buf->rtime = pinfo [0].ki_runtime; -#elif (defined __FreeBSD__) && (__FreeBSD_version <= 500013) - buf->rtime = pinfo [0].kp_proc.p_runtime; -#else - buf->rtime = tv2sec (pinfo [0].kp_proc.p_rtime); -#endif - - buf->frequency = 1000000; - buf->flags = _glibtop_sysdeps_proc_time; + glibtop_suid_leave (server); -#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) || (defined(OpenBSD) && (OpenBSD >= 199912)) - glibtop_suid_enter (server); + buf->rtime = pinfo [0].ki_runtime * 1e-6; - if (kvm_read (server->machine.kd, - (unsigned long) pinfo [0].kp_proc.p_stats, - &pstats, sizeof (pstats)) != sizeof (pstats)) { - glibtop_warn_io_r (server, "kvm_read (pstats)"); + len = sizeof (ci); + if (sysctlbyname ("kern.clockrate", &ci, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.clockrate) (%d)", pid); + glibtop_suid_leave (server); return; } - glibtop_suid_leave (server); - - rup = &pstats.p_ru; - calcru(&(pinfo [0]).kp_proc, - &rup->ru_utime, &rup->ru_stime, NULL); - - buf->utime = tv2sec (pstats.p_ru.ru_utime); - buf->stime = tv2sec (pstats.p_ru.ru_stime); - - buf->cutime = tv2sec (pstats.p_cru.ru_utime); - buf->cstime = tv2sec (pstats.p_cru.ru_stime); + buf->frequency = (ci.stathz ? ci.stathz : ci.hz); + buf->flags = _glibtop_sysdeps_proc_time; - buf->start_time = (guint64) pstats.p_start.tv_sec; + buf->rtime *= buf->frequency; - buf->flags |= _glibtop_sysdeps_proc_time_user; -#else -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) -#if (__FreeBSD_version >= 500016) || defined(__FreeBSD_kernel__) if ((pinfo [0].ki_flag & PS_INMEM)) { + buf->utime = (pinfo [0].ki_runtime * 1e-6) * buf->frequency; + buf->stime = tv2sec (pinfo [0].ki_rusage.ru_stime) * buf->frequency; + buf->cutime = tv2sec (pinfo [0].ki_childtime) * buf->frequency; +#if (__FreeBSD_version >= 600006) || defined(__FreeBSD_kernel__) + buf->cstime = tv2sec (pinfo [0].ki_rusage_ch.ru_stime) * buf->frequency; #else - if ((pinfo [0].ki_flag & P_INMEM)) { -#endif - buf->utime = pinfo [0].ki_runtime; - buf->stime = tv2sec (pinfo [0].ki_rusage.ru_stime); - buf->cutime = tv2sec (pinfo [0].ki_childtime); -#if (__FreeBSD_version >= 600000) || (__FreeBSD_kernel_version >= 600000) - buf->cstime = tv2sec (pinfo [0].ki_rusage_ch.ru_stime); -#else - buf->cstime = 0; + buf->cstime = 0; #endif buf->start_time = tv2sec (pinfo [0].ki_start); - buf->flags = _glibtop_sysdeps_proc_time_user; + buf->flags |= _glibtop_sysdeps_proc_time_user; } - - glibtop_suid_enter (server); - -#elif (__FreeBSD_version <= 500013) - - if ((pinfo [0].kp_proc.p_flag & P_INMEM) && - kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, - (unsigned long) &u_addr->u_stats, - (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) - { - - buf->utime = tv2sec (pinfo[0].kp_eproc.e_stats.p_ru.ru_utime); - buf->stime = tv2sec (pinfo[0].kp_eproc.e_stats.p_ru.ru_stime); - buf->cutime = tv2sec (pinfo[0].kp_eproc.e_stats.p_cru.ru_utime); - buf->cstime = tv2sec (pinfo[0].kp_eproc.e_stats.p_cru.ru_stime); - buf->start_time = tv2sec (pinfo[0].kp_eproc.e_stats.p_start); - buf->flags = _glibtop_sysdeps_proc_time_user; - glibtop_suid_leave (server); - } -#else - - if ((pinfo [0].kp_proc.p_flag & P_INMEM) && - kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, - (unsigned long) &u_addr->u_stats, - (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) - { - /* This is taken form the kernel source code of - * FreeBSD 2.2.6. */ - - /* Well, we just do the same getrusage () does ... */ - - register struct rusage *rup; - - glibtop_suid_leave (server); - - rup = &pstats.p_ru; - calcru(&(pinfo [0]).kp_proc, - &rup->ru_utime, &rup->ru_stime, NULL); - - buf->utime = tv2sec (pstats.p_ru.ru_utime); - buf->stime = tv2sec (pstats.p_ru.ru_stime); - - buf->cutime = tv2sec (pstats.p_cru.ru_utime); - buf->cstime = tv2sec (pstats.p_cru.ru_stime); - - buf->start_time = tv2sec (pstats.p_start); - - buf->flags = _glibtop_sysdeps_proc_time_user; - } -#endif - glibtop_suid_leave (server); -#endif } - diff --git a/sysdeps/freebsd/procuid.c b/sysdeps/freebsd/procuid.c index 133c6b97..c7f130c2 100644 --- a/sysdeps/freebsd/procuid.c +++ b/sysdeps/freebsd/procuid.c @@ -33,18 +33,14 @@ static const unsigned long _glibtop_sysdeps_proc_uid = (1L << GLIBTOP_PROC_UID_EGID) + (1L << GLIBTOP_PROC_UID_PID) + (1L << GLIBTOP_PROC_UID_PPID) + (1L << GLIBTOP_PROC_UID_PGRP) + (1L << GLIBTOP_PROC_UID_TPGID) + (1L << GLIBTOP_PROC_UID_PRIORITY) + -(1L << GLIBTOP_PROC_UID_NICE); - -static const unsigned long _glibtop_sysdeps_proc_uid_groups = -0L; +(1L << GLIBTOP_PROC_UID_NICE) + (1L << GLIBTOP_PROC_UID_GID); /* Init function. */ void glibtop_init_proc_uid_p (glibtop *server) { - server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid | - _glibtop_sysdeps_proc_uid_groups; + server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid; } /* Provides detailed information about a process. */ @@ -56,13 +52,6 @@ glibtop_get_proc_uid_p (glibtop *server, glibtop_proc_uid *buf, struct kinfo_proc *pinfo; int count = 0; -#if LIBGTOP_VERSION_CODE >= 1001000 -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - struct ucred ucred; - void *ucred_ptr; -#endif -#endif - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_UID), 0); memset (buf, 0, sizeof (glibtop_proc_uid)); @@ -77,10 +66,8 @@ glibtop_get_proc_uid_p (glibtop *server, glibtop_proc_uid *buf, return; } -#if (defined(__FreeBSD__) && (__FreeBSD_version >= 500013)) || defined(__FreeBSD_kernel__) - #define PROC_RUID ki_ruid -#define PROC_SVUID ki_svuid +#define PROC_EUID ki_uid #define PROC_RGID ki_rgid #define PROC_SVGID ki_svgid #define PROC_PPID ki_ppid @@ -88,22 +75,9 @@ glibtop_get_proc_uid_p (glibtop *server, glibtop_proc_uid *buf, #define PROC_TPGID ki_tpgid #define PROC_NICE ki_nice #define PROC_PRIORITY ki_pri.pri_user -#else - -#define PROC_RUID kp_eproc.e_pcred.p_ruid -#define PROC_SVUID kp_eproc.e_pcred.p_svuid -#define PROC_RGID kp_eproc.e_pcred.p_rgid -#define PROC_SVGID kp_eproc.e_pcred.p_svgid -#define PROC_PPID kp_eproc.e_ppid -#define PROC_PGID kp_eproc.e_pgid -#define PROC_TPGID kp_eproc.e_tpgid -#define PROC_NICE kp_proc.p_nice -#define PROC_PRIORITY kp_proc.p_priority - -#endif buf->uid = pinfo [0].PROC_RUID; - buf->euid = pinfo [0].PROC_SVUID; + buf->euid = pinfo [0].PROC_EUID; buf->gid = pinfo [0].PROC_RGID; buf->egid = pinfo [0].PROC_SVGID; @@ -112,39 +86,7 @@ glibtop_get_proc_uid_p (glibtop *server, glibtop_proc_uid *buf, buf->tpgid = pinfo [0].PROC_TPGID; buf->nice = pinfo [0].PROC_NICE; -#if defined(__NetBSD__) && defined(SACTIVE) - buf->priority = 0; -#else buf->priority = pinfo [0].PROC_PRIORITY; -#endif - /* Set the flags for the data we're about to return*/ buf->flags = _glibtop_sysdeps_proc_uid; - - /* Use LibGTop conditionals here so we can more easily merge this - * code into the LIBGTOP_STABLE_1_0 branch. */ -#if 0 - /* This probably also works with other versions, but not yet - * tested. Please remove the conditional if this is true. */ -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) - ucred_ptr = (void *) pinfo [0].kp_eproc.e_pcred.pc_ucred; - - if (ucred_ptr) { - if (kvm_read (server->machine.kd, (unsigned long) ucred_ptr, - &ucred, sizeof (ucred)) != sizeof (ucred)) { - glibtop_warn_io_r (server, "kvm_read (ucred)"); - } else { - int count = (ucred.cr_ngroups < GLIBTOP_MAX_GROUPS) ? - ucred.cr_ngroups : GLIBTOP_MAX_GROUPS; - int i; - - for (i = 0; i < count; i++) - buf->groups [i] = ucred.cr_groups [i]; - buf->ngroups = count; - - buf->flags |= _glibtop_sysdeps_proc_uid_groups; - } - } -#endif -#endif } diff --git a/sysdeps/freebsd/sem_limits.c b/sysdeps/freebsd/sem_limits.c index 191c25c0..a7c82a2a 100644 --- a/sysdeps/freebsd/sem_limits.c +++ b/sysdeps/freebsd/sem_limits.c @@ -26,96 +26,111 @@ #include <glibtop/error.h> #include <glibtop/sem_limits.h> -#include <glibtop_suid.h> +#include <sys/types.h> +#include <sys/sysctl.h> -#if defined(__bsdi__) && (_BSDI_VERSION < 199700) -/* Older versions of BSDI don't seem to have this. */ +static unsigned long _glibtop_sysdeps_sem_limits = +(1L << GLIBTOP_IPC_SEMMAP) + (1L << GLIBTOP_IPC_SEMMNI) + +(1L << GLIBTOP_IPC_SEMMNS) + (1L << GLIBTOP_IPC_SEMMNU) + +(1L << GLIBTOP_IPC_SEMMSL) + (1L << GLIBTOP_IPC_SEMOPM) + +(1L << GLIBTOP_IPC_SEMUME) + (1L << GLIBTOP_IPC_SEMUSZ) + +(1L << GLIBTOP_IPC_SEMVMX) + (1L << GLIBTOP_IPC_SEMAEM); -void -glibtop_init_sem_limits_p (glibtop *server) -{ } +/* Init function. */ void -glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) +glibtop_init_sem_limits_s (glibtop *server) { - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SEM_LIMITS), 0); - - memset (buf, 0, sizeof (glibtop_sem_limits)); + server->sysdeps.sem_limits = _glibtop_sysdeps_sem_limits; } -#else +/* Provides information about sysv sem limits. */ -/* #define KERNEL to get declaration of `struct seminfo'. */ +void +glibtop_get_sem_limits_s (glibtop *server, glibtop_sem_limits *buf) +{ + size_t len; + int semmap, semmni, semmns, semmnu, semmsl, semopm, semume, semusz; + int semvmx, semaem; -#if (defined(__FreeBSD__) && (__FreeBSD_version < 410000)) || defined(__bsdi__) -#define KERNEL 1 -#else -#define _KERNEL 1 -#endif + glibtop_init_s (&server, GLIBTOP_SYSDEPS_SEM_LIMITS, 0); -#include <sys/ipc.h> -#include <sys/sem.h> + memset (buf, 0, sizeof (glibtop_sem_limits)); -static unsigned long _glibtop_sysdeps_sem_limits = -(1L << GLIBTOP_IPC_SEMMAP) + (1L << GLIBTOP_IPC_SEMMNI) + -(1L << GLIBTOP_IPC_SEMMNS) + (1L << GLIBTOP_IPC_SEMMNU) + -(1L << GLIBTOP_IPC_SEMMSL) + (1L << GLIBTOP_IPC_SEMOPM) + -(1L << GLIBTOP_IPC_SEMUME) + (1L << GLIBTOP_IPC_SEMUSZ) + -(1L << GLIBTOP_IPC_SEMVMX) + (1L << GLIBTOP_IPC_SEMAEM); + if (server->sysdeps.sem_limits == 0) + return; -/* The values in this structure never change at runtime, so we only - * read it once during initialization. We have to use the name `_seminfo' - * since `seminfo' is already declared external in <sys/sem.h>. */ -static struct seminfo _seminfo; + len = sizeof (semmap); + if (sysctlbyname ("kern.ipc.semmap", &semmap, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semmap)"); + return; + } -/* nlist structure for kernel access */ -static struct nlist nlst [] = { - { "_seminfo" }, - { 0 } -}; + len = sizeof (semmni); + if (sysctlbyname ("kern.ipc.semmni", &semmni, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semmni)"); + return; + } -/* Init function. */ + len = sizeof (semmns); + if (sysctlbyname ("kern.ipc.semmns", &semmns, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semmns)"); + return; + } -void -glibtop_init_sem_limits_p (glibtop *server) -{ - if (kvm_nlist (server->machine.kd, nlst) < 0) { - glibtop_warn_io_r (server, "kvm_nlist (sem_limits)"); + len = sizeof (semmnu); + if (sysctlbyname ("kern.ipc.semmnu", &semmnu, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semmnu)"); return; } - if (kvm_read (server->machine.kd, nlst [0].n_value, - &_seminfo, sizeof (_seminfo)) != sizeof (_seminfo)) { - glibtop_warn_io_r (server, "kvm_read (seminfo)"); + len = sizeof (semmsl); + if (sysctlbyname ("kern.ipc.semmsl", &semmsl, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semmsl)"); return; } - server->sysdeps.sem_limits = _glibtop_sysdeps_sem_limits; -} + len = sizeof (semopm); + if (sysctlbyname ("kern.ipc.semopm", &semopm, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semopm)"); + return; + } -/* Provides information about sysv sem limits. */ + len = sizeof (semume); + if (sysctlbyname ("kern.ipc.semume", &semume, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semume)"); + return; + } -void -glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) -{ - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SEM_LIMITS), 0); + len = sizeof (semusz); + if (sysctlbyname ("kern.ipc.semusz", &semusz, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semusz)"); + return; + } - memset (buf, 0, sizeof (glibtop_sem_limits)); + len = sizeof (semvmx); + if (sysctlbyname ("kern.ipc.semvmx", &semvmx, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semvmx)"); + return; + } - if (server->sysdeps.sem_limits == 0) + len = sizeof (semaem); + if (sysctlbyname ("kern.ipc.semaem", &semaem, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.semaem)"); return; + } - buf->semmap = _seminfo.semmap; - buf->semmni = _seminfo.semmni; - buf->semmns = _seminfo.semmns; - buf->semmnu = _seminfo.semmnu; - buf->semmsl = _seminfo.semmsl; - buf->semopm = _seminfo.semopm; - buf->semvmx = _seminfo.semvmx; - buf->semaem = _seminfo.semaem; + buf->semmap = semmap; + buf->semmni = semmni; + buf->semmns = semmns; + buf->semmnu = semmnu; + buf->semmsl = semmsl; + buf->semopm = semopm; + buf->semume = semume; + buf->semusz = semusz; + buf->semvmx = semvmx; + buf->semaem = semaem; buf->flags = _glibtop_sysdeps_sem_limits; } -#endif /* either a newer BSDI or no BSDI at all. */ - diff --git a/sysdeps/freebsd/shm_limits.c b/sysdeps/freebsd/shm_limits.c index c7b2584b..4251e9b6 100644 --- a/sysdeps/freebsd/shm_limits.c +++ b/sysdeps/freebsd/shm_limits.c @@ -26,91 +26,72 @@ #include <glibtop/error.h> #include <glibtop/shm_limits.h> -#include <glibtop_suid.h> - -#if defined(__bsdi__) && (_BSDI_VERSION < 199700) -/* Older versions of BSDI don't seem to have this. */ - -void -glibtop_init_shm_limits_p (glibtop *server) -{ } - -void -glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) -{ - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SHM_LIMITS), 0); - - memset (buf, 0, sizeof (glibtop_shm_limits)); -} - -#else - -/* #define KERNEL to get declaration of `struct shminfo'. */ - -#if (defined(__FreeBSD__) && (__FreeBSD_version < 410000)) || defined(__bsdi__) -#define KERNEL 1 -#else -#define _KERNEL 1 -#endif - -#include <sys/ipc.h> -#include <sys/shm.h> +#include <sys/types.h> +#include <sys/sysctl.h> static unsigned long _glibtop_sysdeps_shm_limits = (1L << GLIBTOP_IPC_SHMMAX) + (1L << GLIBTOP_IPC_SHMMIN) + (1L << GLIBTOP_IPC_SHMMNI) + (1L << GLIBTOP_IPC_SHMSEG) + (1L << GLIBTOP_IPC_SHMALL); -/* The values in this structure never change at runtime, so we only - * read it once during initialization. We have to use the name `_shminfo' - * since `shminfo' is already declared external in <sys/shm.h>. */ -static struct shminfo _shminfo; - -/* nlist structure for kernel access */ -static struct nlist nlst [] = { - { "_shminfo" }, - { 0 } -}; - /* Init function. */ void -glibtop_init_shm_limits_p (glibtop *server) +glibtop_init_shm_limits_s (glibtop *server) { - if (kvm_nlist (server->machine.kd, nlst) < 0) { - glibtop_warn_io_r (server, "kvm_nlist (shm_limits)"); - return; - } - - if (kvm_read (server->machine.kd, nlst [0].n_value, - &_shminfo, sizeof (_shminfo)) != sizeof (_shminfo)) { - glibtop_warn_io_r (server, "kvm_read (shminfo)"); - return; - } - server->sysdeps.shm_limits = _glibtop_sysdeps_shm_limits; } /* Provides information about sysv ipc limits. */ void -glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) +glibtop_get_shm_limits_s (glibtop *server, glibtop_shm_limits *buf) { - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SHM_LIMITS), 0); + size_t len; + int shmmax, shmmin, shmmni, shmseg, shmall; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_SHM_LIMITS, 0); memset (buf, 0, sizeof (glibtop_shm_limits)); if (server->sysdeps.shm_limits == 0) return; - buf->shmmax = _shminfo.shmmax; - buf->shmmin = _shminfo.shmmin; - buf->shmmni = _shminfo.shmmni; - buf->shmseg = _shminfo.shmseg; - buf->shmall = _shminfo.shmall; + len = sizeof (shmmax); + if (sysctlbyname ("kern.ipc.shmmax", &shmmax, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.shmmax)"); + return; + } - buf->flags = _glibtop_sysdeps_shm_limits; -} + len = sizeof (shmmin); + if (sysctlbyname ("kern.ipc.shmmin", &shmmin, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.shmmin)"); + return; + } -#endif /* either a newer BSDI or no BSDI at all. */ + len = sizeof (shmmni); + if (sysctlbyname ("kern.ipc.shmmni", &shmmni, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.shmmni)"); + return; + } + len = sizeof (shmseg); + if (sysctlbyname ("kern.ipc.shmseg", &shmseg, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.shmseg)"); + return; + } + + len = sizeof (shmall); + if (sysctlbyname ("kern.ipc.shmall", &shmall, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (kern.ipc.shmall)"); + return; + } + + buf->shmmax = shmmax; + buf->shmmin = shmmin; + buf->shmmni = shmmni; + buf->shmseg = shmseg; + buf->shmall = shmall; + + buf->flags = _glibtop_sysdeps_shm_limits; +} diff --git a/sysdeps/freebsd/swap.c b/sysdeps/freebsd/swap.c index 438b36ae..c9934481 100644 --- a/sysdeps/freebsd/swap.c +++ b/sysdeps/freebsd/swap.c @@ -30,396 +30,67 @@ static const unsigned long _glibtop_sysdeps_swap = (1L << GLIBTOP_SWAP_TOTAL) + (1L << GLIBTOP_SWAP_USED) + -(1L << GLIBTOP_SWAP_FREE) + (1L << GLIBTOP_SWAP_PAGEIN) + -(1L << GLIBTOP_SWAP_PAGEOUT); +(1L << GLIBTOP_SWAP_FREE); -#if defined(__FreeBSD__) || defined(__bsdi__) || defined(__FreeBSD_kernel__) +static const unsigned long _glibtop_sysdeps_swap_paging = +(1L << GLIBTOP_SWAP_PAGEIN) + (1L << GLIBTOP_SWAP_PAGEOUT); -#include <sys/conf.h> -#ifdef __bsdi__ -#include <vm/swap_pager.h> -#else -#if (__FreeBSD_version < 400005) && !defined(__FreeBSD_kernel__) -#include <sys/rlist.h> -#endif -#endif -#include <sys/vmmeter.h> - -/* nlist structure for kernel access */ - -#if defined(__bsdi__) -static struct nlist nlst [] = { - { "_swapstats" }, /* general swap info */ - { 0 } -}; -#elif __FreeBSD__ < 4 -static struct nlist nlst [] = { -#define VM_SWAPLIST 0 - { "_swaplist" },/* list of free swap areas */ -#define VM_SWDEVT 1 - { "_swdevt" }, /* list of swap devices and sizes */ -#define VM_NSWAP 2 - { "_nswap" }, /* size of largest swap device */ -#define VM_NSWDEV 3 - { "_nswdev" }, /* number of swap devices */ -#define VM_DMMAX 4 - { "_dmmax" }, /* maximum size of a swap block */ - { 0 } -}; -#endif - -#elif defined(__NetBSD__) || defined(__OpenBSD__) - -#if (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) -#include <uvm/uvm_extern.h> -#include <sys/swap.h> -#else -#include <vm/vm_swap.h> -#endif - -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) -static int mib_uvmexp [] = { CTL_VM, VM_UVMEXP }; -#else -/* nlist structure for kernel access */ -static struct nlist nlst2 [] = { - { "_cnt" }, - { 0 } -}; -#endif +static int pagesize; /* Init function. */ void glibtop_init_swap_p (glibtop *server) { -#if defined(__FreeBSD__) || defined(__bsdi__) || defined(__FreeBSD_kernel__) -#if __FreeBSD__ < 4 || defined(__bsdi__) - if (kvm_nlist (server->machine.kd, nlst) < 0) { - glibtop_warn_io_r (server, "kvm_nlist (swap)"); - return; - } -#else - struct kvm_swap dummy; - - if (kvm_getswapinfo (server->machine.kd, &dummy, 1, 0) != 0) { - glibtop_warn_io_r (server, "kvm_swap (swap)"); - return; - } -#endif -#endif - -#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) && !defined(__OpenBSD__) - if (kvm_nlist (server->machine.kd, nlst2) < 0) { - glibtop_warn_io_r (server, "kvm_nlist (cnt)"); - return; - } -#endif + pagesize = getpagesize (); - server->sysdeps.swap = _glibtop_sysdeps_swap; + server->sysdeps.swap = _glibtop_sysdeps_swap | + _glibtop_sysdeps_swap_paging; } /* Provides information about swap usage. */ -/* - * This function is based on a program called swapinfo written - * by Kevin Lahey <kml@rokkaku.atl.ga.us>. - */ - void glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - -# if (__FreeBSD__ < 4) && !defined(__FreeBSD_kernel__) - char *header; - int hlen, nswdev, dmmax; - int div, nfree, npfree; - struct swdevt *sw; - long blocksize, *perdev; - struct rlist head; - struct rlisthdr swaplist; - struct rlist *swapptr; - size_t sw_size; - u_long ptr; -# else + size_t len; + unsigned int swappgsout, swappgsin; int nswdev; struct kvm_swap kvmsw[16]; -# endif - -#elif defined(__bsdi__) - struct swapstats swap; -#elif defined(__NetBSD__) || defined(__OpenBSD__) - struct swapent *swaplist; -#endif - - int nswap, i; - int avail = 0, inuse = 0; - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - struct uvmexp uvmexp; - size_t length_uvmexp; -#else - /* To get `pagein' and `pageout'. */ - struct vmmeter vmm; -#endif - static int swappgsin = -1; - static int swappgsout = -1; glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SWAP), 0); memset (buf, 0, sizeof (glibtop_swap)); + memset (kvmsw, 0, sizeof (kvmsw)); - if (server->sysdeps.swap == 0) - return; - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - length_uvmexp = sizeof (uvmexp); - if (sysctl (mib_uvmexp, 2, &uvmexp, &length_uvmexp, NULL, 0)) { - glibtop_warn_io_r (server, "sysctl (uvmexp)"); - return; - } -#else - /* This is used to get the `pagein' and `pageout' members. */ - - if (kvm_read (server->machine.kd, nlst2[0].n_value, - &vmm, sizeof (vmm)) != sizeof (vmm)) { - glibtop_warn_io_r (server, "kvm_read (cnt)"); - return; - } -#endif - - if (swappgsin < 0) { - buf->pagein = 0; - buf->pageout = 0; - } else { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - buf->pagein = vmm.v_swappgsin - swappgsin; - buf->pageout = vmm.v_swappgsout - swappgsout; -#else -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - buf->pagein = uvmexp.swapins - swappgsin; - buf->pageout = uvmexp.swapouts - swappgsout; -#else - buf->pagein = vmm.v_swpin - swappgsin; - buf->pageout = vmm.v_swpout - swappgsout; -#endif -#endif - } - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - swappgsin = vmm.v_swappgsin; - swappgsout = vmm.v_swappgsout; -#else -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) || defined(__OpenBSD__) - swappgsin = uvmexp.swapins; - swappgsout = uvmexp.swapouts; -#else - swappgsin = vmm.v_swpin; - swappgsout = vmm.v_swpout; -#endif -#endif - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - -#if (__FreeBSD__ < 4) && !defined(__FreeBSD_kernel__) - - /* Size of largest swap device. */ - - if (kvm_read (server->machine.kd, nlst[VM_NSWAP].n_value, - &nswap, sizeof (nswap)) != sizeof (nswap)) { - glibtop_warn_io_r (server, "kvm_read (nswap)"); - return; - } - - /* Number of swap devices. */ - - if (kvm_read (server->machine.kd, nlst[VM_NSWDEV].n_value, - &nswdev, sizeof (nswdev)) != sizeof (nswdev)) { - glibtop_warn_io_r (server, "kvm_read (nswdev)"); - return; - } - - /* Maximum size of a swap block. */ - - if (kvm_read (server->machine.kd, nlst[VM_DMMAX].n_value, - &dmmax, sizeof (dmmax)) != sizeof (dmmax)) { - glibtop_warn_io_r (server, "kvm_read (dmmax)"); - return; - } - - /* List of free swap areas. */ - - if (kvm_read (server->machine.kd, nlst[VM_SWAPLIST].n_value, - &swaplist, sizeof (swaplist)) != sizeof (swaplist)) { - glibtop_warn_io_r (server, "kvm_read (swaplist)"); - return; - } - - /* Kernel offset of list of swap devices and sizes. */ - - if (kvm_read (server->machine.kd, nlst[VM_SWDEVT].n_value, - &ptr, sizeof (ptr)) != sizeof (ptr)) { - glibtop_warn_io_r (server, "kvm_read (swdevt)"); - return; - } - - /* List of swap devices and sizes. */ - - sw_size = nswdev * sizeof (*sw); - sw = g_malloc (sw_size); - - if (kvm_read (server->machine.kd, ptr, sw, sw_size) != (ssize_t)sw_size) { - glibtop_warn_io_r (server, "kvm_read (*swdevt)"); - return; - } - - perdev = g_malloc (nswdev * sizeof (*perdev)); - - /* Count up swap space. */ - - nfree = 0; - memset (perdev, 0, nswdev * sizeof(*perdev)); - - swapptr = swaplist.rlh_list; - - while (swapptr) { - int top, bottom, next_block; - - if (kvm_read (server->machine.kd, (int) swapptr, &head, - sizeof (struct rlist)) != sizeof (struct rlist)) { - glibtop_warn_io_r (server, "kvm_read (swapptr)"); - return; - } - - top = head.rl_end; - bottom = head.rl_start; - - nfree += top - bottom + 1; - - /* - * Swap space is split up among the configured disks. - * - * For interleaved swap devices, the first dmmax blocks - * of swap space some from the first disk, the next dmmax - * blocks from the next, and so on up to nswap blocks. - * - * The list of free space joins adjacent free blocks, - * ignoring device boundries. If we want to keep track - * of this information per device, we'll just have to - * extract it ourselves. - */ - while (top / dmmax != bottom / dmmax) { - next_block = ((bottom + dmmax) / dmmax); - perdev[(bottom / dmmax) % nswdev] += - next_block * dmmax - bottom; - bottom = next_block * dmmax; - } - perdev[(bottom / dmmax) % nswdev] += - top - bottom + 1; - - swapptr = head.rl_next; - } - - header = getbsize (&hlen, &blocksize); - - div = blocksize / 512; - avail = npfree = 0; - for (i = 0; i < nswdev; i++) { - int xsize, xfree; - - /* - * Don't report statistics for partitions which have not - * yet been activated via swapon(8). - */ - if (!(sw[i].sw_flags & SW_FREED)) - continue; - - /* The first dmmax is never allocated to avoid trashing of - * disklabels - */ - xsize = sw[i].sw_nblks - dmmax; - xfree = perdev[i]; - inuse = xsize - xfree; - npfree++; - avail += xsize; - } - - /* - * If only one partition has been set up via swapon(8), we don't - * need to bother with totals. - */ - inuse = avail - nfree; - - g_free (sw); - g_free (perdev); + nswdev = kvm_getswapinfo (server->machine.kd, kvmsw, 16, 0); + if (nswdev < 1) return; buf->flags = _glibtop_sysdeps_swap; - buf->used = inuse; - buf->free = avail; - - buf->total = inuse + avail; - -#else - - nswdev = kvm_getswapinfo(server->machine.kd, kvmsw, 16, 0); - - buf->flags = _glibtop_sysdeps_swap; + /* See the man page for kvm_getswapinfo(3) to see why we can do this. */ + buf->used = kvmsw[nswdev].ksw_used; + buf->total = kvmsw[nswdev].ksw_total; - buf->used = kvmsw[nswdev].ksw_used * getpagesize(); - buf->total = kvmsw[nswdev].ksw_total * getpagesize(); + buf->total *= pagesize; + buf->used *= pagesize; buf->free = buf->total - buf->used; -#endif - -#elif defined(__bsdi__) - - /* General info about swap devices. */ - - if (kvm_read (server->machine.kd, nlst[0].n_value, - &swap, sizeof (swap)) != sizeof (swap)) { - glibtop_warn_io_r (server, "kvm_read (swap)"); - return; - } - - buf->flags = _glibtop_sysdeps_swap; - - buf->used = swap.swap_total - swap.swap_free; - buf->free = swap.swap_free; - - buf->total = swap.swap_total; - -#elif defined(__NetBSD__) || defined(__OpenBSD__) - - nswap = swapctl (SWAP_NSWAP, NULL, 0); - if (nswap < 0) { - glibtop_warn_io_r (server, "swapctl (SWAP_NSWAP)"); + len = sizeof (swappgsout); + if (sysctlbyname ("vm.stats.vm.v_swappgsout", &swappgsout, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (vm.stats.vm.v_swappgsout)"); return; } - swaplist = g_malloc (nswap * sizeof (struct swapent)); - - if (swapctl (SWAP_STATS, swaplist, nswap) != nswap) { - glibtop_warn_io_r (server, "swapctl (SWAP_STATS)"); - g_free (swaplist); + len = sizeof (swappgsin); + if (sysctlbyname ("vm.stats.vm.v_swappgsin", &swappgsin, &len, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (vm.stats.vm.v_swappgsin)"); return; } - for (i = 0; i < nswap; i++) { - avail += swaplist[i].se_nblks; - inuse += swaplist[i].se_inuse; - } - - g_free (swaplist); - - buf->flags = _glibtop_sysdeps_swap; - - buf->used = inuse; - buf->free = avail; + buf->pagein = (guint64) swappgsin; + buf->pageout = (guint64) swappgsout; - buf->total = inuse + avail; -#endif + buf->flags |= _glibtop_sysdeps_swap_paging; } diff --git a/sysdeps/freebsd/sysinfo.c b/sysdeps/freebsd/sysinfo.c index 10cbd6f3..9e281ca0 100644 --- a/sysdeps/freebsd/sysinfo.c +++ b/sysdeps/freebsd/sysinfo.c @@ -73,6 +73,10 @@ init_sysinfo (glibtop *server) g_hash_table_insert (cpuinfo->values, "vendor_id", g_strdup(model)); + g_ptr_array_add (cpuinfo->labels, "model name"); + g_hash_table_insert (cpuinfo->values, "model name", + g_strdup(model)); + g_ptr_array_add (cpuinfo->labels, "cpu MHz"); g_hash_table_insert (cpuinfo->values, "cpu MHz", g_strdup_printf("%d", mhz)); diff --git a/sysdeps/freebsd/uptime.c b/sysdeps/freebsd/uptime.c index a7d8e40e..8a371f18 100644 --- a/sysdeps/freebsd/uptime.c +++ b/sysdeps/freebsd/uptime.c @@ -28,19 +28,23 @@ #include <glibtop/cpu.h> -#include <glibtop_suid.h> +#include <sys/types.h> +#include <sys/sysctl.h> static const unsigned long _glibtop_sysdeps_uptime = -(1L << GLIBTOP_UPTIME_UPTIME) + (1L << GLIBTOP_UPTIME_IDLETIME); +(1L << GLIBTOP_UPTIME_UPTIME); + +static const unsigned long _glibtop_sysdeps_idletime = +(1L << GLIBTOP_UPTIME_IDLETIME); static const unsigned long _required_cpu_flags = -(1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_IDLE) + +(1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_CPU_FREQUENCY); /* Init function. */ void -glibtop_init_uptime_p (glibtop *server) +glibtop_init_uptime_s (glibtop *server) { server->sysdeps.uptime = _glibtop_sysdeps_uptime; } @@ -48,14 +52,17 @@ glibtop_init_uptime_p (glibtop *server) /* Provides uptime and idle time. */ void -glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf) +glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf) { -#if defined(__NetBSD__) || defined(__OpenBSD__) time_t now; - time_t uptime; int mib[2]; struct timeval boottime; size_t size; + glibtop_cpu cpu; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_UPTIME, 0); + + memset (buf, 0, sizeof (glibtop_uptime)); mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; @@ -64,20 +71,10 @@ glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf) boottime.tv_sec != 0) { time(&now); buf->uptime = now - boottime.tv_sec; - /* XXX: don't know a useful value to put here. */ - buf->idletime = 0; buf->flags = _glibtop_sysdeps_uptime; } -#else - glibtop_cpu cpu; - - glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_UPTIME), 0); - - memset (buf, 0, sizeof (glibtop_uptime)); - - /* We simply calculate it from the CPU usage. */ - glibtop_get_cpu_p (server, &cpu); + glibtop_get_cpu_s (server, &cpu); /* Make sure all required fields are present. */ @@ -86,9 +83,8 @@ glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf) /* Calculate values. */ - buf->uptime = (double) cpu.total / (double) cpu.frequency; buf->idletime = (double) cpu.idle / (double) cpu.frequency; + buf->idletime /= (double) (server->ncpu + 1); - buf->flags = _glibtop_sysdeps_uptime; -#endif + buf->flags |= _glibtop_sysdeps_idletime; } |