DragonFlyBSD Kernel Audit
DF-0920 / trigger_mmap.c
← back to finding ↓ download raw
/* trigger_mmap.c - trigger async NFS bio via mmap page faults.
 *
 * mmap the NFS file and touch pages sequentially. The kernel's vm_fault
 * path goes through nfs_getpages which uses async bio (nfs_readrpc_bio)
 * to read pages. If the server returns JUKEBOX, the iod reader hits the
 * kprintf at nfs_iod.c:135.
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv) {
    const char *path = argc > 1 ? argv[1] : "/mnt/anyfile";
    int fd = open(path, O_RDONLY);
    if (fd < 0) { perror("open"); return 1; }

    struct stat st;
    if (fstat(fd, &st) < 0) { perror("fstat"); return 1; }
    fprintf(stderr, "file size = %lld\n", (long long)st.st_size);

    size_t len = st.st_size;
    if (len == 0) len = 1024 * 1024;
    void *map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) { perror("mmap"); return 1; }

    /* Touch pages sequentially to trigger async readahead via nfs_getpages. */
    volatile char sum = 0;
    for (size_t off = 0; off < len; off += 4096) {
        sum += ((char *)map)[off];
    }
    fprintf(stderr, "sum = %d (touched %zu pages)\n", (int)sum, len / 4096);

    munmap(map, len);
    close(fd);
    return 0;
}