#1116709 hw-detect: list_deb_firmware() does not find files in trixie packages after /usr merge

Package:
src:hw-detect
Source:
src:hw-detect
Submitter:
alexander barakin
Date:
2025-10-06 09:03:02 UTC
Severity:
normal
Tags:
#1116709#5
Date:
2025-09-30 13:48:26 UTC
From:
To:
after implementation of https://wiki.debian.org/UsrMerge
firmware packages in trixie contain /usr/lib/firmware
in the paths (instead of /lib/firmware in bookworm).

compare:
https://packages.debian.org/bookworm-backports/all/firmware-iwlwifi/filelist
/lib/firmware/intel/ibt-0040-0041.ddc
...

and:
https://packages.debian.org/trixie/all/firmware-iwlwifi/filelist
/usr/lib/firmware/intel/ibt-0040-0041.ddc
...

therefore, the list_deb_firmware() function from check-missing-firmware.sh
does not find files in new packages.

the simplest solution is to ignore the "/usr" in the file paths
(the patch is attached).

#1116709#10
Date:
2025-09-30 14:14:52 UTC
From:
To:
Update on this bug:

1. With debian-installer 20250803+deb13u1 and hw-detect 1.171, the firmware
for the laptop’s network card won’t install. The installer freezes at
“Detect network hardware.”
In /var/log/syslog the last line is: hw-detect exited nonzero.

2. After applying this patch, everything works: the install finishes and
the firmware gets installed.

#1116709#15
Date:
2025-09-30 14:47:10 UTC
From:
To:
Hi Andrew and Alexander,

Andrew Kornilov <akornilov@gmail.com> (2025-09-30):

Yes, that's a very good find, thanks.

Sorry you had to go through this, this never-ending transition is a huge
mess… we should probably fix not only unstable (and testing after a few
days) but also backport to stable, just in case some packages end up
getting updated with the new paths there (e.g. via security).

It might also make sense to check whether we need to do something
similar in debian-cd. From a quick look there:

    kibi@tokyo:~/debian-cd/debian-cd.git (master =)$ git grep -l lib/firmware
    debian/changelog
    tools/boot/bookworm/common.sh
    tools/boot/forky/common.sh
    tools/boot/trixie/common.sh
    tools/generate_firmware_task

Survey:
 - all three common.sh iterate over both lib/firmware and
   usr/lib/firmware, we're good already.
 - the last two (trixie and forky) additionally write a metadata file
   under the usr/lib/firmware, that's in line with the new location.
 - the last one also iterates on both locations.

TL;DR: Hopefully no changes needed on the debian-cd side. Sorry for the
digression, but firmware support really needs some cooperation between
debian-installer and debian-cd, so I thought I'd double check…


Cheers,

#1116709#20
Date:
2025-09-30 15:16:00 UTC
From:
To:
Cyril Brulebois <kibi@debian.org> (2025-09-30):

Let's backpedal a bit: looking at trixie's initial release (13.0), we
already had firmware-iwlwifi with /usr/lib/firmware paths, and I'm
*pretty sure* that works fine!

What wasn't mentioned in this bug report is that we're talking about
custom builds, not about official images. (See, that's why you shouldn't
contact individual maintainers directly, and instead include all context
in a public conversation in the first place…)

Are you missing Contents-firmware files, possibly because you're using
an old debian-cd branch, or maybe no debian-cd at all?

If that's indeed the case, the patch is only needed for the fallback
code, so that's less serious than what I thought.

Example with the non-fallback code:

    May 22 01:12:42 check-missing-firmware: looking at dmesg for the first time
    May 22 01:12:42 check-missing-firmware: saving timestamp for a later use: [   27.986681]
    May 22 01:12:42 check-missing-firmware: looking for firmware file rtw88/rtw8821c_fw.bin requested by rtw_8821ce
    May 22 01:12:42 check-missing-firmware: looking for firmware file rtw88/rtw8821c_fw.bin requested by rtw_8821ce
    May 22 01:12:42 check-missing-firmware: looking for firmware file rtw88/rtw8821c_fw.bin requested by rtw_8821ce
    May 22 01:12:42 check-missing-firmware: missing firmware files (rtw88/rtw8821c_fw.bin) for rtw_8821ce
    May 22 01:12:42 check-missing-firmware: mainloop iteration #1
    May 22 01:12:42 check-missing-firmware: lookup with /cdrom/firmware/Contents-firmware
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    May 22 01:12:42 check-missing-firmware: installing firmware package /cdrom/firmware/firmware-realtek_20250410-2_all.deb (non-free-firmware)
    May 22 01:12:42 check-missing-firmware: modprobe: FATAL: Module rtw_8821ce not found.
    May 22 01:12:42 check-missing-firmware: modprobe: FATAL: Module rtw_8821ce not found in directory /lib/modules/6.12.29-amd64
    May 22 01:12:42 check-missing-firmware: removing and loading kernel module rtw88_8821ce as well (actual module for rtw_8821ce)

