]> git.ipfire.org Git - thirdparty/dracut-ng.git/commitdiff
fix(dracut): rework timeout for devices added via --mount and --add-device
authorAntonio Alvarez Feijoo <antonio.feijoo@suse.com>
Mon, 4 Nov 2024 12:31:13 +0000 (13:31 +0100)
committerNeal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
Sun, 10 Nov 2024 13:37:56 +0000 (14:37 +0100)
Currently, dracut adds a systemd dropin that sets an infinite timeout _only_ for
the underlying persistent devices of each host device that must be active in the
initrd. E.g.:

```
localhost:~ # dracut -f --stdlog 3 --install "/mnt" --mount "/dev/sda1 /mnt btrfs rw,relatime"
localhost:~ # lsinitrd | grep timeout.conf
-rw-r--r--   2 root     root            0 Oct 28 14:21 etc/systemd/system/dev-disk-by\x2duuid-0d1b24c2\x2df112\x2d48ef\x2d8442\x2d1001cffc92f0.device.d/timeout.conf
localhost:~ # ls -l /dev/disk/by-uuid/0d1b24c2-f112-48ef-8442-1001cffc92f0
lrwxrwxrwx 1 root root 10 Oct 28 11:43 /dev/disk/by-uuid/0d1b24c2-f112-48ef-8442-1001cffc92f0 -> ../../sda1
```

It can be verified in the emergency shell:

```
sh-5.2# systemctl show --property JobRunningTimeoutUSec /dev/disk/by-uuid/0d1b24c2-f112-48ef-8442-1001cffc92f0
JobRunningTimeoutUSec=infinity
sh-5.2# systemctl show --property JobRunningTimeoutUSec /dev/sda1
JobRunningTimeoutUSec=1min 30s
```

This can cause a problem if a user application expects to mount /dev/sda1 in the
initrd (that's why it was explicitly added `--mount "/dev/sda1 ..."`), but for
some reason the link is not created within 1min 30s.

dracut-functions.sh
dracut.sh
modules.d/99base/module-setup.sh

index 245c69cb6cadb8081f525ada3190d7a3d5bb9e62..eaeb1c4e2db6958d081fac3a700e366e8db07703 100755 (executable)
@@ -607,9 +607,9 @@ for_each_host_dev_and_slaves_all() {
     local _dev
     local _ret=1
 
-    [[ "${host_devs[*]}" ]] || return 2
+    [[ "${host_devs[*]}" ]] || [[ "${user_devs[*]}" ]] || return 2
 
-    for _dev in "${host_devs[@]}"; do
+    for _dev in "${host_devs[@]}" "${user_devs[@]}"; do
         [[ -b $_dev ]] || continue
         if check_block_and_slaves_all "$_func" "$(get_maj_min "$_dev")"; then
             _ret=0
@@ -622,9 +622,9 @@ for_each_host_dev_and_slaves() {
     local _func="$1"
     local _dev
 
-    [[ "${host_devs[*]}" ]] || return 2
+    [[ "${host_devs[*]}" ]] || [[ "${user_devs[*]}" ]] || return 2
 
-    for _dev in "${host_devs[@]}"; do
+    for _dev in "${host_devs[@]}" "${user_devs[@]}"; do
         [[ -b $_dev ]] || continue
         check_block_and_slaves "$_func" "$(get_maj_min "$_dev")" && return 0
     done
index 20935c6f9b59c100b62e0361d02f46735586a099..0e3d0d8b16a8027657047c3b55e87e47a27cc31d 100755 (executable)
--- a/dracut.sh
+++ b/dracut.sh
@@ -328,6 +328,16 @@ push_host_devs() {
     done
 }
 
+# Fills up user_devs stack variable and makes sure there are no duplicates
+push_user_devs() {
+    local _dev
+    for _dev in "$@"; do
+        [[ -z $_dev ]] && continue
+        [[ " ${user_devs[*]} " == *" $_dev "* ]] && return
+        user_devs+=("$_dev")
+    done
+}
+
 check_conf_file() {
     if grep -H -e '^[^#]*[+]=\("[^ ]\|.*[^ ]"\)' "$@"; then
         printf '\ndracut[W]: <key>+=" <values> ": <values> should have surrounding white spaces!\n' >&2
@@ -1698,7 +1708,7 @@ for line in "${fstab_lines[@]}"; do
             push_host_devs "$mp"
         done
     fi
-    push_host_devs "$dev"
+    push_user_devs "$dev"
     host_fs_types["$dev"]="$3"
 done
 
@@ -1710,12 +1720,12 @@ for f in $add_fstab; do
 done
 
 for dev in $add_device; do
-    push_host_devs "$dev"
+    push_user_devs "$dev"
 done
 
 if ((${#add_device_l[@]})); then
     add_device+=" ${add_device_l[*]} "
-    push_host_devs "${add_device_l[@]}"
+    push_user_devs "${add_device_l[@]}"
 fi
 
 if [[ $hostonly ]] && [[ $hostonly_default_device != "no" ]]; then
@@ -1841,7 +1851,7 @@ _get_fs_type() {
     return 1
 }
 
-for dev in "${host_devs[@]}"; do
+for dev in "${host_devs[@]}" "${user_devs[@]}"; do
     _get_fs_type "$dev"
     check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
 done
@@ -1867,7 +1877,7 @@ export initdir dracutbasedir \
     omit_drivers mdadmconf lvmconf root_devs \
     use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
     stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
-    host_fs_types host_devs swap_devs sshkey add_fstab \
+    host_fs_types host_devs user_devs swap_devs sshkey add_fstab \
     DRACUT_VERSION \
     prefix filesystems drivers \
     hostonly_cmdline loginstall \
index 13639bd45364c149cef19150ed5365dfe51cca59..2290beb805db2efd9a97455f6d736444972b2cfa 100755 (executable)
@@ -72,7 +72,7 @@ install() {
 
     ## save host_devs which we need bring up
     if [[ $hostonly_cmdline == "yes" ]]; then
-        if [[ -n ${host_devs[*]} ]]; then
+        if [[ -n ${host_devs[*]} ]] || [[ -n ${user_devs[*]} ]]; then
             dracut_need_initqueue
         fi
         if [[ -f $initdir/lib/dracut/need-initqueue ]] || ! dracut_module_included "systemd"; then
@@ -105,6 +105,22 @@ install() {
                         *) ;;
                     esac
                 done
+
+                for _dev in "${user_devs[@]}"; do
+
+                    case "$_dev" in
+                        /dev/?*) wait_for_dev "$_dev" 0 ;;
+                        *) ;;
+                    esac
+
+                    _pdev=$(get_persistent_dev "$_dev")
+                    [[ $_dev == "$_pdev" ]] && continue
+
+                    case "$_pdev" in
+                        /dev/?*) wait_for_dev "$_pdev" 0 ;;
+                        *) ;;
+                    esac
+                done
             )
         fi
     fi