Samba
沒有 EOF,當程序在 cifs mount 上讀取自己的執行檔時
我的基於 java 的安裝程序無法將自身複製到目標目錄,吃掉所有磁碟空間,我認為這是一個 java 錯誤,但後來我用 plain 複製了它
dd
。當我嘗試使用足夠大的緩衝區(131072)讀取我自己的執行檔時,讀取操作突然返回大於實際文件大小的值並且永遠不會返回 EOF:
DD=/media/distr/dd ( /bin/cp /bin/dd $DD $DD bs=131071 if=$DD of=/dev/null count=20 $DD bs=131072 if=$DD of=/dev/null count=20 ) 0+1 records in 0+1 records out 55256 bytes (55 kB) copied, 0.00211071 s, 26.2 MB/s 20+0 records in 20+0 records out 2621440 bytes (2.6 MB) copied, 0.0194318 s, 135 MB/s
僅當
samba
伺服器和cifs
掛載都在 Oracle Linux 6.6 上執行時才會發生samba 3.6.23-12.0.1.el6
。它是什麼?核心、cifs 或 samba 錯誤?
dd的strace:
[root@ec-stage-db-2 ~]# strace $DD bs=131072 if=$DD of=/dev/null count=20 execve("/mnt/dd", ["/mnt/dd", "bs=131072", "if=/mnt/dd", "of=/dev/null", "count=20"], [/* 32 vars */]) = 0 brk(0) = 0x13e8000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172ee000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=79239, ...}) = 0 mmap(NULL, 79239, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcc172da000 close(3) = 0 open("/lib64/librt.so.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@!\3002=\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=47104, ...}) = 0 mmap(0x3d32c00000, 2128816, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3d32c00000 mprotect(0x3d32c07000, 2093056, PROT_NONE) = 0 mmap(0x3d32e06000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x3d32e06000 close(3) = 0 open("/lib64/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\356\3011=\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1926760, ...}) = 0 mmap(0x3d31c00000, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3d31c00000 mprotect(0x3d31d8a000, 2097152, PROT_NONE) = 0 mmap(0x3d31f8a000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18a000) = 0x3d31f8a000 mmap(0x3d31f8f000, 18696, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3d31f8f000 close(3) = 0 open("/lib64/libpthread.so.0", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340]\0002=\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=145896, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172d9000 mmap(0x3d32000000, 2212848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3d32000000 mprotect(0x3d32017000, 2097152, PROT_NONE) = 0 mmap(0x3d32217000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x3d32217000 mmap(0x3d32219000, 13296, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3d32219000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172d8000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172d7000 arch_prctl(ARCH_SET_FS, 0x7fcc172d8700) = 0 mprotect(0x3d32e06000, 4096, PROT_READ) = 0 mprotect(0x3d31f8a000, 16384, PROT_READ) = 0 mprotect(0x3d32217000, 4096, PROT_READ) = 0 mprotect(0x3d3161f000, 4096, PROT_READ) = 0 munmap(0x7fcc172da000, 79239) = 0 set_tid_address(0x7fcc172d89d0) = 39608 set_robust_list(0x7fcc172d89e0, 0x18) = 0 futex(0x7fffa32a778c, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x7fffa32a778c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7fcc172d8700) = -1 EAGAIN (Resource temporarily unavailable) rt_sigaction(SIGRTMIN, {0x3d32005c60, [], SA_RESTORER|SA_SIGINFO, 0x3d3200f710}, NULL, 8) = 0 rt_sigaction(SIGRT_1, {0x3d32005cf0, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x3d3200f710}, NULL, 8) = 0 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0 rt_sigaction(SIGUSR1, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGUSR1, {0x401be0, [INT USR1], SA_RESTORER, 0x3d31c326a0}, NULL, 8) = 0 rt_sigaction(SIGINT, {0x401bd0, [INT USR1], SA_RESTORER|SA_NODEFER|SA_RESETHAND, 0x3d31c326a0}, NULL, 8) = 0 brk(0) = 0x13e8000 brk(0x1409000) = 0x1409000 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=99158576, ...}) = 0 mmap(NULL, 99158576, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcc11446000 close(3) = 0 open("/mnt/dd", O_RDONLY) = 3 dup2(3, 0) = 0 close(3) = 0 lseek(0, 0, SEEK_CUR) = 0 open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 dup2(3, 1) = 1 close(3) = 0 mmap(NULL, 143360, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc11423000 read(0, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0\340\32@\0\0\0\0\0"..., 131072) = 131072 write(1, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0\340\32@\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072 close(0) = 0 close(1) = 0 open("/usr/share/locale/locale.alias", O_RDONLY) = 0 fstat(0, {st_mode=S_IFREG|0644, st_size=2512, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172ed000 read(0, "# Locale name alias data base.\n#"..., 4096) = 2512 read(0, "", 4096) = 0 close(0) = 0 munmap(0x7fcc172ed000, 4096) = 0 open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = 0 fstat(0, {st_mode=S_IFREG|0644, st_size=435, ...}) = 0 mmap(NULL, 435, PROT_READ, MAP_PRIVATE, 0, 0) = 0x7fcc172ed000 close(0) = 0 write(2, "20+0 records in\n20+0 records out"..., 3320+0 records in 20+0 records out ) = 33 write(2, "2621440 bytes (2.6 MB) copied", 292621440 bytes (2.6 MB) copied) = 29 write(2, ", 0.0245485 s, 107 MB/s\n", 24, 0.0245485 s, 107 MB/s ) = 24 close(2) = 0 exit_group(0) = ?
完成測試腳本。我不能報告這個錯誤,因為我必須為此付費。
#!/bin/bash set -e # systemd #SMB_START="systemctl start smbd.service nmbd.service" #SMB_RELOAD="systemctl reload smbd.service" # initscripts SMB_START="service smb start" SMB_RELOAD="service smb reload" cleanup() { echo cleanup... >&2 sed -i -n -e "/# added by test-samba-bug BEGIN/b m10; p; b" -e :m10 -e n -e "/# added by test-samba-bug END/b" -e "b m10" /etc/samba/smb.conf umount -f /tmp/test-samba-bug-mnt 2>/dev/null || true rm -rf /tmp/test-samba-bug /tmp/test-samba-bug-mnt } cleanup trap cleanup EXIT mkdir -p /tmp/test-samba-bug /tmp/test-samba-bug-mnt chcon -R -t samba_share_t /tmp/test-samba-bug 2>/dev/null || true >>/etc/samba/smb.conf cat <<EOF # added by test-samba-bug BEGIN [test-samba-bug] path = /tmp/test-samba-bug public = yes # added by test-samba-bug END EOF # service smb stop $SMB_START $SMB_RELOAD mount -t cifs -oguest //localhost/test-samba-bug /tmp/test-samba-bug-mnt command cp /bin/dd /tmp/test-samba-bug/ DD=/tmp/test-samba-bug-mnt/dd #$DD bs=131071 if=$DD of=/dev/null count=20 $DD bs=131072 if=$DD of=/tmp/test-samba-bug/copied count=20 echo comparing copied file contents cmp /bin/dd /tmp/test-samba-bug/copied || { echo "test failed" >&2 exit 1 }
假設你不能在同一台機器上用另一個文件系統重現這個問題,它一定是一個 samba 錯誤。
無論是客戶端還是伺服器問題都有點爭議,但我猜這與映射執行並打開讀取的同一個文件有關,這可能處理不正確,因為讀取呼叫不應該返回任何超出eof的東西。錯誤的文件元數據(即大小)也可能導致此類行為。