如何设置系统启动时等待丢失硬盘的超时时间?

如何设置系统启动时等待丢失硬盘的超时时间?

系统:带有 EFI 启动的 Ubuntu 20.04。


解释一下我为什么需要这个

我配置了两个swap分区:

  • 第二个 HDD 上有一个主交换区。用于休眠。(休眠功能最好在 HDD 上使用,以延长 SSD 的使用寿命。)
  • SSD 上的第二个交换分区与系统一起。这是当我使用 SSD 作为单个磁盘时的情况 - 当第二个 HDD 被移除和丢失时。在这种情况下,我只希望系统正常工作 - 即使没有休眠功能(或使用 SSD 上的交换分区)。

我做了什么

  • 在硬盘上创建交换分区。
  • 将其 UUID 设置为 resume for Grub

/etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=25d5d4af-736a-4232-a4bb-492499bc1038"
  • 将两个交换分区设置为fstab优先于 HDD 上的交换分区以及nofailx-systemd.device-timeout=3s选项。此选项适用于缺少 HDD 的情况。如果没有此选项并且缺少 HDD,系统会在启动过程中挂起 90 秒。

/etc/fstab交换分区的配置:

#swap on HDD
UUID=25d5d4af-736a-4232-a4bb-492499bc1038 none            swap    nofail,pri=20,x-systemd.device-timeout=3s              0       0
#swap on SDD
UUID=e78a171a-3c52-4cd1-b86a-17709f4b49d9 none            swap    pri=10              0       0

我遇到了什么问题

当 SSD 和 HDD 一起连接到笔记本电脑时,一切都很好。当 HDD 在系统启动过程中丢失时,Grub会尝试在 HDD 上查找带有交换分区,并因此挂起约 33 秒。

系统启动后,在日志中出现以下关于等待丢失的硬盘(我故意删除的)和交换分区超时的消息:

