Subject: Re: pkg/33444: sysutils/gkrellm fails to build after recent I/O stats changes
To: None <cube@NetBSD.org, gnats-admin@netbsd.org, pkgsrc-bugs@netbsd.org,>
From: Anthony Mallet <anthony.mallet@useless-ficus.net>
List: pkgsrc-bugs
Date: 05/23/2006 22:05:02
The following reply was made to PR pkg/33444; it has been noted by GNATS.

From: Anthony Mallet <anthony.mallet@useless-ficus.net>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: pkg/33444: sysutils/gkrellm fails to build after recent I/O stats changes
Date: Tue, 23 May 2006 22:33:58 +0200

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