[Bug 195507] New: Patch to fix memory usage report on FreeBSD 5.x and later

Bruce Cran bruce at cran.org.uk
Sat Jun 6 22:16:53 BST 2009


https://bugs.kde.org/show_bug.cgi?id=195507

           Summary: Patch to fix memory usage report on FreeBSD 5.x and
                    later
           Product: kinfocenter
           Version: unspecified
          Platform: FreeBSD Ports
        OS/Version: FreeBSD
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: general
        AssignedTo: unassigned-bugs at kde.org
        ReportedBy: bruce at cran.org.uk


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 at 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);
 }

-- 
Configure bugmail: https://bugs.kde.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the Unassigned-bugs mailing list