diff mbox series

[bug#66099,gnome-team,v3,1/3] gnu: eudev: Update libudev version to 251.

Message ID ab54b51365fb18c06f235fedf451e64bad0c88bb.1696083614.git.vivien@planete-kraus.eu
State New
Headers show
Series Update eudev and upower | expand

Commit Message

Vivien Kraus Sept. 19, 2023, 11:23 a.m. UTC
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
<prefix>/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.

Another unreleased patch for PR 255 is also included.

I think everything could work out for Guix if we add a new profile hook that:
1. Calls udevadm hwdb --update -o <profile>/lib/udev/hwdb.bin;
2. Set UDEV_HWDB_BIN to <profile>/lib/udev/hwdb.bin.

This is why there are actually 2 search paths: one for UDEV_HWDB_PATH, and one
for UDEV_HWDB_BIN (the latter accepting only 1 value).

* gnu/packages/linux.scm (eudev): Update to v3.2.12, but bump version to
3.2.14.beta.
[#:phases] <allow-eudev-hwdb>: New phase.
<build-hwdb>: Update accordingly.
[native-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/patches/eudev-pr-255.patch: New file.
* gnu/packages/linux.scm (eudev): Use them here.
* gnu/local.mk (dist_patch_DATA): Register them here.
* guix/profiles.scm (udev-hwdb-bin): New profile hook to generate hwdb.bin.
(%default-profile-hooks): Register it here.
---
 gnu/local.mk                                  |   3 +
 gnu/packages/linux.scm                        |  38 ++-
 gnu/packages/patches/eudev-bump-to-251.patch  | 134 ++++++++
 .../patches/eudev-hwdb-bin-path.patch         | 309 ++++++++++++++++++
 gnu/packages/patches/eudev-pr-255.patch       |  39 +++
 guix/profiles.scm                             |  29 ++
 6 files changed, 538 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
 create mode 100644 gnu/packages/patches/eudev-pr-255.patch

Comments

Liliana Marie Prikler Sept. 30, 2023, 5:59 p.m. UTC | #1
Am Dienstag, dem 19.09.2023 um 13:23 +0200 schrieb Vivien Kraus:
> 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 <prefix>/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.
> 
> Another unreleased patch for PR 255 is also included.
> 
> I think everything could work out for Guix if we add a new profile
> hook that:
> 1. Calls udevadm hwdb --update -o <profile>/lib/udev/hwdb.bin;
> 2. Set UDEV_HWDB_BIN to <profile>/lib/udev/hwdb.bin.
> 
> This is why there are actually 2 search paths: one for
> UDEV_HWDB_PATH, and one for UDEV_HWDB_BIN (the latter accepting only
> 1 value).
Move personal comments below the --- line, keeping explanations above
the ChangeLog.

> * gnu/packages/linux.scm (eudev): Update to v3.2.12, but bump version
> to 3.2.14.beta.
Why not simply use git-version and a commit?  Or alternative have
v3.2.12 as the version while cherry-picking those commits.
> [#:phases] <allow-eudev-hwdb>: New phase.
> <build-hwdb>: Update accordingly.
> [native-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/patches/eudev-pr-255.patch: New file.
You might want to rename these patches to explain what they do in the
file name, e.g. "eudev-libudev251-compat.patch".
> * gnu/packages/linux.scm (eudev): Use them here.
> * gnu/local.mk (dist_patch_DATA): Register them here.
> * guix/profiles.scm (udev-hwdb-bin): New profile hook to generate
> hwdb.bin.
> (%default-profile-hooks): Register it here.
Unless it's absolutely required to make use of eudev, you might want to
separate this hook into a separate patch.


Cheers
Maxim Cournoyer Oct. 1, 2023, 10:02 p.m. UTC | #2
Hi,

Vivien Kraus <vivien@planete-kraus.eu> writes:

> 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
> <prefix>/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.
>
> Another unreleased patch for PR 255 is also included.
>
> I think everything could work out for Guix if we add a new profile hook that:
> 1. Calls udevadm hwdb --update -o <profile>/lib/udev/hwdb.bin;
> 2. Set UDEV_HWDB_BIN to <profile>/lib/udev/hwdb.bin.
>
> This is why there are actually 2 search paths: one for UDEV_HWDB_PATH, and one
> for UDEV_HWDB_BIN (the latter accepting only 1 value).
>
> * gnu/packages/linux.scm (eudev): Update to v3.2.12, but bump version to
> 3.2.14.beta.
> [#:phases] <allow-eudev-hwdb>: New phase.
> <build-hwdb>: Update accordingly.
> [native-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/patches/eudev-pr-255.patch: New file.
> * gnu/packages/linux.scm (eudev): Use them here.
> * gnu/local.mk (dist_patch_DATA): Register them here.
> * guix/profiles.scm (udev-hwdb-bin): New profile hook to generate hwdb.bin.
> (%default-profile-hooks): Register it here.

Impressive work!  It seems your patches were warmly welcomed (already
merged!) in eudev, which is excellent (and should mean a v4 doesn't need
patches anymore, using a specific commit with a git-version computed
version.

[...]

>      (build-system gnu-build-system)
>      (arguments
>       (list
> @@ -4297,18 +4300,25 @@ (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")))
> +    (native-search-paths
> +      (list (search-path-specification
> +              (variable "UDEV_HWDB_PATH")
> +              (files '("lib/udev/hwdb.d")))
> +            ;; Never install a hwdb.bin file, always let the udev-hwdb-bin
> +            ;; profile hook generate it.
> +            (search-path-specification
> +              (variable "UDEV_HWDB_BIN")
> +              (files '("lib/udev/hwdb.bin"))
> +              (file-type 'regular)
> +              (separator #f))))

Maybe add a ;singled valued comment to the end of the above line.  Note
that given that file is to be generated in a profile hook, UDEV_HWDB_BIN
would never be set at *build* time, but that should not matter
much (the build environment being containerized and all).)

[...]

> diff --git a/guix/profiles.scm b/guix/profiles.scm
> index c88672c25a..d308e7fb88 100644
> --- a/guix/profiles.scm
> +++ b/guix/profiles.scm
> @@ -1905,6 +1905,34 @@ (define (texlive-font-maps manifest)
>                              (hook . texlive-font-maps)))
>          (return #f))))
>  
> +(define (udev-hwdb-bin manifest)
> +  "Return a derivation that builds lib/udev/hwdb.bin."
                                      ^
                                      @file{lib/udev/hwdb.bin}

> +  (define eudev
> +    (module-ref (resolve-interface '(gnu packages linux)) 'eudev))
> +  (define build
> +    (with-imported-modules
> +        (source-module-closure '((guix build utils)))
> +      #~(begin
> +          (use-modules (guix build utils))
> +          (let* ((inputs '#$(manifest-inputs manifest))
> +                 (hwdb-directories
> +                  (filter
> +                   file-exists?
> +                   (map (lambda (directory)
> +                          (string-append directory "/lib/udev/hwdb.d"))
> +                        inputs))))
> +            (setenv "UDEV_HWDB_PATH"
> +                    (string-join hwdb-directories ":")))

It'd be nicer to user 'evaluate-search-paths' with the UDEV_HWDB_PATH
search path.

> +          (invoke #$(file-append eudev "/bin/udevadm")
> +                  "hwdb" "--update"
> +                  "-o" (string-append #$output "/lib/udev/hwdb.bin")))))
> +  (gexp->derivation "udev-hwdb-bin" build
> +                    #:substitutable? #f
> +                    #:local-build? #t
> +                    #:properties
> +                    `((type . profile-hook)
> +                      (hook . udev-hwdb-bin))))
>
>  (define %default-profile-hooks
>    ;; This is the list of derivation-returning procedures that are called by
>    ;; default when making a non-empty profile.
> @@ -1919,6 +1947,7 @@ (define %default-profile-hooks
>          gtk-icon-themes
>          gtk-im-modules
>          texlive-font-maps
> +        udev-hwdb-bin
>          xdg-desktop-database
>          xdg-mime-database))

My only issue with this hook is that it introduces 'eudev' as a hard
dependency for generating guix profiles.  Would it make sense to follow
the approach used in 'gdk-pixbuf-loaders-cache-file', which is to look
if eudev is already part of the profile inputs (transitively), and skip
the hook if it isn't?
Liliana Marie Prikler Oct. 2, 2023, 5:02 p.m. UTC | #3
Am Sonntag, dem 01.10.2023 um 18:02 -0400 schrieb Maxim Cournoyer:
> > +            (search-path-specification
> > +              (variable "UDEV_HWDB_BIN")
> > +              (files '("lib/udev/hwdb.bin"))
> > +              (file-type 'regular)
> > +              (separator #f))))
> 
> Maybe add a ;singled valued comment to the end of the above line. 
> Note that given that file is to be generated in a profile hook,
> UDEV_HWDB_BIN would never be set at *build* time, but that should not
> matter much (the build environment being containerized and all).)
> 
> [...]
> 
> > +          (invoke #$(file-append eudev "/bin/udevadm")
> > +                  "hwdb" "--update"
> > +                  "-o" (string-append #$output
> > "/lib/udev/hwdb.bin")))))
> > +  (gexp->derivation "udev-hwdb-bin" build
> > +                    #:substitutable? #f
> > +                    #:local-build? #t
> > +                    #:properties
> > +                    `((type . profile-hook)
> > +                      (hook . udev-hwdb-bin))))
> > 
> >  (define %default-profile-hooks
> >    ;; This is the list of derivation-returning procedures that are
> > called by
> >    ;; default when making a non-empty profile.
> > @@ -1919,6 +1947,7 @@ (define %default-profile-hooks
> >          gtk-icon-themes
> >          gtk-im-modules
> >          texlive-font-maps
> > +        udev-hwdb-bin
> >          xdg-desktop-database
> >          xdg-mime-database))
> 
> My only issue with this hook is that it introduces 'eudev' as a hard
> dependency for generating guix profiles.  Would it make sense to
> follow the approach used in 'gdk-pixbuf-loaders-cache-file', which is
> to look if eudev is already part of the profile inputs
> (transitively), and skip the hook if it isn't?
Speaking of which, since eudev is basically system config stuff, I
think it might be better *not* to have the variable and the hook and
instead build the hwdb as part of udev-service-type.  Assuming, of
course, that we can already specify a fallback via config file – if no
such switch exists, we'd have to add it.

Cheers
diff mbox series

Patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 72c9954492..6efe1944e7 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1127,6 +1127,9 @@  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/eudev-pr-255.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..7b69ad7466 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -4265,16 +4265,19 @@  (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"
+                                       "eudev-pr-255.patch"))))
     (build-system gnu-build-system)
     (arguments
      (list
@@ -4297,18 +4300,25 @@  (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")))
+    (native-search-paths
+      (list (search-path-specification
+              (variable "UDEV_HWDB_PATH")
+              (files '("lib/udev/hwdb.d")))
+            ;; Never install a hwdb.bin file, always let the udev-hwdb-bin
+            ;; profile hook generate it.
+            (search-path-specification
+              (variable "UDEV_HWDB_BIN")
+              (files '("lib/udev/hwdb.bin"))
+              (file-type 'regular)
+              (separator #f))))
     (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: <cover.1695104483.git.vivien@planete-kraus.eu>
+References: <cover.1695104483.git.vivien@planete-kraus.eu>
+From: Boian Bonev <bbonev@ipacct.com>
+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 <vivien@planete-kraus.eu>
+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
+
diff --git a/gnu/packages/patches/eudev-pr-255.patch b/gnu/packages/patches/eudev-pr-255.patch
new file mode 100644
index 0000000000..505a5e7074
--- /dev/null
+++ b/gnu/packages/patches/eudev-pr-255.patch
@@ -0,0 +1,39 @@ 
+From b9cc389aabf14379685e4582c3275c23f5a9d0bc Mon Sep 17 00:00:00 2001
+Message-ID: <b9cc389aabf14379685e4582c3275c23f5a9d0bc.1696071334.git.vivien@planete-kraus.eu>
+From: NaofumiHonda <honda@math.sci.hokudai.ac.jp>
+Date: Tue, 22 Aug 2023 00:17:45 +0900
+Subject: [PATCH] Clear sysattr cache if a null pointer is passed (#255)
+
+* Clear sysattr cache if a null pointer is passed
+
+* remove tabs
+---
+ src/libudev/libudev-device.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c
+index ac67ce846..d6bc4032a 100644
+--- a/src/libudev/libudev-device.c
++++ b/src/libudev/libudev-device.c
+@@ -1557,9 +1557,15 @@ _public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, cons
+         dev = udev_device;
+         if (sysattr == NULL)
+                 return -EINVAL;
+-        if (value == NULL)
+-                value_len = 0;
+-        else
++        if (value == NULL) {
++                struct udev_list_entry *list_entry;
++
++                list_entry = udev_list_get_entry(&udev_device->sysattr_value_list);
++                list_entry = udev_list_entry_get_by_name(list_entry, sysattr);
++                if (list_entry != NULL)
++                        udev_list_entry_delete(list_entry);
++                goto out;
++        } else
+                 value_len = strlen(value);
+ 
+         strscpyl(path, sizeof(path), udev_device_get_syspath(dev), "/", sysattr, NULL);
+-- 
+2.41.0
+
diff --git a/guix/profiles.scm b/guix/profiles.scm
index c88672c25a..d308e7fb88 100644
--- a/guix/profiles.scm
+++ b/guix/profiles.scm
@@ -1905,6 +1905,34 @@  (define (texlive-font-maps manifest)
                             (hook . texlive-font-maps)))
         (return #f))))
 
+(define (udev-hwdb-bin manifest)
+  "Return a derivation that builds lib/udev/hwdb.bin."
+  (define eudev
+    (module-ref (resolve-interface '(gnu packages linux)) 'eudev))
+  (define build
+    (with-imported-modules
+        (source-module-closure '((guix build utils)))
+      #~(begin
+          (use-modules (guix build utils))
+          (let* ((inputs '#$(manifest-inputs manifest))
+                 (hwdb-directories
+                  (filter
+                   file-exists?
+                   (map (lambda (directory)
+                          (string-append directory "/lib/udev/hwdb.d"))
+                        inputs))))
+            (setenv "UDEV_HWDB_PATH"
+                    (string-join hwdb-directories ":")))
+          (invoke #$(file-append eudev "/bin/udevadm")
+                  "hwdb" "--update"
+                  "-o" (string-append #$output "/lib/udev/hwdb.bin")))))
+  (gexp->derivation "udev-hwdb-bin" build
+                    #:substitutable? #f
+                    #:local-build? #t
+                    #:properties
+                    `((type . profile-hook)
+                      (hook . udev-hwdb-bin))))
+
 (define %default-profile-hooks
   ;; This is the list of derivation-returning procedures that are called by
   ;; default when making a non-empty profile.
@@ -1919,6 +1947,7 @@  (define %default-profile-hooks
         gtk-icon-themes
         gtk-im-modules
         texlive-font-maps
+        udev-hwdb-bin
         xdg-desktop-database
         xdg-mime-database))