⬢ DragonFlyBSD Kernel Audit
DF-5108 / ulmon.c
← back to finding ↓ download raw
/*
 * ulmon: dump candidate usedlocks fields from VINUM_PLEXCONFIG(plex 0)
 * while the hammer runs. struct plex has usedlocks at ~offset 172
 * (x86_64, from vinumvar.h:548-588). Print ints 164..188 to eyeball.
 * build: cc -O2 -o ulmon ulmon.c ; usage: ./ulmon [seconds]
 */
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#define	L	'F'
/* _IOWR size must equal kernel sizeof(struct plex); 712 measured below */
#define	VINUM_PLEXCONFIG(sz)	_IOWR(L, 68, char[sz])

int
main(int argc, char **argv)
{
	int fd, i, sec = (argc > 1) ? atoi(argv[1]) : 30;
	int max[10];
	static char buf[2048];
	int idx = 0, sz;

	for (sz = 184; sz <= 216; sz += 8) {	/* probe the size the kernel accepts */
		memset(buf, 0, sizeof(buf));
		memcpy(buf, &idx, sizeof(idx));
		fd = open("/dev/vinum/control", O_RDWR);
		if (ioctl(fd, VINUM_PLEXCONFIG(sz), buf) == 0)
			break;
		close(fd);
	}
	if (sz > 248) {
		fprintf(stderr, "no working size: %s\n", strerror(errno));
		return (1);
	}
	fprintf(stderr, "PLEXCONFIG size=%d\n", sz);
	memset(max, 0, sizeof(max));
	fd = open("/dev/vinum/control", O_RDWR);
	for (i = 0; i < sec * 4; i++) {
		int j, off = 196;
		memset(buf, 0, sizeof(buf));
		memcpy(buf, &idx, sizeof(idx));
		if (ioctl(fd, VINUM_PLEXCONFIG(sz), buf) < 0) {
			perror("plexconfig");
			return (1);
		}
		for (j = 0; j < 10; j++)
			max[j] = *(int *)(buf + off + j * 4);
		printf("t=%2d:", i / 4);
		for (j = 0; j < 8; j++)
			printf(" %3d@%d", *(int *)(buf + 196 + j * 4), 196 + j * 4);
		printf("\n");
		fflush(stdout);
		usleep(250000);
	}
	return (0);
}