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.

posted @ 2022-01-27 21:31  mmgithub123  阅读(238)  评论(0)    收藏  举报