Rebuild and Query the Linux Hardware Database with systemd-hwdb
You will finish with a safe way to query the hardware database and a controlled workflow for rebuilding it after a .hwdb change. The installed command is systemd 255 from the udev package, version 255.4-1ubuntu8.17 on this machine.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes for a query, or longer if you are editing a hardware rule. You need a shell for the read-only parts. Rebuilding the database normally needs elevated privileges because the compiled file is written below /etc/udev or /usr/lib/udev.
Checkpoint
If you only need to inspect an existing result, stop after step 2. Steps 3 to 6 are for maintaining the database.
1. Confirm the installed command
Start with the local version and help text. These commands only read the executable:
$ systemd-hwdb --version
systemd 255 (255.4-1ubuntu8.17)
$ dpkg-query -W -f='${Package} ${Version}\n' udev
udev 255.4-1ubuntu8.17
$ systemd-hwdb --help
systemd-hwdb [OPTIONS...] COMMAND ...
The command accepts two operational commands: update and query MODALIAS. Do not confuse systemd-hwdb with a service that continuously watches hardware. It manages the compiled database used at runtime.
2. Query a device modalias
A modalias is the lookup string supplied to the database. Use one from the device or subsystem you are investigating. This known PCI example is useful for a quick smoke test:
$ systemd-hwdb query 'pci:v00008086d000015B7*'
ID_VENDOR_FROM_DATABASE=Intel Corporation
ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I219-LM
The command prints matching key-value properties. The exact result depends on the installed database and the modalias. A query can legitimately produce no properties when nothing matches, so do not treat an empty result as proof that the device is absent.
Capture the status immediately if a script needs to distinguish a successful query from a failed one:
$ systemd-hwdb query 'pci:v00008086d000015B7*' >/tmp/hwdb-result
$ status=$?
$ printf 'query status: %s\n' "$status"
query status: 0
$ sed -n '1,20p' /tmp/hwdb-result
The temporary output file is optional and can be removed after inspection. Quote the modalias: characters such as * must reach systemd-hwdb, rather than being expanded by the shell.
3. Find the source rules before editing
The binary database is generated from .hwdb files in /usr/lib/udev/hwdb.d and /etc/udev/hwdb.d. Files are processed in lexical order. A file in /etc replaces a file with the same name in /usr/lib, while a later-sorting record can provide a higher-priority value for a key.
Inspect the installed rules without changing them:
$ find /usr/lib/udev/hwdb.d /etc/udev/hwdb.d \
-maxdepth 1 -type f -name '*.hwdb' -print | sort
$ rg -n 'ID_VENDOR_FROM_DATABASE|ID_MODEL_FROM_DATABASE' \
/usr/lib/udev/hwdb.d /etc/udev/hwdb.d
Only files ending in .hwdb are read. A record begins with one or more match lines at column one. Its property lines begin with one space and use KEY=VALUE. A blank line ends the record. Keep those boundaries exact; indentation that looks harmless can change whether a line is a property.
Safety warning
Changing a rule changes hardware properties presented by udev after the compiled database is rebuilt. Before editing an existing file, save a copy and record the original query output. Prefer a new, clearly named file in /etc/udev/hwdb.d for a local override.
4. Add a narrowly scoped local rule
Use the exact modalias pattern you intend to match. The following is a template, not a rule to paste unchanged:
# /etc/udev/hwdb.d/90-local-hardware.hwdb
pci:v00008086d0000REPLACE*
ID_MODEL_FROM_DATABASE=Example device label
Replace REPLACE with a verified device identifier and remove the trailing space after the match line. The leading space before ID_MODEL_FROM_DATABASE is required. Keep the pattern as specific as possible. A broad pattern can alter several devices, and when multiple records match, their properties are combined.
Do not edit /usr/lib/udev/hwdb.d for a local machine override. Package upgrades can replace files there. A matching filename in /etc/udev/hwdb.d can override the packaged file, but a distinct later-sorting filename is usually easier to review.
5. Rebuild the binary database
Back up the existing binary and run the update as root. This is the state-changing step:
$ sudo cp -p /etc/udev/hwdb.bin \
/etc/udev/hwdb.bin.before-local-hardware
$ sudo systemd-hwdb update
update reads the source files and writes the compiled database to /etc/udev/hwdb.bin. On an immutable image or another workflow that ships the compiled file from /usr, use --usr instead:
$ sudo systemd-hwdb --usr update
The command is quiet on a successful update on this installation. Check the status rather than relying on visible output:
$ printf 'update status: %s\n' "$?"
update status: 0
Do not run both destinations casually. Choose the destination that matches the way your system manages its compiled database. The --strict option makes an update return non-zero for any parsing error, which is useful in an automated check:
$ sudo systemd-hwdb --strict update
$ printf 'strict update status: %s\n' "$?"
strict update status: 0
6. Verify the result and recover if necessary
Query the same modalias again. This is the most direct check that the rebuilt database contains the property you intended:
$ systemd-hwdb query 'pci:v00008086d0000REPLACE*'
ID_MODEL_FROM_DATABASE=Example device label
If the result is wrong, first check the match string, the leading space on property lines, the blank line separating records, and lexical file precedence. Then remove or correct the local rule and rerun the same update command. The backup made in step 5 gives you a recovery point for the compiled file:
$ sudo mv /etc/udev/hwdb.bin.before-local-hardware /etc/udev/hwdb.bin
$ systemd-hwdb query 'pci:v00008086d000015B7*'
Restore the source file as well, or the next update will recreate the unwanted result. If a parsing problem is hard to spot, rerun with --strict and inspect every recently changed .hwdb file.
7. Use an alternate root for image work
When building a filesystem image rather than changing the running host, use --root=PATH to point at that filesystem root:
$ sudo systemd-hwdb --root=/path/to/image --usr --strict update
PATH is a placeholder. Confirm it is the intended image before running the command. The option changes where the command looks for and writes the database; it does not make an arbitrary path safe by itself. Use an absolute path and check the resulting image files before booting or deploying it.
Done means
- You queried a quoted modalias and checked the command status.
- You identified the source directory, file precedence and record indentation that apply.
- You backed up the compiled database before a privileged update.
- You used the correct destination, with
--strictwhere parsing errors must fail the operation. - You queried the same modalias after rebuilding and know how to restore the backup.