In your case I'm assuming you're getting *without* there?


Cheers,

#1116709#25
Date:
2025-09-30 15:57:21 UTC
From:
To:
Hi Cyril,

Thank you.
Yes, you are absolutely right: i forgot to mention that we use live-build
to build the ISO and it (or its tools) does not generate the
"/cdrom/firmware/Contents-firmware" file (not sure why), so the
check-missing-firmware.sh iterates over all the files inside the
/cdrom/firmware/ folder.
That's why i was wondering why nobody else reports this issue.

#1116709#30
Date:
2025-09-30 15:57:47 UTC
From:
To:
alexander barakin <alex@barak.in> writes:

Here's a variation on that which avoids the `grep | sed | grep` pipe,
and takes advantage of the fact that we have support for -E in d-i.

https://salsa.debian.org/installer-team/hw-detect/-/merge_requests/14

BTW I notice mentions of /lib/firmware in a few other places:

=-=-=-=
packages/hw-detect/check-missing-firmware.sh
184:        if [ ! -e /lib/firmware/$fwfile ] ; then
217:                    target="/lib/firmware${sdir:+/$sdir}"

packages/busybox/util-linux/mdev.c
64://config:    /lib/firmware/ and if it exists, send it to the kernel for
900: * - userspace checks /lib/firmware/$FIRMWARE
903: * - userspace copies /lib/firmware/$FIRMWARE into /sys/$DEVPATH/data
912:    /* check for /lib/firmware/$FIRMWARE */
914:    if (chdir("/lib/firmware") == 0)

installation-guide/en/using-d-i/loading-firmware.xml
31:copied to the correct location (<filename>/lib/firmware</filename>) and
=-=-=-=

do they also need fixing? (I'd guess that the symlinks mean this
shouldn't break things, but eventually we should probably settle on
using the real location)

Cheers, Phil.

#1116709#35
Date:
2025-09-30 16:32:07 UTC
From:
To:
[ Re-adding submitter… ]

Philip Hands <phil@hands.com> (2025-09-30):

If we go for that, maybe include some comments to explain what that's
doing, so that non-sed experts can grok what's happening?

Probably can be updated, I'm not expecting changes because of the
symlink.

Ditto.

That's a topic for busybox upstream, no opinion.

Would probably make sense to update.


Unless I missed something, none of those need fixing in stable.


Cheers,

#1116709#40
Date:
2025-09-30 16:43:54 UTC
From:
To:
Andrew Kornilov <akornilov@gmail.com> (2025-09-30):

Adding debian-live@ for information.

TL;DR: For images generated by live-build, firmware lookup cannot rely
on Contents-firmware files (apparently not generated, I didn't check
myself), which leads to using a fallback that's currently buggy (lack of
support for /usr/lib/firmware in hw-detect's list_deb_firmware).

We're looking into fixing the latter, but you might want to address the
former as well? In which case, some debian-cd.git pointers:

    kibi@tokyo:~/debian-cd/debian-cd.git (master =)$ git log -G Contents-firmware
    commit 7eea34f26fd61035e443d67bff8f08e5e66196df
    Author: Cyril Brulebois <kibi@debian.org>
    Date:   Sun Feb 19 03:42:36 2023 +0100

        make-firmware-image: fix missing Contents-firmware index (Closes: #1031598)

    commit d7796845f47493a327d74cb6a211e5cadadb7fb0
    Author: Cyril Brulebois <kibi@debian.org>
    Date:   Wed Feb 8 12:22:51 2023 +0100

        Document recent changes.

    commit 32291d88a3987cb9b05b65a1fc5747e69049a882
    Author: Steve McIntyre <steve@einval.com>
    Date:   Sun Oct 9 01:43:12 2022 +0100

        Add a Contents-firmware file

        to help with looking up firmware packages in d-i


Cheers,

#1116709#45
Date:
2025-09-30 17:26:46 UTC
From:
To:
Hello Andrew,

live-build should be able to generate /firmware/Contents-firmware (and
the dep11 pattern files). The official Debian images all contain this
file, so the fallback is not triggered there. Additionally, live-build
looks both in /usr/lib and /lib for the directory firmware in firmware
packages.

@Andrew: Which version of live-build are you using? (lb --version)

Thanks Cyril.

@Cyril: there should be no additional work for live-build

https://sources.debian.org/src/live-build/1%3A20250814/functions/firmwarelists.sh#L53

With kind regards,
Roland Clobus

#1116709#50
Date:
2025-09-30 21:55:12 UTC
From:
To:
Hi Roland,

@Andrew: Which version of live-build are you using? (lb --version)


We still use the version 20240810. We upgraded it from the bookworm version
and it has been working fine till latest Trixie's changes (we build a
custom ISO based on the mostly Bookworm packages + Trixie's kernel +
debian-installer + some more not important updates).

