Bug 195507 - Patch to fix memory usage report on FreeBSD 5.x and later
Summary: Patch to fix memory usage report on FreeBSD 5.x and later
Status: RESOLVED FIXED
Alias: None
Product: kinfocenter
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: FreeBSD Ports FreeBSD
: NOR normal
Target Milestone: ---
Assignee: Unassigned bugs mailing-list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-06 23:16 UTC by Bruce Cran
Modified: 2010-02-09 18:36 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
libkvm cmake module (945 bytes, text/plain)
2009-06-06 23:20 UTC, Bruce Cran
Details
Patch to fix memory report on FreeBSD (5.32 KB, patch)
2009-06-06 23:21 UTC, Bruce Cran
Details
Updated patch to kinfocenter to fix memory report on FreeBSD (5.21 KB, patch)
2010-02-09 15:54 UTC, Bruce Cran
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bruce Cran 2009-06-06 23:16:51 UTC
Version:            (using KDE 4.2.4)
Compiler:          gcc 4.2.1 
OS:                FreeBSD
Installed from:    FreeBSD Ports

The memory usage report on FreeBSD is broken because it uses obsolete sysctl nodes and the wrong data types: on a 4GB amd64 system for example the total memory is reported as 17GB.  The included patch fixes those problems. However, the cache and buffer statistics are misleading since it's impossible to obtain accurate data from userland on FreeBSD due to the VM architecture. Other applications do report the same data so I've included it too.

kdebase-4.2.4/apps/cmake/modules/FindKVM.cmake:
# - Try to find the KVM library
# Once done this will define
#
#  KVM_FOUND - system has the KVM library
#  KVM_INCLUDE_DIR - the KVM include directory
#  KVM_LIBRARIES - The libraries needed to use KVM

IF(KVM_LIBRARIES)
   SET(KVM_FIND_QUIETLY TRUE)
ENDIF(KVM_LIBRARIES)

# IF(SSL_EAY_DEBUG AND SSL_EAY_RELEASE)
#    SET(LIB_FOUND 1)
# ENDIF(SSL_EAY_DEBUG AND SSL_EAY_RELEASE)

FIND_PATH(KVM_INCLUDE_DIR kvm.h )

FIND_LIBRARY(KVM_LIBRARIES NAMES kvm )

IF(KVM_INCLUDE_DIR AND KVM_LIBRARIES)
   SET(KVM_FOUND TRUE)
ELSE(KVM_INCLUDE_DIR AND KVM_LIBRARIES)
   SET(KVM_FOUND FALSE)
ENDIF (KVM_INCLUDE_DIR AND KVM_LIBRARIES)

IF (KVM_FOUND)
   IF (NOT KVM_FIND_QUIETLY)
      MESSAGE(STATUS "Found libKVM: ${KVM_LIBRARIES}")
   ENDIF (NOT KVM_FIND_QUIETLY)
ELSE (KVM_FOUND)
   IF (KVM_FIND_REQUIRED)
      MESSAGE(FATAL_ERROR "Could NOT find libKVM")
   ENDIF (KVM_FIND_REQUIRED)
ENDIF (KVM_FOUND)

MARK_AS_ADVANCED(KVM_INCLUDE_DIR KVM_LIBRARIES)

kdebase-4.2.4.diff:
Only in kdebase4/work/kdebase-4.2.4/apps/cmake/modules: FindKVM.cmake
diff -U3 -r kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt kdebase4/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt
--- kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt	2009-06-06 21:07:45.000000000 +0100
+++ kdebase4/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt	2009-06-06 21:42:31.000000000 +0100
@@ -57,6 +57,13 @@
 
 kde4_add_kdeinit_executable( kinfocenter ${kinfocenter_SRCS})
 
