第 4 章 从 Debian 9(stretch)升级

目录

4.1. 升级前的准备
4.1.1. 备份数据和配置文件
4.1.2. 提前告知用户
4.1.3. 准备服务停机
4.1.4. 准备故障恢复
4.1.5. 为升级准备安全环境
4.1.6. 验证网络接口名称支持
4.2. 检查 APT 配置状态
4.2.1. proposed-updates 区
4.2.2. 非官方源
4.2.3. 禁用 APT pinning
4.2.4. 检查包状态
4.3. 准备 APT source-list 文件
4.3.1. 添加互联网 APT 源
4.3.2. 添加本地镜像 APT 源
4.3.3. 从光学介质中添加 APT 源
4.4. 升级软件包
4.4.1. 记录会话
4.4.2. 更新软件包列表
4.4.3. 确保您有足够的空间升级
4.4.4. 最小系统升级
4.4.5. 升级系统
4.5. 升级期间可能遇到的问题
4.5.1. Dist-upgrade 失败,显示无法立即配置
4.5.2. 预期的删除
4.5.3. 冲突或预依赖循环
4.5.4. 文件冲突
4.5.5. 配置文件变化
4.5.6. 将会话切换到控制台
4.6. 升级内核与相关包
4.6.1. 安装内核元软件包
4.7. 为下个发布版本做准备
4.7.1. 清理已删除的软件包
4.8. 过时的软件包
4.8.1. 过渡哑包

4.1. 升级前的准备

我们建议您在升级前阅读第 5 章 buster 中需要注意的问题。它描述的潜在问题与升级过程没有直接联系,但您仍可能需要在开始前了解这些信息。

4.1.1. 备份数据和配置文件

在升级系统前,强烈建议您进行一次完整的备份,或者至少备份您不愿意丢失的数据和配置信息。升级工具和流程是非常可靠的,但升级过程中的硬件错误可能会对您的系统造成严重损害。

您需要备份的内容主要包括 /etc/var/lib/dpkg/var/lib/aptitude/pkgstates 下的文件,以及 dpkg --get-selections "*" 命令的输出(命令行中的引号必须要有)。如果您使用 aptitude 来管理系统上的软件包,您还需要备份 /var/lib/aptitude/pkgstates

升级过程本身不会修改 /home 下的任何内容。但某些程序(比如部分 Mozilla 套件,以及 GNOME 和 KDE 桌面环境)会在新版本的程序第一次启动时用新的默认值来覆盖现有的用户设置。做为一种预防措施,您也许想备份用户目录下的隐藏文件和目录(dotfiles)。该备份有助于您恢复或者重建原有设置。另外,您可能还需要把该事项通知给用户。

任何软件包安装操作都必须以超级用户权限执行,您可以以 root 身份登录,或使用 su 或者 sudo 来获取必要的访问权限。

升级需要几个前提条件,您应当在实际升级前检查它们。

4.1.2. 提前告知用户

提前通知所有用户您正在计划的任何升级将是明智的决定,虽然通过 ssh 连接访问您系统的用户可能在升级过程中不会注意到什么东西,而且应该可以继续正常工作。

如果您希望采取更多的预防措施,请在升级前备份或者卸载 /home 分区。

当升级到 buster 时您需要进行内核升级,所以将需要重启。一般说来,这将在升级完成后进行。

4.1.3. 准备服务停机

系统提供的服务可能与升级包含的软件包相关联。如果是这种情况,请注意,在升级期间,当相关软件包被更换和配置时,这些服务将被停止。在此期间,这些服务将无法使用。

这些服务的精确停机时间将根据系统中升级的软件包数量而有所不同,并且还要包括系统管理员在软件包升级过程中回答任何配置问题的时间。请注意,如果升级过程无人值守,并且系统在升级过程中请求输入,则很可能在很长时间内无法使用[1]服务。

如果正在升级的系统为您的用户或网络[2]提供关键服务,则可以使用最小系统升级减少停机时间,如第 4.4.4 节 “最小系统升级”所述,之后是内核升级和重新启动,然后升级与关键服务关联的软件包。在执行第 4.4.5 节 “升级系统”所描述的完整升级前升级这些软件包。这样,您可以确保这些关键服务在全面升级的过程中运行并可用,并减少其停机时间。

4.1.4. 准备故障恢复

尽管 Debian 尝试确保您的系统始终保持可引导,但您在升级后的重启过程中仍有可能遇到问题。发行说明的这一章和下一章都记录了已知的潜在问题。

