一、问题背景

在解决了 /var/log 磁盘写满问题后,重启开发板发现系统无法正常启动,卡在紧急模式(Emergency Mode),提示需要输入 root 密码进行维护。

如下调整后,无法启动,win11DG挂载删除journal文件无效,只能连显示器恢复模式下修改,主要还是修改/etc/fstab开机启动

root@pbsbc01h3:~#  systemctl stop systemd-journald
Warning: Stopping systemd-journald.service, but it can still be activated by:
  systemd-journald-audit.socket
  systemd-journald-dev-log.socket
  systemd-journald.socket
root@pbsbc01h3:~#  rm -rf /var/log/journal
root@pbsbc01h3:~# touch /var/log/journal
root@pbsbc01h3:~# chmod 000 /var/log/journal
root@pbsbc01h3:~# chattr +i /var/log/journal
root@pbsbc01h3:~# mount --bind /dev/null /var/log/journal
root@pbsbc01h3:~# echo "/dev/null /var/log/journal none bind 0 0" | sudo tee -a /etc/fstab/dev/null /var/log/journal none bind 0 0
root@pbsbc01h3:~# systemctl start systemd-journald
root@pbsbc01h3:~# ls -la /var/log/journal
crw-rw-rw- 1 root root 1, 3 May 25 14:37 /var/log/journal
root@pbsbc01h3:~# df -h /var/log/
Filesystem      Size  Used Avail Use% Mounted on
/dev/zram0      124M  520K  115M   1% /var/log
root@pbsbc01h3:~# reboot
调整了如上配置后,无法启动,win11挂载,删除/var/log/journal目录,还是无法启动,该如何操作

二、问题现象

系统启动后显示:

Give root password for maintenance
(or press Control-D to continue):

多次输入密码后仍然无法正常启动,最终进入紧急模式。

三、问题原因分析

3.1 直接原因

之前的配置中执行了以下操作:

# 创建文件并锁定
touch /var/log/journal
chmod 000 /var/log/journal
chattr +i /var/log/journal

# 绑定挂载并写入 fstab
mount --bind /dev/null /var/log/journal
echo "/dev/null /var/log/journal none bind 0 0" | sudo tee -a /etc/fstab

3.2 根本原因

操作导致的问题
touch /var/log/journal创建了文件而不是目录
chmod 000权限全禁,无法读写
chattr +i文件被设为不可变,连 root 也无法删除/修改
mount --bind /dev/null覆盖路径,但文件仍被锁定
echo ... >> /etc/fstab开机自动执行绑定挂载

结果systemd-journald 启动时无法正常操作 /var/log/journal,导致服务启动失败,系统进入紧急模式。

四、解决方案

4.1 方案一:在紧急模式中修复(如果可以登录)

如果能进入紧急模式并输入 root 密码:

# 1. 重新挂载根文件系统为读写
mount -o remount,rw /

# 2. 编辑 fstab,删除问题行
nano /etc/fstab
# 删除或注释:/dev/null /var/log/journal none bind 0 0

# 3. 删除被锁定的文件
rm -rf /var/log/journal
mkdir -p /var/log/journal
chmod 755 /var/log/journal

# 4. 恢复 journald 配置
cat > /etc/systemd/journald.conf << 'EOF'
[Journal]
Storage=auto
EOF

# 5. 重启
reboot

4.2 方案二:通过读卡器在 Windows 上修复

使用 DiskGenius 等工具挂载 SD 卡:

  1. 删除 /etc/fstab 文件(或删除问题行)
  2. 删除 /var/log/journal 文件/目录
  3. 新建 journal 目录
  4. 安全弹出 SD 卡,插回开发板测试

注意:DiskGenius 无法查看/修改 chattr +i 属性,只能删除重建。

4.3 方案三:在另一台 Linux 系统中挂载修复(最彻底)

将 SD 卡通过读卡器插入另一台 Linux 电脑:

# 1. 查看设备名
sudo fdisk -l
# 假设 SD 卡是 /dev/sda1

# 2. 挂载
sudo mkdir -p /mnt/sdcard
sudo mount /dev/sda1 /mnt/sdcard

# 3. 查看并清除不可变标志
cd /mnt/sdcard/var/log
lsattr journal              # 查看是否有 'i' 标志
sudo chattr -i journal      # 清除不可变标志

# 4. 删除并重建目录
sudo rm -rf journal
sudo mkdir journal
sudo chmod 755 journal

# 5. 删除问题配置文件
sudo rm -f /mnt/sdcard/etc/fstab
sudo rm -rf /mnt/sdcard/etc/systemd/journald.conf.d/

# 6. 恢复 journald 默认配置
echo '[Journal]
Storage=auto' | sudo tee /mnt/sdcard/etc/systemd/journald.conf

# 7. 卸载
cd /
sudo umount /mnt/sdcard

五、修复后的配置

5.1 最终有效的 journald 配置

[Journal]
Storage=volatile
RuntimeMaxUse=40M

5.2 配置说明

参数作用
Storage=volatile内存模式日志只写内存,不写磁盘
RuntimeMaxUse=40M40MB上限控制内存占用

不需要添加的参数Compress=noSyncIntervalSec=0ForwardToSyslog=no 等在 volatile 模式下无效或默认已优化。

5.3 验证配置生效

# 检查磁盘日志目录(应该不存在或为空)
ls -la /var/log/journal

# 检查内存日志目录(应该有内容)
ls -la /run/log/journal/

# 检查磁盘占用
df -h /var/log/

六、经验教训总结

6.1 禁止的危险操作

操作风险
chattr +i 锁定文件/目录无法删除/修改,可能导致服务启动失败
mount --bind /dev/null 覆盖路径导致服务无法正常读写
/etc/fstab 中添加测试挂载开机自动执行,错误配置会导致无法启动

6.2 正确的日志管理方式

对于需要限制日志大小的场景,正确做法是:

# 只修改服务配置,不锁定文件系统
sudo tee /etc/systemd/journald.conf << 'EOF'
[Journal]
Storage=volatile
RuntimeMaxUse=40M
EOF

sudo systemctl restart systemd-journald
sudo rm -rf /var/log/journal   # 清理已存在的磁盘日志

6.3 修复原则

当遇到 chattr +i 导致的问题时:

  1. 必须在 Linux 环境下使用 chattr -i 解除锁定
  2. Windows 工具(如 DiskGenius)无法处理 Linux 扩展属性
  3. 最可靠的方法:在另一台 Linux 系统中挂载后操作

七、验证清单

修复完成后,确认以下项目:

  • [x] 系统能正常启动,不再进入紧急模式
  • [x] /etc/fstab 中没有问题挂载行
  • [x] /var/log/journal 是正常目录(权限 755)
  • [x] journald 服务正常运行
  • [x] /var/log 占用很小(< 1MB)
  • [x] 日志正常写入内存(/run/log/journal/

八、相关命令速查

命令用途
lsattr /path/to/file查看文件/目录的特殊属性
chattr -i /path/to/file解除不可变标志
mount -o remount,rw /在紧急模式下重新挂载根分区为读写
systemctl default退出紧急模式,继续正常启动
journalctl --header查看 journal 当前状态和存储位置

标签: none

添加新评论