Linux 如何升级正在使用的软件包?

Linux 如何升级正在使用的软件包?

我正在使用Arch Linux,例如,我可以在上网时进行系统升级。如果程序本身正在使用,如何升级浏览器软件包?或者例如内核?是否需要停止可执行文件才能替换为新的可执行文件?或者下次重启时会发生这种情况吗?

答案1

光盘上的浏览器文件刚刚被替换。正在运行的程序(如果不完全在内存中)使旧的可执行文件保持打开状态,直到程序关闭(但在此之前,这些文件不再是您通过目录条目获取的可执行文件)。下次重新启动浏览器时,您将获得该版本。

除了在重新启动时加载的程序(即内核)之外,无需重新启动。 有些程序可以对内核进行适当的修补,甚至不需要重新启动,但这不是同一回事。

答案2

正如您所怀疑的,类 Unix 系统可以防止大多数正在执行的文件被覆盖。以下是该标准的相关内容:打开系统调用:

如果出现以下情况,open() 函数可能会失败:

[ETXTBSY] 该文件是正在执行的纯过程(共享文本)文件,oflag 为 O_WRONLY 或 O_RDWR。

但正在执行的文件仍然可以未链接的,这就是包管理器的工作方式。

以下是在 Debian 和 Ubuntu 上安装刚刚发布的dpkg新版本时所做的操作:/bin/cpio

open("/bin/cpio.dpkg-new", O_WRONLY|O_CREAT|O_EXCL, 0) = 10
// lots of reads and writes omitted from this listing.
// It's copying the new version into dpkg-new
fchown(10, 0, 0)                  = 0 
fchmod(10, 0755)                  = 0 
close(10)                         = 0 
rename("/bin/cpio.dpkg-new", "/bin/cpio") = 0 

详细来说,这个:

  • 将新版本复制到cpio.dpkg-new与 相同的目录中cpio
  • 将所有者和文件权限设置为包规定的任何内容
  • 重命名cpio.dpkg-newcpio

安全地安装文件的新版本而不会处于文件不存在的位置(即使是瞬间)的方法是使用改名系统调用。这要求两个文件位于同一文件系统中,这就是 dpkg 在与旧版本相同的目录中创建新版本 cpio 的原因。标准说:

int 重命名(const char *旧, const char *新);

rename() 函数应更改文件的名称。 old 参数指向要重命名的文件的路径名。新参数指向文件的新路径名。

如果新参数命名的链接存在,则应将其删除并将旧的重命名为新的。在这种情况下,在整个重命名操作过程中,名为 new 的链接应对其他进程保持可见,并引用操作开始之前 new 或 old 引用的文件。

该术语可能有点令人困惑,因为老的新的rename这里的文件是新版本cpiocpio 的旧版本, 分别。

最后,这是回答你问题的关键:

如果新参数指定的链接存在,并且当文件被删除时,文件的链接计数变为 0,并且没有进程打开该文件,则该文件占用的空间将被释放,并且该文件将不再可访问。如果一个或多个进程在删除最后一个链接时打开了该文件,则应在 rename() 返回之前删除该链接,但文件内容的删除应推迟到对该文件的所有引用都关闭为止。

最后一句意味着,如果任何进程在完成cpio时打开(或正在运行)rename,它们将继续查看文件以前的内容,直到关闭文件(或退出)。

Archpacman似乎做了大致相同的事情:

snprintf(checkfile, len, "%s.paccheck", filename);
...
if(perform_extraction(handle, archive, entry, checkfile, entryname_orig)) {
    errors++;
    goto needbackup_cleanup;
}
...
if(try_rename(handle, checkfile, filename)) {
    errors++;
}

尽管包管理器努力安全地安装新文件,但在使用过程中更新程序时可能会出现一些问题。例如,firefox 软件包有十多个可执行文件和共享对象。在更新期间运行旧版本 Firefox 的用户可能会发现他们在更新完成后调用的扩展与旧版本 Firefox 不兼容。我最近在Ubuntu上更新了firefox,apt-get打印出:

请重新启动所有正在运行的 Firefox 实例,否则您将遇到问题。

如果您是多用户系统的系统管理员,最好向用户社区宣布待处理的更新。

相关内容