Skip site navigation (1)Skip section navigation (2)
Date:      Fri,  1 Dec 2006 13:29:06 +0000 (GMT)
From:      barrie.archer@uk.fujitsu.com
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        problems@freebmd.org.uk
Subject:   ports/106134: [patch] Memory size incorrectly shown on backhand status page
Message-ID:  <20061201132906.9E9CA30CD81@equality.thebunker.net>
Resent-Message-ID: <200612011330.kB1DUFcT042718@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         106134
>Category:       ports
>Synopsis:       [patch] Memory size incorrectly shown on backhand status page
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Dec 01 13:30:14 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Barrie Archer<barrie.archer@uk.fujitsu.com>
>Release:        FreeBSD 4.11-RELEASE-p11 i386
>Organization:
FreeBMD
>Environment:
System: FreeBSD 4.11-RELEASE-p11
Apache/1.3.33 (Unix) 
mod_backhand/1.2.2 DAV/1.0.3
>Description:
The columns "Total mem" and "Avail mem" on the backhand status page
have impossibly large values that are apparently not related to the
actual server memory sizes. This occurs when a server has more
than 2GB of memory.
>How-To-Repeat:
This problem appears to occur as a result of using backhand 1.2.2 on 
FreeBSD on machines with more than 2GB of memory.
>Fix:
Patch provided. This takes the file platform.c from Rev 1.12 (which
is in release 1.2.2 of backhand) to Rev 1.17 (latest) and then 
further corrects the problem described. Changes from 1.12 to 1.17 
are mainly concerned with similar problems on other platforms.
--- patch-platform.c_to_1.17_plus_BSD_over_4MB.c begins here ---
--- platform.c_1.12.c	Tue Nov 28 06:33:52 2006
+++ platform.c	Tue Nov 28 06:25:27 2006
@@ -1,46 +1,46 @@
-	/* ======================================================================
-	 * Copyright (c) 1998-1999 The Johns Hopkins University.
-	 * All rights reserved.
-	 * The following code was written by Theo Schlossnagle for use in the
-	 * Backhand project at The Center for Networking and Distributed Systems
-	 * at The Johns Hopkins University.
-	 * Please refer to the LICENSE file before using this software.
-	 * ======================================================================
-	*/
-	/* This is exported for use in builtins.c */
-	int find_highest_arriba(serverstat *ss) {
-	  int i, highest=0;
-	  for(i=0;i<HARD_SERVER_LIMIT;i++)
-	    highest = MAX(highest,
-			  ss[i].arriba);
-	  return highest;
-	}
-	static int find_max_load(serverstat *ss, int ha) {
-	  int i, highest=0;
-	  float myaa;
-	  for(i=0;i<HARD_SERVER_LIMIT;i++) {
-	    if(ss[i].arriba) myaa = (float)ha/(float)ss[i].arriba;
-	    else myaa = 0;
-	    highest = MAX(highest,
-			  (float)ss[i].load*myaa);
-	  }
-	  return highest;
-	}
-	static int set_high_watermark(void) {
-	  int i=0, aload, ha;
-	  ha = find_highest_arriba(serverstats);
-	  aload = find_max_load(serverstats, ha);
-	  if(aload>0) aload-=1; /* n - delta */
-	  aload /= 1000; /* places hwm @ mag(load)*/
-	  aload <<= 1;
-	  while(aload >>=1) i++; /* log2(1+n-delta) */
-	  aload = 1 << i; /* 2^(n+1) */
-	  for(i=0;i<HARD_SERVER_LIMIT;i++)
-	    aload = MAX(aload, serverstats[i].load_hwm/1000);
-	  return aload;
-	}
+/* ======================================================================
+ * Copyright (c) 1998-1999 The Johns Hopkins University.
+ * All rights reserved.
+ * The following code was written by Theo Schlossnagle for use in the
+ * Backhand project at The Center for Networking and Distributed Systems
+ * at The Johns Hopkins University.
+ * Please refer to the LICENSE file before using this software.
+ * ======================================================================
+*/
+/* This is exported for use in builtins.c */
+int find_highest_arriba(serverstat *ss) {
+  int i, highest=0;
+  for(i=0;i<HARD_SERVER_LIMIT;i++)
+    highest = MAX(highest,
+		  ss[i].arriba);
+  return highest;
+}
+static int find_max_load(serverstat *ss, int ha) {
+  int i, highest=0;
+  float myaa;
+  for(i=0;i<HARD_SERVER_LIMIT;i++) {
+    if(ss[i].arriba) myaa = (float)ha/(float)ss[i].arriba;
+    else myaa = 0;
+    highest = MAX(highest,
+		  (float)ss[i].load*myaa);
+  }
+  return highest;
+}
+static int set_high_watermark(void) {
+  int i=0, aload, ha;
+  ha = find_highest_arriba(serverstats);
+  aload = find_max_load(serverstats, ha);
+  if(aload>0) aload-=1; /* n - delta */
+  aload /= 1000; /* places hwm @ mag(load)*/
+  aload <<= 1;
+  while(aload >>=1) i++; /* log2(1+n-delta) */
+  aload = 1 << i; /* 2^(n+1) */
+  for(i=0;i<HARD_SERVER_LIMIT;i++)
+    aload = MAX(aload, serverstats[i].load_hwm/1000);
+  return aload;
+}
 
-	#ifdef LINUX
+#ifdef LINUX
 #ifndef CPUSTATES
 #define CPUSTATES 4
 #endif
