From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:403:478a::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms9.migadu.com with LMTPS id MJEqFPv8F2W1KgAAG6o9tA:P1 (envelope-from ) for ; Sat, 30 Sep 2023 12:48:27 +0200 Received: from aspmx1.migadu.com ([2001:41d0:403:478a::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id MJEqFPv8F2W1KgAAG6o9tA (envelope-from ) for ; Sat, 30 Sep 2023 12:48:27 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id E939544D56 for ; Sat, 30 Sep 2023 12:48:26 +0200 (CEST) Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=planete-kraus.eu header.s=albinoniA header.b=wA82C2Ws; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=gnu.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1696070907; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:resent-cc: resent-from:resent-sender:resent-message-id:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=7Sx/LBvoQPhf07NE3embJcbCfEBoXtY2Fouj/uGLdrY=; b=YkKzcqKRk0/uwkYeibuEQKubEpOA3D03OcHSNsyEyq701d0UrHrcdIZ18i/kC4PLtEYJzF F/Jrrz5VDmczv0aU83F6zHrt2tJ/NbUKA0w1DyruvOLsmEEjDrPMglTEYrbpyUNaNsFcSc ij9KPU+P0h6fTujchU8+dmxsmBOlYZO8wYx8SbJqgFbu6KqHKLYW2BXGlqawKUydxPvXZx DhbaoKPLc3tTQ5vX0eCy80LKkyYVDRUtDxzijHeWqH18t9q4ixwXmyj3+jV6l6lMGUyst8 NWEVkqT6CBtpOjIFfA5qIIvbsXSPGP3yQV7M3cn/Dw3M16tuhgCx0UPVd2fltQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1696070907; a=rsa-sha256; cv=none; b=kChOC0eGXej2lm5U+DdfNYCVjyM5A6uH6N2Al+IuKmrhrbrcETV2a5wkK9iwOhClG01/fs 4duviPrC12juManua1dm43qkpk4Sji7bUo/FIaRlfjf8Uc6CgCQCeAzanho1PawbVpvTQv zvDChCgg6C1LixJy19ROe0FxwBXqTN+UKslmGnqWb1QZxoiVEVgMbSO1WpIgxwmELqTVTK ndIjF/EcBuBDu5mE9H2Za+9h9j9LV9e80RmefofKQzzz74iEB1glQhFA44GMnJk8PBvDfx Q31unT+VhNI9voxPKUYIDF5m1vB9qUYZiuOnWohJ3xqd7mROIFu9ORMKwhGrLA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=planete-kraus.eu header.s=albinoniA header.b=wA82C2Ws; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=gnu.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qmXVn-0007aJ-BP; Sat, 30 Sep 2023 06:47:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qmXVl-0007YG-AY for guix-patches@gnu.org; Sat, 30 Sep 2023 06:47:49 -0400 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qmXVk-0003xk-44 for guix-patches@gnu.org; Sat, 30 Sep 2023 06:47:49 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qmXVz-0003lf-Cg for guix-patches@gnu.org; Sat, 30 Sep 2023 06:48:03 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#66099] [WIP PATCH gnome-team v2 1/3] gnu: eudev: Update libudev version to 251. Resent-From: Vivien Kraus Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 30 Sep 2023 10:48:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 66099 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Liliana Marie Prikler ,66099@debbugs.gnu.org Cc: rg@raghavgururajan.name, maxim.cournoyer@gmail.com Received: via spool by 66099-submit@debbugs.gnu.org id=B66099.169607084914323 (code B ref 66099); Sat, 30 Sep 2023 10:48:03 +0000 Received: (at 66099) by debbugs.gnu.org; 30 Sep 2023 10:47:29 +0000 Received: from localhost ([127.0.0.1]:57796 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qmXVQ-0003iq-0e for submit@debbugs.gnu.org; Sat, 30 Sep 2023 06:47:29 -0400 Received: from planete-kraus.eu ([89.234.140.182]:48792) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qmXVK-0003hw-LG for 66099@debbugs.gnu.org; Sat, 30 Sep 2023 06:47:24 -0400 Received: from planete-kraus.eu (localhost.lan [127.0.0.1]) by planete-kraus.eu (OpenSMTPD) with ESMTP id b01f7927; Sat, 30 Sep 2023 10:47:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=planete-kraus.eu; h= message-id:in-reply-to:references:from:date:subject:mime-version :content-type:content-transfer-encoding:to:cc; s=albinoniA; bh=N zcE4NE462ijEDP9ENqJivz9WhU=; b=wA82C2WsbQuTc/MDNvktHgz3XMV9qtveP QhLv+/ve/AtZiBG+LzYC6r600gTMKS34wyVVb61fL4hB6jWcaqQgTyJ6aarNNiFN BqZ6qQDVURmkB5Sa66Ejd+xr1rhaBC45SvRDGCHN2UIEIF1OePRVkNdjhia8BSQM Ga20I14KxIXYfkaumOBMPsiCmlqq/jxBU3jpCypI4QwyC2l/4fJl2oX4tA5JwYPD +IFlfIvXWdANr5rwIF245+Mzg9XgKVfWIlV6mBTOrowzt9sQAf+TbkGIwIjNeVwE 2smISqxY9r0sh/2eEZ5Rvcu2odruTsqEfEeyq1RXzDXHhQtSEmZJA== Received: by planete-kraus.eu (OpenSMTPD) with ESMTPSA id 373a9cf6 (TLSv1.3:TLS_CHACHA20_POLY1305_SHA256:256:NO); Sat, 30 Sep 2023 10:47:05 +0000 (UTC) Message-ID: <18ff7cf952823194b52adcd0e6a13171d701ab94.1696070591.git.vivien@planete-kraus.eu> In-Reply-To: References: Date: Tue, 19 Sep 2023 13:23:22 +0200 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-Agent: Evolution 3.46.4 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Vivien Kraus X-ACL-Warn: , Vivien Kraus via Guix-patches From: Vivien Kraus via Guix-patches via Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: guix-patches-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Scanner: mx0.migadu.com X-Migadu-Spam-Score: -4.24 X-Spam-Score: -4.24 X-Migadu-Queue-Id: E939544D56 X-TUID: 9u7KPxN9qrWJ Support for version 251 is only provided as a merge request for now: https://github.com/eudev-project/eudev/pull/253 This merge request bumps the eudev version to 3.2.14, but it has not been released yet. Eudev now has a hardware database that installs descriptions of hardware in /etc, but they should go to /lib prior to being used. I added a phase to copy all the /etc files to /lib. I submitted 3 patches to make udev hwdb more guix-friendly, fused in eudev-hwdb-bin-path.patch. libudev requires an indexed binary file that knows about all devices, and this file is generated by udevadm hwdb --update -o /lib/udev/hwdb.bin. This udevadm hwdb command respects the UDEV_HWDB_PATH to collect all entries for the hwdb. Then, libudev can use UDEV_HWDB_BIN to select the database at run-time. I think everything could work out for Guix if we add a new profile hook that: 1. Calls udevadm hwdb --update -o /lib/udev/hwdb.bin; 2. Set UDEV_HWDB_BIN to /lib/udev/hwdb.bin. Unfortunately, I don’t know how to do that profile hook thing. Do you have pointers? * gnu/packages/linux.scm (eudev): Update to v3.2.12, but bump version to 3.2.14.beta. [#:phases] : New phase. : Update accordingly. [search-paths]: Add UDEV_HWDB_PATH. * gnu/packages/patches/eudev-bump-to-251.patch: New file. * gnu/packages/patches/eudev-hwdb-bin-path.patch: New file. * gnu/packages/linux.scm (eudev): Use them here. * gnu/local.mk (dist_patch_DATA): Register them here. --- gnu/local.mk | 2 + gnu/packages/linux.scm | 32 +- gnu/packages/patches/eudev-bump-to-251.patch | 134 ++++++++ .../patches/eudev-hwdb-bin-path.patch | 309 ++++++++++++++++++ 4 files changed, 463 insertions(+), 14 deletions(-) create mode 100644 gnu/packages/patches/eudev-bump-to-251.patch create mode 100644 gnu/packages/patches/eudev-hwdb-bin-path.patch diff --git a/gnu/local.mk b/gnu/local.mk index 72c9954492..6c98ede191 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1127,6 +1127,8 @@ dist_patch_DATA = \ %D%/packages/patches/esmini-use-pkgconfig.patch \ %D%/packages/patches/esmtp-add-lesmtp.patch \ %D%/packages/patches/eudev-rules-directory.patch \ + %D%/packages/patches/eudev-bump-to-251.patch \ + %D%/packages/patches/eudev-hwdb-bin-path.patch \ %D%/packages/patches/exercism-disable-self-update.patch \ %D%/packages/patches/extempore-unbundle-external-dependencies.patch \ %D%/packages/patches/extundelete-e2fsprogs-1.44.patch \ diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm index 85e3d9845d..5ea44e886e 100644 --- a/gnu/packages/linux.scm +++ b/gnu/packages/linux.scm @@ -4265,16 +4265,18 @@ (define-public eudev ;; The post-systemd fork, maintained by Gentoo. (package (name "eudev") - (version "3.2.11") + (version "3.2.14.beta") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/gentoo/eudev") - (commit (string-append "v" version)))) + (commit "v3.2.12"))) (file-name (git-file-name name version)) (sha256 (base32 - "0dzaqwjnl55f69ird57wb6skahc6l7zs1slsrzqqfhww33icp6av")) - (patches (search-patches "eudev-rules-directory.patch")))) + "0wpckjxzsb4wkj3pwnw14zmp3z8ivf03hjbgs838q5gfridpxnf7")) + (patches (search-patches "eudev-rules-directory.patch" + "eudev-bump-to-251.patch" + "eudev-hwdb-bin-path.patch")))) (build-system gnu-build-system) (arguments (list @@ -4297,18 +4299,20 @@ (define-public eudev (substitute* (string-append #$output "/lib/libudev.la") (("old_library=.*") "old_library=''\n"))))) - (add-after 'install 'build-hwdb + (add-after 'install 'allow-eudev-hwdb (lambda _ - ;; Build OUT/etc/udev/hwdb.bin. This allows 'lsusb' and - ;; similar tools to display product names. - ;; - ;; XXX: This can't be done when cross-compiling. Find another way - ;; to generate hwdb.bin for cross-built systems. - #$@(if (%current-target-system) - #~(#t) - #~((invoke (string-append #$output "/bin/udevadm") - "hwdb" "--update")))))) + ;; eudev distributes the hwdb, but each file has to be enabled + ;; by being copied under /lib/udev/hwdb.d. We accept all of + ;; them. + (symlink (string-append #$output "/etc/udev/hwdb.d") + (string-append #$output "/lib/udev/hwdb.d"))))) #:configure-flags #~(list "--enable-manpages"))) + (search-paths + (list (search-path-specification + (variable "UDEV_HWDB_PATH") + (files '("lib/udev/hwdb.d"))))) + ;; FIXME: there needs to be a profile hook that calls udevadm hwdb + ;; --update -o /lib/udev/hwdb.bin (native-inputs (list autoconf automake diff --git a/gnu/packages/patches/eudev-bump-to-251.patch b/gnu/packages/patches/eudev-bump-to-251.patch new file mode 100644 index 0000000000..96a73f4ede --- /dev/null +++ b/gnu/packages/patches/eudev-bump-to-251.patch @@ -0,0 +1,134 @@ +From 4d29151078c351569767dfef490a29e379afd430 Mon Sep 17 00:00:00 2001 +Message-ID: <4d29151078c351569767dfef490a29e379afd430.1695104483.git.vivien@planete-kraus.eu> +In-Reply-To: +References: +From: Boian Bonev +Date: Tue, 30 May 2023 16:16:33 +0000 +Subject: [PATCH 1/1] Update as per IRC discussion + +Bump udev version to 251 + +Export dummies for + + - udev_device_has_current_tag + - udev_device_get_current_tags_list_entry + +since the current eudev device database does not support the concept of +current tags + +bump version to 3.2.14 +--- + README.md | 18 ++++++++++++------ + configure.ac | 4 ++-- + src/libudev/libudev-device.c | 11 +++++++++++ + src/libudev/libudev.h | 2 ++ + src/libudev/libudev.sym | 6 ++++++ + 5 files changed, 33 insertions(+), 8 deletions(-) + +diff --git a/README.md b/README.md +index 848ef3348..6016380ba 100644 +--- a/README.md ++++ b/README.md +@@ -1,11 +1,17 @@ +-This git repo is a fork of git://anongit.freedesktop.org/systemd/systemd +-with the aim of isolating udev from any particular flavor of system +-initialization. In this case, the isolation is from systemd. ++**eudev** is a standalone dynamic and persistent device naming support (aka ++userspace devfs) daemon that runs independently from the init system. ++**eudev** strives to remain init system and linux distribution neutral. It is ++currently used as the devfs manager for more than a dozen different linux ++distributions. ++ ++This git repo is a fork of git://anongit.freedesktop.org/systemd/systemd with ++the aim of isolating udev from any particular flavor of system initialization. ++In this case, the isolation is from systemd. + + This is a project started by Gentoo developers and testing was initially being +-done mostly on OpenRC. We welcome contribution from others using a variety of +-system initializations to ensure eudev remains system initialization and +-distribution neutral. On 2021-08-20 Gentoo decided to abandon eudev and a new ++done mostly on OpenRC. We welcome contribution from others using a variety of ++system initializations to ensure **eudev** remains system initialization and ++distribution neutral. On 2021-08-20 Gentoo decided to abandon eudev and a new + project was established on 2021-09-14 by Alpine, Devuan and Gentoo + contributors (alphabetical order). + +diff --git a/configure.ac b/configure.ac +index 3e31b0ebc..0d9a135bc 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1,6 +1,6 @@ + AC_PREREQ([2.68]) +-AC_INIT([eudev],[3.2.12],[https://github.com/gentoo/eudev/issues]) +-AC_SUBST(UDEV_VERSION, 243) ++AC_INIT([eudev],[3.2.14],[https://github.com/gentoo/eudev/issues]) ++AC_SUBST(UDEV_VERSION, 251) + AC_CONFIG_SRCDIR([src/udev/udevd.c]) + + AC_USE_SYSTEM_EXTENSIONS +diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c +index ac67ce846..7d7a6622e 100644 +--- a/src/libudev/libudev-device.c ++++ b/src/libudev/libudev-device.c +@@ -1819,6 +1819,12 @@ _public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_dev + return udev_list_get_entry(&udev_device->tags_list); + } + ++_public_ struct udev_list_entry *udev_device_get_current_tags_list_entry(struct udev_device *udev_device) ++{ ++ // TODO: eudev database does not support current tags ++ return udev_device_get_tags_list_entry(udev_device); ++} ++ + /** + * udev_device_has_tag: + * @udev_device: udev device +@@ -1842,6 +1848,11 @@ _public_ int udev_device_has_tag(struct udev_device *udev_device, const char *ta + return false; + } + ++_public_ int udev_device_has_current_tag(struct udev_device *udev_device, const char *tag) { ++ // TODO: eudev database does not support current tags ++ return udev_device_has_tag(udev_device, tag); ++} ++ + #define ENVP_SIZE 128 + #define MONITOR_BUF_SIZE 4096 + static int update_envp_monitor_buf(struct udev_device *udev_device) +diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h +index 8491d2b81..0202964d6 100644 +--- a/src/libudev/libudev.h ++++ b/src/libudev/libudev.h +@@ -100,6 +100,7 @@ int udev_device_get_is_initialized(struct udev_device *udev_device); + struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device); + struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device); + struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device); ++struct udev_list_entry *udev_device_get_current_tags_list_entry(struct udev_device *udev_device); + struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device); + const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key); + const char *udev_device_get_driver(struct udev_device *udev_device); +@@ -110,6 +111,7 @@ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device + const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr); + int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, char *value); + int udev_device_has_tag(struct udev_device *udev_device, const char *tag); ++int udev_device_has_current_tag(struct udev_device *udev_device, const char *tag); + + /* + * udev_monitor +diff --git a/src/libudev/libudev.sym b/src/libudev/libudev.sym +index 76726fca7..d56c2aeab 100644 +--- a/src/libudev/libudev.sym ++++ b/src/libudev/libudev.sym +@@ -118,3 +118,9 @@ global: + udev_queue_flush; + udev_queue_get_fd; + } LIBUDEV_199; ++ ++LIBUDEV_247 { ++global: ++ udev_device_has_current_tag; ++ udev_device_get_current_tags_list_entry; ++} LIBUDEV_215; +-- +2.41.0 + diff --git a/gnu/packages/patches/eudev-hwdb-bin-path.patch b/gnu/packages/patches/eudev-hwdb-bin-path.patch new file mode 100644 index 0000000000..f6fa91dad0 --- /dev/null +++ b/gnu/packages/patches/eudev-hwdb-bin-path.patch @@ -0,0 +1,309 @@ +From 097290727d6e16aa2e5859e3cd6f0c5ea4c47101 Mon Sep 17 00:00:00 2001 +Message-ID: <097290727d6e16aa2e5859e3cd6f0c5ea4c47101.1696060300.git.vivien@planete-kraus.eu> +From: Vivien Kraus +Date: Tue, 26 Sep 2023 18:17:34 +0200 +Subject: [PATCH] Improvements for Guix + +--- +This is the combination of: + + - https://github.com/eudev-project/eudev/pull/262 + - https://github.com/eudev-project/eudev/pull/263 + - https://github.com/eudev-project/eudev/pull/264 + + src/libudev/libudev-hwdb.c | 37 +++++++++-- + src/libudev/libudev.h | 4 +- + src/udev/udevadm-hwdb.c | 127 +++++++++++++++++++++++++++++++++---- + 3 files changed, 149 insertions(+), 19 deletions(-) + +diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c +index 62029e2b2..f7212c519 100644 +--- a/src/libudev/libudev-hwdb.c ++++ b/src/libudev/libudev-hwdb.c +@@ -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; +diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h +index 8491d2b81..e4bc18970 100644 +--- a/src/libudev/libudev.h ++++ b/src/libudev/libudev.h +@@ -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); +diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c +index d14a3434f..c2214dc91 100644 +--- a/src/udev/udevadm-hwdb.c ++++ b/src/udev/udevadm-hwdb.c +@@ -35,11 +35,69 @@ + * 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 ssize_t follow_path (const char *path_variable, char **destination, size_t max) { ++ 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 (n < max) { ++ 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 (n < max) { ++ destination[n] = NULL; ++ } ++ return n; ++} ++ ++static char ** list_conf_file_dirs (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"); ++ ssize_t path_length = 0; ++ if (path_variable != NULL) { ++ path_length = follow_path(path_variable, NULL, 0); ++ if (path_length < 0) { ++ return NULL; ++ } ++ } ++ char **all_dirs = malloc((path_length + 2 + 1) * sizeof (char *)); ++ if (all_dirs == NULL) { ++ return NULL; ++ } ++ for (ssize_t i = 0; i < path_length + 2 + 1; i++) { ++ all_dirs[i] = NULL; ++ } ++ ssize_t error = follow_path(path_variable, all_dirs, path_length + 1); ++ all_dirs[path_length] = strdup(main_hwdb_dir); ++ all_dirs[path_length + 1] = strdup(libexec_dir); ++ all_dirs[path_length + 2] = NULL; ++ if (error < 0 ++ || all_dirs[path_length] == NULL ++ || all_dirs[path_length + 1] == NULL) { ++ for (ssize_t i = 0; i < path_length + 2 + 1; i++) { ++ free(all_dirs[i]); ++ } ++ free(all_dirs); ++ all_dirs = NULL; ++ } ++ return all_dirs; ++} + + /* in-memory trie objects */ + struct trie { +@@ -564,10 +622,15 @@ 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" +- " -h,--help\n\n"); ++ " -h,--help\n" ++ "\n" ++ "The HWDB is searched in the UDEV_HWDB_PATH search path, " ++ UDEV_HWDB_DIR ", and " UDEV_LIBEXEC_DIR "/hwdb.d.\n" ++ "\n"); + } + + static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { +@@ -578,6 +641,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 +649,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; +@@ -619,9 +701,18 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { + return EXIT_FAILURE; + } + ++ if (root) { ++ char *full_hwdb_bin = strjoin(root, "/", hwdb_bin, NULL); ++ if (full_hwdb_bin == NULL) { ++ rc = EXIT_FAILURE; ++ goto out; ++ } ++ free (hwdb_bin); ++ hwdb_bin = full_hwdb_bin; ++ } ++ + if (update) { + char **files, **f; +- _cleanup_free_ char *hwdb_bin = NULL; + + trie = new0(struct trie, 1); + if (!trie) { +@@ -644,7 +735,20 @@ 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_dirs = list_conf_file_dirs (); ++ if (conf_file_dirs == NULL) { ++ rc = EXIT_FAILURE; ++ goto out; ++ } ++ err = conf_files_list_strv(&files, ".hwdb", root, ++ (const char * const*) conf_file_dirs); ++ size_t dir_to_cleanup = 0; ++ for (dir_to_cleanup = 0; ++ conf_file_dirs[dir_to_cleanup] != NULL; ++ dir_to_cleanup++) { ++ free (conf_file_dirs[dir_to_cleanup]); ++ } ++ free (conf_file_dirs); + if (err < 0) { + log_error_errno(err, "failed to enumerate hwdb files: %m"); + rc = EXIT_FAILURE; +@@ -672,7 +776,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; + +base-commit: 0d86dd9a2a57d5d0809de6395dc36abe515818b5 +-- +2.41.0 + -- 2.41.0