/*
 * feeder.c -- DF-2979 T3 helper (runs as ROOT).
 *
 * Pins itself to cpu0 (same as poc T3) and raw-reads 128KB blocks of the
 * real hammer2 root disk in a tight loop. Each read is a physread/physio
 * transfer: the kernel pbuf that carries the disk data is released back to
 * the pbuf_mem pool immediately. The unprivileged poc on the same cpu
 * recycles that exact pbuf (LIFO bucket) for its failing read and, via
 * kern_physio.c:112-121, receives the disk bytes that root just read.
 */
#include <sys/types.h>
#include <sys/usched.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
	static char buf[131072];
	int fd, i, iters = 5000;
	int cpu = 0;

	if (argc > 1)
		iters = atoi(argv[1]);
	if (usched_set(getpid(), USCHED_SET_CPU, &cpu, sizeof(cpu)) < 0) {
		perror("usched_set");
		return 2;
	}
	fd = open("/dev/vbd0s1d", O_RDONLY);
	if (fd < 0) { perror("open /dev/vbd0s1d"); return 2; }
	for (i = 0; i < iters; i++) {
		ssize_t r = pread(fd, buf, sizeof(buf), 0);
		if (r != (ssize_t)sizeof(buf)) {
			perror("read"); return 2;
		}
	}
	printf("feeder: done %d reads\n", iters);
	return 0;
}
