mount_null twice in a row panics
doing (for example) 'mount_null /usr /mnt' twice in a row panics the
box. Backtrace attached. I can send a dump but it's reliably reproducible.
Current directory is /var/crash/
Unread portion of the kernel message buffer:
panic: lockmgr: locking against myself
Trace beginning at frame 0xd5ea2afc
panic(d5ea2b20,c2b323a8,0,0,d5ea2b30) at panic+0x8c
panic(c058671c,d5a34100,20000,c2b323a8,20002) at panic+0x8c
lockmgr(c2b323a8,20002) at lockmgr+0x2f9
vn_lock(c2b322e8,20002,c2b322e8,c2b322e8,d2b2e3e8) at vn_lock+0x21
vget(c2b322e8,20002,d2b2e3e0,d5ea2cc4,c033125b) at vget+0x25
nullfs_root(d2b2e1d8,d5ea2bb8) at nullfs_root+0x1b
sys_mount(d5ea2cf0,6,0,0,d2b2dd58) at sys_mount+0x7b9
syscall2(d5ea2d40) at syscall2+0x1ef
Xint0x80_syscall() at Xint0x80_syscall+0x36
panic: from debugger
dumping to dev #ad/0x20001, blockno 2097456
GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-dragonfly".
#0 dumpsys () at ./machine/thread.h:83
#1 0xc02e21d6 in boot (howto=260)
#2 0xc02e22f7 in panic (fmt=0xc053bcf6 "from debugger")
#3 0xc01662b5 in db_panic (addr=-1068661196, have_addr=0, count=-1,
#4 0xc0166920 in db_command_loop ()
#5 0xc0168ef4 in db_trap (type=3, code=0)
#6 0xc04d8787 in kdb_trap (type=3, code=0, regs=0xd5ea2aa8)
#7 0xc04e9c09 in trap (frame=0xd5ea2aa8)
#8 0xc04d9497 in calltrap ()
#9 0xc04d8634 in Debugger (msg=0xc0552292 "panic") at ./cpu/cpufunc.h:73
#10 0xc02e22ee in panic (fmt=0xc058671c "lockmgr: locking against myself")
#11 0xc02d75a9 in lockmgr (lkp=0xc2b323a8, flags=131074)
#12 0xc0332546 in vn_lock (vp=0xc2b322e8, flags=131074)
#13 0xc032b41d in vget (vp=0xc2b322e8, flags=18)
#14 0xd58f7c2a in ?? ()
#15 0xc033125b in sys_mount (uap=0xd5ea2cf0)
#16 0xc04e95ba in syscall2 (frame=0xd5ea2d40)
#17 0xc04d9546 in Xint0x80_syscall ()
#18 0x080493a8 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
#4 Updated by Johannes.Hofmann about 5 years ago
I just tried it in a vkernel and the problem occurs if the
null-mounted directory is on HAMMER.
In that case during the second mount_null call,
VFS_ROOT(mp, &newdp) called from checkdirs() in turn called from sys_mount()
tries to acquire the same lock, that was already acquired by vn_lock()
from sys_mount() directly.
Doing checkdirs() after vn_unlock(vp) makes the problem go away, but
of course it might not be allowed to call checkdirs() without the lock
#5 Updated by dillon about 5 years ago
:Johannes Hofmann <Johannes.Hofmann@gmx.de> added the comment:
:I just tried it in a vkernel and the problem occurs if the
:null-mounted directory is on HAMMER.
:In that case during the second mount_null call,
:VFS_ROOT(mp, &newdp) called from checkdirs() in turn called from sys_mount(=
:tries to acquire the same lock, that was already acquired by vn_lock()
:from sys_mount() directly.
:Doing checkdirs() after vn_unlock(vp) makes the problem go away, but
:of course it might not be allowed to call checkdirs() without the lock
Hmm. I think we can safely call checkdirs() without the lock
protection as long as the vnode still has a ref, which it does.
The cache entries are still locked.
I will commit the change, we should be able to get enough testing
in prior to the release.
#6 Updated by swildner about 5 years ago
Fixed per Matt's commit: