【问题标题】:Why does rename() return false despite moving a file successully to an NFS mounted disk?尽管将文件成功移动到 NFS 挂载的磁盘,为什么 rename() 返回 false?
【发布时间】:2013-11-22 13:31:58
【问题描述】:

将文件从本地磁盘移动到 NFS 挂载磁盘时,我收到 Invalid argument 警告。尽管出现错误消息,但文件已成功移动

Warning: rename(/tmp/image.jpg,/mnt/remote.server-disk1/image.jpg): Invalid argument

挂载的磁盘:

$ df
remote.server:/disk1 917G  269M  871G   1% /mnt/remote.server-disk1

远程服务器上导出的磁盘:

$ cat /etc/exports
/disk1 remote.server(rw,sync,root_squash,secure,crossmnt,anonuid=504,anongid=504)

rename()之前本地磁盘上的文件:

$ stat /tmp/image.jpg
File: `image.jpg'
Size: 2105          Blocks: 8          IO Block: 4096   regular file
Device: 803h/2051d  Inode: 33556339    Links: 1
Access: (0777/-rwxrwxrwx)  Uid: (  501/  apache)   Gid: (  501/  apache)
...

rename() 后远程磁盘上的文件:

$ stat /disk1/image.jpg
File: `image.jpg'
Size: 2105          Blocks: 8          IO Block: 4096   regular file
Device: 821h/2081d  Inode: 34603214    Links: 1
Access: (0777/-rwxrwxrwx)  Uid: (  501/  apache)   Gid: (  501/  apache)
...

有什么想法吗? 谢谢

【问题讨论】:

    标签: php linux rename file-permissions nfs


    【解决方案1】:

    也许是因为你这样做没有引号

    rename(/tmp/image.jpg,/mnt/remote.server-disk1/image.jpg);

    尝试添加引号

    rename('/tmp/image.jpg', '/mnt/remote.server-disk1/image.jpg');

    【讨论】:

    • 这就是 PHP 报告错误的方式。我在代码中使用源文件和目标文件的变量。
    【解决方案2】:

    我无法解决这个问题,但是 copy() 然后 unlink() 正常工作。

    【讨论】:

      【解决方案3】:

      Unix 中,您不能在文件系统之间重命名移动,而是必须 >将文件从一个源位置复制目标位置,然后删除源。这将解释您收到的错误消息。但是,似乎不清楚为什么它仍然采取行动。这可能与权限有关,或者 NFS 挂载的磁盘在本地缓存。

      【讨论】:

      • 我的情况 - 在 nfs 上使用 php rename(),同样的警告,返回 false - 文件没有移动,而是复制了;原件还在。在 rename() 之后,操作没有说明本地磁盘上的文件。 php 发出警告而不是错误并返回 false 是有意义的,因为它没有完全成功。
      【解决方案4】:

      可能有点晚了,但我认为答案可能是因为与目标文件系统相关的权限。

      我们遇到了同样的问题,并且 strace 给了我们正确的诊断:

      strace php -r "rename('SOURCE_FILE', 'DST_FILE');";
      ...
      chown("SOURCE_FILE", 0, 0) = -1 EINVAL (Invalid argument)                                                                                                                                                       
      write(2, "PHP Warning:  rename(SOURCE_FILE"..., 192PHP Warning:  rename(SOURCE_FILE): Invalid argument in Command line code on line 1
      ) = 192
      write(1, "bool(false)\n", 12bool(false)
      

      在我们的例子中,目标文件系统是一个版本为 4 的 NFS,并启用了 idmap。

      即使是简单的

      chown $(whoami) $DST_FILE
      

      没有工作。

      使用 nfs-common utils 启用 idmap 是默认行为(至少在 debian 下)。 因此,即使您通过使用复制 + 取消链接来修复它(顺便说一句,这是最好的方法),它仍然可能隐藏您的底层文件系统中的问题。

      (禁用 idmap :https://forums.aws.amazon.com/thread.jspa?threadID=235501

      【讨论】:

        猜你喜欢
        • 2020-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-12
        • 1970-01-01
        • 2018-11-15
        • 2021-07-03
        • 2019-08-28
        相关资源
        最近更新 更多