将 maildir 网络共享 (CIFS) 迁移到新的存储服务器后,我开始遇到文件权限问题(用户无法删除旧邮件)。我的 IMAP 服务是 Dovecot,但我们可以在比该服务更低的级别上识别问题。
因为root
我可以导航到托管文件的服务器和安装文件的服务器(以下称为“客户端”)上显示此问题的邮件目录,并体验/观察以下行为:
ls
在两台计算机上显示相同的文件列表和权限。- 自迁移以来权限并不完全匹配,但权限更改不会影响行为。 (以后的所有操作都是针对具有权限的文件执行的
-rw-rw---- 1 mail mail
。) - 执行 as 操作
mail
代替root
not 也没有效果。 尝试更改权限,例如
chmod g-rw *
:- 在服务器上工作正常
- 在客户端上对于迁移后创建的文件运行良好
客户端上的预迁移文件会产生此错误:
chmod:更改“1479603582.M874812P11259.Pantheon,S = 84750,W = 85933:2,Sa”的权限:参数无效
- 尝试读取文件:
- 在服务器上工作正常
- 在客户端文件名自动完成和 vim 报告上
Permission Denied
寻找可能影响旧文件的任何 ACL,我在服务器上得到以下输出:
root@<storage-server>:/<path-to-share>/<site>/<user>/folders/cur# getfacl <filename>
# file: <filename>
# owner: mail
# group: mail
user::rw-
group::rw-
other::---
getfattr
什么也不输出。
存储服务器以前是一个基于 Solaris+debian 的废弃软件操作系统 (Nexenta),在 ZFS 存储池上使用 CIFS 服务。现在是 Ubuntu 16.04,再次在 ZFS 存储池上使用 CIFS 服务。在所有情况下,ACL 均受支持但未在任何地方使用。
我的 Samba 共享配置:
[Maildir]
path = /<path-to-share>
browseable = no
guest ok = no
valid users = mail
writable = yes
create mode = 0660
directory mode = 0770
其安装为//<host>/Maildir /var/mail cifs auto,credentials=/root/.smb_mail,user,rw,exec 0 0
.该文件系统及其父系统的所有 zfs 属性均采用默认值。
我尝试删除创建模式/目录模式,并将@mail添加到有效用户,但都没有效果。
我的权限怎么可能出错?
更新:
我尝试切换到 NFS 共享,问题仍然存在。我尝试使用 和 将 maildir 内容复制到新位置(在不同的新文件系统中) ,cp -r
并且chown -r mail:mail
它仍然存在,同时从完全不同的路径提供服务。
最后,我尝试了mv somefile backup && rm somefile && cat backup > somefile && chown mail:mail somefile
,尝试读取该文件仍然失败,权限被拒绝。
我不知道如何以独立于共享机制、逻辑位置、unix 权限/所有权、甚至任何形式的文件元数据的方式阻止对特定文件的操作。
更新2:
我再次尝试切换到 NFS 共享,这次权限问题消失了。但是我不想切换到 NFS,因为它会导致其他问题,特别是启动问题。问题肯定出在 samba 上,但是清除所有操作数据(各种 .tdb 和 .dat 文件等)也没有帮助。
更新3:
问题已缩小到包含冒号的文件名。重命名文件以删除冒号会使其在客户端中可读,而使用冒号重命名为任意原始名称会使其不可读。随着时间的推移,Dovecot 似乎正在重命名文件以跟踪某些信息,并添加一个冒号,最终使所有邮件不可读/不可写,但以前也会出现这种情况。
一些额外的观察结果:在客户端上创建并读取带有冒号的文件是可行的(并且冒号在服务器上显示为双引号)。顺便说一句,这就是我们首先获取带有冒号的文件名的方式...较新的文件似乎有 2 个冒号,但在服务器上显示为有一个双引号和一个冒号。
它开始看起来像是某种编码问题 - 特别奇怪,因为这两个系统第一次是同质的。
答案1
Samba 不允许在文件名中使用冒号,并使用字符重新映射(到引号)以可能对 Windows 友好的方式支持它们。在某些时候,对此的处理是不同的,导致服务器端的文件名中出现实际的冒号。那,或者我可能在某个时候实际上已经通过共享复制了文件。 (不太可能,因为在过渡期间一切都是通过 zfs 增量发送来维护的。)此外,当使用 NFS 服务器时,Dovecot 开始应用重命名,这也会破坏 Samba 的更新内容。
由于冒号是嵌入在文件名中的一次性元数据的一部分,如果不正确,则会重新生成,因此我使用脚本从共享中删除所有真正的冒号:find "$@" -name '*:*' -exec rename 's/://g' {} +
。
(我尝试更聪明一点,但文件名只是出现用双引号代替冒号,并且计算出精确的翻译对于努力来说价值微乎其微,尤其是在 12 个小时的头撞之后。)
此后,所有文件再次可读,唯一真正的数据丢失是必须将一堆电子邮件标记为再次读取。我只希望这个修复是一次性的。