mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-11-23 23:10:57 +07:00
Dynamically get the udevadm hwdb files with a path variable
Introduce UDEV_HWDB_PATH, containing a colon-separated path with hwdb files in it. The whole path is searched, in addition to the system locations, when searching for hwdb files. Due to how conf_files_list_strv is implemented, as a thin wrapper around the internal function, it is easy to also implement a variant accepting a search path in the same way. Since the internal function expects an allocated array of allocated strings, the path scanning is done in 2 steps, to first get the array length, and then duplicate the items. It is not possible to use strtok(_r) here because it would work for only 1 pass. * src/shared/conf-files.c (conf_files_list_follow_path): New function. (conf_files_list_strv_path): Use it here. * src/shared/conf-files.h: Export the signature for the _path variant. * src/udev/udevadm-hwdb.c (list_conf_file_path): New function replacing conf_file_dirs. (help): Document the search path for hwdb files. (adm_hwdb): Use list_conf_file_path and conf_files_list_strv_path. * man/udevadm.xml: Mention UDEV_HWDB_PATH. * man/udev.xml: Same. * man/udevadm.8: Regenerate. * man/udev.7: Same.
This commit is contained in:
parent
0d86dd9a2a
commit
65e17b2f2f
14
man/udev.7
14
man/udev.7
@ -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
|
||||
@ -535,13 +535,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
|
||||
|
@ -736,12 +736,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>,
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
@ -567,7 +573,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[]) {
|
||||
@ -644,7 +655,14 @@ 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);
|
||||
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);
|
||||
free (conf_file_path);
|
||||
if (err < 0) {
|
||||
log_error_errno(err, "failed to enumerate hwdb files: %m");
|
||||
rc = EXIT_FAILURE;
|
||||
|
Loading…
Reference in New Issue
Block a user