☰
snapd 安装致 yum 崩溃:OpenSSL 符号冲突与依赖修复
2026/10/26 5:02:26 网站建设 项目流程

装 snap 环境本来是件很轻的事,几条命令的事,结果我在一台业务机上执行完sudo yum install snapd,还没等到装完的提示符回落,随手再敲一个yum就见到了这么一行东西:libk5crypto.so.3: undefined symbol: EVP_KDF_ctrl, version OPENSSL_1_1_1。那一瞬间的感觉,熟悉的人都懂——SSH 还连着,命令还能敲,但整台机器的包管理器已经废了,yum起不来,rpm之外几乎没有趁手的工具,想装什么都装不了。这个报错表面上看是 OpenSSL 的符号问题,根子上却是依赖链上的一次错位:某个库被换成了另一套 ABI,而调用方还按老规矩要符号。这篇内容我打算把这条链路从头拆到尾,包括我是怎么在没有yum的情况下把系统救回来的、每一步为什么这么选、以及装带第三方依赖的包时哪些操作我后来再也不敢图省事。适合手里管着 7 系企业发行版、经常要跟 EPEL 之类扩展源打交道的人看,也适合刚接手老机器、还没被依赖地狱教育过的新手。

1. 先把报错读薄:一行错误信息里的四个独立信息点

1.1 EVP_KDF_ctrl 是 OpenSSL 1.1.1 才有的符号

EVP_KDF_ctrl这个函数不是 OpenSSL 的元老,它是 1.1.1 这条线上才正式暴露出来的 KDF(密钥派生函数)控制接口。1.0.2 时代的 OpenSSL 做密钥派生基本靠PKCS5_PBKDF2_HMAC这类散装函数,没有统一的 EVP_KDF 抽象;到了 3.0,这套接口又被重构掉了,EVP_KDF_ctrl被EVP_KDF_CTX_set_params和EVP_KDF_derive取代,等于说这个符号的生命周期就压在 1.1.1 这一个版本带上。

这一点非常关键,因为它决定了排查方向:报错说这个符号找不到,说明libk5crypto.so.3在链接时是照着 1.1.1 的头文件和符号表编出来的,但运行时真正加载进来的那份libcrypto并不提供它。可能是加载到了一份 1.0.2 改名过来的库,也可能是一份编译时裁掉了相关特性的 1.1.x,还可能是路径污染导致载入了错误的一份文件。三种情况表现一致,成因完全不同,后面的定位手段也不一样。

我见过有人一上来就怀疑是"openssl 装了两份",然后去find / -name "libcrypto*"满盘搜,搜出一堆结果反而更乱。正确的顺序是先确认"调用方要什么",再去确认"提供方给了什么",而不是先去找文件。

1.2 libk5crypto 为什么会跑去向 libcrypto 要符号

libk5crypto.so.3是 krb5 这套 Kerberos 实现里的加密支撑库,负责 AES、DES 之类的算法封装和密钥派生。krb5 从 1.17 往后逐步把内部的加密实现往 OpenSSL 上靠,一部分密钥派生逻辑直接改用了 OpenSSL 的 EVP_KDF 接口,于是libk5crypto对libcrypto的符号依赖就从一个"软依赖"变成了硬绑定——版本对不上直接起不来。

普通用户平时感知不到这一层,是因为 Kerberos 只在ssh、curl、yum这些工具需要做 GSSAPI 认证时才会被拉起来。而 yum 恰好走的是pycurl→libcurl→libkrb5这条链,libcurl在编译时通常带上了 GSSAPI 支持,所以每次启动 yum,动态链接器都会把libkrb5.so.3和libk5crypto.so.3一起载入。krb5 一崩,yum 跟着崩。

这也解释了一个很反直觉的现象:明明报错跟 Kerberos 八竿子打不着,你也没配过任何 KDC,为什么 yum 会被 Kerberos 的库拖死。因为这不是"用到才加载",而是"链接了就加载"。

1.3 "version OPENSSL_1_1_1" 是符号版本,不是文件名

标题里那一串被截断成了version OPENSSL_1,实际完整的通常是version OPENSSL_1_1_1或OPENSSL_1_1_0。这个version后面跟的东西是 ELF 的符号版本标记,是 GNU 工具链在做符号版本化时写进去的,跟"你机器上装了几个 openssl 文件"没关系。

