DF-5015 / squeeze.c
/* squeeze.c -- wire memory (root setup tool for DF-5015 verification): * mlocks 32MB chunks until free page count drops to the target floor, * then holds. Exit/unlink releases everything (kernel unlocks on close). */ #include <sys/types.h> #include <sys/mman.h> #include <sys/sysctl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/resource.h> static long free_pages(void) { size_t len; u_int v = 0; static int real_mib[CTL_MAXNAME]; static size_t real_len; if (real_len == 0) { real_len = CTL_MAXNAME; if (sysctlnametomib("vm.stats.vm.v_free_count", real_mib, &real_len)) return -1; } len = sizeof(v); if (sysctl(real_mib, real_len, &v, &len, NULL, 0)) return -1; return v; } int main(int argc, char **argv) { long target = atol(argv[1]); /* target free pages floor */ long chunk = 32 << 20; void *p; if (argc < 2) return 64; { struct rlimit rl; rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_MEMLOCK, &rl)) printf("squeeze: setrlimit: %s\n", strerror(errno)); } for (;;) { if (free_pages() <= target) break; p = mmap(NULL, chunk, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (p == MAP_FAILED) { printf("squeeze: mmap failed at free=%ld\n", free_pages()); break; } memset(p, 1, chunk); if (mlock(p, chunk)) { printf("squeeze: mlock failed at free=%ld: %s\n", free_pages(), strerror(errno)); munmap(p, chunk); break; } } printf("squeeze: holding at free=%ld (target %ld)\n", free_pages(), target); fflush(stdout); pause(); return 0; } |