services: udev: Use a fixed location for the rules directory and config.

Fixes <https://issues.guix.gnu.org/47681>.

This change adjusts the location of the udev configuration file and rules
directory to a fixed location.  Since udev relies on inotify to discover
change to its rules directory (/etc/udev/rules.d), by using a fixed directory
layout, new udev rules can be automatically picked up without restarting the
service.

* gnu/services/base.scm (udev-rules-union): Build rules output directly
in #$output.
(udev-shepherd-service)[start]: Adjust the UDEV_CONFIG_FILE and
EUDEV_RULES_DIRECTORY environment variables.
[actions]: Remove field.  The 'rules' action is no longer useful.
(udev.conf): New variable.
(udev-etc): New procedure.
(udev-service-type): Extend the etc-service-type with it.
This commit is contained in:
Maxim Cournoyer 2022-02-01 00:32:50 -05:00
parent 82d19441b9
commit e9fa17eb98
No known key found for this signature in database
GPG key ID: 1260E46482E63562

View file

@ -15,7 +15,7 @@
;;; Copyright © 2020, 2021 Brice Waegeneire <brice@waegenei.re> ;;; Copyright © 2020, 2021 Brice Waegeneire <brice@waegenei.re>
;;; Copyright © 2021 qblade <qblade@protonmail.com> ;;; Copyright © 2021 qblade <qblade@protonmail.com>
;;; Copyright © 2021 Hui Lu <luhuins@163.com> ;;; Copyright © 2021 Hui Lu <luhuins@163.com>
;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2021, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2022 Guillaume Le Vaillant <glv@posteo.net> ;;; Copyright © 2022 Guillaume Le Vaillant <glv@posteo.net>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
@ -1995,8 +1995,7 @@ item of @var{packages}."
(find directory-exists? (find directory-exists?
(map (cut string-append directory <>) %standard-locations))) (map (cut string-append directory <>) %standard-locations)))
(mkdir-p (string-append #$output "/lib/udev")) (union-build #$output
(union-build (string-append #$output "/lib/udev/rules.d")
(filter-map rules-sub-directory '#$packages))))) (filter-map rules-sub-directory '#$packages)))))
(computed-file "udev-rules" build)) (computed-file "udev-rules" build))
@ -2046,14 +2045,7 @@ item of @var{packages}."
(define udev-shepherd-service (define udev-shepherd-service
;; Return a <shepherd-service> for UDEV with RULES. ;; Return a <shepherd-service> for UDEV with RULES.
(match-lambda (match-lambda
(($ <udev-configuration> udev rules) (($ <udev-configuration> udev)
(let* ((rules (udev-rules-union (cons* udev kvm-udev-rule rules)))
(udev.conf (computed-file "udev.conf"
#~(call-with-output-file #$output
(lambda (port)
(format port
"udev_rules=\"~a/lib/udev/rules.d\"\n"
#$rules))))))
(list (list
(shepherd-service (shepherd-service
(provision '(udev)) (provision '(udev))
@ -2106,15 +2098,14 @@ item of @var{packages}."
(make-static-device-nodes directory)) (make-static-device-nodes directory))
(umask old-umask)) (umask old-umask))
(let ((pid (fork+exec-command (list udevd) (let ((pid (fork+exec-command
(list udevd)
#:environment-variables #:environment-variables
(cons* (cons*
;; The first one is for udev, the second one for ;; The first one is for udev, the second one for
;; eudev. ;; eudev.
(string-append "UDEV_CONFIG_FILE=" #$udev.conf) "UDEV_CONFIG_FILE=/etc/udev/udev.conf"
(string-append "EUDEV_RULES_DIRECTORY=" "EUDEV_RULES_DIRECTORY=/etc/udev/rules.d"
#$(file-append
rules "/lib/udev/rules.d"))
(string-append "LINUX_MODULE_DIRECTORY=" (string-append "LINUX_MODULE_DIRECTORY="
(getenv "LINUX_MODULE_DIRECTORY")) (getenv "LINUX_MODULE_DIRECTORY"))
(default-environment-variables))))) (default-environment-variables)))))
@ -2139,22 +2130,29 @@ item of @var{packages}."
(respawn? #f) (respawn? #f)
;; We need additional modules. ;; We need additional modules.
(modules `((gnu build linux-boot) ;'make-static-device-nodes' (modules `((gnu build linux-boot) ;'make-static-device-nodes'
,@%default-modules)) ,@%default-modules)))))))
(actions (list (shepherd-action (define udev.conf
(name 'rules) (computed-file "udev.conf"
(documentation "Display the directory containing #~(call-with-output-file #$output
the udev rules in use.") (lambda (port)
(procedure #~(lambda (_) (format port "udev_rules=\"/etc/udev/rules.d\"~%")))))
(display #$rules)
(newline)))))))))))) (define udev-etc
(match-lambda
(($ <udev-configuration> udev rules)
`(("udev"
,(file-union
"udev" `(("udev.conf" ,udev.conf)
("rules.d" ,(udev-rules-union (cons* udev kvm-udev-rule
rules))))))))))
(define udev-service-type (define udev-service-type
(service-type (name 'udev) (service-type (name 'udev)
(extensions (extensions
(list (service-extension shepherd-root-service-type (list (service-extension shepherd-root-service-type
udev-shepherd-service))) udev-shepherd-service)
(service-extension etc-service-type udev-etc)))
(compose concatenate) ;concatenate the list of rules (compose concatenate) ;concatenate the list of rules
(extend (lambda (config rules) (extend (lambda (config rules)
(match config (match config