18a272653SPeter Holm#!/bin/sh 28a272653SPeter Holm 38a272653SPeter Holm# 48a272653SPeter Holm# Copyright (c) 2011 Peter Holm <pho@FreeBSD.org> 58a272653SPeter Holm# All rights reserved. 68a272653SPeter Holm# 78a272653SPeter Holm# Redistribution and use in source and binary forms, with or without 88a272653SPeter Holm# modification, are permitted provided that the following conditions 98a272653SPeter Holm# are met: 108a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright 118a272653SPeter Holm# notice, this list of conditions and the following disclaimer. 128a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 138a272653SPeter Holm# notice, this list of conditions and the following disclaimer in the 148a272653SPeter Holm# documentation and/or other materials provided with the distribution. 158a272653SPeter Holm# 168a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 178a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 188a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 198a272653SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 208a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 218a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 228a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 238a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 248a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 258a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 268a272653SPeter Holm# SUCH DAMAGE. 278a272653SPeter Holm# 288a272653SPeter Holm 298a272653SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 308a272653SPeter Holm 31*088cc7d2SAlexander Ziaee# Demonstrate rename(2) cache problem for tmpfs(4). Fixed in r226987. 328a272653SPeter Holm# Variation of rename6.sh 338a272653SPeter Holm 348a272653SPeter Holm. ../default.cfg 358a272653SPeter Holm 368a272653SPeter Holmhere=`pwd` 378a272653SPeter Holmcd /tmp 388a272653SPeter Holmsed '1,/^EOF/d' < $here/$0 > tmpfs8.c 398a272653SPeter Holmmycc -o tmpfs8 -Wall -Wextra -O2 tmpfs8.c 408a272653SPeter Holmrm -f tmpfs8.c 418a272653SPeter Holmcd $here 428a272653SPeter Holm 438a272653SPeter Holmmount | grep $mntpoint | grep -q tmpfs && umount -f $mntpoint 448a272653SPeter Holmmount -t tmpfs tmpfs $mntpoint 458a272653SPeter Holmchmod 777 $mntpoint 468a272653SPeter Holm 478a272653SPeter Holmsu $testuser -c "cd $mntpoint; /tmp/tmpfs8" 488a272653SPeter Holm 498a272653SPeter Holmwhile mount | grep $mntpoint | grep -q tmpfs; do 508a272653SPeter Holm umount $mntpoint || sleep 1 518a272653SPeter Holmdone 528a272653SPeter Holmrm -f /tmp/tmpfs8 538a272653SPeter Holmexit 548a272653SPeter HolmEOF 558a272653SPeter Holm#include <err.h> 568a272653SPeter Holm#include <errno.h> 578a272653SPeter Holm#include <fcntl.h> 588a272653SPeter Holm#include <sched.h> 598a272653SPeter Holm#include <signal.h> 608a272653SPeter Holm#include <stdio.h> 618a272653SPeter Holm#include <stdlib.h> 628a272653SPeter Holm#include <strings.h> 638a272653SPeter Holm#include <sys/param.h> 648a272653SPeter Holm#include <sys/stat.h> 658a272653SPeter Holm#include <sys/time.h> 668a272653SPeter Holm#include <sys/wait.h> 678a272653SPeter Holm#include <time.h> 688a272653SPeter Holm#include <unistd.h> 698a272653SPeter Holm 708a272653SPeter Holmpid_t spid; 718a272653SPeter Holmconst char *logfile = "test.log"; 728a272653SPeter Holmchar new[128]; 738a272653SPeter Holm 748a272653SPeter Holmvoid 758a272653SPeter Holmcleanup() 768a272653SPeter Holm{ 778a272653SPeter Holm kill(spid, SIGINT); 788a272653SPeter Holm} 798a272653SPeter Holm 808a272653SPeter Holmstatic void 818a272653SPeter HolmStat() 828a272653SPeter Holm{ 838a272653SPeter Holm struct stat sb; 848a272653SPeter Holm int i; 858a272653SPeter Holm 868a272653SPeter Holm setproctitle("Stat"); 878a272653SPeter Holm for (;;) { 888a272653SPeter Holm for (i = 0; i < 1000; i++) { 898a272653SPeter Holm stat(logfile, &sb); 908a272653SPeter Holm stat(new, &sb); 918a272653SPeter Holm } 928a272653SPeter Holm// usleep(1000); 938a272653SPeter Holm usleep(100); 948a272653SPeter Holm } 958a272653SPeter Holm} 968a272653SPeter Holm 978a272653SPeter Holmint 988a272653SPeter Holmmain(void) 998a272653SPeter Holm{ 1008a272653SPeter Holm struct stat sb1, sb2, sb3; 1018a272653SPeter Holm int fd, i, r1, r2, r3; 1028a272653SPeter Holm 1038a272653SPeter Holm if ((spid = fork()) == 0) 1048a272653SPeter Holm Stat(); 1058a272653SPeter Holm 1068a272653SPeter Holm setproctitle("main"); 1078a272653SPeter Holm atexit(cleanup); 1088a272653SPeter Holm for (i = 0; i < 200000; i++) { 1098a272653SPeter Holm bzero(&sb1, sizeof(sb1)); 1108a272653SPeter Holm bzero(&sb2, sizeof(sb2)); 1118a272653SPeter Holm if ((fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) 1128a272653SPeter Holm err(1, "creat(%s)", logfile); 1138a272653SPeter Holm close(fd); 1148a272653SPeter Holm 1158a272653SPeter Holm sprintf(new, "test.log.%05d", i); 1168a272653SPeter Holm if ((fd = open(new, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) 1178a272653SPeter Holm err(1, "creat(%s)", new); 1188a272653SPeter Holm write(fd, "xxx", 3); 1198a272653SPeter Holm close(fd); 1208a272653SPeter Holm if ((r3 = stat(new, &sb3)) == -1) 1218a272653SPeter Holm err(1, "stat(%s)", new); 1228a272653SPeter Holm#if 1 1238a272653SPeter Holm if (rename(logfile, new) == -1) 1248a272653SPeter Holm warn("rename(%s, %s)", logfile, new); 1258a272653SPeter Holm#else 1268a272653SPeter Holm /* No cache problem is seen */ 1278a272653SPeter Holm if (link(logfile, new) == -1) 1288a272653SPeter Holm err(1, "link(%s, %s)", logfile, new); 1298a272653SPeter Holm if (unlink(logfile) == -1) 1308a272653SPeter Holm err(1, "unlink(%s)", logfile); 1318a272653SPeter Holm#endif 1328a272653SPeter Holm /* 1338a272653SPeter Holm * stat() for logfile and new will be identical sometimes, 1348a272653SPeter Holm * but only when Stat() is running. 1358a272653SPeter Holm */ 1368a272653SPeter Holm r1 = stat(logfile, &sb1); 1378a272653SPeter Holm r2 = stat(new, &sb2); 1388a272653SPeter Holm if (r1 == 0 && r2 == 0 && 1398a272653SPeter Holm bcmp(&sb1, &sb2, sizeof(sb1)) == 0) { 1408a272653SPeter Holm fprintf(stderr, "FAIL 1\n"); 1418a272653SPeter Holm fprintf(stderr, "%-15s: ino = %4ju, nlink = %ju, " 1428a272653SPeter Holm "size = %jd\n", logfile, (uintmax_t)sb1.st_ino, 1438a272653SPeter Holm (uintmax_t)sb1.st_nlink, sb1.st_blocks); 1448a272653SPeter Holm fprintf(stderr, "%-15s: ino = %4ju, nlink = %ju, " 1458a272653SPeter Holm "size = %jd\n", new , (uintmax_t)sb2.st_ino, 1468a272653SPeter Holm (uintmax_t)sb2.st_nlink, sb2.st_blocks); 1478a272653SPeter Holm } 1488a272653SPeter Holm if (bcmp(&sb2, &sb3, sizeof(sb2)) == 0) { 1498a272653SPeter Holm fprintf(stderr, "Old to file is lingering\n"); 1508a272653SPeter Holm } 1518a272653SPeter Holm if (sb2.st_ino == sb3.st_ino) { 1528a272653SPeter Holm fprintf(stderr, "FAIL 2\n"); 1538a272653SPeter Holm if (r1 == 0) 1548a272653SPeter Holm fprintf(stderr, 1558a272653SPeter Holm "sb1: %-15s: ino = %4ju, nlink = %ju, " 1568a272653SPeter Holm "size = %jd\n", logfile, 1578a272653SPeter Holm (uintmax_t)sb1.st_ino, 1588a272653SPeter Holm (uintmax_t)sb1.st_nlink, sb1.st_blocks); 1598a272653SPeter Holm if (r2 == 0) 1608a272653SPeter Holm fprintf(stderr, 1618a272653SPeter Holm "sb2: %-15s: ino = %4ju, nlink = %ju, " 1628a272653SPeter Holm "size = %jd\n", new, (uintmax_t)sb2.st_ino, 1638a272653SPeter Holm (uintmax_t)sb2.st_nlink, sb2.st_blocks); 1648a272653SPeter Holm if (r3 == 0) 1658a272653SPeter Holm fprintf(stderr, 1668a272653SPeter Holm "sb3: %-15s: ino = %4ju, nlink = %ju, " 1678a272653SPeter Holm "size = %jd\n", new, (uintmax_t)sb3.st_ino, 1688a272653SPeter Holm (uintmax_t)sb3.st_nlink, sb3.st_blocks); 1698a272653SPeter Holm exit(1); 1708a272653SPeter Holm } 1718a272653SPeter Holm unlink(new); 1728a272653SPeter Holm } 1738a272653SPeter Holm 1748a272653SPeter Holm kill(spid, SIGINT); 1758a272653SPeter Holm wait(NULL); 1768a272653SPeter Holm 1778a272653SPeter Holm return (0); 1788a272653SPeter Holm} 179