#!/bin/sh [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 # Rename cache problem scenario mntpoint=/mnt mdstart=5 part=a here=`pwd` cd /tmp sed '1,/^EOF/d' < $here/$0 > r9.c cc -o r9 -Wall -Wextra -O2 r9.c rm -f r9.c cd $here mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart mdconfig -a -t swap -s 2g -u $mdstart bsdlabel -w md$mdstart auto newfs -U md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint rm -rf $mntpoint/.snap chmod 777 $mntpoint (while true; do ls -lRi $mntpoint > /dev/null 2>&1; done) & pid=$! (cd $mntpoint; /tmp/r9) kill $pid > /dev/null 2>&1 wait while mount | grep -q md${mdstart}$part; do umount $mntpoint || sleep 1 done mdconfig -d -u $mdstart rm -f /tmp/r9 exit EOF #include #include #include #include #include #include #include #include #include #include #include #include #include #include pid_t spid; char *fromFile = "fromFile.log"; char toFile[128]; void cleanup() { kill(spid, SIGINT); } static void statFrom() { struct stat sb; setproctitle("Stat"); for (;;) { stat(fromFile, &sb); } } int main(void) { struct stat fb, tb, fa, ta; int fd, i; if ((spid = fork()) == 0) statFrom(); setproctitle("main"); atexit(cleanup); for (i = 0;; i++) { bzero(&fb, sizeof(fb)); bzero(&tb, sizeof(tb)); bzero(&fa, sizeof(fa)); bzero(&ta, sizeof(ta)); if ((fd = open(fromFile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) err(1, "creat(%s)", fromFile); close(fd); sprintf(toFile, "toFile.log.%05d", i); if ((fd = open(toFile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) err(1, "creat(%s)", toFile); write(fd, "xxx", 3); close(fd); stat(fromFile, &fb); stat(toFile, &tb); if (rename(fromFile, toFile) == -1) warn("rename(%s, %s)", fromFile, toFile); stat(fromFile, &fa); if (stat(toFile, &ta) == -1) err(1, "stat(%s)", toFile); if (tb.st_ino == ta.st_ino) { fprintf(stderr, "FAIL: old and new \"To\" inode number is identical\n"); fprintf(stderr, "stat() before the rename():\n"); fprintf(stderr, "%-16s: ino = %4d, nlink = %d, size = %jd\n", fromFile, fb.st_ino, fb.st_nlink, fb.st_blocks); fprintf(stderr, "%-16s: ino = %4d, nlink = %d, size = %jd\n", toFile, tb.st_ino, tb.st_nlink, tb.st_blocks); fprintf(stderr, "\nstat() after the rename():\n"); if (fa.st_ino != 0) fprintf(stderr, "%-16s: ino = %4d, nlink = %d, size = %jd\n", fromFile, fa.st_ino, fa.st_nlink, fa.st_blocks); fprintf(stderr, "%-16s: ino = %4d, nlink = %d, size = %jd\n", toFile, ta.st_ino, ta.st_nlink, ta.st_blocks); kill(spid, SIGINT); exit(1); } unlink(toFile); } kill(spid, SIGINT); wait(NULL); return (0); }