DNF 系统升级

dnf-plugin-system-upgradeDNF 包管理程序的插件。它可用于将您的系统升级到最新的 Fedora 版本。Fedora Silverblue 和 Fedora CoreOS 使用 rpm-ostree,相关方法请参考 rpm-ostree 文档

这是推荐的命令行升级方法。过程如下:

  1. 系统正常运行期间下载软件包

  2. 系统重启进入特殊环境(作为 systemd target 执行)开始安装下载的软件包

  3. 完成后,系统再次重启进入新版 Fedora

系统升级

任何系统升级都存在一定风险,因此在进行系统级别的升级前一定要 备份您的数据 。 作为预防措施,可预先下载 Fedora Workstation Live 镜像 以防出现问题。

  1. 从命令行升级,可执行:

    sudo dnf upgrade --refresh

    然后重启计算机。

    重要事宜: 不要跳过此步骤。系统更新需要获取新版本的签名密钥,有了这些签名密钥通常可解决不少升级相关的问题。

  2. 如果还没有安装,请先安装 dnf-plugin-system-upgrade:

    sudo dnf install dnf-plugin-system-upgrade
  3. 下载要更新的软件包:

    sudo dnf system-upgrade download --releasever=35

    可将 --releasever= 后面的数字修改成您需要升级到的 Fedora 版本号。多数人都要升级到最新的稳定版本,也就是 35,当然有时您运行的版本比 34 还要早,这时您可能要升级到 34。经测试,系统升级仅正式支持最多跨两个版本的升级(比如从 3335)。如果您需要跨多个版本进行升级,建议将升级过程分成几次完成。(了解更多)。

    您还可以使用 36 将系统升级到 Branched,或者使用 rawhide 将系统升级到 Rawhide。要注意,这两种版本都不是稳定版。有关这两个版本的升级过程及常见问题请阅读前面链接中相应的章节。

  4. 如果您的软件包存在未解决的依赖关系,升级过程将不会继续,您需要再次运行升级命令,并加上 --allowerasing 选项来解决此问题。这种问题一般是因为从第三方软件源安装了软件包,但第三方软件源没有及时发布最新版的软件仓库造成的。仔细检查 dnf 升级时的输出,来确定哪些软件包可以移除。这些软件包通常不会对系统功能造成影响,但某些可能对您的生产环境极为重要。

    • 对于未解决的依赖关系,您还可以通过给命令加上 --best 选项查看更多详细信息。

    • 在再次运行 dnf system-upgrade download 前,如果您需要手动移除或安装某些软件包,建议您给 dnf 命令加上 --setopt=keepcache=1 选项。否则在操作后整个下载的软件包缓存都会被删除,那样只能重新把所有软件包再下载一遍。

  5. 开启升级过程。这会将计算机重启(重启会立即进行!没有确认提示也没有倒计时。因此在开启升级过程前一定关闭其他程序并保存您当前的工作内容)至运行于终端的升级过程中。

    sudo dnf system-upgrade reboot
  6. 升级过程完成后,计算机会再次重启进入升级后的 Fedora 系统。

选做的升级后任务

成功升级后您还可以做一些升级后任务。

这一节主要面向高级用户。如果您平时不怎么接触终端窗口,则可以跳过本节内容。

更新系统配置文件

多数配置文件保存在 /etc 目录下。如果您修改过软件包的配置文件,RPM 会创建以 .rpmnew 结尾的新配置文件,或者将您修改的配置文件备份为 .rpmsave 结尾的文件。您可以直接搜索这些文件,也可以用 rpmconf 工具简化您的操作。要安装 rpmconf,请执行:

sudo dnf install rpmconf

安装完成后执行:

sudo rpmconf -a

某些第三方软件会把编辑后的配置文件放到 `/etc/yun.repos.d/ `下面,将这些文件恢复到初始版本可能导致无法升级该软件。请牢记要仔细核验此目录下的配置文件。

更多信息可查看命令手册(man rpmconf)。

升级后的软件包配置

如果您使用 rpmconf 将系统配置文件升级为软件包自带的配置文件,那么某些配置可能会出现变化。升级完成后,您应该验证 /etc/ssh/sshd_config/etc/nsswitch.conf/etc/ntp.conf 及其他配置文件是否符合您的预期要求。比如 OpenSSH 升级后,sshd_config 会恢复到软件包的默认配置值。默认配置中 不会 启用公钥验证,且允许密码验证。

清理旧软件包

通过以下命令您可查看依赖关系出现问题的软件包列表:

sudo dnf repoquery --unsatisfied

列表应该是空的,但如果列出了依赖关系出问题的软件包,则可以考虑删除它们,因为它们很有可能无法正常工作了。

您还可以用以下命令查看重复安装的软件包(同一个软件包安装了多个版本):

sudo dnf repoquery --duplicates

Run sudo dnf update first, as this list is only valid if you have a fully updated system. Otherwise, you will see a list of installed packages that are no longer in the repositories because an update is available. This list may also contain packages installed from third-party repositories who may not have updated their repositories.

官方源的软件包应该安装最新版本。但系统中的有些软件包可能已不会在源中提供。要列出这些软件包,可执行:

sudo dnf list extras

如果看到有您不需要的软件包,可执行如下命令将其删除:

sudo dnf remove $(sudo dnf repoquery --extras --exclude=kernel,kernel-\*)

不再使用的软件包可以放心的删除,命令是:

sudo dnf autoremove

对一个软件包来说,如果您没有明确要求进行安装,并且也没有其它软件包依赖它,DNF 就会认为这个软件包不再需要。但这并不代表这个软件包没有用或者您不会用到它。仅删除您确定不再需要的软件包

清除旧内核

