Subject: | bus errors when .cdb used over NFS is replaced |
When CDB_File has a .cdb file open in an nfs-mounted directory, it will
crash with a bus error when the file is replaced or deleted.
This is due to mmap() losing the mapping when the file handle becomes
invalid (output is using 0.97):
Program received signal SIGBUS, Bus error.
memcpy () at ../sysdeps/x86_64/memcpy.S:102
102 ../sysdeps/x86_64/memcpy.S: No such file or directory.
in ../sysdeps/x86_64/memcpy.S
Current language: auto
The current source language is "auto; currently asm".
(gdb) bt
#0 memcpy () at ../sysdeps/x86_64/memcpy.S:102
#1 0x00007ffff046b8b5 in cdb_read (c=0x61c8f0,
buf=0x7fffffffe880 "RQ{\222j%\230\r", len=8, pos=228074858)
at CDB_File.xs:221
#2 0x00007ffff046bc5e in cdb_findnext (c=0x61c8f0,
key=0x638f30 "name:549389", len=11) at CDB_File.xs:289
#3 0x00007ffff046da83 in XS_CDB_File_FETCH (my_perl=0x7fffffffe880,
cv=0x63a5a8) at CDB_File.xs:473
#4 0x00007ffff7b1d5f5 in Perl_pp_entersub (my_perl=0x602010) at
pp_hot.c:2891
#5 0x00007ffff7b1bb36 in Perl_runops_standard (my_perl=0x602010) at
run.c:40
#6 0x00007ffff7ac071c in S_run_body (my_perl=<value optimized out>)
at perl.c:2431
#7 perl_run (my_perl=<value optimized out>) at perl.c:2349
#8 0x0000000000400d3c in main ()
When -DHASMMAP is removed from the Makefile, i.e. CDB_File is built
without mmap() support, CDB_File crashes (more gently) with:
Read of CDB_File failed: Protocol error at (eval 5) line 9.
While the mmap() error probably cannot be avoided, it would allow better
recovery on the Perl side if CDB_File didn't crash with a bus error
(e.g. die'ing instead would allow catching with eval and reopening the
file).
How to reproduce (untested):
- mount a directory over NFS
- put a .cdb file in that directory
- write a Perl script that opens the file with CDB_File (tie or
TIEHASH() interface) and reads one key every second in an infinite loop)
- replace the file on the server, e.g. by rsync'ing a new .cdb file over
the original one
- the Perl script will crash with a bus error