如果用户使用动态链接的应用程序,并且系统正在升级,是否有任何保护机制可以防止应用程序损坏?
还是要看申请情况?
答案1
正如@Kusalananda 所提到的,通常升级是通过删除旧文件并创建一个同名的新文件来完成的。这实际上会创建一个带有新 inode 的新文件,只要旧文件打开,系统就可以自由使用它。
作为一个简化的例子,像这样的东西
rm /bin/cat
cp /new/version/of/cat /bin/cat
将创建一个逻辑上的新文件,并且即使cat
可能正在运行也可以工作。图书馆也是如此。(以上是一个示例,并不是现实世界中升级文件的可靠方法。)
有人可以尝试就地更改二进制文件,而不是创建一个具有相同名称的新二进制文件。在这种情况下,至少 Linux 实际上会阻止对正在使用的可执行文件进行更改:
window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy
但是,这似乎不适用于动态加载的库......
我复制了一份libc.so.6
用于测试,并在使用时用零填充:
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
linux-vdso.so.1 (0x00007ffcfaf30000)
libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo
Segmentation fault
(同时在另一个窗口中,在 之后foo
,段错误之前)
window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000
程序本身对此无能为力,因为我实际上在线编辑了它的代码。
(这可能取决于系统,我在 Debian Jessie 8.5、Linux 3.16.7-ckt25-2+deb8u3 上进行了测试。特别是 IIRC Windows 系统在防止正在使用的文件被修改方面更加积极。)
所以我想答案是升级通常是通过避免任何问题的方式完成的,这得益于文件系统内部结构。但是(在 Linux 上)似乎没有任何措施来防止实际损坏动态库。
答案2
如果文件在打开状态下取消链接,则不会“正确删除”文件。当它们关闭时,它们使用的磁盘空间将再次被视为“空闲”。这也适用于当前正在运行的应用程序及其共享库。
我看到的唯一失败的情况是,如果程序用于dlopen()
按需加载共享库,或者程序必须按需访问其他文件,例如字典、主题文件或突然消失的其他文件。
举例说明:vim
在一个 shell 会话中运行,同时删除另一个 shell 会话中的安装vim
不会“损坏”或终止当前正在运行的vim
会话。但有些事情会开始失败,例如拼写检查,这需要vim
在安装中打开文件。