内网里折腾 AnolisOS 8.x,最容易卡住新手的不是内核参数也不是服务配置,而是最基础的那一步——配本地 repo 源。我前阵子接手一批只连内网的机器,AnolisOS 8.8 装完,第一件事想装个 nginx,敲下去直接回一句cannot find a valid baseurl for repo,当场就知道外网源指望不上了。说白了,本地源就是把安装镜像或者内网的文件服务挂在本地,让 dnf 从自己的硬盘上找包,彻底断掉对外网的依赖。这篇东西适合三类人看:一是要在离线机房里做初始化部署的运维,二是准备批量装机、想先把源规划好的实施人员,三是刚接触 AnolisOS、还分不清它和 CentOS 7 仓库结构差异的同行。顺带提一句,看到“repo”这个词别急着往代码仓库那边想,在系统运维语境里它说的就是软件包仓库,跟 Git 那个 repo 是两码事,虽然热词里两个都在飘。
1. 从一条 baseurl 报错说起:AnolisOS 8.x 本地源到底在解决什么
1.1 那条 "cannot find a valid baseurl" 到底在抱怨什么
很多人第一次遇到这个报错,第一反应是网络不通,于是去 ping 网关、去查 DNS,折腾半天发现网络好得很。其实 dnf 的意思非常直白:它按配置文件里的baseurl去取仓库元数据,取不到。取不到的原因有且只有几种——域名解析不了、HTTP 请求被拦、地址写错了、或者那个地址后面压根没有repodata目录。
CentOS 7 时代那句经典的cannot find a valid baseurl for repo: base/7/x86_64就是典型,仓库 ID 叫base,指向的 mirrorlist 地址失效了。AnolisOS 8 的写法不一样,仓库 ID 通常是BaseOS、AppStream这种,报错信息里会直接带出对应的 ID,比如for repo: BaseOS。看到 ID 就能立刻定位到是哪个.repo文件里的哪个[section]出问题,这比漫无目的地猜要高效得多。
我习惯的处理顺序是:先dnf repolist --all把当前所有仓库和状态打出来,看清楚哪些是enabled、哪些是disabled;再cat一遍/etc/yum.repos.d/下所有文件,确认没有一个失效的地址在里面。这两步做完,问题基本就浮出来了。
1.2 真正需要本地源的三种现场
不是所有人都需要本地源。如果你的机器能正常访问公共镜像站,那配个外网源就够了,本地源纯属多此一举。但下面这三种场景,本地源几乎是唯一解。
第一种是纯离线机房。生产网段和办公网物理隔离,机器连公网 DNS 都没有,任何指向互联网的baseurl都是死地址。这种环境里你不配本地源,机器就等于没有包管理能力,只能靠手工传 rpm 包一个个rpm -ivh,依赖关系能把人逼疯。
第二种是批量初始化。五十台、一百台机器要装同一套软件,如果每台都去外网拉包,带宽和镜像站的压力是小事,速度参差不齐、中途断流导致的失败才是麻烦。挂一份 ISO 到本地,装包速度直接按磁盘 IO 走,而且每台机器拿到的包版本完全一致,不会出现 A 机器装了nginx-1.20.1-1、B 机器装成nginx-1.20.1-2这种版本漂移。
第三种是公共源临时抽风或版本下线。上游镜像站调整目录结构、某个版本的仓库被归档,都会让原本好好的baseurl突然失效。这种情况下,把 ISO 挂在本地作为兜底源,能保证你手头的故障处理流程不被打断。我在一次紧急排障时就吃过这个亏,半夜公共源响应极慢,dnf install一直转圈,最后靠本地挂载的 ISO 把工具装上才把问题解决。
1.3 AnolisOS 8 的仓库结构跟 CentOS 7 完全不是一回事
这是最容易踩的一个认知坑。CentOS 7 的 DVD ISO 挂载后,包全都堆在根目录下的Packages/里,repodata也在根目录,所以你配一个baseurl=file:///mnt/iso就完事了。
AnolisOS 8 走的是 RHEL 8 那一套,ISO 挂载后根目录下是两个并列的目录:BaseOS和AppStream。前者放的是核心系统组件、基础命令、内核、glibc 这类必须存在的包;后者放的是应用流、开发工具、语言运行时,还有那个让人又爱又恨的 module(模块流)机制。两个目录各自带独立的repodata,也就意味着你必须写两个[section],分别指向这两个路径,一个都不能少。
漏写 AppStream 的后果很典型:dnf install一个普通的开发库会提示找不到包,但系统基础包又能装,让人误以为是包名写错了。实际上包就在 AppStream 里躺着,只是你没告诉 dnf 去哪儿找。理解这一点,后面所有配置都会顺理成章。
2. 镜像选型与挂载:本地源的地基必须在动手前打牢
2.1 DVD、everything、minimal 三种镜像的取舍
镜像选错,后面全白搭。AnolisOS 8.x 官方提供的镜像种类不少,跟本地源强相关的就三种,差异很大。
| 镜像类型 | 体积量级 | 包覆盖范围 | 适合做本地源吗 |
|---|---|---|---|
| DVD | 约 8-10 GB | BaseOS 全量 + AppStream 全量 | 适合,最常用 |
| everything | 约 15 GB 以上 | 全量包,含大量可选组件 | 适合,覆盖最全 |
| minimal | 约 2 GB 以内 | 仅够完成最小化安装 | 不适合,装不了额外软件 |
| boot | 几百 MB | 仅引导,安装时联网取包 | 完全不适合 |
结论很直接:做本地源请用 DVD 或 everything。minimal 镜像装系统够用,但它里面根本没有完整的Packages集合,你拿它当源,等于开了个空仓库。我见过有人拿 boot 镜像挂上去当源,然后反复检查 repo 文件写了十几遍,问题其实出在镜像本身。
选 everything 还是 DVD?如果内网机器需要装容器工具链、多种语言运行时、图形化组件,everything 更省心,一次挂载全都有。如果只是常规服务器角色,DVD 完全够,体积还小一半,传输和挂载都更快。
2.2 下载后先校验,别等装到一半才发现镜像坏了
这一步很多人跳过,然后在配置阶段被各种莫名其妙的现象折磨:repodata读不出来、元数据校验失败、包解压报错。镜像传输过程中出错的概率并不低,尤其是用 U 盘拷贝或者内网 FTP 中转的时候。
校验方式就是用官方给出的校验值比对 SHA256:
sha256sum AnolisOS-8.8-x86_64-dvd.iso拿到的结果跟官方发布页上的值逐位比对,一致才继续。别嫌这一步慢,一个 9 GB 的镜像算校验值也就一两分钟,比后面花两小时排查一个坏镜像划算得多。
还有个容易被忽略的点:ISO 文件本身要放在一个不会被清理的目录里,比如/opt/iso/或者独立的数据盘,千万别随手扔在/tmp或者某个用户的家目录里。系统一重启清空/tmp,你的本地源就凭空消失了,而且因为fstab里还留着挂载项,开机时还会卡住报错。
2.3 挂载点怎么选,以及怎么让它开机自动挂
挂载点我用得最多的是/mnt/iso,简单直观。也有同行喜欢放/media/dvd,无所谓,只要路径后续在 repo 文件里写对就行。关键动作是建目录、挂载、验证三步:
mkdir -p /mnt/iso mount -o loop,ro -t iso9660 /opt/iso/AnolisOS-8.8-x86_64-dvd.iso /mnt/iso ls /mnt/isols的输出应该能看到BaseOS、AppStream、EFI、isolinux、images这些东西。如果只看到Packages和repodata,说明你挂的是 CentOS 7 系的镜像,拿错盘了。-o loop是把普通文件当块设备用,ro是只读挂载,这个参数建议一定加上,避免误写损坏镜像。
重点是持久化。mount命令只在当前开机周期有效,重启就没了。要开机自动挂,得写进/etc/fstab:
echo "/opt/iso/AnolisOS-8.8-x86_64-dvd.iso /mnt/iso iso9660 loop,ro 0 0" >> /etc/fstab注意:改完
fstab之后一定要执行mount -a验证一遍。fstab 写错会导致系统启动时进入紧急模式,而离线机房里往往没有带外管理,恢复起来非常痛苦。mount -a无报错输出,才算真正安全。
还有一个细节:fstab里最好用绝对路径写 ISO 文件位置,别用相对路径或者带变量的写法。另外如果镜像放在 NFS 或者 iSCSI 挂载的盘上,fstab里还要加_netdev选项,否则开机顺序不对,本地源同样会挂载失败。
3. repo 文件怎么写:从 file:// 到局域网 HTTP 源
3.1 最小可用的本地源配置
挂载点稳了之后,配置文件就是水到渠成的事。在/etc/yum.repos.d/下新建一个文件,名字随便起,但最好能一眼看出用途,比如anolis-local.repo:
[anolis-local-BaseOS] name=AnolisOS 8 Local BaseOS baseurl=file:///mnt/iso/BaseOS enabled=1 gpgcheck=0 [anolis-local-AppStream] name=AnolisOS 8 Local AppStream baseurl=file:///mnt/iso/AppStream enabled=1 gpgcheck=0这里有个必须记住的书写规则:file://后面跟绝对路径时是三个斜杠。第一个和第二个斜杠是协议本身的一部分,第三个才是路径的起始斜杠。写成file://mnt/iso/BaseOS是错的,dnf 会把它当成主机名叫mnt的地址去访问,报错时还很不直观。这个坑我见过太多人踩,包括我自己早期也踩过。
3.2 为什么 BaseOS 和 AppStream 必须写两个 section
前面提过 ISO 是两个并列目录,这里展开说说为什么不能偷懒合二为一。dnf 的每个[section]代表一个独立的仓库,它只认你这个 section 指向的baseurl下面的repodata。如果你只写一个 section 指向/mnt/iso,dnf 会去找/mnt/iso/repodata/repomd.xml,而这个文件在 AnolisOS 8 的 ISO 上是不存在的,它藏在BaseOS/和AppStream/里面。结果就是元数据获取失败,仓库直接被标记为不可用。
两个 section 的分工也很清晰:BaseOS负责基础系统,AppStream负责应用和模块。它们之间是有依赖关系的,比如你装php,包本体在 AppStream,但它依赖的一些底层库可能在 BaseOS。两个仓库同时启用,dnf 才能完整地解析依赖树。只启用其中一个,会出现"包找得到但依赖解不开"的诡异现象。
命名上的建议是前缀加个标识,比如anolis-local-BaseOS,别直接叫BaseOS。原因很简单,如果这台机器上还残留着指向外网的官方 repo 文件,ID 撞车会引起混乱,dnf repolist输出里两个同名仓库谁生效说不清楚。加前缀是最省事的规避方式。
3.3 逐字段拆解:baseurl、gpgcheck、enabled、cost、priority
配置文件里能写的字段不少,常用的这么几个,搞懂含义比死记模板有用。
baseurl:仓库根地址,可以直接用file://,也可以是http://、ftp://。支持写多条,dnf 会依次尝试。name:仓库的人类可读名称,出现在dnf repolist的输出里,写得清楚点,将来自己或者同事排障的时候能省不少事。enabled:1启用,0禁用。这个字段的最大价值在于临时切换,需要的时候改一下就能把一个仓库摘出去,不用删文件。gpgcheck:是否对包做 GPG 签名校验。本地 ISO 源通常图省事关掉,但生产环境更稳妥的做法是开启并指定gpgkey。gpgkey:签名密钥文件路径,AnolisOS 通常在/etc/pki/rpm-gpg/下,具体文件名建议先ls看一眼确认。cost:多个仓库提供同一个包时的成本权重,默认 1000,值越小优先级越高。priority:需要装dnf-plugins-core才能生效的优先级字段,数值越小越优先,用来防止某个仓库的包覆盖掉另一个仓库的版本。module_hotfixes:处理模块流冲突时用的,一般场景用不上,遇到模块包被过滤才需要开。
如果开启 GPG 校验,写法是这样的:
[anolis-local-BaseOS] name=AnolisOS 8 Local BaseOS baseurl=file:///mnt/iso/BaseOS enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-anolis关掉校验的理由很实际:ISO 是你自己校验过哈希值的,来源可信,再走一遍签名校验只是增加配置复杂度。但如果本地源是通过内网 HTTP 共享的,多台机器都在用,那还是打开校验更稳,能防止文件在传输过程中被意外改动。
3.4 把本地源升级成内网共享源
单机挂 ISO 只解决了自己,如果你手上是二十台机器,一台台传 ISO 既不现实也浪费磁盘。这时候更好的做法是选一台机器当源服务器,把 ISO 里的内容发布出去,其他机器通过 HTTP 访问。
标准做法是用 Apache:
dnf install -y httpd mkdir -p /var/www/html/anolis8 mount -o loop,ro -t iso9660 /opt/iso/AnolisOS-8.8-x86_64-dvd.iso /mnt/iso cp -a /mnt/iso/BaseOS /mnt/iso/AppStream /var/www/html/anolis8/ restorecon -Rv /var/www/html/anolis8 systemctl enable --now httpd这里有个特别容易被忽略的点:restorecon。SELinux 在 Enforcing 模式下,Apache 只能读取带有httpd_sys_content_t标签的目录。你用cp复制过去的文件继承的是源目录的标签,Apache 会返回 403,而客户端看到的报错是cannot find a valid baseurl,完全没有提权限二字,排查方向极其容易被带偏。执行一次restorecon -Rv把标签重置,问题立刻消失。
防火墙如果开着,还要放行 HTTP:
firewall-cmd --permanent --add-service=http firewall-cmd --reload客户端那边的 repo 文件就换成服务器的地址:
[anolis-net-BaseOS] name=AnolisOS 8 Shared BaseOS baseurl=http://10.0.0.10/anolis8/BaseOS enabled=1 gpgcheck=0用 IP 而不是主机名,是为了避免去依赖 DNS 解析,内网环境下这一步能省掉很多麻烦。共享源的另一个好处是后续更新只改服务器一份,客户端不用动。
4. 生效验证:clean、makecache、repolist 的顺序不能乱
4.1 旧缓存是最大的干扰源
repo 文件写完了,很多人直接dnf install,结果报错说找不到包,然后开始怀疑配置文件。实际情况往往是 dnf 还在用之前的缓存元数据。
dnf 会把仓库元数据缓存在/var/cache/dnf/下面,按仓库 ID 分目录存放。你改了baseurl,但缓存里还是旧地址的数据,dnf 在缓存有效期内不会重新去拉。所以改完配置的第一步永远是:
dnf clean all dnf makecacheclean all会清掉元数据和包缓存,makecache则按当前配置重新生成。执行makecache时最好盯着输出,它会逐个仓库打印状态。看到某个仓库报Failed to synchronize cache就说明这个仓库还是有问题,需要回头查配置。
顺序千万别倒过来,makecache之后再clean all等于白干。这个顺序我一开始也搞反过,当时还纳闷为什么清完缓存再装包反而变慢了。
4.2 屏蔽原来的外网源
AnolisOS 8 装完之后,/etc/yum.repos.d/里通常已经有一批指向公共镜像的 repo 文件。这些文件在离线环境里全是死地址,保留它们的后果是每次dnf操作都要先等超时——每个失效仓库都要等 HTTP 连接超时,几十秒就这么耗掉了,体验极差。
处理办法有两种。简单粗暴的是把它们挪走:
mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ mv /etc/yum.repos.d/backup/anolis-local.repo /etc/yum.repos.d/注意最后一行要把自己的本地源文件挪回来,否则连本地源一起被移走了。更稳妥一点的做法是保留文件,把里面的enabled全改成0:
sed -i 's/^enabled=1/enabled=0/g' /etc/yum.repos.d/*.repo这个命令有个副作用,它会连你自己的本地源一起关掉,执行完记得手动把anolis-local.repo里的enabled改回1。我一般会在执行前先把自己那个文件挪出去,处理完再挪回来,逻辑上更清晰。
还有个更精准的方式是用dnf config-manager单独禁用某个仓库:
dnf config-manager --set-disabled 'anolis*' dnf config-manager --set-enabled 'anolis-local-*'这个工具来自dnf-plugins-core,没装的话先装上。它的好处是不动文件内容,纯靠配置状态切换,回滚也方便。
4.3 module 元数据带来的额外一层坑
AnolisOS 8 的 AppStream 里有 module 机制,同一个软件可以有不同的模块流,比如不同版本的 PHP、Node.js。这一层机制会在本地源上多出一个坑:如果repodata里的模块元数据没有正确读取,某些包会被默认过滤掉,表现出来就是"包明明在 ISO 里,但 dnf 就是找不到"。
验证模块元数据是否正常,用这个命令:
dnf module list正常的话会打出一堆模块名、流版本和状态。如果输出为空或者报错,说明模块元数据没加载成功,多数情况下是 AppStream 的 repo 配置有问题,回去检查baseurl是不是精确指向了/mnt/iso/AppStream。
安装带模块的包时,如果遇到"多个流冲突"的提示,可以显式指定流:
dnf module install php:7.4具体有哪些流可选,dnf module list php一看便知。本地源和模块机制配合本身没有问题,关键是两个仓库都要启用,元数据都要能读到。
4.4 实测验证与结果判读
配置全部做完,该验证的还是要验证。三个命令就够:
dnf repolist dnf repolist --all dnf install -y treednf repolist显示的是当前启用且可用的仓库,输出里应该只有你配的本地源,仓库数量、包数量都有统计。如果某个仓库的包数量显示为 0,说明元数据读到了但内容是空的,八成是baseurl指到了上一层目录。
dnf repolist --all会把禁用的仓库也列出来,用来确认没有遗漏的失效源。
最后用一个无足轻重的小包做实际安装测试,tree就挺合适,体积小、依赖简单。装完再rpm -q tree确认一下,整个链路就算跑通了。我习惯再补一个dnf remove tree清场,避免给基础镜像留下多余包。
5. 配完装不上包:一条完整的排查链路
5.1 挂载丢了是第一嫌疑
排障要从最外层往里查,第一站永远是挂载点。ls /mnt/iso如果输出为空或者报No such file or directory,后面的配置再完美也没用。
挂载丢失最常见的原因是重启后fstab没生效。检查两件事:fstab里那一行是不是还在,执行mount -a有没有报错。还有一种情况是 ISO 文件被移动或者删除了,fstab里的路径变成死路径,开机时挂载失败。这种问题在/var/log/boot.log或者dmesg里能翻到线索。
我给自己定过一条规矩:所有涉及本地源的机器,交付前必须做一次重启验证。不重启你永远不知道fstab写对没写对,而离线机房重启一次的代价可能是一趟现场。
5.2 GPG 校验失败要不要关
gpgcheck=1但gpgkey没配或者路径写错时,装包会报Public key for xxx.rpm is not installed。这时候有两个选择。
关闭校验最快:
gpgcheck=0但更正确的做法是找到密钥文件并指定。先看看系统里有哪些:
ls /etc/pki/rpm-gpg/AnolisOS 的密钥文件名里通常带 anolis 字样,确认之后写进配置。如果系统里没有,ISO 的根目录下一般也放了一份,可以复制过来。生产环境我倾向于打开校验,多一层保障,而且配置一次就长期有效。
5.3 repodata 缺失与路径细节
如果报的是Failed to download metadata for repo或者repomd.xml not found,问题基本锁定在路径上。手动验证一下:
ls /mnt/iso/BaseOS/repodata/repomd.xml文件存在,说明源侧没问题,那就回头检查 repo 文件里的baseurl。常见的书写错误有这么几个:三斜杠写成两斜杠、路径大小写不对(Linux 是大小写敏感的,baseos和BaseOS完全不同)、路径末尾多加了斜杠导致拼接出双斜杠、把/mnt/iso当成了baseurl而不是/mnt/iso/BaseOS。
这些都是低级错误,但在深夜排障的时候特别容易犯。我的习惯是把baseurl那一行复制出来,用ls把file://前缀去掉后粘贴验证,一分钟确认,比反复读配置快得多。
5.4 排查速查表
把上面的经验整理成一张表,出问题的时候按顺序过一遍。
| 报错或现象 | 最可能的原因 | 处理方式 |
|---|---|---|
| cannot find a valid baseurl | 挂载丢失或 baseurl 写错 | 检查ls /mnt/iso,核对三斜杠与路径 |
| Failed to download metadata | 指向目录无 repodata | 确认路径到BaseOS/AppStream这一层 |
| Public key is not installed | gpgkey 未配置 | 指定密钥路径或临时gpgcheck=0 |
| 包在 ISO 里但找不到 | AppStream 未启用或模块未加载 | 检查两个 section,跑dnf module list |
| repolist 包数量为 0 | baseurl 指到了上一层 | 逐级ls确认 repodata 位置 |
| 命令执行长时间卡住 | 存在失效的外网源 | 禁用或移走旧 repo 文件 |
| HTTP 共享源报 403 | SELinux 上下文不对 | 执行restorecon -Rv /var/www/html |
这张表基本上覆盖了九成以上的现场问题。剩下的疑难杂症,去/var/log/dnf.log和/var/log/dnf.rpm.log里翻,日志信息比终端提示详细得多。
6. 运维视角的长期维护:让这套源活得更久
6.1 版本升级时的处理方式
AnolisOS 8.x 的小版本迭代(比如 8.6 到 8.8)会带来包版本更新,如果内网机器需要跟着升级,本地源也要同步替换。
处理思路有两套。保守方案是换盘:把新的 ISO 传进服务器,改/opt/iso/下的文件名,同时更新fstab里的路径,重新挂载,dnf clean all && dnf makecache。这套流程简单,回滚也容易,出问题把旧 ISO 换回来就行。
激进方案是保留多个版本的源同时提供,用priority字段控制优先级,让 dnf 优先用新版本,同时在某个包出兼容问题时还能退回旧版本。这个方案适合有严格版本控制需求的场景,但配置复杂度明显上升,仓库数量翻倍,元数据加载也变慢。中小规模环境我一般不推荐,简单可靠比灵活更重要。
有一点必须强调:小版本升级时,gpgkey文件有可能跟着变。升级之后如果突然冒出签名校验失败,先去看密钥文件是不是被替换了。
6.2 一个自用的检查脚本
重复操作多了就该脚本化。我给自己写了个检查脚本,放在/usr/local/bin/check-local-repo.sh,跑一遍就能知道本地源的状态是否健康:
#!/bin/bash ISO="/opt/iso/AnolisOS-8.8-x86_64-dvd.iso" MNT="/mnt/iso" echo "== 1. ISO 文件 ==" [ -f "$ISO" ] && echo "OK: 镜像存在" || { echo "FAIL: 镜像不存在"; exit 1; } echo "== 2. 挂载状态 ==" mountpoint -q "$MNT" && echo "OK: 已挂载" || echo "FAIL: 未挂载" echo "== 3. repodata ==" for d in BaseOS AppStream; do [ -f "$MNT/$d/repodata/repomd.xml" ] \ && echo "OK: $d repodata 正常" \ || echo "FAIL: $d repodata 缺失" done echo "== 4. 仓库列表 ==" dnf repolist 2>/dev/null | tail -n +1脚本本身不复杂,价值在于把检查动作固化下来。排查故障最怕漏项,有了脚本,每次按同一套流程走,不会因为着急而跳过某一步。这个脚本我也一起交给过同事,反馈是交接和巡检的时候确实省事。
6.3 多机统一源的下发思路
最后一件事是怎么让几十台机器用上同一份源配置。手工一台台改是不现实的,思路有三种。
最简单的是把 repo 文件放到内网 HTTP 服务器上,客户端用一条命令拉下来:
wget -O /etc/yum.repos.d/anolis-local.repo http://10.0.0.10/repo/anolis-local.repo dnf clean all && dnf makecache这套流程可以直接写进装机后的初始化脚本,配合自动化工具批量执行。
稍微规范一点的做法是做成一个 rpm 包,把 repo 文件和fstab配置一起打进包里,装机后dnf install一下,源配置和挂载全部到位。这种方式的好处是能纳入版本管理,每次变更都有记录,出问题可以回滚到上一个版本。
再进一步就是把这一整套东西纳入配置管理工具的管控范围,每台机器的 repo 文件状态可以随时查询和纠正。规模上百台之后,人工核对状态的成本会迅速上升,早点把这层自动化做起来,后面的维护量是断崖式下降的。
我自己是从第二个方案过渡到第三个的。中间踩过的坑是:早期用 wget 拉文件,服务器上的文件被误改了一行没发现,结果所有新装机器都拿到了一份错误的配置,等到有人反馈装不上包才发现。加了校验值比对之后就再没出过类似问题,所以无论用哪种下发方式,都建议在脚本里对文件做一次校验。
最后分享一个实操中的小体会:本地源的配置文件和挂载信息,最好单独记录下来放在内网文档里,包括 ISO 的完整文件名、存放路径、挂载点、SELinux 相关处理。这些东西在半年后回头看的时候,如果没有记录,光靠翻服务器上的配置文件是拼不出完整上下文的。我吃过这个亏,一台老机器的 ISO 路径被人挪过,fstab里的记录又没更新,接手的人查了大半天才搞明白。