Merge pull request #262 from vivien-consider-dropping-github/master

Dynamically get the udevadm hwdb files with a path variable
This commit is contained in:
Boian Bonev 2023-10-01 00:45:45 +03:00 committed by GitHub
commit 805c07a07b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 114 additions and 19 deletions

View File

@ -540,13 +540,17 @@ character itself\&.
The hwdb files are read from the files located in the system hwdb directory
/usr/lib/udev/hwdb\&.d, the volatile runtime directory
/run/udev/hwdb\&.d
and the local administration directory
/etc/udev/hwdb\&.d\&. All hwdb 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
the local administration directory
/etc/udev/hwdb\&.d, and any other directory in the
\fBUDEV_HWDB_PATH\fR
search path variable\&. All hwdb 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
/etc
have the highest priority, files in
/run
take precedence over files with the same name in
/usr/lib\&. This can be used to override a system\-supplied hwdb file with a local file if needed; a symlink in
/usr/lib, and the content of
\fBUDEV_HWDB_PATH\fR
comes last\&. This order can be used to override a system\-supplied hwdb file with a local file if needed; a symlink in
/etc
with the same name as a hwdb file in
/usr/lib, pointing to

View File

@ -738,12 +738,15 @@
<para>The hwdb files are read from the files located in the
system hwdb directory <filename>/usr/lib/udev/hwdb.d</filename>,
the volatile runtime directory <filename>/run/udev/hwdb.d</filename>
and the local administration directory <filename>/etc/udev/hwdb.d</filename>.
the local administration directory <filename>/etc/udev/hwdb.d</filename>,
and any other directory in the <envar>UDEV_HWDB_PATH</envar> search path variable.
All hwdb 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 <filename>/etc</filename>
have the highest priority, files in <filename>/run</filename> take precedence
over files with the same name in <filename>/usr/lib</filename>. This can be
have the highest priority, files in <filename>/run</filename>
take precedence over files with the same name in
<filename>/usr/lib</filename>, and the content of
<envar>UDEV_HWDB_PATH</envar> comes last. This order can be
used to override a system-supplied hwdb file with a local file if needed;
a symlink in <filename>/etc</filename> with the same name as a hwdb file in
<filename>/usr/lib</filename>, pointing to <filename>/dev/null</filename>,

View File

@ -356,7 +356,11 @@ Maintain the hardware database index in
.PP
\fB\-u\fR, \fB\-\-update\fR
.RS 4
Compile the hardware database information located in /usr/lib/udev/hwdb\&.d/, /etc/udev/hwdb\&.d/ and store it in
Compile the hardware database information located in
/etc/udev/hwdb\&.d/,
/usr/lib/udev/hwdb\&.d/, and under the
\fBUDEV_HWDB_PATH\fR
path environment variable, and store it in
/etc/udev/hwdb\&.bin\&. This should be done after any update to the source files; it will not be called automatically\&. The running udev daemon will detect a new database on its own and does not need to be notified about it\&.
.RE
.PP

View File