很多人卡在这一步,以为报错是在说"你要 OPENSSL_1 这个文件",然后去搜find / -name "OPENSSL_1*",当然什么都找不到。这里要建立的直觉是:ELF 的符号版本是一张表,.gnu.version_r段里记着"我需要 libcrypto.so.1.1 这个对象提供版本为 OPENSSL_1_1_1 的那批符号"。动态链接器会拿着这张表去目标库里核对,版本对不上就报 undefined symbol。

想看这张表长什么样,readelf -V /usr/lib64/libk5crypto.so.3就能看到完整的版本需求列表,里面会明确写着需要哪个库、哪个版本节点、涉及哪些符号。这条命令在后面的定位过程中是我用得最多的一条。

1.4 为什么偏偏是 yum 先倒下,而不是 ssh

这里有个容易被忽略的细节:ssh 也用 GSSAPI,但 ssh 通常只在真正发起 GSSAPI 认证时才去dlopen相关模块,而且很多发行版的 ssh 编译时把 GSSAPI 做成了可选项。yum 不一样,它是个 Python 脚本,跑起来第一步就是 import 一堆 C 扩展,pycurl.so是其中之一,链接器在进程启动阶段就把整条依赖链拉起来了,没有任何延迟加载的余地。

我当时的实际验证方法是ldd /usr/lib64/python2.7/site-packages/pycurl.so(7 系发行版的 yum 是 Python 2 写的),输出里能清清楚楚看到libcurl.so.4→libkrb5.so.3→libk5crypto.so.3→libcrypto.so.1.1这条链路。顺带说一句,head -1 $(which yum)能看到 shebang 指向/usr/bin/python,确认它确实是 Python 2 脚本,这样你就知道该去哪个 site-packages 目录下找扩展模块。

2. 装 snapd 这一步到底动了哪块地基

2.1 依赖解析的真实链条:snapd → krb5-libs → openssl-libs

snapd 本身并不是个轻量包,它要管理 squashfs 镜像、要挂 FUSE、要跟 systemd 打交道,从扩展源装的时候往往会顺带拉一堆依赖。在 7 系发行版上,一次yum install snapd的依赖树里,krb5-libs被提升版本是相当常见的结果——不是因为 snapd 直接依赖 Kerberos,而是依赖树里某个中间包(认证、远程拉取、策略相关)声明了更高版本的 krb5。

问题就出在这个"顺带提升"上。老机器的openssl-libs常年停在 1.0.2 那条线上,很多业务组件是照着这个版本编译的,运维出于稳定考虑也不敢随便动它。于是形成了一种很别扭的状态:krb5-libs被拉到了一个新版本,这个新版本是照着 OpenSSL 1.1.1 编译的;而openssl-libs还老老实实待在 1.0.2。两边要求的 ABI 不一致,符号自然对不上。

用一条命令就能把这件事看清楚:rpm -qp --requires krb5-libs-*.rpm | grep -i -E "openssl|libcrypto",看它到底声明了对哪个 soname 的依赖。如果输出里出现libcrypto.so.1.1,那就说明这版 krb5 是奔着 1.1.1 去的,跟 1.0.2 系统的libcrypto.so.10完全不是一个世界。

2.2 两种归因:库被覆盖了,还是需求被拉高了

同样是undefined symbol,底层成因其实分两类,处理方式差别很大。

第一类是需求被拉高:调用方(这里是libk5crypto)换成了新版本,它要新符号,而系统里根本没有对应版本的库。这种情况下ldd能正常解析到文件,readelf -V也能看到版本需求,只是目标库里那个版本节点不存在或者没有这个符号。我遇到的多数是这一类。

第二类是提供方被覆盖:系统里本来有一份正确的libcrypto.so.1.1,结果被某个第三方包用另一份文件顶掉了,路径没变、文件名没变,内容变了。这种更阴险,因为rpm -q查出来的包名看起来没问题,但文件的实际内容已经被替换。

区分方法很直接:先rpm -qf /usr/lib64/libcrypto.so.1.1看归属,再用rpm -V校验这个包的文件完整性。如果rpm -V openssl-libs输出的那几行里,libcrypto.so.1.1前面出现大小写或 MD5 不一致的标记,那就是文件被动了手脚,"提供方被覆盖"这条归因就坐实了。

我当时这台机器的情况是前者:krb5-libs从 1.15 被拉到了 1.18,而openssl-libs纹丝没动。所以修复方向不是"找回被覆盖的库",而是"把 krb5 拉回跟系统 openssl 匹配的版本"。

