我刚刚将我的 ubuntu lucid 升级到 natty,升级过程中它用较新版本替换了大多数正在运行的应用程序。
这是如何工作的?(应用程序不会崩溃吗?)如果一个库文件升级了,而一个正在寻找旧库的正在运行的应用程序试图加载它,应用程序会发生什么?
答案1
Linux(和其他 UNIX)区分了姓名一个文件(关联)、文件本身(通常用索引节点),并打开文件的句柄。当你要删除文件时,你调用该unlink()
调用 - 这将删除关联指向该文件的句柄(也可以使用rename()
不同的 inode 覆盖它)。但是,如果打开指向该文件的句柄(或其他链接 - 文件可以有多个硬链接)保持不变,索引节点它会保留下来,文件内容也会保留下来,直到所有链接和句柄都消失。
因此,使用库或其他任何方式运行的程序都会保留对旧版本的句柄(通常通过内存映射隐式实现),因此它会保留在磁盘上。它只是不再有文件名,并且会在使用它的所有程序关闭时(或在下次重新启动时、在文件系统检查或日志重放期间)被清除。
此外,请注意,期望使用“旧库”的程序将与较新版本的库配合使用。Linux 库被分配一个文件名(“soname”),该文件名反映了库提供的 ABI(应用程序二进制接口)的版本。例如,我的系统上的 C 库是libc.so.6
。任何针对旧版本 libc 编译的程序,但仍然是实现版本 6 ABI 的 libc 版本,都可以很好地使用它。非常旧的程序将查找libc.so.5
或libc.so.4
或某些东西;在这种情况下,您还需要保留旧版本 - 但由于文件名不同,所以这不是问题。
答案2
与 Windows 不同的是,您能删除或替换打开的文件;给出简化解释,对文件的新请求将打开新文件,现有句柄将使用创建时存在的文件。换句话说,在 Linux 中,您可以拥有仍然存在的文件/文件版本,尽管目录结构中不再有指向它们的指针;那些文件/文件版本不再存在,根本没有指向它们的指针(已关闭等)。
通常,正在运行的应用程序会预先加载所需的库,因此您描述的问题只会在安装包时的非常特定的时间情况下发生:正在运行的应用程序仍在使用旧版本的库,而新启动的应用程序使用新版本的库。
这不仅用于发行版升级,而且发生在每个软件包升级上(dist-upgrade 只是为该过程添加了几个自动化步骤)。
答案3
许多 Linux 进程在升级其来源软件包后仍可继续运行 - 但有些则不行。根据我的经验,如果在 KDE 运行时对其进行升级,则 KDE 永远无法正常工作。您可能会遇到崩溃和/或无法注销的情况。