@ -521,11 +521,16 @@
<term><option>-u</option></term>
<term><option>--update</option></term>
<listitem>
<para>Compile the hardware database information located in /usr/lib/udev/hwdb.d/,
/etc/udev/hwdb.d/ and store it in <filename>/etc/udev/hwdb.bin</filename>. This should be done after
any update to the source files; it will not be called automatically. The running
udev daemon will detect a new database on its own and does not need to be
notified about it.</para>
<para>Compile the hardware database information located in
<filename>/etc/udev/hwdb.d/</filename>,
<filename>/usr/lib/udev/hwdb.d/</filename>, and under the
<envar>UDEV_HWDB_PATH</envar> path environment variable,
and store it in
<filename>/etc/udev/hwdb.bin</filename>. This should be
done after any update to the source files; it will not be
called automatically. The running udev daemon will detect
a new database on its own and does not need to be notified
about it.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -143,3 +143,64 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char *root, con
return conf_files_list_strv_internal(strv, suffix, root, copy);
}
/* Copy every non-empty path element from path_variable to
destination, and add a final NULL pointer. If destination is NULL,
then only count the number of non-empty path elements. Return
-ENOMEM if the copy failed, or the number of elements. */
static ssize_t conf_files_list_follow_path (const char *path_variable, char **destination) {
/* This function is not using strtok_r, because two passes are
required: the first one to count the number of elements,
the second one to actually copy them once an array of the
correct size has been allocated. */
size_t n = 0;
if (path_variable != NULL) {
while (path_variable[0] == ':') {
path_variable++;
}
while (path_variable[0] != '\0') {
const char *end = strchr(path_variable, ':');
if (end == NULL) {
end = path_variable + strlen(path_variable);
}
if (destination != NULL) {
destination[n] = strndup(path_variable, end - path_variable);
if (destination[n] == NULL) {
return -ENOMEM;
}
}
n++;
path_variable = end;
while (path_variable[0] == ':') {
path_variable++;
}
}
}
if (destination != NULL) {
destination[n] = NULL;
}
return n;
}
/* path is a colon-separated list of directories. */
int conf_files_list_strv_path(char ***strv, const char *suffix, const char *root, const char* path) {
_cleanup_strv_free_ char **copy = NULL;
assert(strv);
assert(suffix);
ssize_t path_length = conf_files_list_follow_path(path, NULL);
if (path_length < 0)
return -ENOMEM;
copy = new0(char *, path_length + 1);
if (!copy)
return -ENOMEM;
ssize_t error = conf_files_list_follow_path(path, copy);
if (error < 0)
return -ENOMEM;
assert (error == path_length);
return conf_files_list_strv_internal(strv, suffix, root, copy);
}

View File

@ -23,3 +23,4 @@
#include "macro.h"
int conf_files_list_strv(char ***strv, const char *suffix, const char *root, const char* const* dirs);
int conf_files_list_strv_path(char ***strv, const char *suffix, const char *root, const char* path);

View File

@ -35,11 +35,17 @@
* Uses a Patricia/radix trie to index all matches for efficient lookup.
*/
static const char * const conf_file_dirs[] = {
UDEV_HWDB_DIR,
UDEV_LIBEXEC_DIR "/hwdb.d",
NULL
};
static char *list_conf_file_path (void) {
static const char *main_hwdb_dir = UDEV_HWDB_DIR;
static const char *libexec_dir = UDEV_LIBEXEC_DIR "/hwdb.d";
const char *path_variable = getenv ("UDEV_HWDB_PATH");
/* UDEV_HWDB_PATH comes last, so that it cannot override
system settings. */
/* System settings can be overriden by putting the files in
/etc. */
/* path_variable may be NULL, strjoin works either way. */
return strjoin(main_hwdb_dir, ":", libexec_dir, ":", path_variable, NULL);
}
/* in-memory trie objects */
struct trie {
@ -568,7 +574,12 @@ static void help(void) {
" --usr generate in " UDEV_LIBEXEC_DIR " instead of /etc/udev\n"
" -t,--test=MODALIAS query database and print result\n"
" -r,--root=PATH alternative root path in the filesystem\n"
" -h,--help\n\n");
" -h,--help\n"
"\n"
"The HWDB is searched in "
UDEV_HWDB_DIR ", " UDEV_LIBEXEC_DIR "/hwdb.d, "
"and the UDEV_HWDB_PATH search path.\n"
"\n");
}
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
@ -677,7 +688,13 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
}
trie->nodes_count++;
err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs);
_cleanup_free_ char *conf_file_path = list_conf_file_path ();
if (conf_file_path == NULL) {
rc = EXIT_FAILURE;
goto out;
}
err = conf_files_list_strv_path(&files, ".hwdb", root,
conf_file_path);
if (err < 0) {
log_error_errno(err, "failed to enumerate hwdb files: %m");
rc = EXIT_FAILURE;