DF-3061 / run.sh
#!/bin/sh # DF-3061 reproduction (run inside the DragonFly guest as root) # Baseline expectation: kernel panic ("nfs - retry rename" then # "Fatal trap 12 ... lockmgr_release+0x11") within ~1-3 minutes. set -x mkdir -p /export /mnt/nfs echo "/export -maproot=root localhost" > /etc/exports rpcbound=$(pgrep rpcbind); [ -z "$rpcbound" ] && rpcbind pgrep nfsd >/dev/null || /sbin/nfsd -t -u -n 4 sleep 1 pgrep mountd >/dev/null || /sbin/mountd & sleep 2 mount | grep -q /mnt/nfs || mount localhost:/export /mnt/nfs cat > /tmp/cl.c <<'EOF' #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char **argv){ const char *d = argv[1]; char a[512], b[512]; snprintf(a,sizeof(a),"%s/src",d); snprintf(b,sizeof(b),"%s/dst",d); for(;;){ int fd=open(a,O_CREAT,0666); if(fd>=0) close(fd); rename(a,b); rename(b,a); unlink(a); } } EOF cat > /tmp/rc4.c <<'EOF' #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sched.h> int main(int argc, char **argv){ const char *d=argv[1]; char a[512],b[512]; int i=0,fd; snprintf(a,sizeof(a),"%s/src",d); snprintf(b,sizeof(b),"%s/dst",d); if((fd=open(a,O_CREAT,0666))>=0) close(fd); for(;;){ i++; if ((i & 63)==0) unlink(a); else if ((i & 63)==1) { fd=open(a,O_CREAT,0666); if(fd>=0) close(fd); } rename(b,a); rename(a,b); sched_yield(); } } EOF cc -O2 -o /tmp/cl /tmp/cl.c || exit 1 cc -O2 -o /tmp/rc4 /tmp/rc4.c || exit 1 pkill rc4 2>/dev/null; pkill cl 2>/dev/null; sleep 1 rm -f /export/* /mnt/nfs/* for i in 1 2; do /tmp/rc4 /export >/dev/null 2>&1 & done for i in 1 2 3 4 5 6; do /tmp/cl /mnt/nfs >/dev/null 2>&1 & done sleep 300 pkill rc4; pkill cl dmesg | grep -c "nfs - retry rename" # baseline: guest panics before this point; patched: prints count and exits 0 |