在您引导至最新的内核并且系统一切正常后,您可以删掉之前的内核。为了避免意外删除,即使执行 dnf autoremove 后,旧内核也会保留。

一个比较简单的删除旧内核的办法是使用一段脚本进行。以下的脚本会在 Fedora 每次更新后执行,而且不依赖于系统升级。

#!/usr/bin/env bash

old_kernels=($(dnf repoquery --installonly --latest-limit=-1 -q))
if [ "${#old_kernels[@]}" -eq 0 ]; then
    echo "No old kernels found"
    exit 0
fi

if ! dnf remove "${old_kernels[@]}"; then
    echo "Failed to remove old kernels"
    exit 1
fi

echo "Removed old kernels"
exit 0

升级后文件系统中可能会有一些零散失效的符号链接。安装 symlinks 工具可以清理并删除这些旧链接。

sudo dnf install symlinks

工具安装好后,您可从类似下方显示的结果中检查无效的符号链接。-r 表示递归。

sudo symlinks -r /usr | grep dangling

在您确认完失效的符号链接后,可以将它们按如下方式删掉。-d 表示删除。

sudo symlinks -r -d /usr

解决升级后的问题

仅在升级后遇到问题时再执行这些步骤。

重建 RPM 数据库

当您使用 RPM/DNF 工具时,如果看到警告出现,那么可能是您的数据库受到了损坏。重建数据库可以帮您确认是否能够解决问题。操作前一定记得先备份 /var/lib/rpm/。重建命令为:

sudo rpm --rebuilddb

使用 distro-sync 解决依赖问题

系统升级工具默认会使用 dnf distro-sync。如果您的系统部分进行了升级或者遇到软件包依赖问题,可以尝试再次手动运行 distro-sync 看是否能解决问题。该操作会尝试将您安装的软件包版本与软件仓库中的保持一致,即使这样做会降级某些软件包:

sudo dnf distro-sync

您还可以使用 --allowerasing 选项,这可以删除那些依赖关系得不到解决的软件包。在执行删除前,一定要仔细核对将要删除的软件包。

sudo dnf distro-sync --allowerasing

用最新的 SELinux 策略重新标记文件

如果遇到有关 SELinux 策略的警告,这可能是某些文件的 SELinux 权限有错误。如果先前曾经禁用了 SELinux,那会有可能发生此类问题。要给系统重新标记 SELinux,可执行以下命令,然后重启:

sudo fixfiles -B onboot

由于要检查并修复系统中所有文件的 SELinux 权限标签,因此启动时间可能会比较长。

常见问题

如何上报有关升级的问题?

  1. 查看 常见错误,看看问题是不是已经上报过。

  2. 搜索 Bugzilla 查看已有错误报告

如果没有找到关于您遇到问题的报告,您可以从搜索页面提交一个新的报告。请按照 github repo 中的 README 的介绍或查看 man dnf.plugin.system-upgrade 的内容,完成 bug 报告。

如果升级后遇到的问题与某个软件包有关,可以直接针对此软件包提交 bug 报告。

DNF 系统升级是否会在升级过程中验证它运行或安装的软件包的有效性?

是的。新版 Fedora 的软件包签名密钥会发送到旧版本的 Fedora 系统上,以便让 DNF 验证所下载软件包的完整性。如果有必要,您可以禁用此功能,但这样做会让您面临恶意软件攻击的威胁。

第三方源中的软件包会升级吗?

是的,如果这些源像常规 DNF 源一样配置,并且版本号没有硬编码到软件源文件(通常位于 /etc/yum.repos.d/)中的话。像 RPM Fusion 这样常用的第三方源,是可以正常升级的。但是,如果是在 Fedora 新版本正式发布前或者刚发布后很短的时间内尝试升级的话,由于第三方源可能还没有更新它们的软件源路径,DNF 可能无法找到要升级的软件包。通常情况下,这并不会妨碍升级的成功运行。此外您也可以稍后更新第三方软件包。

可以从结束支持 (EOL) 的版本升级吗?

强烈建议将生产环境或处于公用网络上的 EOL 系统进行升级。

从 Fedora 20 或更早的版本进行升级所带来的风险需要您自行斟酌,因为 DNF 并不是这些版本中默认的包管理工具。如果您的系统已进入 EOL,但它是 Fedora 20 之后的版本,您也可以尝试进行升级,虽然这种方式*不被支持*。您可能要陆续一步一步地先升级到中间版本,直到最后升级到当前受支持的版本。或者可以尝试直接一步升级到当前受支持的版本,当然这样也是不受支持的,其*风险需要您自行承担*。

可以一次跨多个版本升级吗(比如 30→34)?

升级到相邻的下一个版本(如 3435))或者隔一个版本升级(比如 3335 )都是支持的。不过还是强烈建议您在系统版本结束支持(EOL)前进行升级操作。如果您运行的版本是 N,那么它大概会在 N+2 版本发布后一个月左右结束支持。The Fedora Release Life Cycle is specifically designed to provide this approximate one month "grace period" to allow users the choice to upgrade their systems on a yearly basis, i.e. once every two releases. You can study Releases to see the current release status and schedule. Around a month after the new release comes out, the last-but-one release becomes End of Life (EOL). The upgrade is likely to work successfully after the release goes EOL, but the time period after the new release may be uncertain.

*不支持*跨两个以上版本的升级,因此出现的问题不会看作是严重 bug。

要进行跨两个以上版本的升级时,您需要导入要升级版本的 GPG 密钥。做法如下:

sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-N-primary

N 代表 Fedora 版本号。)

我可以用 DNF 系统升级功能将系统升级到预发布版本吗(比如 Beta 版)?

可以,但会像预发布版本其它组件一样,可能会出现暂时的功能失效。