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;