因此,当您的系统重启失败(或对于远程管理系统来说,无法连接网络)时,请确保您能够将其恢复。

如果您通过 ssh 远程连接进行升级,则建议您采取必要的预防措施以便通过远程串口终端来访问该服务器。在升级内核并重新启动后,有可能您将不得不通过本地控制台修复系统配置。还有,如果系统在升级过程中意外重启您可能需要使用本地控制台进行修复。

通常我们建议使用 buster Debian 安装程序的救援模式进行应急恢复。使用安装程序的优点是,您可以从众多修复方式中选择最适合您情况的一种。有关详细信息,请参阅安装指南第 8 章中的修复损坏的系统Debian 安装程序常见问题

如果上述步骤失败了,您需要采取替代方案来启动您的系统以便访问和修复它。其中一种选择是使用特制的急救盘或者 Linux live CD。以这些介质引导后,您应该可以挂载您的根文件系统并 chroot 到它里面来检查并修复问题。

4.1.4.1. initrd 引导时使用调试环境

initramfs-tools 软件包在其生成的 initrd 中包含一个调试 shell[3]。如果出现问题,比如 initrd 无法挂载根文件系统,那么您将进入到此调试 shell 中,其具有一些基本命令可帮助您跟踪问题,并有机会修复它。

需要检查的几个基本项目:/dev 下是否存在正确的设备文件;加载了什么模块(cat /proc/modules);dmesg 的输出中有关驱动加载的错误信息。dmesg 的输出还会显示哪个设备文件被指定给哪个磁盘;您还应该将其与 echo $ROOT 的输出进行核对,以确保根文件系统在预想的设备上。

如果您确实修复了问题,输入 exit 会退出调试 shell,并从先前失败的地方继续启动进程。当然您还需要修复更深层次的问题,并重新生成 initrd,以使下次引导不再失败。

4.1.4.2. systemd 引导时使用调试 shell

如果在 systemd 下启动失败,可以通过更改内核命令行来获取调试性 root shell。如果基本的引导成功,但某些服务无法启动,则向内核参数添加 systemd.unit=rescue.target 可能会有用。

否则,内核参数 systemd.unit=emergency.target 将在最早可能的时机为您提供 root shell。但此时,根文件系统还未以读写权限挂载。您必须手动执行以下操作:

# mount -o remount,rw /
      

有关在 systemd 下调试启动故障的更多信息,请参见 Diagnosing Boot Problems 一文。

4.1.5. 为升级准备安全环境

[重要]重要

如果您正在使用某些虚拟专用网络(VPN)服务(例如 tinc),则该服务可能在整个升级过程中都不可用。请参阅第 4.1.3 节 “准备服务停机”

为了在远程升级时获得额外的可靠性保障,我们建议您在由 screen 程序生成的虚拟控制台中执行升级过程。它能帮助您可靠地重新连接机器,并确保即使远程连接暂时中断,升级过程也不会被打断。

4.1.6. 验证网络接口名称支持

从旧版本升级而来,且仍然在使用形如 eth0wlan0 的旧式网络接口名称的系统,在升级到 buster 后,网络连接可能会中断;请参考第 5.1.5 节 “从旧有网络接口名称进行迁移” 的信息以正确进行迁移。

4.2. 检查 APT 配置状态

本章中描述的升级过程是针对纯净的 Debian 稳定版系统的。如果您的 APT 配置加入了 stretch 之外的额外软件源,或者您安装了来自其他版本或第三方来源的软件包,那么为了确保升级过程可靠,您可能需要事先去除这些可能导致问题的因素。

APT 用于确定应从哪个源下载软件包的主要配置文件是 /etc/apt/sources.list,但它也可以使用 /etc/apt/sources.list.d/ 目录中的文件 - 详情见 sources.list(5)。 如果您的系统使用多个 source-list 文件,那么您需要确保它们保持一致。

下面有两种方法可以查找并非来自 Debian 的已安装软件包,使用 aptitude 或者 apt-forktracer。 请注意,它们都不是 100% 准确(例如,aptitude 示例将列出曾经由 Debian 提供但不再包含的软件包,例如旧的内核软件包)。

$ aptitude search '~i(!~ODebian)'
$ apt-forktracer | sort
  

不支持直接从旧于 Debian 9(stretch)的版本升级。请按照 Debian 9 发行说明中的步骤,先升级到 9。