I've checked the code and see it contains the "Firmware_List_From_Contents"
function but a simpler version.

We will upgrade it after some tests. Right now we applied the attached
patch and it works (but slow, of course).

Thank you all, guys. Now i see that we should use the latest live-build
version (however, it might not work with bookworm packages, not sure right
now).

#1116709#55
Date:
2025-09-30 22:13:31 UTC
From:
To:
Andrew Kornilov <akornilov@gmail.com> (2025-10-01):

Thanks anyway for the report, patch, and follow-ups.

I totally understand how it makes sense not to move everything from
oldstable to stable (I'm always slow to catch up personally), and why
you encountered this issue.

Now that we have a clear picture of what happens (more of a corner case
than a general breakage we would have noticed months ago!), I still
think it would make sense to teach the fallback code about the “new
directory”, in unstable and then in trixie (which would only land after
a point release).

Phil, if you want to take the lead on the upload to unstable (with or
without my comment suggestion, definitely not a blocker!), I can deal
with the trixie preps?


Cheers,

#1116709#60
Date:
2025-10-02 12:07:45 UTC
From:
To:
Hello Andrew,

The live-build package is tested with sid, testing, stable and
oldstable, so you should be fine to use bookworm with trixie mixed in.

You can even use the git version.

It was fixed in git some time ago. The version from trixie is
sufficiently new.

Ok, I'm closing this bug report. If you have issues with the current
live-build, please file a bug report against that package.

With kind regards,
Roland Clobus

#1116709#65
Date:
2025-10-02 14:40:46 UTC
From:
To:
Roland Clobus <rclobus@rclobus.nl> (2025-10-02):

Reopening, as like I said in a previous message[1], it still looked like
something worth fixing in hw-detect, see proposal at [2].

  1. https://bugs.debian.org/1116709#40
  2. https://bugs.debian.org/1116709#55


Cheers,

#1116709#72
Date:
2025-10-06 09:01:33 UTC
From:
To:
Cyril Brulebois <kibi@debian.org> writes:

Looking at this particular example:

	udpkg -c "$1" | sed -nE 's!^\.(/usr)?/lib/firmware/(.)!\2!p'

The things that make that work are:

  `-n` option and the 'p' flag at the end of the pattern:

     The `-n` tells sed to suppress its output, which we do in order to
     not need the initial grep that was selecting just the line we're
     interested in. The sed replacement pattern then selects that line,
     and does a replacement, and the `p` means:

       If the pattern matched, print the resulting pattern space
       (so what's on the line after the substitution).

  `-E` means "Use extended regular expressions" which is why I can get
       away without backslash-escaping the parentheses.

  `\2` this is whatever the second match was, which is the single
       character after the slash that is matched by `(.)`.  The reason
       for that is to make sure that the pattern does not match the
       directory that the `grep -v '^$'` was there to remove, and since
       it does not match, the line is suppressed by the `-n` and there
       is no need to have a final grep to get rid of it.

       Since we stop matching at that character, whatever's left on the
       rest of the line will be untouched, and will therefore be
       "printed" to STDOUT as a result of the `p` flag.


A very quick grep seems to show that the `sed -e ...p` usage appears 216
times in the existing D-I code. The use of a `\2` is seen 46 times, with
`\1` (so the same concept) used 353 times, while `-E` is obviously a
more recent arrival, with only 11 hits.

I'm sure we don't want to add comments to all of those instances, so
perhaps we need a README.sed (or some such) covering the features that
actually get used in D-I, and the ways of doing things that do not
involve redundant pipelines with repetitive (and thus hard to maintain)
parameters.

If you like, I could start the README as another MR, using the above
explanation as an initial draft.  Perhaps that could grow into a more
general guide of what works or doesn't in the D-I environment, in which
case it needs a better name.

Cheers, Phil.