@@ -143,23 +143,42 @@
   ourcpu = (ourcpu==0.0)?0.0:(states[0]/ourcpu); //states[0] == IDLE
   ourcpu *= 1000.0;
   /* Find the memory now */
-  tmem = -1;
-  amem = -1;
+  tmem = 0;
+  amem = 0;
+
   if((proc_stat=fopen(MEMFILE,"r")) == NULL) {
     perror(MEMFILE);
   } else {
+    long long int tm, um, fm, sm, bm, cm;
+    tm=-1; um=-1; fm=-1; sm=-1; bm=-1; cm=-1;
+
     while(fgets(dummy, 100, proc_stat)) {
       if(strncmp(dummy, "Mem:", 4)==0) {
-	int tm, um, fm, sm, bm, cm;
-	sscanf(dummy+5, "%d %d %d %d %d %d", &tm, &um, &fm, &sm, &bm, &cm);
-	tmem=tm/(1024*1024);
-	fm /= (1024*1024);
-	bm /= (1024*1024);
-	cm /= (1024*1024);
-	amem=MAX(fm+bm+cm-5, 0); // Free + Cached + Buffered ???
-	break;
+        sscanf(dummy+5, "%Ld %Ld %Ld %Ld %Ld %Ld", &tm, &um, &fm, &sm, &bm, &cm);
+        tmem=tm/(1024*1024);
+        fm /= (1024*1024);
+        bm /= (1024*1024);
+        cm /= (1024*1024);
+        break;
+      }
+      if(strncmp(dummy, "MemTotal:", 9)==0) {
+        sscanf(dummy+9, "%Ld kB", &tm);
+        tmem = tm/(1024);
+      }
+      if(strncmp(dummy, "Cached:", 7)==0) {
+        sscanf(dummy+7, "%Ld kB", &cm);
+        cm /= (1024);
+      }
+      if(strncmp(dummy, "Buffers:", 8)==0) {
+        sscanf(dummy+8, "%Ld kB", &bm);
+        bm /= (1024);
+      }
+      if(strncmp(dummy, "MemFree:", 8)==0) {
+        sscanf(dummy+8, "%Ld kB", &fm);
+        fm /= (1024);
       }
     }
+    amem=MAX(fm+bm+cm-5, 0); // Free + Cached + Buffered ???
     fclose(proc_stat);
   }
   /* Find the load now */
@@ -267,10 +286,10 @@
       kstat_named_t *kn;
       syspages = k;
       if(kstat_read(kctl, syspages, 0)!=-1 &&
-	 (kn = (kstat_named_t *)kstat_data_lookup(syspages, "physmem"))!=NULL)
+	 (kn = (kstat_named_t *)kstat_data_lookup(syspages, "physmem"))!=NULL) {
 	kn->value.ul /= 1024; /* pgsize in kb, we want mb */
 	physmem = pgsize*kn->value.ul;
-      else
+    } else
         physmem = 0;
     } else if(!strncmp(k->ks_name, "system_misc", 11)) {
       sysmisc = k;
@@ -383,10 +402,10 @@
   ss->tmem = physmem;
   if(syspages &&
      kstat_read(kctl, syspages, 0)!=-1 &&
-     ((kn = (kstat_named_t *)kstat_data_lookup(syspages, "freemem"))!=NULL))
+     ((kn = (kstat_named_t *)kstat_data_lookup(syspages, "freemem"))!=NULL)) {
     kn->value.ul /= 1024; /* pgsize in kb, we want mb */
     ss->amem = pgsize*kn->value.ul;
-  else
+  } else
     ss->amem = 0;
   if(!ss->contact.sin_port)
     if(webport) {
@@ -538,10 +557,12 @@
 void initstat(void) {
   int mib[2];
   size_t len;
+  long long int memsize;
   mib[0] = CTL_HW;
   mib[1] = HW_USERMEM;
-  len = sizeof(int);
-  sysctl(mib, 2, &usermem, &len, NULL, 0);
+  len = sizeof(long long int);
+  sysctl(mib, 2, &memsize, &len, NULL, 0);
+  usermem = (len==4)?(unsigned int) memsize/(1024*1024):(int) (memsize/(1024*1024));
   mib[1] = HW_NCPU;
   sysctl(mib, 2, &ncpu, &len, NULL, 0);
   mib[1] = HW_PAGESIZE;
@@ -577,7 +598,7 @@
   sysctl(mib, 2, &ourload, &len, NULL, 0);
   ss->load = (int)1000.0*((float)ourload.ldavg[0]/(float)ourload.fscale);
   ss->load_hwm=set_high_watermark()*1000;
-  ss->tmem=(int)usermem/(1024*1024); /* in mb */
+  ss->tmem=usermem;
 #ifdef VM_TOTAL
   mib[1] = VM_TOTAL;
 #else
@@ -589,8 +610,7 @@
 #endif
   len = sizeof(struct vmtotal);
   sysctl(mib, 2, &ourmem, &len, NULL, 0);
-  ourmem.t_free /= 1024*1024; /* calculate in mb */
-  ss->amem=(int)usermem-(ourpagesize*ourmem.t_free);
+  ss->amem=(int)(ourpagesize*((unsigned long long int)ourmem.t_free)/(1024*1024));
   ss->cpu =(int)ourcpu;
   ss->ncpu=(int)ncpu;
   /* Fill out hostname */
--- patch-platform.c_to_1.17_plus_BSD_over_4MB.c ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061201132906.9E9CA30CD81>