Sam*_*Sam 20 filesystems upgrade dynamic-linking files
这里它说你可以重写一个可执行文件,这个进程会运行得很好——当一个进程重新启动时它会被重新读取。
但是,当我尝试在进程运行时替换二进制文件(使用 scp,从开发到测试服务器)时,它显示“文件繁忙”。如果我替换共享库文件 (*.so),链接它的所有进程都会崩溃。
为什么这样?我错过了什么吗?如何在不停止/崩溃进程的情况下替换二进制文件?
pet*_*rph 22
正如为什么软件包在升级时运行良好?,锁定放在 inode 上而不是文件名上。当您加载并执行二进制文件时,该文件被标记为忙碌 - 这就是为什么您在尝试写入文件时会收到 ETXTBSY(文件忙碌)错误的原因。
现在,对于共享库,它略有不同:库将内存映射到进程的地址空间mmap()。尽管MAP_DENYWRITE可能会被指定,但至少 Linux 上的 Glibc 会默默地忽略它(根据手册页,请随意检查源代码)-检查此线程。因此,您实际上可以写入文件,并且由于它是内存映射的,因此几乎可以立即看到任何更改 - 这意味着如果您足够努力,您可以通过覆盖库来设法使 您的机器变砖。
因此,正确的更新方法是:
删除文件,从文件系统中删除对数据的引用,以便任何可能想要使用它的新生成的应用程序都无法访问它,同时保持数据可供任何已经打开(或映射)的人访问;
创建一个包含更新内容的新文件。
新创建的进程将使用更新的内容,运行的应用程序将访问旧版本。这是任何健全的包管理实用程序所做的。请注意,它并非完全没有任何危险 - 例如,dlsym()如果库的 API 静默更改,动态加载代码(使用和朋友)的应用程序将遇到麻烦。
如果您想真正安全,请关闭系统,从另一个操作系统实例挂载文件系统,更新并再次启动更新的系统。
rpm 升级也是如此——运行二进制文件和库,而没有任何崩溃。
那么区别是什么呢:
这不会就地替换文件:引用 in-use-binary 的 inode 仍然“忙碌”,直到最后一个打开它的对象完成。将使用新的 inode-number 创建新文件。
现在scp或cp将尝试就地替换文件 - 这将更改 inode 所指的内容。这不起作用 - 正如您所描述的。
| 归档时间: |
|
| 查看次数: |
10113 次 |
| 最近记录: |