DF-2628 / linkloop.c
/* * DF-2628 link loop: hammer link(payload, lnk) forever; unlink on * success; after every failure stat(payload) and report any nlink rise * (link failed but link count inflated = the bug). * * usage: linkloop <dir> */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <time.h> #include <sys/stat.h> #include <signal.h> #include <stdlib.h> static void bye(int sig __unused) { _exit(0); } int main(int argc, char **argv) { char payload[512], lnk[512]; long base = -1, best = -1, attempts = 0, fails = 0; int hits = 0; time_t t0 = time(NULL); struct stat st; if (argc < 2) { fprintf(stderr, "usage: %s <dir> [seconds]\n", argv[0]); return 64; } if (argc >= 3) { signal(SIGALRM, bye); alarm(atoi(argv[2])); } snprintf(payload, sizeof(payload), "%s/payload", argv[1]); snprintf(lnk, sizeof(lnk), "%s/lnk", argv[1]); if (stat(payload, &st) < 0) { perror(payload); return 1; } base = st.st_nlink; setvbuf(stdout, NULL, _IONBF, 0); printf("linkloop uid=%d payload nlink=%ld\n", getuid(), base); for (;;) { int r = link(payload, lnk); ++attempts; if (r == 0) { unlink(lnk); continue; } ++fails; if (stat(payload, &st) == 0 && st.st_nlink > base && st.st_nlink > best) { best = st.st_nlink; ++hits; printf("[%lds] HIT: link errno=%d but nlink %ld -> %ld " "(inflation +%ld)\n", (long)(time(NULL) - t0), errno, base, best, best - base); } } return 0; } |