diff --git a/man/udev.7 b/man/udev.7 index 37a5905eb..56e6b0113 100644 --- a/man/udev.7 +++ b/man/udev.7 @@ -565,7 +565,10 @@ 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\&. If +if you want ship the compiled database in an immutable image by using +\fB\-\-usr\fR, or anywhere on the system by using +\fB\-\-output\fR\&. During runtime only the binary database is used\&. +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" diff --git a/man/udev.xml b/man/udev.xml index bbbc2d97a..e3756c07c 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -767,7 +767,7 @@ udevadm8 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. If UDEV_HWDB_BIN + If UDEV_HWDB_BIN 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. diff --git a/man/udevadm.8 b/man/udevadm.8 index f6e2cfc39..3f201597f 100644 --- a/man/udevadm.8 +++ b/man/udevadm.8 @@ -380,6 +380,11 @@ Query the database with a modalias string, and print the retrieved properties\&. Alternative root path in the file system for reading and writing files\&. .RE .PP +\fB\-o\fR, \fB\-\-output=\fR\fB\fIstring\fR\fR +.RS 4 +Specify the exact location where to write the compiled database\&. +.RE +.PP \fB\-h\fR, \fB\-\-help\fR .RS 4 Print help text\&. diff --git a/man/udevadm.xml b/man/udevadm.xml index efd01118f..7da0eef20 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml @@ -552,6 +552,13 @@ Alternative root path in the file system for reading and writing files. + + + + + Specify the exact location where to write the compiled database. + + diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index d14a3434f..9dde04460 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -564,6 +564,7 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam static void help(void) { printf("Usage: udevadm hwdb OPTIONS\n" " -u,--update update the hardware database\n" + " -o,--output=.../hwdb.bin generate in .../hwdb.bin instead of /etc/udev/hwdb.bin\n" " --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" @@ -578,6 +579,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { { "update", no_argument, NULL, 'u' }, { "usr", no_argument, NULL, ARG_USR }, + { "output", required_argument, NULL, 'o' }, { "test", required_argument, NULL, 't' }, { "root", required_argument, NULL, 'r' }, { "help", no_argument, NULL, 'h' }, @@ -585,19 +587,37 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { }; const char *test = NULL; const char *root = ""; - const char *hwdb_bin_dir = "/etc/udev"; bool update = false; struct trie *trie = NULL; int err, c; int rc = EXIT_SUCCESS; - while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0) + _cleanup_free_ char *hwdb_bin = strdup("/etc/udev/hwdb.bin"); + if (hwdb_bin == NULL) { + rc = EXIT_FAILURE; + goto out; + } + + while ((c = getopt_long(argc, argv, "uo:t:r:h", options, NULL)) >= 0) switch(c) { case 'u': update = true; break; case ARG_USR: - hwdb_bin_dir = UDEV_LIBEXEC_DIR; + free(hwdb_bin); + hwdb_bin = strdup(UDEV_LIBEXEC_DIR "/hwdb.bin"); + if (hwdb_bin == NULL) { + rc = EXIT_FAILURE; + goto out; + } + break; + case 'o': + free(hwdb_bin); + hwdb_bin = strdup(optarg); + if (hwdb_bin == NULL) { + rc = EXIT_FAILURE; + goto out; + } break; case 't': test = optarg; @@ -621,7 +641,20 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { if (update) { char **files, **f; - _cleanup_free_ char *hwdb_bin = NULL; + + if (strlen(root)) { + /* --root has been specified, prepend it to + the hwdb.bin destination file. */ + char *full_hwdb_bin = strjoin(root, "/", hwdb_bin, NULL); + /* Do nothing if no --root, so that hwdb_bin + may still be relative. */ + if (full_hwdb_bin == NULL) { + rc = EXIT_FAILURE; + goto out; + } + free (hwdb_bin); + hwdb_bin = full_hwdb_bin; + } trie = new0(struct trie, 1); if (!trie) { @@ -672,7 +705,6 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { log_debug("strings dedup'ed: %8zu bytes (%8zu)", trie->strings->dedup_len, trie->strings->dedup_count); - hwdb_bin = strjoin(root, "/", hwdb_bin_dir, "/hwdb.bin", NULL); if (!hwdb_bin) { rc = EXIT_FAILURE; goto out;