+IF (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
+    find_package(KVM REQUIRED)
+    include_directories(${KVM_INCLUDE_DIRS})
+    set(LIBS ${LIBS} ${KVM_LIBRARIES})
+    target_link_libraries(kinfocenter ${LIBS})
+ENDIF (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
+
 target_link_libraries(kdeinit_kinfocenter ${KDE4_KIO_LIBS} ${KDE4_KHTML_LIBS} ${KDE4_KUTILS_LIBS} )
 
 install(TARGETS kdeinit_kinfocenter          ${INSTALL_TARGETS_DEFAULT_ARGS})
diff -U3 -r kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp kdebase4/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp
--- kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp	2009-06-06 21:07:45.000000000 +0100
+++ kdebase4/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp	2009-06-06 21:42:15.000000000 +0100
@@ -1,90 +1,67 @@
-
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <sys/vmmeter.h>
 
 #include <vm/vm_param.h>
+#include <kvm.h>
 
-#include <stdlib.h>
-#include <stdio.h>
+#include <fcntl.h>
+#include <paths.h>
 #include <unistd.h>
 
 void KCMMemory::fetchValues()
 {
-    char blah[10], buf[80], *used_str, *total_str;
     /* Stuff for sysctl */
-    int memory;
     size_t len;
-    /* Stuff for swap display */
-    int used, total, _free;
-    FILE *pipe;
 
-    len=sizeof(memory);
+    unsigned long memory;
+    len = sizeof(memory);
     sysctlbyname("hw.physmem", &memory, &len, NULL, 0);
   
-    snprintf(blah, 10, "%d", memory);
     // Numerical values
 
     // total physical memory (without swap space)
     memoryInfos[TOTAL_MEM] = MEMORY(memory);
+ 
+    unsigned int cached;
+    len = sizeof(cached);
+    if (sysctlbyname("vm.stats.vm.v_cache_count", &cached, &len, NULL, 0) == -1 || !len)
+        memoryInfos[CACHED_MEM] = NO_MEMORY_INFO;
+    else
+        memoryInfos[CACHED_MEM] = MEMORY(cached) * PAGE_SIZE;
+
+    unsigned int free;
+    len = sizeof(free);
+    if (sysctlbyname("vm.stats.vm.v_free_count", &free, &len, NULL, 0) == -1 || !len)
+        memoryInfos[FREE_MEM] = NO_MEMORY_INFO;
+    else
+        memoryInfos[FREE_MEM] = MEMORY(free) * PAGE_SIZE;
 
     // added by Brad Hughes bhughes@trolltech.com
     struct vmtotal vmem;
-#ifdef __GNUC__ 
-    #warning "FIXME: memoryInfos[CACHED_MEM]"
-#endif    
-    memoryInfos[CACHED_MEM] = NO_MEMORY_INFO;
-
-    // The sysctls don't work in a nice manner under FreeBSD v2.2.x
-    // so we assume that if sysctlbyname doesn't return what we
-    // prefer, assume it's the old data types.   FreeBSD prior
-    // to 4.0-R isn't supported by the rest of KDE, so what is
-    // this code doing here.
 
     len = sizeof(vmem);
-    if (sysctlbyname("vm.vmmeter", &vmem, &len, NULL, 0) == 0) 
-	memoryInfos[SHARED_MEM]   = MEMORY(vmem.t_armshr) * PAGE_SIZE;
-    else 
-        memoryInfos[SHARED_MEM]   = NO_MEMORY_INFO;
-
-    int buffers;
-    len = sizeof (buffers);
-    if ((sysctlbyname("vfs.bufspace", &buffers, &len, NULL, 0) == -1) || !len)
-	memoryInfos[BUFFER_MEM]   = NO_MEMORY_INFO;
+    if (sysctlbyname("vm.vmtotal", &vmem, &len, NULL, 0) == -1 || !len)
+        memoryInfos[SHARED_MEM] = NO_MEMORY_INFO;
     else
-	memoryInfos[BUFFER_MEM]   = MEMORY(buffers);
+         memoryInfos[SHARED_MEM] = MEMORY(vmem.t_armshr) * PAGE_SIZE;
 
-    // total free physical memory (without swap space)
-    int free;
-    len = sizeof (buffers);
-    if ((sysctlbyname("vm.stats.vm.v_free_count", &free, &len, NULL, 0) == -1) || !len)
-	memoryInfos[FREE_MEM]     = NO_MEMORY_INFO;
+    long buffers;
+    len = sizeof(buffers);
+    if ((sysctlbyname("vfs.bufspace", &buffers, &len, NULL, 0) == -1) || !len)
+        memoryInfos[BUFFER_MEM] = NO_MEMORY_INFO;
     else
-	memoryInfos[FREE_MEM]     = MEMORY(free) * getpagesize();
+        memoryInfos[BUFFER_MEM] = MEMORY(buffers);
 
-    // Q&D hack for swap display. Borrowed from xsysinfo-1.4
-    if ((pipe = popen("/usr/sbin/pstat -ks", "r")) == NULL) {
-	used = total = 1;
-	return;
+    struct kvm_swap swap[1];
+    kvm_t *kvm_handle;
+    kvm_handle = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
+
+    if (kvm_handle != NULL && kvm_getswapinfo(kvm_handle, swap, 1, 0) != -1) {
+        memoryInfos[SWAP_MEM]     = MEMORY(swap[0].ksw_total) * PAGE_SIZE;
+        memoryInfos[FREESWAP_MEM] = MEMORY(swap[0].ksw_total - swap[0].ksw_used) * PAGE_SIZE;
     }
 
-    fgets(buf, sizeof(buf), pipe);
-    fgets(buf, sizeof(buf), pipe);
-    fgets(buf, sizeof(buf), pipe);
-    fgets(buf, sizeof(buf), pipe);
-    pclose(pipe);
-
-    strtok(buf, " ");
-    total_str = strtok(NULL, " ");
-    used_str = strtok(NULL, " ");
-    used = atoi(used_str);
-    total = atoi(total_str);
-
-    _free=total-used;
-
-    // total size of all swap-partitions
-    memoryInfos[SWAP_MEM] = MEMORY(total) * 1024;
-
-    // free memory in swap-partitions
-    memoryInfos[FREESWAP_MEM] = MEMORY(_free) * 1024;
+    if (kvm_handle != NULL)
+        kvm_close(kvm_handle);
 }
Comment 1 Bruce Cran 2009-06-06 23:20:34 UTC
Created attachment 34333 [details]
libkvm cmake module
Comment 2 Bruce Cran 2009-06-06 23:21:36 UTC
Created attachment 34334 [details]
Patch to fix memory report on FreeBSD
Comment 3 Bruce Cran 2010-02-09 15:54:37 UTC
Created attachment 40618 [details]
Updated patch to kinfocenter to fix memory report on FreeBSD
Comment 4 Raphael Kubo da Costa 2010-02-09 18:32:08 UTC
SVN commit 1087863 by rkcosta:

Fix memory usage information on FreeBSD 5.x+.

Patch by Bruce Cran from the FreeBSD team.

BUG: 195507


 M  +5 -0      CMakeLists.txt  
 M  +35 -58    memory/memory_fbsd.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1087863
Comment 5 Raphael Kubo da Costa 2010-02-09 18:36:16 UTC
SVN commit 1087867 by rkcosta:

Backport r1087863.

Fix memory usage information on FreeBSD 5.x+.

Patch by Bruce Cran from the FreeBSD team.

CCBUG: 195507


 M  +5 -0      CMakeLists.txt  
 M  +35 -58    memory/memory_fbsd.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1087867