golang samba cifs 文件系统 中断panic unlink interrupted system call
程序日志:
Jan 27 19:23:58 cspost[28369]: panic: update ScandSource file.DeleteDir: unlinkat /opt/scandata/392066599894386302: interru
pted system call
系统日志 /var/log/message
Jan 27 14:48:39 10- kernel: CIFS VFS: \\\scandata Close interrupted close
Jan 27 20:27:01 10- kernel: CIFS VFS: Send error in read = -4
Jan 27 20:30:36 10- kernel: CIFS VFS: \\\scandata Close interrupted close
Jan 27 20:49:00 10- kernel: CIFS VFS: \\\scandata Close interrupted close
Jan 27 20:55:21 10- kernel: CIFS VFS: Send error in read = -4
可以设置环境变量缓解:
比如在systemd 的 service块内配置:
Environment=GODEBUG=asyncpreemptoff=1
本质是 unix linux syscall 系统调用 kernel的 EINTR error问题。是一个常见问题。
在golang 和cifs samba挂载网络存储时调用场景下触发的。
go官方代码解决:
https://github.com/golang/go/commit/e64675a79fef5924f268425de021372df874010e
https://go-review.googlesource.com/c/go/+/236997/
https://go-review.googlesource.com/c/go/+/232862/
自己在代码里解决:
https://github.com/rfjakob/gocryptfs/commit/25f1727de9e5681a5ceefe1516a5a01fa4ca624a
https://github.com/golang/go/issues/40846
https://github.com/golang/go/issues/38033
https://github.com/rclone/rclone/issues/5163
There have been various reports of rclone (and the go runtime) not working well with samba/cifs.
There was a workaround added to go1.16 which is probably helping you here, so if I had to guess, that is what is helping.
Possibly this issue golang/go#38836 or this one golang/go#39237
https://github.com/golang/go/issues/38836
Thanks for the info. It's the use of CIFS that causes this. I think the only fix is to fix #20400.
That sucks. This is happening in the context of ioutil.ReadFile(), but I should assume it will happen regardless of the method?
Yes, it can happen in general.
For 1.14 you can make the problem less likely to occur by setting GODEBUG=asyncpreemptoff=1 in the environment. But it can still happen if your process receives a signal
The handler did set SA_RESTART. What happened here is that reading from CIFS didn't honor it. At least, that is my assumption, since CIFS is a networked file system.
https://github.com/golang/go/issues/39237
Change https://golang.org/cl/236997 mentions this issue: os: always check for EINTR in calls to open
I'm going to add a check for EINTR in calls to open. I think that should fix the problem with Go.
Quite right, sorry, it will only fix the problem with os.Open. I don't know what to do with the readdirent problem, but it sounds like that is a kernel bug, and not something we can avoid in Go. So I'm going to close this issue now. Please comment if you disagree
https://forum.rclone.org/t/seeing-failed-to-read-directory-entry-readdirent-no-such-file-or-directory-with-v1-52-2/17816/26
Yes it looks like that go1.15 doesn't quite fix the issue. I suspect there is a kernel bug in there too, but if the workaround works for you that is a result
Rclone users have been having the same problem (see forum)
Using go1.15rc1 appears to fix the EINTR errors but does not fix the ENOENT errors.
Using export GODEBUG=asyncpreemptoff=1 does fix the problem completely.
So I guess CIFS is incorrectly returning ENOENT instead of EINTR on receipt of a signal?
@rfjakob did you get anywhere with trying to report this to the CIFS developers or upstream? I don't see any replies to your message.
浙公网安备 33010602011771号