问题描述
我刚刚将我的 ubuntu lucid 升级到 natty ,在升级过程中它用更新的版本替换了大多数正在运行的应用程序。
How does this work? (Won’t the applications crash?) What will happen to the application if a lib file got upgraded and a running application which is looking for a older lib tries to load it?
最佳回答
Linux(和其他 UNIX)区分文件名(链接)、文件本身(通常用 inode 标识)和文件的打开句柄。当你去删除一个文件时,你调用 unlink()
调用 – 这会删除文件的链接(你也可以使用 rename()
用不同的 inode 覆盖它)。但是,如果文件的打开句柄(或其他链接 – 文件可以有多个硬链接)保留,则 inode 保留,文件内容也保留,直到所有链接和句柄消失。
因此,使用库运行程序或任何保留旧版本句柄的程序(通常通过内存映射隐含),所以它保留在磁盘上。它只是不再有文件名,并且将在所有使用它的程序关闭时(或在下次重新启动时,在文件系统检查或日志重放期间)被清理。
此外,请注意,期望 ‘old library’ 的程序可以在较新版本的库中正常运行。 Linux 库被分配了一个文件名 (‘soname’),它反映了库提供的 ABI(应用程序二进制接口)的版本。例如,我系统上的 C 库是 libc.so.6
。任何针对旧版本 libc 编译的程序,但仍然是实现版本 6 ABI 的 libc 版本,都可以正常工作。真正的旧程序会寻找 libc.so.5
或 libc.so.4
或其他东西;在这种情况下,您还需要保留旧版本 – 但由于文件名不同,这不是问题。
次佳回答
与 Windows 不同,您可以删除或替换打开的文件;为了简化解释,对文件的新请求打开新文件,现有句柄使用创建时存在的文件。换句话说,在 Linux 中,您可以拥有仍然存在的文件/文件版本,尽管在目录结构中不再有指向它们的指针;那些不再存在,根本没有指向它们的指针(关闭和全部)。
通常正在运行的应用程序会预先加载所需的库,因此您描述的问题只会在安装包时非常特定的时间情况下发生:正在运行的应用程序仍在使用旧版本的库,新启动的应用程序使用新版本一。
这不仅用于发行版升级,而且在每次软件包升级时都会发生(dist-upgrade 只是在该过程中添加了几个自动步骤)。