MaaAssistantArknights / maa-cli

MAA命令行工具 | A simple CLI for MAA.
GNU Affero General Public License v3.0
39 stars 8 forks source link

把maa-core安装在nfs挂载点中的时候,remove_dir_all可能会失败,导致无法正常升级 #319

Closed starrin closed 1 month ago

starrin commented 1 month ago

由于我用来运行maa-cli的云服务器的硬盘空间有限,我把maa-climaa-core都放到了一个nfs文件系统中,今天检查服务器日志发现服务器在定时执行maa update时发生了报错

9月 06 14:00:32 systemd[1]: Started maa.service - Run maa.
9月 06 14:00:32 bash[54811]: maa-cli update
9月 06 14:04:46 bash[54844]: Fetching MaaCore version info (channel: stable)...
9月 06 14:04:46 bash[54844]: Found newer MaaCore version: v5.6.0 (current: v5.5.11452)
9月 06 14:04:46 bash[54844]: Downloading MaaCore 5.6.0...
9月 06 14:04:46 bash[54844]: Testing download speed...
9月 06 14:05:06 bash[54844]: Downloading from fastest mirror...
9月 06 14:07:09 bash[54844]: Installing MaaCore...
9月 06 14:07:09 bash[54844]: Error: Directory not empty (os error 39)
9月 06 14:07:09 systemd[1]: maa.service: Deactivated successfully.
9月 06 14:07:09 systemd[1]: maa.service: Consumed 1.552s CPU time.

再次尝试执行maa update也无法进行(提示MaaCore无法加载),只能执行maa install,应该是第一次执行失败时remove_dir_all实际上已经清空了library文件夹导致的

$ sudo -u maa-worker ./maa-run.sh update
Fetching MaaCore version info (channel: stable)...
Error: Failed to load MaaCore!

Caused by:
    libMaaCore.so: cannot open shared object file: No such file or directory
$ sudo -u maa-worker ./maa-run.sh install
Fetching MaaCore version info (channel: stable)...
Downloading MaaCore 5.6.0...
Already downloaded, skip downloading
Installing MaaCore...
Extracting archive file...
Done!
Already up to date.

在网上也能搜索到少量类似反馈,有rust的,也有pythonshutil的,我怀疑是linux中的nfs客户端有缺陷,在递归删除文件夹中的文件时有延迟导致会概率发生这个问题 类似的问题在我这里已经不是第一次出现了,还好这次我及时发现了,不然晚点基建又得崩😭 根据这个问题的表现,感觉maa-cli在实现ensure_clean方法时进行一次重试就能规避这个bug,不知道是否方便

wangl-cc commented 1 month ago

我想了一下,可以把 Core 和资源安装在一个临时的目录,在确保安装完成之后,把原本的文件移动到里临时位置并把安装新的文件移到目标目录,最后再自信删除操作,确保不会安装或者删除失败导致 Core 直接没有了。不过我不确定把这个临时的文件夹在哪里比较合适,如果临时目录和目标目录不在同一个文件系统里会导致性能问题,同时跨文件系统移动可能也会导致删除失败问题。当然,最好的方法是避免把原本的目录清空,而是通过类似 https://github.com/MaaAssistantArknights/MaaRelease/issues/146 方式来进行增量更新,避免进行清空文件夹操作,毕竟资源文件真的很多。但是目前就多尝试几次来解决这个问题吧。

starrin commented 1 month ago

我想了一下,可以把 Core 和资源安装在一个临时的目录,在确保安装完成之后,把原本的文件移动到里临时位置并把安装新的文件移到目标目录,最后再自信删除操作,确保不会安装或者删除失败导致 Core 直接没有了。不过我不确定把这个临时的文件夹在哪里比较合适,如果临时目录和目标目录不在同一个文件系统里会导致性能问题,同时跨文件系统移动可能也会导致删除失败问题。当然,最好的方法是避免把原本的目录清空,而是通过类似 MaaAssistantArknights/MaaRelease#146 方式来进行增量更新,避免进行清空文件夹操作,毕竟资源文件真的很多。但是目前就多尝试几次来解决这个问题吧。

方不方便在重试之前加个短一点的延时?0.1s或者0.2s左右的应该就可以,感觉这样基本上就能规避nfs文件系统的问题了