Sophie

Sophie

distrib > * > 2008.0 > x86_64 > by-pkgid > 906fab9b037e667950cf6d9004747878 > files > 3

rusers-0.17-15mdv2008.0.src.rpm

2006-03-23  Gwenole Beauchesne  <gbeauchesne@mandriva.com>

	* rpc.rstatd/rstat_proc.c (errno): Nuke stupid decl.
	(getstat_26): Tentatively grok new kernel 2.6 stats.
	(getstat): Dispatch wrt. running kernel.

--- netkit-rusers-0.17/rpc.rstatd/rstat_proc.c.2.6-stats	2006-03-23 11:56:05.231195000 +0100
+++ netkit-rusers-0.17/rpc.rstatd/rstat_proc.c	2006-03-23 16:06:44.904817544 +0100
@@ -50,7 +50,7 @@ static char rcsid[] = "$OpenBSD: rstat_p
 #include <rpc/rpc.h>
 #include <sys/socket.h>
 #include <syslog.h>
-#include <sys/errno.h>
+#include <errno.h>
 #include <sys/param.h>
 #include <unistd.h>
 
@@ -58,6 +58,7 @@ static char rcsid[] = "$OpenBSD: rstat_p
 
 #include <assert.h>
 #include <ctype.h>
+#include <sys/utsname.h>
 
 #define	CP_USER		0
 #define	CP_NICE		1
@@ -307,7 +308,6 @@ static int havedisk(void);
 void	rstat_service(struct svc_req *rqstp, SVCXPRT *transp);
 
 static int stat_is_init = 0;
-extern int errno;
 
 #ifndef FSCALE
 #define FSCALE (1 << 8)
@@ -395,10 +395,106 @@ struct _ldisk {
 	unsigned int wblk[MAX_DISKS];
 };
 
+static int
+is_kernel_version(int major, int minor, int revision)
+{
+  static int kern_major = -1, kern_minor = -1, kern_revision = -1;
+  if (kern_major < 0) {
+    struct utsname buf;
+    kern_major = kern_minor = kern_revision = 0;
+    if (uname(&buf) == 0)
+      sscanf(buf.release, "%d.%d.%d", &kern_major, &kern_minor, &kern_revision);
+  }
+  return (kern_major > major
+	  || (kern_major == major && kern_minor > minor)
+	  || (kern_major == major && kern_minor == minor && kern_revision >= revision));
+}
+
+/* NOTES:
+ * - Newer kernels use 64-bit values, so results may be truncated for 32-bit systems
+ * - Only _ldisk->xfer[] seems to be used, so don't bother to fill in rio[] et al.
+ */
 static void
-getstat(unsigned long *cuse, unsigned long *cice, unsigned long *csys, unsigned long *cide,
-	     unsigned *pin, unsigned *pout, unsigned *sin, unsigned *sout,
-	     unsigned *itot, unsigned *i1, unsigned *ct, struct _ldisk *d)
+getstat_26(unsigned long *cuse, unsigned long *cice, unsigned long *csys, unsigned long *cide,
+	   unsigned *pin, unsigned *pout, unsigned *sin, unsigned *sout,
+	   unsigned *itot, unsigned *i1, unsigned *ct, struct _ldisk *d)
+{
+  FILE *fp;
+  char line[1024];
+
+  if ((fp = fopen("/proc/stat", "r")) != NULL) {
+    while ((fgets(line, sizeof(line), fp)) != NULL) {
+      if (strncmp(line, "cpu ", 4) == 0) {
+		unsigned long long v_user, v_nice, v_system, v_idle;
+		sscanf(line, "cpu  %llu %llu %llu %llu", &v_user, &v_nice, &v_system, &v_idle);
+		*cuse = v_user;
+		*cice = v_nice;
+		*csys = v_system;
+		*cide = v_idle;
+      }
+      else if (strncmp(line, "ctxt", 4) == 0) {
+		unsigned long long v;
+		sscanf(line, "ctxt %llu", &v);
+		*ct = v;
+      }
+      else if (strncmp(line, "intr", 4) == 0) {
+		unsigned long long v_irq_tot;
+		unsigned int v_irq1 = 1;
+		sscanf(line, "intr %llu %u", &v_irq_tot, &v_irq1);
+		assert(v_irq_tot > v_irq1);
+		*itot = v_irq_tot;
+		*i1 = v_irq1;
+      }
+    }
+    fclose(fp);
+  }
+
+  if ((fp = fopen("/proc/vmstat", "r")) != NULL) {
+    while ((fgets(line, sizeof(line), fp)) != NULL) {
+      if (line[0] != 'p')
+		continue;
+      unsigned int *vp = NULL;
+      if (strncmp(line, "pgpgin", 6) == 0)
+		vp = pin;
+      else if (strncmp(line, "pgpgout", 7) == 0)
+		vp = pout;
+      else if (strncmp(line, "pswpin", 6) == 0)
+		vp = sin;
+      else if (strncmp(line, "pswpout", 7) == 0)
+		vp = sout;
+      if (vp)
+		sscanf(line, "%*s %u", vp);
+    }
+    fclose(fp);
+  }
+
+  if ((fp = fopen("/proc/diskstats", "r")) != NULL) {
+    int ndisks = 0;
+    while ((fgets(line, sizeof(line), fp)) != NULL) {
+      unsigned int v1, v2, v4, v5;
+      unsigned long long v3;
+      int n = sscanf(line, "%*d %*d %*s %u %u %llu %u %u", &v1, &v2, &v3, &v4, &v5);
+      if (v1 == 0 && v2 == 0 && v3 == 0 && v4 == 0)
+		continue;
+      if (n == 5)
+		d->xfer[ndisks] = v1 + v5;
+      else if (n == 4)
+		d->xfer[ndisks] = v1 + v3;
+      else {
+		assert(n == 5 || n == 4);
+		continue;
+      }
+      if (++ndisks >= MAX_DISKS)
+		break;
+    }
+    fclose(fp);
+  }
+}
+
+static void
+getstat_24(unsigned long *cuse, unsigned long *cice, unsigned long *csys, unsigned long *cide,
+		   unsigned *pin, unsigned *pout, unsigned *sin, unsigned *sout,
+		   unsigned *itot, unsigned *i1, unsigned *ct, struct _ldisk *d)
 {
   static int stat;
 #define	BUFFSIZE	1024
@@ -441,6 +537,21 @@ getstat(unsigned long *cuse, unsigned lo
   }
 }
 
+static void
+getstat(unsigned long *cuse, unsigned long *cice, unsigned long *csys, unsigned long *cide,
+	unsigned *pin, unsigned *pout, unsigned *sin, unsigned *sout,
+	unsigned *itot, unsigned *i1, unsigned *ct, struct _ldisk *d)
+{
+  if (is_kernel_version(2,6,0))
+    getstat_26(cuse, cice, csys, cide, pin, pout, sin, sout, itot, i1, ct, d);
+  else if (is_kernel_version(2,4,20))
+    getstat_24(cuse, cice, csys, cide, pin, pout, sin, sout, itot, i1, ct, d);
+  else {
+	syslog(LOG_ERR, "only kernels newer than 2.4.20 are supported");
+	exit(1);
+  }
+}
+
 static int procnetdev_vsn;
 
 static char *