]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
fix(dracut): default to correct firmware search paths
authorнаб <nabijaczleweli@nabijaczleweli.xyz>
Tue, 26 Apr 2022 14:42:55 +0000 (16:42 +0200)
committerJóhann B. Guðmundsson <johannbg@gmail.com>
Thu, 9 Jun 2022 23:46:52 +0000 (23:46 +0000)
1. /sys/module/firmware_class/parameters/path (fw_path_para), if any
2. /lib/firmware/updates/$(uname -r)
3. /lib/firmware/updates
4. /lib/firmware/$(uname -r)
5. /lib/firmware

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/base/firmware_loader/main.c?h=v5.17#n406

dracut-init.sh
dracut.sh
src/install/dracut-install.c

index 9f9c098015f603f8034710c44fcc6e10d2bc8e27..900e8b8394dbed6fbad34151e1233d41475c4c64 100644 (file)
@@ -72,8 +72,6 @@ srcmods="$dracutsysrootdir/lib/modules/$kernel/"
 }
 export srcmods
 
-[[ $DRACUT_FIRMWARE_PATH ]] || export DRACUT_FIRMWARE_PATH="/lib/firmware/updates:/lib/firmware:/lib/firmware/$kernel"
-
 # export standard hookdirs
 [[ $hookdirs ]] || {
     hookdirs="cmdline pre-udev pre-trigger netroot "
index 408f54d1c32aee953b8b01ebdccdde2f356ecabe..0b7199661a0a5aa5fd40491d90567ea00ab07c06 100755 (executable)
--- a/dracut.sh
+++ b/dracut.sh
@@ -1020,7 +1020,10 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
 [[ $dracutbasedir ]] || dracutbasedir="$dracutsysrootdir"/usr/lib/dracut
-[[ $fw_dir ]] || fw_dir="$dracutsysrootdir/lib/firmware/updates:$dracutsysrootdir/lib/firmware:$dracutsysrootdir/lib/firmware/$kernel"
+[[ $fw_dir ]] || {
+    fw_path_para=$(< /sys/module/firmware_class/parameters/path)
+    fw_dir="${fw_path_para:+$dracutsysrootdir$fw_path_para:}$dracutsysrootdir/lib/firmware/updates/$kernel:$dracutsysrootdir/lib/firmware/updates:$dracutsysrootdir/lib/firmware/$kernel:$dracutsysrootdir/lib/firmware"
+}
 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
 [[ $tmpdir ]] || tmpdir="$TMPDIR"
 [[ $tmpdir ]] || tmpdir="$dracutsysrootdir"/var/tmp
index 7c6d91c1543edc1c920669293d21958cde7d4b58..c8b25733d1e70b9964d2a43c9c788587451ac3b4 100644 (file)
@@ -983,9 +983,12 @@ static void usage(int status)
                "\n"
                "  --module,-m       Install kernel modules, instead of files\n"
                "  --kerneldir       Specify the kernel module directory\n"
-               "                     (default: /lib/modules/`uname -r`)\n"
+               "                     (default: /lib/modules/$(uname -r))\n"
                "  --firmwaredirs    Specify the firmware directory search path with : separation\n"
-               "                     (default: DRACUT_FIRMWARE_PATH env var, /lib/firmware if not set)\n"
+               "                     (default: $DRACUT_FIRMWARE_PATH, otherwise kernel-compatible\n"
+               "                      $(</sys/module/firmware_class/parameters/path),\n"
+               "                      /lib/firmware/updates/$(uname -r), /lib/firmware/updates\n"
+               "                      /lib/firmware/$(uname -r), /lib/firmware)\n"
                "  --silent          Don't display error messages for kernel module install\n"
                "  --modalias        Only generate module list from /sys/devices modalias list\n"
                "  -o --optional     If kernel module does not exist, do not fail\n"
@@ -1149,10 +1152,10 @@ static int parse_argv(int argc, char *argv[])
                 log_set_max_level(arg_loglevel);
         }
 
+        struct utsname buf = {0};
         if (!kerneldir) {
-                struct utsname buf;
                 uname(&buf);
-                _asprintf(&kerneldir, "%s%s", "/lib/modules/", buf.release);
+                _asprintf(&kerneldir, "/lib/modules/%s", buf.release);
         }
 
         if (arg_modalias) {
@@ -1161,15 +1164,32 @@ static int parse_argv(int argc, char *argv[])
 
         if (arg_module) {
                 if (!firmwaredirs) {
-                        char *path = NULL;
-
-                        path = getenv("DRACUT_FIRMWARE_PATH");
+                        char *path = getenv("DRACUT_FIRMWARE_PATH");
 
                         if (path) {
                                 log_debug("DRACUT_FIRMWARE_PATH=%s", path);
                                 firmwaredirs = strv_split(path, ":");
                         } else {
-                                firmwaredirs = strv_new("/lib/firmware", NULL);
+                                if (!*buf.release)
+                                        uname(&buf);
+
+                                char fw_path_para[PATH_MAX + 1] = "";
+                                int path = open("/sys/module/firmware_class/parameters/path", O_RDONLY | O_CLOEXEC);
+                                if (path != -1) {
+                                        ssize_t rd = read(path, fw_path_para, PATH_MAX);
+                                        if (rd != -1)
+                                                fw_path_para[rd - 1] = '\0';
+                                        close(path);
+                                }
+                                char uk[22 + sizeof(buf.release)], fk[14 + sizeof(buf.release)];
+                                sprintf(uk, "/lib/firmware/updates/%s", buf.release);
+                                sprintf(fk, "/lib/firmware/%s", buf.release);
+                                firmwaredirs = strv_new(STRV_IFNOTNULL(*fw_path_para ? fw_path_para : NULL),
+                                                        uk,
+                                                        "/lib/firmware/updates",
+                                                        fk,
+                                                        "/lib/firmware",
+                                                        NULL);
                         }
                 }
         }