拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Linux卡在emergency mode?fstab的UUID错配是主因

周六早上我远程连家里那台Linux NAS结果怎么都ping不通。过了一会儿家人拍来一张照片屏幕停在黑底白字的启动界面上面明晃晃一行字“Welcome to emergency mode!”看到这行字我反而松了口气因为这类故障我处理过太多次了。Linux系统卡在启动界面进不去、直接掉进紧急模式十次里有八九次是/etc/fstab里面的UUID和硬盘实际的UUID对不上系统在引导阶段找不到要挂载的分区干脆降级把控制权交回给用户。这台机器的数据盘前阵子刚重新分过区我猜多半是fstab里还残留着旧分区的UUID。输入root密码登录查日志一看果不其然——挂载失败的分区正是那会儿动过的盘。这篇文章适合谁看自己折腾Linux桌面或服务器的买了一台二手服务器准备装NAS的搞嵌入式开发经常要改启动配置的都应该把这篇存下来。不需要你多熟悉systemd只要会敲命令能看懂路径照着下面的排查链路一步步走大概率能自己把系统救回来。1. 紧急模式不是系统崩了是systemd在跟你对暗号很多人第一次看到emergency mode那几行字就慌了以为硬盘坏了、系统报废了。其实不是。我可以负责任地告诉你绝大多数emergency mode都是挂载配置问题不是硬件物理损坏。系统给出的提示原文一般是这样的Welcome to emergency mode! After logging in type journalctl -xb to view system logs systemctl reboot to reboot systemctl default or ^D to try again to boot into default mode. Cannot open access to console the root account is locked.最后那句话不同发行版不一样有的会提示root被锁有的直接让你输root密码。不管哪种你先要知道emergency mode到底是怎么触发的。Linux系统尤其是用了systemd的发行版比如CentOS 7、Ubuntu 16.04、Debian 8在开机引导阶段会按照/etc/fstab文件一条条去挂载分区。fstab的全称是File System Table相当于一份“分区挂载清单”。systemd在启动时会根据这份清单生成对应的挂载单元如果某个挂载项失败了比如设备不存在、UUID对不上、文件系统损坏systemd的依赖关系就会断掉。因为默认的local-fs.target是要等所有fstab里的分区都挂载成功才算完成一旦中间断了系统就进不了multi-user.target或者graphical.target最终被降到最底层的emergency.target。这里要区分两个概念rescue.target和emergency.target。很多教程混着说实际上不一样。rescue.target救援模式会尝试把本地文件系统都挂载好然后给你一个root的shell适合修复系统配置。emergency.target紧急模式更底层它只挂载根文件系统而且通常是只读的其他分区一概不管是systemd能给你的最小运行环境。大多数发行版在fstab挂载失败后会落到emergency.target所以你在“紧急模式”里看不到自己的数据盘这是正常的不是数据丢了。如果启动时没看到emergency mode提示而是卡在黑屏或者直接停在“Reached target Local File Systems (Pre)”之类的状态那就是挂载单元超时或者死锁后面我们单独说。另外一个特别常见的误判是以为emergency mode是硬盘坏了所以找不到设备。实际上很多时候设备在系统里活得好好的只是fstab里写的UUID是旧的或者fstab里写的是/dev/sdb1这种设备路径而内核这次枚举出来的盘符变成了/dev/sdc1。同一个物理分区三个字段/dev/sdb1、/dev/disk/by-uuid/xxxx、UUIDxxxx指向的可能都是它但只有UUID是永久的设备路径会变。这就是为什么现代发行版默认都用UUID而不是设备路径挂载硬盘——盘符的顺序本身就不稳定尤其在挂了多块硬盘、或者BIOS里存储设备探测顺序有变化的时候/dev/sda可能第二天就变成/dev/sdb如果fstab里写的是设备路径开机基本上就是赌博。我把常见触发场景整理成了表格你可以先对号入座触发场景典型表现根因fstab里UUID写错或残留旧UUID报错提示找不到设备blkid能看到盘分区后没有同步更新fstab用dd/Clonezilla/再生龙克隆过系统盘新机器报一堆挂载失败克隆盘继承了旧分区的UUID换过主板、改动过BIOS启动顺序盘符顺序变了fstab用了设备路径而不是UUID拔掉了某块数据盘/备份盘开机进emergency modefstab还挂着那块盘没加nofail参数swap分区UUID不对挂载swap失败格式化过swap分区UUID变了文件系统损坏卡在fsck界面或提示Dependency failed需要手动修复文件系统2. 一步步揪出元凶从journalctl到blkid的完整排查路径进了紧急模式以后别急着瞎改东西也别急着重启。按我下面的顺序来基本两分钟就能定位问题。第一步把根文件系统重新挂载为可写紧急模式下根文件系统默认是只读的ro因为systemd为了保证最小环境的稳定不开任何不必要的东西。你如果直接打开fstab想改保存的时候会提示“Read-only file system”改了个寂寞。所以进来第一件事执行mount -o remountrw /再确认一下mount | grep / 看到根分区挂载方式带rw就说明可以写入了。这条命令建议养成肌肉记忆不管是emergency mode还是rescue mode第一步永远是它。第二步查看启动日志找到挂载失败的元凶紧急模式界面里明确提示了用journalctl -xb查看日志。这条命令的意思是-x显示辅助说明会附带一些SVN代码含义解释-b表示显示本次启动boot的日志。执行journalctl -xb日志一般很长一屏根本看不完你需要用方向键或者PageUp/PageDown翻页按q退出。我习惯的做法是配合grep过滤直接找失败相关的关键词journalctl -xb | grep -i fail\|error\|mount也可以把错误信息直接保存成文件再慢慢看journalctl -xb /tmp/boot.log grep -i fail /tmp/boot.log日志里你会看到类似这样的关键片段Feb 12 08:12:33 nas systemd[1]: Mounting /mnt/data... Feb 12 08:12:34 nas systemd[1]: mount: /mnt/data: new mount failed: No such device or address. Feb 12 08:12:34 nas systemd[1]: Failed to mount /mnt/data. Feb 12 08:12:34 nas systemd[1]: Dependency failed for Local File Systems.看到“No such device or address”基本就实锤了fstab里写的设备和系统实际看到的设备对不上。这时不要着急去翻fstab猜直接把系统里真实的UUID列出来。第三步用blkid列出当前系统实际的分区UUIDblkidblkid会列出当前系统能识别到的所有块设备和它们的UUID、文件系统类型等。举个例子输出长这样/dev/sda1: UUID2b6d4b36-8c7f-4b4f-9a02-5f5d9e6f3e2a BLOCK_SIZE4096 TYPExfs PARTUUIDd0f0c5f2-01 /dev/sda2: UUIDa1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d TYPEswap PARTUUIDd0f0c5f2-02 /dev/sdb1: UUIDc9d8e7f6-5a4b-3c2d-1e0f-abcdefabcdef BLOCK_SIZE4096 TYPEext4 PARTUUIDa1b2c3d4-05然后把这份输出和fstab里的记录做对比。fstab在/etc/fstab直接查看cat /etc/fstab正常情况下你会看到类似这些行# /etc/fstab # file system mount point type options dump pass UUID2b6d4b36-8c7f-4b4f-9a02-5f5d9e6f3e2a / xfs defaults 0 1 UUIDa1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d swap swap defaults 0 0如果fstab里的某个UUID在blkid的输出里完全找不到那这个分区就是孤儿了。要么盘被拔掉了要么分区被重建过、UUID变了。如果blkid里有一个UUID和fstab里写的长得不一样但分区内容明显是同一个盘那就是分区格式化或重建导致UUID变了fstab没跟着更新。第四步判断是哪个挂载点失败如果journalctl输出太杂还有一个更直接的方法在紧急模式下逐条手动挂载fstab里的所有分区哪条报错哪条就是病根。可以用下面这样的循环命令注意如果某一行是特殊选项需要手动看情况mount -amount -a表示挂载fstab中所有未挂载的文件系统。它会按fstab顺序尝试哪一行出错它会直接打印哪一行对应的错误。比如mount: /mnt/data: mount point does not exist.这又是另一种常见问题fstab里指定的挂载点目录不存在。别忘了挂载点本身要提前建好。这种情况新建目录就行mkdir -p /mnt/data3. 修改UUID挂载改fstab的正确姿势和背后逻辑定位到具体是哪一行出了问题接下来就是修复。修fstab不是拿个文本编辑器改了UUID就完事有几个操作细节和验证步骤能帮你少走弯路。3.1 动手前先备份这条真是老生常谈但每次都会有人省略。我见过不少人在紧急模式里手一抖多删一行系统重启后连emergency mode都进不去了只能拿Live CD去救。改任何系统配置文件第一件事永远是备份cp /etc/fstab /etc/fstab.bak.$(date %Y%m%d%H%M)备份文件放当前目录就行它跟fstab待在同一个分区里。万一改坏了系统启动到单用户模式或者用安装盘挂载根分区把备份复制回来就能恢复。注意备份文件名不要带中文、不要带空格越简单越好。3.2 修改fstab中的UUID在紧急模式下vi/vim的用法和平时一样。打开文件vi /etc/fstab找到那个对不上的UUID行把旧的UUID替换成blkid输出里正确的UUID。这里有个易错点复制UUID的时候不要带引号也不要带前后空格。比如UUIDc9d8e7f6-5a4b-3c2d-1e0f-abcdefabcdef /mnt/data ext4 defaults 0 2如果你的分区之前是swap分区那行应该长这样UUIDb1c2d3e4-5f6a-7b8c-9d0e-1f2a3b4c5d6e none swap sw 0 0顺便把fstab的六列字段含义给你整理一下看不懂的行对着查列含义例子第1列设备标识UUID或设备路径UUIDxxxx或/dev/sda1第2列挂载点swap分区写none/boot、/home、none第3列文件系统类型ext4、xfs、swap、ntfs第4列挂载选项defaults、noatime、nofail第5列是否用dump备份0为不备份0第6列fsck检查顺序根分区1其他2swap/光驱013.3 改完先别重启用mount -a验证这是最关键的一步。很多人改完fstab直接reboot结果改错了又进一次紧急模式来回折腾。正确姿势是改完后先用命令验证mount -a这条命令会尝试挂载所有fstab里配置的文件系统。如果执行后没有任何输出、也没有报错说明这一版fstab在语法和设备匹配上基本没问题你再执行systemctl daemon-reload reboot如果你改了好几个挂载点想单独验证某一个也可以直接手动mount那个分区mount /mnt/data注意mount这里不带设备参数也行的前提是fstab里有对应挂载点的配置它会自动去fstab里找。3.4 如果报错是“wrong fs type”或者“mount point does not exist”这两个报错和UUID无关但同样害人。mount: /mnt/data: wrong fs typefstab第3列写的文件系统类型和分区实际格式对不上。比如分区实际是ext4你写了xfs。用blkid能看到真实的TYPE改回来即可。mount point does not exist挂载点目录不存在。用mkdir -p /mnt/data建目录即可。注意fstab里写的是多级路径要先确保父目录都存在。4. 比UUID更值得关注的三种特殊场景swap、克隆盘、可插拔盘上面那套流程能解决绝大多数fstab相关的emergency mode但有三类特殊场景光改UUID还不够得单独处理。4.1 swap分区失败swapon和fstab的双重检查swap分区交换分区写错UUID同样会触发emergency mode。但它的表现和普通数据盘不太一样。实际报错可能是Feb 12 08:12:33 nas systemd[1]: Reached target Swap.或者干脆卡在swap挂载上。如果你用blkid发现swap分区还在但fstab里的UUID是旧的直接改如果blkid里压根没有typeswap的行了说明这个swap分区被删除或者格式化成别的文件系统了。这时候两个选择要么把swap那行从fstab里删掉要么重新建一个swap分区用mkswap注意会清空分区数据。另一个常见误区swap分区那行的挂载点要写none类型写swap选项写sw别写默认的defaults。某些发行版对defaults的swap也能识别但严格按规范来最稳妥。4.2 克隆盘/镜像还原后的UUID冲突不只是fstab的问题用dd、Clonezilla、再生龙这类工具把系统盘整体克隆到新硬盘或者从模板虚拟机导出镜像目标机开机后大概率会出现emergency mode。原因是克隆出来的盘和源盘UUID一模一样但你原来的环境里可能还同时插着源盘两个分区UUID冲突或者目标机的块设备命名变了。这时候很多人只改fstab改了重启还是报错——因为还有另一个地方藏着旧UUIDGRUB引导配置文件。有些发行版比如CentOS/RHEL系列在/etc/default/grub或者生成好的/boot/grub2/grub.cfg里会写死rootUUIDxxxx这样的内核引导参数。如果这个UUID对不上内核连根分区都挂不上系统进度可能连emergency mode都到不了直接卡在更早的阶段。排查方法是执行cat /proc/cmdline这个文件记录的是内核本次启动实际接收到的引导参数。如果里面显示rootUUID旧UUID而blkid显示根分区已经是新UUID你就需要更新GRUB配置grub2-mkconfig -o /boot/grub2/grub.cfg # 或者Debian/Ubuntu系 # update-grub注意这一步可能需要chroot或者正常系统环境下执行如果你人已经在emergency mode且根分区能只读挂载上可以先把fstab修好然后用grub2-mkconfig重新生成引导配置。最稳的是用Live CD启动chroot进系统再执行引导修复但那是另一个话题这里不展开。4.3 给可插拔设备加nofail把“可选盘”从启动依赖里摘出来这是我最想强调的一件事如果你fstab里挂了外接移动硬盘、USB存储、或者不是每次开机都一定在的备份盘请在挂载选项那一列加上nofail。比如UUIDxxxx-xxxx /mnt/backup exfat defaultsnofailx-systemd.device-timeout10 0 2nofail的意思就是告诉systemd这块盘挂不上也没关系不要因为它失败就阻塞系统启动。这个参数能救你于水火。我见过不止一个人因为一块平时插着的移动硬盘偶尔没插导致整台服务器进不了系统只能远程失联后干瞪眼。与之配套的参数还有x-systemd.device-timeout10意思是等待设备出现最多10秒超时就放弃。默认情况下systemd对某些设备类型的等待时间可能长达90秒甚至更久你会觉得系统“卡死”在启动界面其实是在等一个永远不会出现的设备。加上这个超时参数最多等多长时间你自己说了算。注意nofail是给非系统盘准备的。根分区、/boot、/home这种系统关键分区千万不要加nofail否则系统遇到真正的磁盘故障时也照常启动然后会因为缺少模块在半路出各种奇怪问题把故障掩盖起来反而更难排查。5. 那些“看似UUID问题其实不是”的启动卡死场景处理过大量引导问题之后你会发现emergency mode只是Linux启动故障里比较友好的那一种。还有几种情况现象相似但根因完全不同有时候会把人绕晕。5.1 文件系统损坏fsck会在启动时和你对话如果分区确实还在、UUID也对得上但文件系统内部有损坏比如突然断电、强行关机systemd的启动过程会触发fsck检查。这时候屏幕可能不会进emergency mode而是卡在一段文字界面提示你手动运行fsck/dev/sdb1 contains a file system with errors check forced.这种情况下你要么输入root密码执行修复要么在emergency mode里手动运行fsck /dev/sdb1注意执行fsck前要确保对应分区没有被挂载。如果它在fstab里你正在emergency mode里通常不会自动挂载可以放心修。修完再重启。fsck修完以后UUID不会变不需要改动fstab。这个场景经常被误报成“fstab出问题”白白折腾半天。5.2 根分区挂载失败连emergency mode都进不去的情况前面说的所有修复都建立在systemd还能把根分区挂上、让你进emergency mode的前提下。如果根分区自己的UUID在引导参数里就是错的或者根分区所在设备根本没被内核识别系统会卡在更早的阶段——initramfs阶段可能直接给你一个dracut shellCentOS/RHEL系或者busybox shellUbuntu/Debian系dracut:/#这时候看到的是dracut提示符而不是emergency mode。说明内核没能从根设备上读取根文件系统系统连systemd都还没跑起来。处理方式通常是在dracut shell里检查实际可用的设备blkid把实际根分区的UUID记下来然后重启用GRUB引导按e编辑启动项把rootUUID旧值改成刚才查到的正确UUID按CtrlX或F10引导进去后再重新生成grub配置。如果你对GRUB编辑不熟建议用系统安装盘或Live USB引导chroot进去修复更加万无一失。5.3 网络挂载NFS/CIFS导致的启动卡死等设备等到天荒地老如果你fstab里写了NFS或者SMB/CIFS网络共享的挂载项比如家里NAS的共享目录而系统启动时网络还没就绪或者NAS没开机systemd会因为网络挂载单元一直等待表现为开机过程非常漫长甚至像卡死。这种不一定会进emergency mode因为systemd还在等超时。解决方案就是在网络挂载项的选项里加_netdevnofailx-systemd.automountx-systemd.device-timeout30_netdev告诉systemd这是一个网络设备必须等网络就绪后再尝试挂载。x-systemd.automount是懒挂载模式开机时不真正挂载等有人访问挂载点时再触发挂载可以大幅提升开机速度。这个方案适合那种“访问到了才需要通的”网络共享。6. 应急处置时的几个实操心得最后分享一些平时不容易从文档里学到的经验都是我在真实环境里踩坑踩出来的。关于root账户被锁的问题。有些发行版比如Ubuntu默认root密码是随机的锁定的状态emergency mode里提示无法登录root。这种情况下如果你必须得进emergency mode大多数时候需要在GRUB引导菜单里按e编辑启动项在内核参数那一行末尾加上systemd.unitrescue.target或者single然后再引导这样系统会以提权方式给你一个shell。这个操作比修fstab更偏底层我建议大家在虚拟机里先练一遍。journalctl日志里红字优先原则。用journalctl -xb | grep -i fail过滤到的内容可能很多看的时候优先找包含Failed to mount、Dependency failed for这些关键字的行它们会直接指向出问题的挂载单元。那些Failed to start之类的内容多数是挂载失败的连带反应不用管。记住找准主故障点比把所有报错都修一遍重要得多。把要改的行注释起来而不是删掉。修改fstab时拿不准的那行先用#注释掉重启验证没问题后再清理。注释行不会参与挂载但保留了原始记录出了问题你还能看到原来写的是什么对排查非常有用。一个行为准则不要总盯着“改一下试试”要找到为什么UUID会变。如果你的机器没有任何磁盘变更操作UUID突然对不上了这时候要警惕是不是硬盘本身出了问题。我的习惯是先用smartctl -a /dev/sdb看看硬盘健康状态确认没有硬件故障再改fstab。不然你今天把UUID改了明天盘彻底不认了数据就真的麻烦了。我处理启动故障比较多的那阵子家里那台服务器几乎每两个月就要进一次emergency mode。后来养成了习惯凡是挂数据盘、备份盘、移动盘一律在fstab里配好nofail凡是动过分区表改完立刻同步fstab和grub配置绝不拖到重启那一刻凡是克隆磁盘先辈份新的系统开一次机再往生产环境里接。养成这几个习惯之后紧急模式半年都见不到一次。可一旦真碰到了这整套排查链路二十分钟内基本都能定位问题所在——先看journalctl里的Failed to mount再用blkid对照实际UUID改完用mount -a验证一把最后reboot收工。整个过程不复杂每一步都有明确的判断依据。你只要记住emergency mode不是死刑判决它只是系统在用最朴素的方式告诉你有个分区没挂上来修一下。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门