kde-workspace/ksysguard/ksysguardd/FreeBSD/Memory.c
Ivailo Monev ddf3119680 ksysguard: correct sysctl() and sysctlbyname() return value checks
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2021-07-07 12:50:15 +02:00

334 lines
9.2 KiB
C

/*
KSysGuard, the KDE System Guard
Copyright (c) 2010-2011 David Naylor <naylor.b.david@gmail.com>
Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <sys/types.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <vm/vm_param.h>
#include "Command.h"
#include "Memory.h"
#include "ksysguardd.h"
#define MEM_ACTIVE 0
#define MEM_INACTIVE 1
#define MEM_WIRED 2
#define MEM_CACHED 3
#define MEM_BUFFERED 4
#define MEM_FREE 5
#define MEM_TOTAL 6
static size_t memory_stats[7];
#define SWAP_IN 0
#define SWAP_OUT 1
#define SWAP_USED 2
#define SWAP_FREE 3
#define SWAP_TOTAL 4
static size_t swap_stats[5];
static size_t swap_old[2];
static int pagesize;
void kvm_getswapinfo_sysctl(size_t *ksw_used, size_t *ksw_total);
void initMemory(struct SensorModul* sm)
{
char *nlistf = NULL;
char *memf = NULL;
char buf[_POSIX2_LINE_MAX];
pagesize = getpagesize();
registerMonitor("mem/physical/active", "integer", printMActive, printMActiveInfo, sm);
registerMonitor("mem/physical/inactive", "integer", printMInactive, printMInactiveInfo, sm);
registerMonitor("mem/physical/application", "integer", printMApplication, printMApplicationInfo, sm);
registerMonitor("mem/physical/wired", "integer", printMWired, printMWiredInfo, sm);
registerMonitor("mem/physical/cached", "integer", printMCached, printMCachedInfo, sm);
registerMonitor("mem/physical/buf", "integer", printMBuffers, printMBuffersInfo, sm);
registerMonitor("mem/physical/free", "integer", printMFree, printMFreeInfo, sm);
registerMonitor("mem/physical/used", "integer", printMUsed, printMUsedInfo, sm);
registerMonitor("mem/swap/free", "integer", printSwapFree, printSwapFreeInfo, sm);
registerMonitor("mem/swap/used", "integer", printSwapUsed, printSwapUsedInfo, sm);
registerMonitor("mem/swap/pageIn", "integer", printSwapIn, printSwapInInfo, sm);
registerMonitor("mem/swap/pageOut", "integer", printSwapOut, printSwapOutInfo, sm);
registerLegacyMonitor("cpu/pageIn", "float", printSwapIn, printSwapInInfo, sm);
registerLegacyMonitor("cpu/pageOut", "float", printSwapOut, printSwapOutInfo, sm);
swap_old[SWAP_IN] = -1;
swap_old[SWAP_OUT] = -1;
updateMemory();
}
void exitMemory(void)
{
removeMonitor("mem/physical/active");
removeMonitor("mem/physical/inactive");
removeMonitor("mem/physical/application");
removeMonitor("mem/physical/wired");
removeMonitor("mem/physical/cached");
removeMonitor("mem/physical/buf");
removeMonitor("mem/physical/free");
removeMonitor("mem/physical/used");
removeMonitor("mem/swap/free");
removeMonitor("mem/swap/used");
removeMonitor("mem/swap/pageIn");
removeMonitor("mem/swap/pageOut");
removeMonitor("cpu/pageIn");
removeMonitor("cpu/pageOut");
}
int updateMemory(void)
{
size_t len, ksw_used, ksw_total;
int swapin, swapout;
#define CONVERT(v) ((quad_t)(v) * pagesize / 1024)
#define GETSYSCTL(mib, var) \
len = sizeof(var); \
sysctlbyname(mib, &var, &len, NULL, 0);
#define GETPAGESYSCTL(mib, var) \
GETSYSCTL(mib, var) \
var = CONVERT(var);
#define GETMEMSYSCTL(mib, var) \
GETSYSCTL(mib, var) \
var /= 1024;
/*
* Memory
*/
GETPAGESYSCTL("vm.stats.vm.v_active_count", memory_stats[MEM_ACTIVE])
GETPAGESYSCTL("vm.stats.vm.v_inactive_count", memory_stats[MEM_INACTIVE])
GETPAGESYSCTL("vm.stats.vm.v_wire_count", memory_stats[MEM_WIRED])
GETPAGESYSCTL("vm.stats.vm.v_cache_count", memory_stats[MEM_CACHED])
GETPAGESYSCTL("vm.stats.vm.v_free_count", memory_stats[MEM_FREE])
GETMEMSYSCTL("vfs.bufspace", memory_stats[MEM_BUFFERED])
GETMEMSYSCTL("hw.physmem", memory_stats[MEM_TOTAL])
/*
* Swap
*/
GETSYSCTL("vm.stats.vm.v_swappgsin", swapin);
GETSYSCTL("vm.stats.vm.v_swappgsout", swapout);
if (swap_old[SWAP_IN] < 0) {
swap_stats[SWAP_IN] = 0;
swap_stats[SWAP_OUT] = 0;
} else {
swap_stats[SWAP_IN] = CONVERT(swapin - swap_old[SWAP_IN]);
swap_stats[SWAP_OUT] = CONVERT(swapout - swap_old[SWAP_OUT]);
}
/* only for changes */
if (swap_stats[SWAP_IN] > 0 || swap_stats[SWAP_OUT] > 0 || swap_old[SWAP_IN] < 0) {
kvm_getswapinfo_sysctl(&ksw_used, &ksw_total);
swap_stats[SWAP_TOTAL] = CONVERT(ksw_total);
swap_stats[SWAP_USED] = CONVERT(ksw_used);
swap_stats[SWAP_FREE] = CONVERT(ksw_total - ksw_used);
}
swap_old[SWAP_IN] = swapin;
swap_old[SWAP_OUT] = swapout;
return 0;
#undef CONVERT
#undef GETSYSCTL
#undef GETPAGESYSCTL
#undef GETMEMSYSCTL
}
void printMActive(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_ACTIVE]);
}
void printMActiveInfo(const char* cmd)
{
fprintf(CurrentClient, "Active Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]);
}
void printMInactive(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_INACTIVE]);
}
void printMInactiveInfo(const char* cmd)
{
fprintf(CurrentClient, "Inactive Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]);
}
void printMApplication(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_ACTIVE] + memory_stats[MEM_INACTIVE]);
}
void printMApplicationInfo(const char* cmd)
{
fprintf(CurrentClient, "Application (Active and Inactive) Memory\t0\t%ld\tKB\n", memory_stats[MEM_TOTAL]);
}
void printMWired(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_WIRED]);
}
void printMWiredInfo(const char* cmd)
{
fprintf(CurrentClient, "Wired Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]);
}
void printMCached(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_CACHED]);
}
void printMCachedInfo(const char* cmd)
{
fprintf(CurrentClient, "Cached Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]);
}
void printMBuffers(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_BUFFERED]);
}
void printMBuffersInfo(const char* cmd)
{
fprintf(CurrentClient, "Buffer Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]);
}
void printMFree(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_FREE]);
}
void printMFreeInfo(const char* cmd)
{
fprintf(CurrentClient, "Free Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]);
}
void printMUsed(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", memory_stats[MEM_TOTAL] - memory_stats[MEM_FREE]);
}
void printMUsedInfo(const char* cmd)
{
fprintf(CurrentClient, "Used Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]);
}
void printSwapUsed(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_USED]);
}
void printSwapUsedInfo(const char* cmd)
{
fprintf(CurrentClient, "Used Swap Memory\t0\t%lu\tKB\n", swap_stats[SWAP_TOTAL]);
}
void printSwapFree(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_FREE]);
}
void printSwapFreeInfo(const char* cmd)
{
fprintf(CurrentClient, "Free Swap Memory\t0\t%lu\tKB\n", swap_stats[SWAP_TOTAL]);
}
void printSwapIn(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_IN]);
}
void printSwapInInfo(const char* cmd)
{
fprintf(CurrentClient, "Swapped In Memory\t0\t0\tKB/s\n");
}
void printSwapOut(const char* cmd)
{
fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_OUT]);
}
void printSwapOutInfo(const char* cmd)
{
fprintf(CurrentClient, "Swapped Out Memory\t0\t0\tKB/s\n");
}
/* Adapted from src/lib/libkvm/kvm_getswapinfo.c */
#define SWI_MAXMIB 3
void kvm_getswapinfo_sysctl(size_t *ksw_used, size_t *ksw_total)
{
int unswdev;
size_t len;
static int soid[SWI_MAXMIB], dmmax = -1;
static size_t mibi = -1;
struct xswdev xsd;
*ksw_used = 0;
*ksw_total = 0;
if (dmmax == -1) {
len = sizeof(dmmax);
if (sysctlbyname("vm.dmmax", &dmmax, &len, NULL, 0) == -1 || len != sizeof(dmmax)) {
dmmax = -1;
return;
}
}
if (mibi == -1) {
mibi = SWI_MAXMIB - 1;
if (sysctlnametomib("vm.swap_info", soid, &mibi) == -1) {
mibi = -1;
return;
}
}
for (unswdev = 0;; unswdev++) {
soid[mibi] = unswdev;
len = sizeof(xsd);
if (sysctl(soid, mibi + 1, &xsd, &len, NULL, 0) == -1 || len != sizeof(xsd)) {
return;
}
*ksw_used += xsd.xsw_used;
*ksw_total += xsd.xsw_nblks - dmmax;
}
}