2.3 用三条证据把归因钉死

排查这类问题我最怕的就是"猜",所以固定跑三条命令,跑完基本不会有第二种解释。

第一条,rpm -qa | grep -E "krb5|openssl" | sort,把当前装着的所有相关包和版本一次性列清楚。别小看这一步,我遇到过装了openssl11-libs这种并行包的情况,名字里带 openssl 但提供的是另一套路径下的库,不列出来根本想不到。

第二条,readelf -V /usr/lib64/libk5crypto.so.3 | head -40,看它需要的版本节点。如果这里写的是OPENSSL_1_1_1,而系统openssl-libs是 1.0.2,那结论已经出来了,不用再往下猜。

第三条,ls -l /usr/lib64/libcrypto*加readelf -V --dyn-syms /usr/lib64/libcrypto.so.1.1 | grep -i kdf,确认这个文件到底存不存在、导不导出目标符号。这里有个坑要注意:如果文件根本不存在,报错会是cannot open shared object file,而不是undefined symbol。既然报的是后者,说明文件在,只是内容不对——这条推理能帮你省掉很多弯路。

把这三条的输出放在一起看,归因基本就是唯一的了。我在实际排查里还会再加一条ls -l --time-style=full-iso /usr/lib64/libcrypto*,看文件修改时间是不是跟那次yum install的时间吻合,吻合的话因果关系就更明确了。

3. 应急与修复:三条路线的取舍

3.1 为什么我不建议第一时间升级 openssl-libs

看到符号缺失,很多人的第一反应是"那就把 openssl 升上去"。在开发机上这么干顶多折腾半天,在生产机上我强烈不建议,尤其当这台机器跑着一堆老业务组件的时候。

原因是 OpenSSL 从 1.0.2 到 1.1.1 不是打个补丁那么简单,大量老 API 被标记废弃甚至行为变更,结构体变成了不透明指针,很多照着 1.0.2 编译的二进制直接跑不起来。一旦你把系统openssl-libs从 1.0.2 换成 1.1.1,受影响的不只是 krb5,openssh、Python的 ssl 模块、各种语言的加密扩展、数据库客户端,全都会跟着抖一遍。更麻烦的是这种破坏是弥散性的,不会一次性全暴露,可能你今天修好了 yum,明天备份脚本跑不起来,后天某个监控探针连不上。

还有一个隐藏风险:系统里如果同时存在openssl-libs和另外装的并行版本(比如某些仓库提供的openssl11-libs),两者会争抢/usr/lib64下的软链接和ld.so.cache,谁最后被ldconfig扫到就用谁。这种不确定性在排障阶段是最要命的。

我的判断标准很朴素:当系统的根基库版本和业务组件的编译基线一致时,不要为了让一个新装的软件跑起来去动根基库;应该反过来,把那个新软件依赖的东西降回基线。

3.2 路线一:把 krb5-libs 降回与系统匹配的版本

这是我最终选的方案,也是在 7 系老机器上最稳妥的一条。核心思路是:让krb5-libs回到那个照着 1.0.2 编译的版本,符号需求自然就消失了。

具体操作要连带着把同版本族的包一起降,krb5-libs、krb5-workstation、libkadm5这三个通常是同一次构建出来的,版本必须一致,只降一个会引发新的依赖冲突。命令形如:

rpm -Uvh --oldpackage \ krb5-libs-1.15.1-50.el7.x86_64.rpm \ krb5-workstation-1.15.1-50.el7.x86_64.rpm \ libkadm5-1.15.1-50.el7.x86_64.rpm

--oldpackage这个参数是必须的,不加的话 rpm 会认为你在降级而拒绝执行,报package ... is already installed之类的错。这个参数的意思就是"我知道我在往回退,别拦我"。

降级之前一定先rpm -q --whatrequires krb5-libs看一眼有谁依赖它,确认没有哪个业务包硬性要求 1.18 以上。这一步不能省,我见过有人降完 krb5 发现某个自研的认证组件起不来了,因为它编译时用了 1.18 的新接口。

3.3 路线二:从本地介质补回正确的 openssl-libs

如果评估下来确实需要 1.1.1(比如业务侧已经有一批组件在用它),那就走这条路:从发行版的安装介质或者内部镜像源里取出对应版本的openssl-libs,用rpm -Uvh --replacepkgs覆盖安装。

