DragonFlyBSD Kernel Audit
DF-2632 / denseprobe.c
← back to finding ↓ download raw
/*
 * DF-2632 — density probe: same dense-window fill but with fine-grained
 * progress reporting and a pause between batches so the panic-time dirent
 * count can be bracketed.
 *
 * usage: denseprobe <dir> <names-file> <batch> <usecs-sleep>
 */
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

int
main(int argc, char **argv)
{
	FILE *nf;
	char name[256], path[1024];
	const char *dir;
	long created = 0, errors = 0;
	long batch, usecs;
	int fd;

	if (argc != 5) {
		fprintf(stderr,
		    "usage: %s <dir> <names-file> <batch> <usecs>\n",
		    argv[0]);
		return 2;
	}
	dir = argv[1];
	batch = atol(argv[3]);
	usecs = atol(argv[4]);
	if (batch < 1)
		batch = 1;

	nf = fopen(argv[2], "r");
	if (nf == NULL) {
		perror(argv[2]);
		return 2;
	}
	setvbuf(stdout, NULL, _IONBF, 0);
	while (fgets(name, sizeof(name), nf) != NULL) {
		size_t n = strlen(name);
		while (n > 0 && (name[n-1] == '\n' || name[n-1] == '\r'))
			name[--n] = 0;
		if (n == 0)
			continue;
		snprintf(path, sizeof(path), "%s/%s", dir, name);
		fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0644);
		if (fd < 0) {
			++errors;
			if (errors <= 20)
				fprintf(stderr, "create %s: %s\n",
				    name, strerror(errno));
		} else {
			close(fd);
			++created;
		}
		if ((created % batch) == 0 && created) {
			printf("created=%ld errors=%ld\n", created, errors);
			sync();
			usleep(usecs);
		}
	}
	fclose(nf);
	sync();
	printf("DONE created=%ld errors=%ld\n", created, errors);
	return 0;
}