Let libudev find hwdb.bin under UDEV_HWDB_BIN

* src/libudev/libudev-hwdb.c (get_hwdb_bin_paths): New function,
replacing hwdb_bin_paths.
(struct udev_hwdb): New bin_paths field.
(udev_hwdb_new): Initialize it with get_hwdb_bin_paths.
(udev_hwdb_validate): Use the bin_paths field to find hwdb.bin.
(udev_hwdb_unref): Free the bin_paths field.
* src/libudev/libudev.h: Warn about UDEV_HWDB_BIN.
* man/udev.xml: Mention run-time UDEV_HWDB_BIN.
* man/udev.7: Re-generate.
This commit is contained in:
Vivien Kraus 2023-09-30 09:08:48 +02:00
parent 0d86dd9a2a
commit c7da117e5c
4 changed files with 42 additions and 11 deletions

View File

@ -34,7 +34,7 @@ All device information udev processes is stored in the udev database and sent ou
.SH "RULES FILES"
.PP
The udev rules are read from the files located in the system rules directory
/lib/udev/rules\&.d (additionally /usr/lib/udev/rules\&.d when built with --enable-split-usr), the volatile runtime directory
/lib/udev/rules\&.d, the volatile runtime directory
/run/udev/rules\&.d
and the local administration directory
/etc/udev/rules\&.d\&. All rules files are collectively sorted and processed in lexical order, regardless of the directories in which they live\&. However, files with identical filenames replace each other\&. Files in
@ -42,7 +42,7 @@ and the local administration directory
have the highest priority, files in
/run
take precedence over files with the same name in
/lib (or /usr/lib)\&. This can be used to override a system\-supplied rules file with a local file if needed; a symlink in
/lib\&. This can be used to override a system\-supplied rules file with a local file if needed; a symlink in
/etc
with the same name as a rules file in
/lib, pointing to
@ -560,7 +560,9 @@ The content of all hwdb files is read by
and compiled to a binary database located at
/etc/udev/hwdb\&.bin, or alternatively
/usr/lib/udev/hwdb\&.bin
if you want ship the compiled database in an immutable image\&. During runtime only the binary database is used\&.
if you want ship the compiled database in an immutable image\&. If
\fBUDEV_HWDB_BIN\fR
is set at run\-time, and its value identifies a file in the file system, then the binary database located under this name will be used\&. During runtime only the binary database is used\&.
.SH "SEE ALSO"
.PP
\fBudevd\fR(8),

View File

@ -765,7 +765,9 @@
<citerefentry><refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
and compiled to a binary database located at <filename>/etc/udev/hwdb.bin</filename>,
or alternatively <filename>/usr/lib/udev/hwdb.bin</filename> if you want ship the compiled
database in an immutable image.
database in an immutable image. If <envar>UDEV_HWDB_BIN</envar>
is set at run-time, and its value identifies a file in the file system, then the binary
database located under this name will be used.
During runtime only the binary database is used.</para>
</refsect1>

View File

@ -47,6 +47,7 @@ struct udev_hwdb {
struct udev *udev;
int refcount;
char *bin_paths;
FILE *f;
struct stat st;
union {
@ -256,10 +257,28 @@ static int trie_search_f(struct udev_hwdb *hwdb, const char *search) {
return 0;
}
static const char hwdb_bin_paths[] =
"/etc/udev/hwdb.bin\0"
UDEV_LIBEXEC_DIR "/hwdb.bin\0";
static char *get_hwdb_bin_paths (void) {
static const char default_locations[] =
"/etc/udev/hwdb.bin\0"
UDEV_LIBEXEC_DIR "/hwdb.bin\0";
const char *by_env = getenv("UDEV_HWDB_BIN");
if (by_env != NULL) {
char *path = malloc(strlen(by_env) + 1
+ sizeof (default_locations));
if (path != NULL) {
memcpy(path, by_env, strlen(by_env) + 1);
memcpy(path + strlen(by_env) + 1,
default_locations,
sizeof (default_locations));
}
return path;
}
char *path = malloc(sizeof (default_locations));
if (path != NULL) {
memcpy(path, default_locations, sizeof (default_locations));
}
return path;
}
/**
* udev_hwdb_new:
@ -282,7 +301,12 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
udev_list_init(udev, &hwdb->properties_list, true);
/* find hwdb.bin in hwdb_bin_paths */
NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) {
hwdb->bin_paths = get_hwdb_bin_paths();
if (hwdb->bin_paths == NULL) {
udev_hwdb_unref(hwdb);
return NULL;
}
NULSTR_FOREACH(hwdb_bin_path, hwdb->bin_paths) {
hwdb->f = fopen(hwdb_bin_path, "re");
if (hwdb->f)
break;
@ -363,6 +387,7 @@ _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
return NULL;
if (hwdb->map)
munmap((void *)hwdb->map, hwdb->st.st_size);
free(hwdb->bin_paths);
if (hwdb->f)
fclose(hwdb->f);
udev_list_cleanup(&hwdb->properties_list);
@ -381,7 +406,7 @@ bool udev_hwdb_validate(struct udev_hwdb *hwdb) {
return false;
/* if hwdb.bin doesn't exist anywhere, we need to update */
NULSTR_FOREACH(p, hwdb_bin_paths) {
NULSTR_FOREACH(p, hwdb->bin_paths) {
if (stat(p, &st) >= 0) {
found = true;
break;

View File

@ -185,7 +185,9 @@ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev
/*
* udev_hwdb
*
* access to the static hardware properties database
* access to the static hardware properties database; the database to
* use can be overriden by setting the UDEV_HWDB_BIN environment
* variable to its file name
*/
struct udev_hwdb;
struct udev_hwdb *udev_hwdb_new(struct udev *udev);