/var/log/boot.log:[ESC[0;1;31m TIME ESC[0m] Timed out waiting for device ESC[0;1;39m/dev/disk/by-uuid/46e39f74-e1b3-4705-9bac-84ee2593b4d
4ESC[0m.

/var/log/syslog:Feb 23 14:23:26 Device-2 kernel: [    0.032426] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.13.0-28-generic root=UUID=a59635ec-2cef-4396-bdf3-be7e4b23fc73 ro quiet splash resume=UUID=25d5d4af-736a-4232-a4bb-492499bc1038 vt.handoff=7

/var/log/syslog:Feb 23 14:56:14 Device-2 systemd[1]: dev-disk-by\x2duuid-25d5d4af\x2d736a\x2d4232\x2da4bb\x2d492499bc1038.device: Job dev-disk-by\x2duuid-25d5d4af\x2d736a\x2d4232\x2da4bb\x2d492499bc1038.device/start timed out.

我想要的是

设置等待丢失硬盘的超时时间不超过 5 秒。现在系统默认设置为 30-33 秒。


我尝试了以下

  • 在配置中找到超时属性Grub/etc/default/grub可以指定两个相关选项:
  • GRUB_HIDDEN_TIMEOUT
  • GRUB_RECORDFAIL_TIMEOUT

但它们不适用于这种情况。有关此选项的信息可在此处找到:

我尝试分析Grubin的代码/etc/grub.d/,发现这样的超时可能在系统启动配置中指定 - in 。我尝试在配置systemd中找到相应的超时选项:systemd

sudo grep -iR timeout /etc/systemd/
/etc/systemd/system/rescue.target.wants/grub-initrd-fallback.service:TimeoutSec=0
/etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service:ExecStart=/usr/bin/nm-online -s -q --timeout=30
/etc/systemd/system/emergency.target.wants/grub-initrd-fallback.service:TimeoutSec=0
/etc/systemd/system/multi-user.target.wants/ua-reboot-cmds.service:TimeoutSec=0
/etc/systemd/system/multi-user.target.wants/unattended-upgrades.service:TimeoutStopSec=1800
/etc/systemd/system/multi-user.target.wants/grub-initrd-fallback.service:TimeoutSec=0
/etc/systemd/system/multi-user.target.wants/snapd.recovery-chooser-trigger.service:# blocks the service startup until a trigger is detected or a timeout is hit
/etc/systemd/system/sleep.target.wants/grub-initrd-fallback.service:TimeoutSec=0
/etc/systemd/system.conf:#DefaultTimeoutStartSec=90s
/etc/systemd/system.conf:#DefaultTimeoutStopSec=90s
/etc/systemd/system.conf:#DefaultTimeoutAbortSec=
/etc/systemd/user.conf:#DefaultTimeoutStartSec=90s
/etc/systemd/user.conf:#DefaultTimeoutStopSec=90s
/etc/systemd/user.conf:#DefaultTimeoutAbortSec=
/etc/systemd/logind.conf:#HoldoffTimeoutSec=30s

尝试将选项的值从 30 秒更改为 5 秒:

/etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service:ExecStart=/usr/bin/nm-online -s -q --timeout=5
/etc/systemd/logind.conf:#HoldoffTimeoutSec=5s

但这并未产生预期的结果。

我还尝试对交换分区进行相同的设置labels,并使用此标签(而不是 UUID)指定恢复交换分区/dev/disk/by-label/...。但在这种情况下,无法确定将使用两者中的哪个交换分区来从休眠状态加载系统。

我发现了类似的问题: 如何设置 systemd 启动作业“dev-md125.device”的超时(mdadm) 但其中没有systemd关于如何配置 HDD 超时的详细信息。

这里有示例如何TimeoutStartSec设置httpd.service

是否可以在系统启动期间指定 HDD 安装的超时时间?

谢谢。

答案1

就我而言,相同量的延迟(30 秒)是由于 initramfs 脚本中的愚蠢逻辑造成的:

        local slumber=30
        case $DPKG_ARCH in
                powerpc|ppc64|ppc64el)
                        slumber=180
                        ;;
                *)
                        slumber=30
                        ;;
        esac
        if [ "${ROOTDELAY:-0}" -gt $slumber ]; then
                slumber=$ROOTDELAY
        fi

上面忽略了 rootdelay,它小于“slumber”(这个名字和代码一样神奇)。

要修复此问题你应该:

  1. 添加内核启动参数rootdelay=3(编辑/etc/default/grub)并运行update-grub
  2. 使用以下命令修补你的 initramfs 脚本:
--- /usr/share/initramfs-tools/scripts/local    2023-09-25 22:47:50.000000000 +0300
+++ /usr/share/initramfs-tools/scripts/local    2024-02-06 03:35:29.442516895 +0300
@@ -64,9 +64,7 @@
                        slumber=30
                        ;;
        esac
-       if [ "${ROOTDELAY:-0}" -gt $slumber ]; then
-               slumber=$ROOTDELAY
-       fi
+       slumber=${ROOTDELAY:-$slumber}

        case "$dev_id" in
        UUID=*|LABEL=*|PARTUUID=*|/dev/*)
  1. 更新 initrd 映像:
update-initramfs -k 6.7.3-060703-generic -c

或者你可以保存update-initrd到你的/boot

#!/bin/bash
kv=${1#initrd.img-}
kv=${kv#vmlinuz-}
img="initrd.img-$kv"
update-initramfs -k $kv -c
lsinitramfs $img > /boot/$img.txt
  1. 如果您使用的是 Debian,并且不想在initramfs-tools-core更新时覆盖上述补丁,请执行以下操作:
cd /usr/share/initramfs-tools/scripts
dpkg-divert --rename --divert $_/local.orig $_/local

所有上述命令都必须在 root 权限下执行(显然,这样我就不会愚蠢地用sudo命令弄乱它们)。

相关内容