NetBSD/regress/sys/fs/lfs/ckckp/ckckp.c
perseant 0268059112 Introduce two fcntl calls that freeze the filesystem right at the point
where segment 0 is being considered for writing.  This allows for automated
checkpoint vailidity scanning, and could be used (in conjunction with the
existing LFCNREWIND) for e.g. snapshot dumps as well.

Include a regression test that does such scanning.

When writing the Ifile, loop through the dirty block list three times to
make sure that the checkpoint is always consistent (the first and second
times the Ifile blocks can cross a segment boundary; not so the third time
unless the segments are very small).  Discovered by using the aforementioned
regression test.
2006-04-17 20:02:34 +00:00

62 lines
1.4 KiB
C

#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <ufs/ufs/dinode.h>
#include <ufs/lfs/lfs.h>
int main(int argc, char **argv)
{
int fd, e, sno;
char cmd[BUFSIZ], s[BUFSIZ];
FILE *pp;
if (argv[1] == NULL || argv[2] == NULL)
errx(1, "usage: %s <fs-root> <raw-dev>\n", argv[0]);
fd = open(argv[1], 0, 0);
if (fd < 0)
err(1, argv[1]);
fcntl(fd, LFCNWRAPGO, NULL);
sleep(5);
/* Loop forever calling LFCNWRAP{STOP,GO} */
sno = 0;
while(1) {
printf("Waiting until fs wraps\n");
fcntl(fd, LFCNWRAPSTOP, NULL);
/*
* When the fcntl exits, the wrap is about to occur (but
* is waiting for the signal to go). Call our mass-check
* script, and if all is well, continue. The output
* of the script should end with a line that begins with a
* numeric code: zero for okay, nonzero for a failure.
*/
printf("Verifying all checkpoints from s/n %d\n", sno);
sprintf(cmd, "./check-all %s %d", argv[2], sno);
pp = popen(cmd, "r");
s[0] = '\0';
while(fgets(s, BUFSIZ, pp) != NULL)
printf(" %s", s);
if (s[0] == '\0') {
printf("No checkpoints found or script exited\n");
return 0;
}
sscanf(s, "%d %d", &e, &sno);
if (e) {
return 0;
}
pclose(pp);
++sno;
printf("Waiting until fs continues\n");
fcntl(fd, LFCNWRAPGO, NULL);
}
return 0;
}