这里要特别注意--replacepkgs和--force的区别。--replacepkgs是"即使已安装也重新装一遍",行为可控;--force是--replacepkgs加--replacefiles加--oldpackage的组合,它会无视文件冲突直接覆盖,副作用大得多。我在生产环境基本只用前者,后者留到实在没辙的时候。

还有一个细节:覆盖安装之后必须跑一次ldconfig,让/etc/ld.so.cache重新生成。很多人装完发现没生效,就是因为缓存里还指着旧的 inode。判断方法很简单,ldconfig -p | grep libcrypto看看列出来的路径和实际文件对不对得上。

3.4 路线三:先把 snapd 拆干净再谈恢复

有时候最省事的做法是釜底抽薪:把 snapd 及它带进来的一串依赖整个卸掉,让系统回到装之前的状态。

问题在于,yum已经不能用了,只能用rpm -e硬卸。而rpm -e snapd会因为依赖关系被拒绝,得加--nodeps跳过依赖检查。这一步要格外小心,因为--nodeps卸掉的可能不只是 snapd,还可能把某个被别的东西依赖的库一起带走,导致更多命令失效。

我的习惯是先rpm -e --test snapd做一次演练,看 rpm 打算连带卸掉哪些包,把清单打印出来逐条确认。确认没问题再真正执行。--test这个参数救过我不少次,它只做依赖推演不实际动手,成本极低但价值很高。

卸完之后别急着装别的,先rpm -Va跑一遍全量校验,看看有没有别的包的文件在这次折腾里被改坏了。这个命令输出可能会很长,重点看那些标记为missing或者MD5 differ的行。

4. 完整修复实录:从工具崩掉到 yum 复活

4.1 开工前的三分钟备份

在动任何系统库之前,我会做三件事,加起来不超过三分钟,但这三分钟能救命。

第一件,把当前所有相关包的版本信息落盘:rpm -qa | grep -E "krb5|openssl|curl|python" > /root/pkg-baseline-$(date +%F).txt。这份文件是回滚时的对照表,比凭记忆靠谱一百倍。

第二件,把要被覆盖的库文件复制一份到/root/libbackup/,包括libcrypto.so.1.1、libssl.so.1.1、libk5crypto.so.3以及它们的软链接。注意要复制软链接指向的真实文件,不能只复制符号链接本身,否则回滚时链接指向的旧 inode 早就没了。

第三件,确认手上还有一条能进机器的通道。SSH 会话别关,另开一个tmux或screen会话挂着。因为一旦你降级 krb5 失败,sshd有可能因为 PAM 或 GSSAPI 相关的库变动而拒绝新连接——老连接还活着,新连接进不来,这时候你会非常感谢那个没关掉的会话。

4.2 用 rpm 做降级或覆盖安装的完整命令

我在那台机器上的实际操作顺序是这样的。先确认本地有没有可用的 rpm 包,没有的话从内部镜像源取,取包用的是wget而不是curl——这个选择有讲究,后面第 5 节会细说。

拿到包之后,先做一次安装演练:

rpm -Uvh --test --oldpackage krb5-libs-1.15.1-50.el7.x86_64.rpm

--test会告诉你这次操作会不会引发文件冲突、会不会破坏依赖,但不会真的写盘。输出里如果有file /usr/lib64/xxx from install conflicts with file from package yyy,那就是有冲突,得先把冲突的包处理掉。

演练通过后正式执行,然后把同族的另外两个包一起补上。整套动作做完,立刻验证ldd /usr/lib64/libk5crypto.so.3,看它现在链接的是libcrypto.so.10还是libcrypto.so.1.1。如果变成了libcrypto.so.10,说明降级生效了。

