File indexing completed on 2024-05-12 17:00:15
0001 /* 0002 SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "freebsdbackend.h" 0008 0009 #include <systemstats/SensorObject.h> 0010 #include <systemstats/SensorProperty.h> 0011 #include <systemstats/SysctlSensor.h> 0012 0013 #include <fcntl.h> 0014 #include <sys/types.h> 0015 #include <sys/sysctl.h> 0016 #include <unistd.h> 0017 0018 template <typename T> 0019 bool readSysctl(const char *name, T *buffer, size_t size = sizeof(T)) 0020 { 0021 return sysctlbyname(name, buffer, &size, nullptr, 0) != -1; 0022 } 0023 0024 FreeBsdMemoryBackend::FreeBsdMemoryBackend(KSysGuard::SensorContainer* container) 0025 : MemoryBackend(container) 0026 , m_pageSize(getpagesize()) 0027 , m_kd(nullptr) 0028 { 0029 char errorBuffer[_POSIX2_LINE_MAX]; 0030 // Get a descriptor for accesing kernel memory which we need for querying swap info. /dev/null 0031 // indicates that we do not want to directly access kernel memory. 0032 m_kd = kvm_openfiles(nullptr, "/dev/null", nullptr, O_RDONLY, errorBuffer); 0033 if (!m_kd) { 0034 qWarning() << errorBuffer; 0035 } 0036 } 0037 0038 void FreeBsdMemoryBackend::makeSensors() 0039 { 0040 auto totalSensor = new KSysGuard::SysctlSensor<unsigned long long>(QStringLiteral("total"), "hw.physmem", m_physicalObject); 0041 m_total = totalSensor; 0042 m_sysctlSensors.append(totalSensor); 0043 0044 m_used = new KSysGuard::SensorProperty(QStringLiteral("used"), m_physicalObject); 0045 m_application = new KSysGuard::SensorProperty(QStringLiteral("application"), m_physicalObject); 0046 0047 auto capturedPagesToBytes = [this] (auto pages) {return pagesToBytes(pages);}; 0048 0049 auto freeSensor = new KSysGuard::SysctlSensor<uint32_t>(QStringLiteral("free"), "vm.stats.vm.v_free_count", m_physicalObject); 0050 freeSensor->setConversionFunction(capturedPagesToBytes); 0051 m_free = freeSensor; 0052 m_sysctlSensors.push_back(freeSensor); 0053 0054 auto cacheSensor = new KSysGuard::SysctlSensor<uint32_t>(QStringLiteral("cache"),"vm.stats.vm.v_cache_count", m_physicalObject); 0055 cacheSensor->setConversionFunction(capturedPagesToBytes); 0056 m_cache = cacheSensor; 0057 m_sysctlSensors.push_back(cacheSensor); 0058 0059 auto bufferSensor = new KSysGuard::SysctlSensor<uint64_t>(QStringLiteral("buffer"), "vfs.bufspace", m_physicalObject); 0060 m_buffer = bufferSensor; 0061 m_sysctlSensors.push_back(bufferSensor); 0062 0063 m_swapTotal = new KSysGuard::SensorProperty(QStringLiteral("total"), m_swapObject); 0064 m_swapUsed = new KSysGuard::SensorProperty(QStringLiteral("used"), m_swapObject); 0065 m_swapFree = new KSysGuard::SensorProperty(QStringLiteral("free"), m_swapObject); 0066 0067 } 0068 0069 unsigned long long FreeBsdMemoryBackend::pagesToBytes(uint32_t pages) 0070 { 0071 return m_pageSize * pages; 0072 } 0073 0074 void FreeBsdMemoryBackend::update() 0075 { 0076 0077 kvm_swap swapInfo; 0078 // Calling it with just one swapInfo gets us the totals, passing 0 as the last argument is mandatory 0079 if (m_swapObject->isSubscribed() && m_kd && (kvm_getswapinfo(m_kd, &swapInfo, 1, 0) != -1)) { 0080 m_swapTotal->setValue(pagesToBytes(swapInfo.ksw_total)); 0081 m_swapUsed->setValue(pagesToBytes(swapInfo.ksw_used)); 0082 m_swapFree->setValue(pagesToBytes(swapInfo.ksw_total - swapInfo.ksw_used)); 0083 } 0084 0085 for (const auto sysctlSensor : m_sysctlSensors) { 0086 sysctlSensor->update(); 0087 } 0088 0089 m_used->setValue(m_total->value().toULongLong() - m_free->value().toULongLong()); 0090 0091 uint32_t activePages = 0; 0092 uint32_t inactivePages = 0; 0093 if (readSysctl("vm.stats.vm.v_active_count", &activePages) && readSysctl("vm.stats.vm.v_inactive_count", &inactivePages)) { 0094 m_application->setValue(pagesToBytes(activePages + inactivePages)); 0095 } 0096 } 0097 0098