此步骤也假定您的系统已经更新至 stretch 的最新小版本。如果您还未这么做或是不确定,请按照第 A.1 节 “升级您的 stretch 系统”中的步骤执行。

在继续升级之前,还应确保软件包数据库已准备就绪。如果您是 aptitudesynaptic 等其他软件包管理器的用户,请查看任何待处理的操作。如果一个软件包在包管理器中被计划安装或删除,它可能会干扰升级过程。请注意,仅当您的 APT source-list 文件仍指向 stretch 而不是 stablebuster; 时,才能更正此项,请参阅第 A.2 节 “检查您的 APT source-list 文件”

在升级前从您的系统中移除过时的软件包是一个好想法。

4.2.1. proposed-updates 区

如果您已经在 APT source-list 文件中添加了 proposed-updates 区,则应在尝试升级系统之前将其移除。 这是一种减少冲突可能性的预防措施。

4.2.2. 非官方源

如果您的系统上有任何非 Debian 软件包,您应该知道在升级过程中可能会因为依赖关系冲突而移除这些软件包。 如果这些软件包是通过在 APT source-list 文件中添加额外的软件源进行安装的,您应检查该软件源是否还提供了针对 buster 编译的软件包,并在更改 Debian 软件源的同时相应地更改这些软件源。

一些用户可能在他们的 stretch 系统中安装了 Debian 中已有的软件包的非官方的向后移植的更新版本。升级期间那样的包很有可能引起问题,因为它们可能会导致文件冲突[4]。如果确实发生冲突的话,第 4.5 节 “升级期间可能遇到的问题”有一些关于如何处理文件冲突的信息。

4.2.3. 禁用 APT pinning

如果您已经设置 APT 从一个非 stable(如 testing)版安装特定的软件包,您可能必须改变 APT pinning 设置(保存在 /etc/apt/preferences/etc/apt/preferences.d/ 中),以允许将软件包升级至新的 stable 中的版本。更多有关 APT pinning 的信息,请参阅 apt_preferences(5)

4.2.4. 检查包状态

不管用什么方法升级,我们都建议您先检查所有软件包的状态,并验证所有包都处于可升级状态。以下命令会显示任何半安装或是配置失败的包,还有那些有任何错误状态的包。

# dpkg --audit
    

您也可以用 aptitude 来检查系统中的所有软件包的状态,也可以使用如下命令

# dpkg -l | pager
    

或是

# dpkg --get-selections "*" > ~/curr-pkgs.txt
    

在升级前移除所有的 hold 状态是很有必要的。如果有任何对升级而言有重大影响的包处于 hold 状态,升级会失败。

注意 aptitude 使用一种与 apt 以及 dselect 不同的方法来注册 hold 状态的包。 您可以用以下命令来识别 aptitude 中处于 hold 状态的包

# aptitude search "~ahold" 
    

如果您想检查 apt 中哪些包设置了 hold 状态,您应当使用

# dpkg --get-selections | grep 'hold$'
    

如果您在本地更改并重新编译了一个包,且并未重命名它,或是在版本号中放入新的纪元号(epoch),您就必须将它设为 hold 状态,以防止它被升级。

apt 中的 hold 状态的包可以使用以下命令修改:

# echo 软件包名 hold | dpkg --set-selections
    

install 代替 hold 即可清除 hold 状态。

如果有任何需要修复的东西,最好确保您的 APT source-list 文件仍然指向 stretch,就像第 A.2 节 “检查您的 APT source-list 文件”中所解释的那样。

4.3. 准备 APT source-list 文件

在开始升级之前,您必须重新配置 APT 的 source-list 文件(/etc/apt/sources.list 以及 /etc/apt/sources.list.d/ 下的文件)。

APT 将考虑所有已配置的源中包含的所有软件包,并安装具有最高版本号的软件包,优先考虑文件中的第一个条目。 因此,如果您有多个镜像位置,请将本地硬盘放在第一位,然后是 CD-ROM,最后是远程镜像。

一个发行版通常既能通过它的代号(如:stretchbuster)引用,也可以用它的状态名引用(如:oldstablestabletestingunstable)。引用发行版的代号的好处在于,您绝对不会因为新版本的发布而感到惊讶,因此本文使用这种方法。当然,这也意味着您不得不自己关注新版的发行公告。如果转而使用状态名,一旦有新版发行,您将只会看到一堆可用的软件包的更新。

Debian 提供了两个公告邮件列表,以帮助您及时了解与 Debian 发布相关的信息:

4.3.1. 添加互联网 APT 源

在新版安装中,APT 默认使用 Debian APT CDN 服务,该服务确保软件包自动从网络上离您较近的一个服务器下载。由于这是一项相对较新的服务,旧版安装的配置可能仍然指向 Debian Internet 主服务器之一或其中一个镜像。如果您尚未这样做,建议在 APT 配置中切换为使用 CDN 服务。

要使用 CDN 服务,请在 APT 源配置中添加这样一行(假设您在使用 maincontrib):

deb http://deb.debian.org/debian buster main contrib

添加新源后,通过在以前存在的 deb 行前放置一个井号(#)来禁用它们。

不过,如果您通过使用在网络上更接近您的特定的镜像得到了更好的结果,您仍然可以继续这么做。

Debian 镜像地址可以在 https://www.debian.org/distrib/ftplist 找到(参见 list of Debian mirrors 一节)。

例如,假设离您最近的 Debian 镜像是 http://mirrors.kernel.org。 如果使用 Web 浏览器检查该镜像,您会注意到主目录的组织方式如下:

      http://mirrors.kernel.org/debian/dists/buster/main/binary-arm64/...
      http://mirrors.kernel.org/debian/dists/buster/contrib/binary-arm64/...
    

要使用给定的镜像配置 APT,请添加如下所示的一行(同样,假设您正在使用 main and contrib):

deb http://mirrors.kernel.org/debian buster main contrib

注意dists会隐式添加,而版本名称后的参数则用于将路径扩展到多个目录。

同样,添加新源后,禁用以前存在的软件源条目。

4.3.2. 添加本地镜像 APT 源

您可能希望修改 APT source-list 文件以使用本地磁盘上的镜像(可能挂载在 NFS 上),而不是使用远程软件包镜像。

例如,您的软件包镜像可能位于 /var/local/debian/ 下,并且具有如下的目录结构:

      /var/local/debian/dists/buster/main/binary-arm64/...
      /var/local/debian/dists/buster/contrib/binary-arm64/...
    

要让 apt 使用它,需要把这一行添加至 sources.list 文件:

deb file:/var/local/debian buster main contrib

注意dists会隐式添加,而版本名称后的参数则用于将路径扩展到多个目录。

添加新源后,通过在 APT source-list 文件中以前存在的软件源条目前放置一个井号(#)来禁用它们。

4.3.3. 从光学介质中添加 APT 源

如果您 想使用 DVD(或 CD 或蓝光光盘),请在所有 APT source-list 文件中注释掉现有条目,方法是在它们前面放置一个井号(#)。

确保在 /etc/fstab 中有一行允许您挂载 CD-ROM 于 /media/cdrom 挂载点。例如,假设 /dev/sr0 就是您的 CD-ROM,/etc/fstab 中应该带有一行:

      /dev/sr0 /media/cdrom auto noauto,ro 0 0
    

注意在第四列 noauto,ro 之间必须无空格

要验证设置是否有效,插入一片 CD,尝试运行

# mount /media/cdrom    # 这将把 CD 挂载到挂载点
# ls -alF /media/cdrom  # 这应该显示 CD 的根目录
# umount /media/cdrom   # 这将卸载 CD
    

下一步,运行:

# apt-cdrom add
    

每片您所拥有的 Debian 二进制 CD-ROM 都要这么做,以便将每片 CD 的数据添加至 APT 的数据库。

4.4. 升级软件包

从以前的 Debian 版本升级的推荐方法是使用包管理工具 apt

[注意]注意

apt 被设计用于交互式使用,故不应在脚本中使用。 在脚本中,应该使用 apt-get,它具有更适合进行文本处理的稳定输出。

不要忘记挂载所有必需的分区(尤其是根分区和 /usr 分区)为可读写状态,用以下命令:

# mount -o remount,rw /挂载点
  

接下来,您应该仔细检查确认 APT 源条目(在 /etc/apt/sources.list 以及 /etc/apt/sources.list.d/ 下的文件)要么指向 buster,要么指向 stable。 不应该有任何源条目指向stretch。

[注意]注意

CD-ROM 的源有时会指向 unstable。尽管这令人困惑,但您不应该改变它。

4.4.1. 记录会话

强烈推荐您使用 /usr/bin/script 程序来记录升级会话中的交互信息。这样如果有问题了,您就有一份日志,而且需要的话,它也可以在缺陷报告中提供准确的信息。要开始记录,输入:

# script -t 2>~/upgrade-buster步骤.time -a ~/upgrade-buster步骤.script
    

或是类似命令。如果您必须重新运行 typescript(例如,您必须重新启动系统),请使用不同的步骤值,以指示您正在记录的升级步骤。不要将输出文件放在临时目录下,如 /tmp/var/tmp(这些目录下的文件可能会在升级或重启时被删除)。

typescript 也可让您复查屏幕上滚动过去的信息。如果您位于系统的文本用户界面,只要切换至虚拟终端 2(使用 Alt+F2),在登入后,用 less -R ~root/upgrade-buster.script 查看文件。

在完成升级后,您可以在提示符下输入 exit 停止 script

      TODO: (jfs) 可以提一下我在 #400725 中提供的脚本,如果您没有转储 timing 文件,
      这个脚本很有用
    

apt will also log the changed package states in /var/log/apt/history.log and the terminal output in /var/log/apt/term.log. dpkg will, in addition, log all package state changes in /var/log/dpkg.log. If you use aptitude, it will also log state changes in /var/log/aptitude.

如果已经对 script 使用了 -t 选项,您就可以用 scriptplay 程序来回放整个过程:

# scriptreplay ~/upgrade-buster.time ~/upgrade-buster.script
    

4.4.2. 更新软件包列表

首先,需要获取新发行版的可用包列表。执行:

# apt update
    

4.4.3. 确保您有足够的空间升级

在升级系统之前,您必须确保当您开始第 4.4.5 节 “升级系统”中的完整系统升级时,您有足够的硬盘空间。首先,从网络获取的任何需要安装的软件包都存储在 /var/cache/apt/archives(对于正在下载的文件是 partial/ 子目录)中,因此您必须确保存放 /var/ 目录的文件系统分区有足够的空间来临时存放下载好的将要安装到系统的软件包。下载后,您可能在其他文件系统分区中也需要更多的空间,以便安装升级的软件包(可能包含更大的二进制文件或更多数据)及升级中带入的新包。如果您的系统没有足够的空间,您可能在最后得到的是一个未能完全升级却又难以还原的系统。

apt 可以显示有关安装所需磁盘空间的详细信息。 在执行升级之前,您可以通过运行以下命令来查看此估计:

# apt -o APT::Get::Trivial-Only=true full-upgrade
[ ... ]
升级了 XXX 个软件包,新安装了 XXX 个软件包,要卸载 XXX 个软件包,有 XXX 个软件包未被升级。
需要下载 xx.xMB 的归档。
解压缩后会消耗 AAAMB 的额外空间。
    
[注意]注意

由于下一节将要谈到的问题,在即将开始更新前执行这条命令可能会给出一个错误。如果那样的话,您需要等到已经如第 4.4.4 节 “最小系统升级”所述的那样做过最小系统升级,然后再运行这条命令来预估所需的磁盘空间。

如果您没有足够的空间进行升级, apt 将通过类似这样的消息警告您:

E: 您在 /var/cache/apt/archives/ 上没有足够的可用空间。
    

在这种情况下,请确保事先释放空间。您可以:

  • 删除以前安装时下载的软件包(位于 /var/cache/apt/archives)。 通过运行 apt clean 来清理软件包缓存,这将会删除所有以前下载过的软件包文件。

  • 删除被遗忘的软件包。 如果您曾用 aptitudeapt 手动在 stretch 中安装过包,它将会保存手动安装的记录,并且对于由依赖关系拉入的包,在主包删除时能自动识别为不再需要的并标记为冗余。不会将您手动安装的包标记为删除。要删除自动安装的、不再使用的软件包,请运行:

    # apt autoremove
            

    您可以用其它的工具来找出多余的包,例如 deborphandebfostercruft。不要盲目地移除那些工具找到的包,尤其是当您使用了激进的非默认的选项时,很容易产生假阳性结果。强烈推荐在您移除它们之前,手工核查那些建议移除的包(例如:它们的内容、大小以及描述信息)。

  • 删除占用太多空间并且不需要的软件包(您可以在升级后随时重新安装)。 如果您安装了 popularity-contest,则可以使用 popcon-largest-unused 列出占用空间最大的不常使用的软件包。 您可以使用 dpigs(在 debian-goodies 软件包中)或 wajig(运行 wajig size)找到占用最多磁盘空间的软件包。 也可以使用 aptitude 找到它们。 以可视模式启动 aptitude,选择 视图新建平面软件包列表,按 l 并输入 ~i,按 S 并输入 ~installsize。这将为您提供一个方便的列表。

  • 如果不需要的话可以从系统中移除翻译和本地化文件。您可以安装并配置 localepurge 软件包,这样只有一小部分指定的 locale 被保留在系统中。这将减少 /usr/share/locale 所使用的磁盘空间。

  • /var/log/ 下的系统日志临时放到其它系统,或是永久删除。

  • 使用临时的 /var/cache/apt/archives:您可以使用其他文件系统中的临时缓存目录(USB 存储设备,临时硬盘,已在使用的文件系统等等)。

    [注意]注意

    不要使用 NFS,这是因为网络连接可能在升级期间断开。

    例如,假设您将 USB 驱动器挂在 /media/usbkey 下:

    1. 删除以前安装时下载的包:

      # apt clean
                      

    2. /var/cache/apt/archives 目录复制到 USB 驱动器:

      # cp -ax /var/cache/apt/archives /media/usbkey/
                      

    3. 将临时缓存目录挂载至当前使用的目录:

      # mount --bind /media/usbkey/archives /var/cache/apt/archives
                      

    4. 升级后,还原 /var/cache/apt/archives 目录:

      # umount /media/usbkey/archives
                      

    5. 删除留下的 /media/usbkey/archives

    您可以在挂载于系统中的任何文件系统上创建临时缓存目录。

  • 对系统进行最小升级(请参阅第 4.4.4 节 “最小系统升级”)或部分升级,然后再完整升级。这将有可能能先部分升级系统,并允许您在完整升级之前清理包缓存。

请注意,为了安全地删除软件包,建议将 APT source-list 文件切换回 stretch,如第 A.2 节 “检查您的 APT source-list 文件”中所述。

4.4.4. 最小系统升级

在某些情况下,直接完整升级(如下所述)可能会删除大量您希望保留的软件包。因此,我们建议采用两部分升级过程:首先进行最小的升级以解决这些冲突,然后进行完整升级,如第 4.4.5 节 “升级系统”所述。

要开始,请运行:

# apt upgrade
    

这会升级那些不需要删除或安装其它任何包的软件。

当系统空间紧张,并且由于空间限制而无法运行完整升级时,最小的系统升级也将非常有用。

如果安装了 apt-listchanges 软件包,(在默认配置下)它将在分页器中显示有关升级软件包的重要信息。阅读后按 q 退出分页器并继续升级。

4.4.5. 升级系统

一旦您完成了上述步骤,您现在可以继续进行升级的主要部分。请执行:

# apt full-upgrade
    

这将对系统进行一次全面的升级,安装所有包的最新可用版本,解决不同发行版本的软件包之间的所有潜在的依赖关系变化。如有必要,它会安装一些新包(通常是新库,或是重命名的包),并删除任何有冲突的过时包。

当从一组 CD/DVD/BD 升级时,您会在升级期间的某几个地方被要求插入指定的盘片。 您可能不得不多次插入相同的盘片,这是因为互相依赖的包已经被散布到整个盘片组中去了。

无法在不改变其他软件包的安装状态的情况下升级的已安装软件包将停留在当前版本(显示为未被升级)。这个问题可以通过使用 aptitude 选择这些包来安装或是用 apt install 软件包 来解决。

4.5. 升级期间可能遇到的问题

以下部分描述升级到 buster 期间已知可能会出现的问题。

4.5.1. Dist-upgrade 失败,显示无法立即配置

在某些情况下,下载软件包后,apt full-upgrade 步骤可能会失败:

E: 无法立即对 软件包 进行配置。 请查看 man 5 apt.conf 中的 APT::Immediate-Configure
      

如果发生这种情况,运行 apt full-upgrade -o APT::Immediate-Configure=0 应该可以使升级继续。

此问题的另一个可能解决方法是临时将 stretch 和 buster 源都添加到您的 APT source-list 文件中,并运行 apt update

4.5.2. 预期的删除

升级到 buster 的过程可能会要求删除系统上的软件包。精确的软件包列表将根据您安装的软件包集不同而有所不同。发行说明提供了关于这些删除的一般性建议,但如有疑问,建议您在继续之前检查每种方式所显示的要删除包列表。有关 buster 中过时软件包的更多信息,请参见第 4.8 节 “过时的软件包”

4.5.3. 冲突或预依赖循环

有时有必要在 APT 中开启 APT::Force-LoopBreak 选项使之能够临时移除一个重要的包,这是由于冲突或是预依赖循环。 apt 会警告您这一点并中止升级。 您可以通过在 apt 命令行中指定 -o APT::Force-LoopBreak=1 选项来解决这个问题。

有时一个系统的依赖关系太乱了以至于需要手工干预。 通常这意味着使用 apt

# dpkg --remove 软件包名
    

来消除某些引起问题的包,或是

# apt -f install
# dpkg --configure --pending
    

在极端情况下,您可能不得不用类似下面的命令强制重新安装某个包

# dpkg --install /path/to/package_name.deb
    

4.5.4. 文件冲突

如果您从纯净的 stretch 系统升级就不会出现文件冲突,但如果您装有非官方的向后移植的软件包就可能出现冲突。文件冲突会导致类似以下这样的错误:

正在解压缩 <package-foo> (来自 <package-foo-file>) ...
dpkg: 处理软件包 <package-foo> (--install) 时出错:
正试图覆盖 `<some-file-name>',
它同时被包含于软件包 <package-bar> 中
dpkg-deb: subprocess paste killed by signal (Broken pipe)
在处理时有错误发生:
<package-foo>
    

您可以尝试强制删除错误信息中的最后一行提到的软件包来解决文件冲突:

# dpkg -r --force-depends 软件包名
    

在修复这些问题后,您应该可以通过重复前述的 apt 命令来继续升级。

4.5.5. 配置文件变化

升级期间,您将会被询问有关配置或是重新配置一些软件包的问题。如果您被问到是否用软件包维护者的版本替换 /etc/init.d/etc/manpath.config 下的文件时,通常有必要回答 yes 来确保系统一致性。您总是可以恢复老版本的配置文件,因为它们会被保存为带有 .dpkg-old 后缀名的文件。

如果您不确定该做什么,那就记下软件包或文件的名称,以后再妥善处理这些问题。您可以通过在 typescript 文件中搜索来查看升级期间显示在屏幕上的信息。

4.5.6. 将会话切换到控制台

如果您使用系统的本地控制台升级,则可能会发现在升级过程中的某些时候,控制台切换到了不同的视图,并且您无法看到升级过程。例如,在桌面系统中,当显示管理器重新启动时,就可能发生这种情况。

要恢复运行升级的控制台,您必须使用 Ctrl+Alt+F1(如果在图形启动界面)或 Alt+F1(如果在本地文本模式控制台)切换回虚拟终端 1。用和运行升级的虚拟终端号码相同的功能键替换 F1。您还可以使用 Alt+左箭头Alt+右箭头 在不同的文本模式终端间切换。

4.6. 升级内核与相关包

    TODO: 需要通过 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=571255 [elbrus, 2019]
    中的信息进行审核,这部分是否仍然相关? 这个 bug 来自 squeeze。
  

这一节解释了如何升级您的内核,以及明确有关此次升级的潜在问题。您可以安装由 Debian 提供的 linux-image-* 包,或者从源码编译一个自定义的内核。

注意本节的很多信息基于假设,即您会使用一个模块化的 Debian 内核,以及initramfs-toolsudev。如果您选择使用一个不需要 initrd 的自定义内核,或是您使用了一种不同的 initrd 生成器,对您来说某些信息可能不适用。

4.6.1. 安装内核元软件包

当您从 stretch 完整升级至 buster 时,如果没有安装,强烈推荐您安装 linux-image-* 元包。这些元包将在升级过程中自动引入新版本的内核。您可以运行以下命令验证是否安装了上述元包:

# dpkg -l "linux-image*" | grep ^ii | grep -i meta
    

如果您没有看到任何输出,那么您需要手动安装一个新的 linux-image 软件包,或者安装 linux-image 元包。要查看可用的 linux-image 元包列表,请运行:

# apt-cache search linux-image- | grep -i meta | grep -v transition
    

如果您不确定要选哪个包,那就运行 uname -r 并查找带有类似名称的包。 例如,如果您看到 2.6.32-5-amd64,那推荐您安装 linux-image-amd64。 您也可以使用 apt-cache 来查看每个包的详细描述,以帮助您选择最好用的那个。 例如:

# apt-cache show linux-image-amd64
    

然后您应该使用 apt install 来安装。 安装此新内核后,您应该在下一个可能的时刻重新启动,以获得新内核版本提供的特性。 但是,在升级之后的第一次重启之前,请先查看第 5.1.10 节 “升级后在重启前需要做的事”

For the more adventurous there is an easy way to compile your own custom kernel on Debian. Install the kernel sources, provided in the linux-source package. You can make use of the deb-pkg target available in the sources' makefile for building a binary package. More information can be found in the Debian Linux Kernel Handbook, which can also be found as the debian-kernel-handbook package.

如果可能,把内核包的升级从主 full-upgrade 中独立出来是有利的,这能减少暂时不可引导系统的可能性。 请注意,这只应在第 4.4.4 节 “最小系统升级”中描述的最小升级过程之后完成。

4.7. 为下个发布版本做准备

升级完成后,您可以为下一个发布版本做些准备工作。

4.7.1. 清理已删除的软件包

通常建议清理已删除的软件包。如果这些软件包已经在之前的版本升级(例如升级到 stretch)过程中被删除,或者它们是由第三方供应商提供的,则尤其如此。特别地,已知旧的 init.d 脚本会导致问题。

[小心]小心

清理软件包通常也会清除其日志文件,因此您可能希望先备份它们。

以下命令显示所有已删除、但可能在系统上留下配置文件的软件包的列表(如果有的话):

# dpkg -l | awk '/^rc/ { print $2 }'
    

可以使用 apt purge 删除这些软件包。 假设您想一次性清除它们,可以使用以下命令:

# apt purge $(dpkg -l | awk '/^rc/ { print $2 }')
    

如果您使用 aptitude,还可以使用以下的替代方法:

# aptitude search '~c'
# aptitude purge '~c'
    

4.8. 过时的软件包

引进新软件包的同时,buster 也清除了一些曾位于 stretch 的旧软件包。 它不提供对这些过时包的升级。 虽然没有什么可以阻止您继续使用过时的软件包,但 Debian 项目通常会在 buster 发布一年后停止对它的安全更新[5],并且在此期间通常不会提供其他支持。 如果有的话,建议用可用的替代品替换它们。

软件包被从发行版中移除有很多原因,如:它们不再被上游作者维护了;没有 Debian 开发者对维护这个包感兴趣;这些包提供的功能被不同的软件(或新版本)替代了;或者由于它们自身的缺陷,使得它们被认为不适用于 buster。最后一种情况下,这些包有可能仍然位于 unstable 版之下。

有些软件包管理工具提供了简单的方法以寻找已不在任何已知软件仓库的已安装软件包。aptitude 文本用户界面将它们列在了过期的和在本地创建的软件包分类中,它们可以通过以下命令被列出和删除:

# aptitude search '~o'
# aptitude purge '~o'
  

Debian 缺陷跟踪系统通常会提供有关这个包为什么会被移除的额外信息。您应该既查看此包自身的归档缺陷报告,同时也要查看 ftp.debian.org 伪软件包的归档缺陷报告。

要获得 Buster 的过时包列表,请参阅第 5.1.8 节 “值得注意的过时软件包”

4.8.1. 过渡哑包

来自 stretch 的一些软件包可能已在 buster 中被过渡哑包(transitional dummy package)替换,这些软件包是用于简化升级的空占位符。例如,如果以前单个包的应用程序已被拆分为多个,则可以提供与旧包具有相同名称的过渡包,并设置合适的依赖以使新的包被安装。发生这种情况后,可以安全地移除冗余哑包。

绝大多数过渡哑包的描述信息会显示它们的用途。但哑包的描述信息并不统一;特别是,一些 包被设计为保持安装,以便引入完整的软件套件或跟踪某些程序的当前最新版本。您可能还会发现 deborphan 使用 --guess-* 选项(例如 --guess-dummy)可用于检测系统上的过渡哑包。



[1] 如果 debconf 优先级设置为非常高的级别,则可能不会弹出配置提示,但如果默认应答不适用于您的系统,依赖于此的服务将无法启动。

[2] 例如:DNS 或 DHCP 服务,特别是当没有冗余或故障转移时。以 DHCP 为例,如果租用时间低于升级过程完成所需的时间,终端用户可能会断开网络连接。

[3] 此功能可以通过在您的启动参数中添加参数 panic=0 来禁用。

[4] Debian 的包管理系统正常情况下不允许一个软件包移除或是替换另一个软件包所拥有的文件,除非已经被设定为替换那个包。

[5] 或者,直到这段时间内有另一个版本发布为止。在任意时刻,一般仅对两个 stable 版本提供支持。