最后一步是ldconfig,然后yum --version试探一下。我第一次跑的时候还是报错,因为yum的 Python 字节码缓存里还留着旧的模块引用,rm -rf /var/cache/yum/*加上yum clean all(如果能跑起来的话)之后就正常了。

4.3 ldconfig 和缓存清理里最容易踩的两个坑

第一个坑是顺序。必须先装包、再ldconfig,不能反过来。我见过有人装完包忘了跑ldconfig,然后反复排查为什么"文件明明换了还是报错",折腾了半小时。判断缓存是否更新很简单:ldconfig -p | grep -E "libcrypto|libk5crypto",看输出的路径和时间戳。

第二个坑是**ld.so.conf.d里的残留**。如果之前有人为了用某个并行版本的库,在/etc/ld.so.conf.d/下加过一条路径(比如指向某个第三方目录),那么ldconfig重扫的时候会把这个目录里的库也纳入搜索范围,优先级可能压过/usr/lib64。这种情况下你换多少次包都没用,因为加载的根本不是你以为的那个文件。检查方法是cat /etc/ld.so.conf.d/*.conf逐条看,有可疑的就注释掉再ldconfig。

还有一个更隐蔽的情况:环境变量LD_LIBRARY_PATH被写进了某个 profile 文件里。这个变量优先级比ld.so.cache高,一旦被设上,全局生效。排查时echo $LD_LIBRARY_PATH加grep -r LD_LIBRARY_PATH /etc/profile.d/两下就能查清。

4.4 修完之后必须跑的验证清单

yum 能跑起来不等于修好了。我固定跑下面这几条,全绿才算收工。

验证项命令预期结果
依赖链完整性ldd $(which python) | grep "not found"无输出
krb5 库链接版本ldd /usr/lib64/libk5crypto.so.3指向libcrypto.so.10
包文件完整性rpm -Va | grep -E "krb5|openssl"无输出或仅配置文件差异
包管理器可用性yum repolist正常列出仓库
Kerberos 工具链klist -V正常打印版本
SSH 新连接另开会话登录能正常登录

这里重点说两条。rpm -Va的输出里,如果某些行的标记只有c(配置文件变更),那是正常的;如果出现missing或者5(MD5 不符),说明包文件确实被改坏了,需要yum reinstall那个包。klist -V是个很多人不知道的小工具,它能验证 krb5 整套库是否自洽,比单纯看ldd更有说服力。

5. 工具链崩了怎么自救:断网状态下的应急下载

5.1 wget 为什么常常还能用

这是我在这次事故里最有价值的发现。yum挂了、curl挂了(因为curl也走libcurl→libkrb5这条链),但wget往往还能正常工作。

原因在于实现路径不同:curl是基于libcurl这个共享库的,而libcurl又链接了libkrb5;wget则是一个自包含的二进制,直接用 OpenSSL 或 GnuTLS 做 TLS,不经过libcurl,自然也就不会被 krb5 的符号问题牵连。

这个差别平时看不出来,出事的时候就是救命稻草。我当时就是靠wget从内部镜像把krb5-libs的降级包拉下来的,全程没有碰curl和yum。后来我专门验证过:ldd $(which wget) | grep -E "krb5|curl"确实没有任何输出。

同样的道理,python3如果没链接 GSSAPI 相关模块,也能用来做简单的 HTTP 下载。python3 -c "import urllib.request; urllib.request.urlretrieve('http://内部源/xxx.rpm','xxx.rpm')"这一行在关键时刻同样管用。但要注意,某些发行版的 Python 是带着 ssl 模块链接libssl的,ldd一下确认更稳妥。

5.2 从本地源或安装介质取包

如果wget也不行,那就只能走离线路线。发行版的完整安装介质里通常带着全套基础包,挂载之后可以直接从Packages目录取。

mount -o loop /path/to/install.iso /mnt ls /mnt/Packages | grep -E "^krb5-libs-1.15" rpm -Uvh --oldpackage /mnt/Packages/krb5-libs-1.15.1-50.el7.x86_64.rpm

这里有个经验:介质里的包版本要跟你系统的基线版本对得上。7 系的发行版迭代了很多个小版本,1.15.1-37和1.15.1-50虽然都叫 1.15.1,但打过的补丁不一样。降级的目标应该是"跟当前系统其他组件兼容的那个版本",不是"随便一个 1.15.1"。判断办法是对照/etc/redhat-release或者rpm -q --qf "%{VERSION}-%{RELEASE}\n"看系统基线。

5.3 一个可复用的临时救急思路

除了换工具,还有一个思路值得记住:用LD_PRELOAD临时指定库。

比如系统里有两份libcrypto,一份在/usr/lib64,一份在/opt/xxx/lib,你可以这样临时让某个命令用指定的那份:

LD_PRELOAD=/opt/xxx/lib/libcrypto.so.1.1 yum repolist

但这条路我把它明确定义为"临时验证手段",不是修复方案。原因有三:第一,LD_PRELOAD会把指定的库强制注入进程,如果这个库本身又有依赖,可能引发更细的连锁问题;第二,它只对当前命令有效,不改系统状态,重启或者换个 shell 就失效;第三,它容易掩盖真正的问题,让人误以为修好了。

真正有价值的用法是:用它快速验证"换一份正确的库是不是就好了",验证通过之后,再按正规流程去装包、改配置、跑ldconfig。诊断和修复分开,这个习惯在系统层面排障里特别重要。

6. 事后复盘:几条被这次事故教育出来的硬习惯

6.1 装带扩展源的包之前先看依赖树

这次事故之后,我给自己定了条规矩:凡是装来自扩展源或第三方的包,先跑yum install --assumeno <包名>或者yum deplist <包名>,把依赖树看一遍再决定。

--assumeno会在解析完依赖、打印出完整的将要安装/升级/降级的包列表之后停下来问你"要不要继续",你答 no 就什么都不会发生。这个参数的价值在于它把"依赖解析"和"实际写入"分开了,让你有机会在动手之前看到全貌。

那次如果我先跑了这一步,就会看到krb5-libs从 1.15 升到 1.18 这一行,然后立刻反应过来"这个升级会牵动 openssl 的 ABI",后面的麻烦全都可以避免。代价只是多看几行输出,这笔账怎么算都划算。

对于特别关键的生产机,我还会加一层保险:先在测试机上跑一遍完整的安装,rpm -qa | sort > after.txt,跟安装前的before.txt做 diff,看看除了预期的包之外还有哪些被顺带动了。这种"版本漂移"往往是事故的源头。

6.2 rpm -Va 和 rpm -qf 应该成为日常命令

rpm -qf是"这个文件属于哪个包",rpm -Va是"所有包的文件有没有被改过"。这两条我现在的使用频率比yum install还高。

rpm -Va的输出格式是一串标记位加文件名,标记位的含义是:S大小变了、M权限变了、5MD5 变了、D设备号变了、L链接变了、U用户变了、G组变了、T时间戳变了、P能力变了,c表示这是配置文件(这类变更通常正常),missing表示文件丢了。

日常巡检时重点看两类:一是非c标记的5(二进制文件被改,可疑),二是missing(文件被删,可能是被人手动清理过)。我在一台跑了三年的老机器上就靠这个发现过一个被误删的libssl软链接,当时没人报故障,但某天重启后某个服务起不来,就是这个原因。

rpm -qf的用法更直接,遇到不认识的文件,rpm -qf /usr/lib64/xxx.so一看就知道来路。如果返回file ... is not owned by any package,那这个文件就是野的,要么是手工编译装的,要么是别的工具写进去的,两种情况都值得深究。

6.3 把系统的版本基线记录下来

我现在管的所有机器,都有一个/root/.baseline/目录,里面放着几个文件:pkg-list.txt(rpm -qa的完整输出)、repo-list.txt(各仓库的配置文件备份)、ld-conf.txt(/etc/ld.so.conf.d/的全部内容)。这些文件在系统初始化时生成一次,之后每次计划内的变更都更新一次。

这东西的价值在于出事时的对照。diff baseline/pkg-list.txt <(rpm -qa | sort)一条命令,就能看出从基线到现在到底有哪些包被动了,比靠yum history靠谱得多(因为yum history只记录 yum 操作的,用 rpm 直接装的它看不到)。

说到yum history,它确实是个好工具,yum history list能看到历史事务,yum history info <ID>能看到某次事务的完整明细,yum history undo <ID>甚至能回滚。但它有一个前提:yum 得能跑。而这次事故里 yum 恰恰是挂掉的,所以不能把希望全寄托在它身上。

6.4 一个我现在的操作习惯

最后分享一个我现在养成的习惯:在任何一台机器上装"会引入新依赖树"的软件之前,先开两个终端,一个用来操作,一个用来随时准备救场。救场那个终端什么都不干,就挂着tmux,里面提前cd /root/libbackup并把关键库的备份路径准备好。

听起来有点小题大做,但真出问题的时候,这个"准备好的第二终端"能省掉大量慌乱。因为一旦主终端里的包管理器崩了,你最需要的其实是冷静——而冷静的前提是知道退路在哪。我这次能在二十分钟内修好,很大程度上是因为备份和会话都是提前准备好的,剩下的只是执行。

至于 snapd 本身,那次修好之后我还是装上了,但换了种方式:先在测试机上完整走一遍依赖解析,确认它不会再动krb5和openssl的版本,才在生产机上执行。装完之后立刻跑一遍第 4.4 节那张验证表,全绿才算完事。多花十分钟,换来的是一整晚的安稳。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询