ohmu
·
2026-10-15
1#include "swap.h"
2#include "common/debug.h"
3#include "common/sysctl.h"
4
5#include <errno.h>
6#include <string.h>
7#include <vm/vm_param.h>
8#include <sys/stat.h>
9#include <sys/param.h>
10
11static void addSwapEntry(FFlist* result, struct xswdev* xsw, uint32_t pageSizeShift) {
12 if (xsw->xsw_nblks == 0) { // DFBSD reports some /dev/wdog devices with nblks == 0
13 return;
14 }
15
16 FFSwapResult* swap = FF_LIST_ADD(FFSwapResult, *result);
17 if (xsw->xsw_dev == NODEV) {
18 ffStrbufInitStatic(&swap->name, "[NFS]");
19 } else {
20 ffStrbufInitF(&swap->name, "/dev/%s", devname(xsw->xsw_dev, S_IFCHR));
21 }
22 swap->bytesUsed = (uint64_t) xsw->xsw_used << pageSizeShift;
23 swap->bytesTotal = (uint64_t) xsw->xsw_nblks << pageSizeShift;
24}
25
26#if __DragonFly__
27
28const char* ffDetectSwap(FFlist* result) {
29 struct xswdev xsws[32];
30 size_t size = sizeof(xsws);
31 if (sysctlbyname("vm.swap_info_array", xsws, &size, nullptr, 0) < 0) {
32 FF_DEBUG("sysctlbyname(\"vm.swap_info_array\") failed: %s", strerror(errno));
33 return "sysctlbyname(\"vm.swap_info_array\") failed";
34 }
35
36 const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
37
38 size_t count = size / sizeof(struct xswdev);
39 if (count == 0) {
40 return nullptr;
41 }
42
43 if (xsws->xsw_version != XSWDEV_VERSION) {
44 FF_DEBUG("xswdev version mismatch");
45 return "xswdev version mismatch";
46 }
47
48 for (uint32_t i = 0; i < count; ++i) {
49 addSwapEntry(result, &xsws[i], pageSizeShift);
50 }
51
52 return nullptr;
53}
54
55#elif __FreeBSD__
56
57const char* ffDetectSwap(FFlist* result) {
58 int mib[16];
59 size_t mibsize = ARRAY_SIZE(mib);
60 if (sysctlnametomib("vm.swap_info", mib, &mibsize) < 0) {
61 FF_DEBUG("sysctlnametomib(\"vm.swap_info\") failed: %s", strerror(errno));
62 return "sysctlnametomib(\"vm.swap_info\") failed";
63 }
64
65 const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
66
67 for (int n = 0;; ++n) {
68 mib[mibsize] = n;
69 struct xswdev xsw;
70 size_t size = sizeof(xsw);
71 if (sysctl(mib, (uint32_t) (mibsize + 1), &xsw, &size, nullptr, 0) < 0) {
72 break;
73 }
74 if (xsw.xsw_version != XSWDEV_VERSION) {
75 FF_DEBUG("xswdev version mismatch");
76 return "xswdev version mismatch";
77 }
78
79 addSwapEntry(result, &xsw, pageSizeShift);
80 }
81
82 return nullptr;
83}
84
85#endif