这不是一个编程问题。我们有一个用c ++编写的大型系统,在Redhat Enterprise Linux上使用许多共享对象(.so)和本机可执行文件。系统在多个主机上运行,我们使用rsync来保存已部署的二进制文件(共享对象和可执行文件)
如果我们必须修复.so(或可执行文件)中的错误,我们会将其部署到一个位置,然后在所有其他主机上进行rsync
在使用(或运行)时覆盖.so(或可执行文件)是否安全?我读过rm
&由于* nix如何处理cp
(某种引用计数),inode
是安全的。但就rsync
答案 0 :(得分:3)
如果您不使用--in-place
,则在单个文件中完全安全。
对于多个相互依赖的文件来说,它几乎是安全的,但是使用--delay-updates
会有一些风险最小化。
默认(即,不使用--in-place
时),rsync
实际上会在新文件中创建内容,以临时名称命名(类似{{ 1}}),然后在完成时将其重命名为原始文件。
此重命名是一个完全原子操作:尝试打开文件的任何内容都将获取原始文件或替换(在替换完全完成后)。
此外,如果正在使用原始文件,那么即使指向它的目录条目被指向不同inode的新条目覆盖,其引用计数也将非零,因此内容将保留在磁盘上(未删除)直到原始文件不再打开。
但是,对于多个文件,您可能会冒一些风险,即只会原子地替换其中一些文件。如果您正在复制新的.__your_file
和foo
,那么旧的libfoo.so
将无法使用新的foo
和新的libfoo.so
{1}}无法使用旧的foo
,如果您在新的libfoo.so
{libfoo.so
之后尝试启动可执行文件,那么情况会很糟糕{1}}已到位,但rename()
还没有。
rsync可用的修复程序最接近的是foo
选项,它会等到 --delay-updates
和.__foo
完成然后将它们重命名为彼此。仍然没有操作系统级保证您无法看到一个文件的更新版本而不能看到另一个文件的更新版本,但是可以发生这种情况的时间窗口要小得多。
如果使用.__libfoo.so
,则操作系统将因文件正在使用而拒绝写入权限(不对UNIX上的所有访问强制执行,但具体使用{{1强制执行) ,用于可执行文件和共享库);这将是一个"文本文件繁忙"错误。如果您的操作系统没有强制执行此操作,则--in-place
用于提供反映文件内容的内存区域(通常是加载共享库的方式)的任何情况都会导致Bad Things发生在就地覆盖的事件。