guix_mirror_bot pushed a commit to branch master
in repository guix.
commit fd6b17bf20dc0cec2b4edff2928f899ebd2741cc
Author: Giacomo Leidi <[email protected]>
AuthorDate: Sun Jan 4 23:58:56 2026 +0100
gnu: Add tuned-service-type.
* gnu/services/linux.scm
(tuned-configuration,tuned-settings,tuned-ppd-settings): New
configuration records.
(tuned-file-systems,tuned-activation,tuned-shepherd-services,
tuned-kernel-modules): New procedures.
(tuned-service-type): New service type.
* doc/guix.texi: Add service documentation.
Change-Id: I6c8d54c23175c2ea133d99965641c548fb1d6452
---
doc/guix.texi | 198 +++++++++++++++++++++-
gnu/services/linux.scm | 448 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 645 insertions(+), 1 deletion(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 15ed74ed0c..d7f4c41d57 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -111,7 +111,7 @@ Copyright @copyright{} 2022 (@*
Copyright @copyright{} 2022 John Kehayias@*
Copyright @copyright{} 2022–2023 Bruno Victal@*
Copyright @copyright{} 2022 Ivan Vilata-i-Balaguer@*
-Copyright @copyright{} 2023-2025 Giacomo Leidi@*
+Copyright @copyright{} 2023-2026 Giacomo Leidi@*
Copyright @copyright{} 2022 Antero Mejr@*
Copyright @copyright{} 2023 Karl Hallsby@*
Copyright @copyright{} 2023 Nathaniel Nicandro@*
@@ -44972,6 +44972,202 @@ The database location is hard-coded to
@file{/var/lib/rasdaemon/ras-mc_event.db}
@end table
@end deftp
+@cindex tuned
+@cindex system tuning
+@cindex System tuning service for Linux
+@subsubheading TuneD Service
+
+@url{https://tuned-project.org,TuneD} is a system tuning service for Linux. It
+monitors connected devices using the udev device manager and tunes system
+settings according to a selected profile.
+
+It can be integrated with desktop environments like GNOME and KDE: it replaces
+@code{power-profiles-daemon} by implementing the same D-Bus API that they
+already use.
+
+The following is an example configuration that could be suitable for a laptop:
+
+@lisp
+(service tuned-service-type
+ (tuned-configuration
+ (power-profiles-daemon-support? #t)
+ (ppd-settings
+ (tuned-ppd-settings
+ ;; Customize default profiles to use laptop specific ones.
+ (profiles
+ '(("power-saver" . "laptop-ac-powersave")
+ ("balanced" . "balanced")
+ ("performance" . "throughput-performance")))
+ (battery
+ ;; Customize battery profiles to use laptop specific ones.
+ '(("power-saver" . "laptop-battery-powersave")
+ ("balanced" . "balanced-battery")))))))
+@end lisp
+
+For more information, refer to @code{tuned-main.conf(5)}.
+
+@defvar tuned-service-type
+This service spawns and configure the TuneD daemon. The service's value is a
+@code{tuned-configuration} record.
+
+@c %start of fragment
+
+@deftp {Data Type} tuned-configuration
+Available @code{tuned-configuration} fields are:
+
+@table @asis
+@item @code{tuned} (default: @code{tuned}) (type: package)
+The TuneD package.
+
+@item @code{auto-start?} (default: @code{#t}) (type: boolean)
+Whether this service should be started automatically by the Shepherd. If
+it is @code{#f} the service has to be started manually with
+@command{herd start}.
+
+@item @code{power-profiles-daemon-support?} (default: @code{#f}) (type:
boolean)
+Whether the power-profiles-daemon emulation layer should be
+enabled.
+
+@item @code{profiles} (default: @code{'()}) (type: list-of-tuned-plugins)
+User provided profiles for TuneD. Each element of the list is supposed
+to be a list where the first element is the name of the directory where
+plugin files will be placed under @file{/etc/tuned/profiles} and the
+second a file like object containing the plugin files:
+
+@lisp
+(list (list "plugin-name" (plain-file "plugin.conf" "content"))
+ (list "other-plugin"
+ (file-union "plugin-data"
+ (list
+ (list "other-plugin.conf"
+ (plain-file "other-plugin.conf" "content"))
+ (list "other-plugin.scm"
+ (program-file "other-plugin.scm"
+ #~(display "content")))))))
+@end lisp
+
+@item @code{settings} (type: tuned-settings)
+Configuration for TuneD.
+
+@item @code{ppd-settings} (type: tuned-ppd-settings)
+Configuration for the @code{power-profiles-daemon} compatibility layer
+of TuneD.
+
+@item @code{recommend.conf} (type: file-like)
+File like object containing the recommended profile configuration.
+Defaults to @code{%default-tuned-configuration-recommend.conf}.
+
+@end table
+
+@end deftp
+
+
+@c %end of fragment
+
+
+@c %start of fragment
+
+@deftp {Data Type} tuned-settings
+Available @code{tuned-settings} fields are:
+
+@table @asis
+@item @code{daemon?} (default: @code{#t}) (type: boolean)
+Whether to use daemon. Without daemon TuneD just applies tuning.
+
+@item @code{dynamic-tuning?} (default: @code{#f}) (type: boolean)
+Dynamically tune devices, if disabled only static tuning will be used.
+
+@item @code{default-instance-priority} (default: @code{0}) (type: integer)
+Default priority assigned to instances.
+
+@item @code{recommend-command?} (default: @code{#t}) (type: boolean)
+Recommend functionality, if disabled @code{recommend} command will be
+not available in CLI, daemon will not parse @file{recommend.conf} but
+will return one hardcoded profile (by default @code{balanced}).
+
+@item @code{sleep-interval} (default: @code{1}) (type: integer)
+How long to sleep before checking for events (in seconds), higher number
+means lower overhead but longer response time.
+
+@item @code{update-interval} (default: @code{10}) (type: integer)
+Update interval for dynamic tunings (in seconds). It must be a multiple
+of the @code{sleep-interval}.
+
+@item @code{profile-dirs} (type: list-of-profile-dirs)
+List of strings or gexps representing directories to search for
+profiles. In case of collisions in profile names, the latter directory
+takes precedence.
+
+@item @code{extra-content} (type: text-config)
+A list of file-like objects that are appended to the configuration file.
+
+@end table
+
+@end deftp
+
+
+@c %end of fragment
+
+
+@c %start of fragment
+
+@deftp {Data Type} tuned-ppd-settings
+Available @code{tuned-ppd-settings} fields are:
+
+@table @asis
+@item @code{default} (default: @code{"balanced"}) (type: string)
+Default PPD profile.
+
+@item @code{battery-detection?} (default: @code{#t}) (type: boolean)
+Whether to enable battery detection.
+
+@item @code{sysfs-acpi-monitor?} (default: @code{#t}) (type: boolean)
+Whether to react to changes of ACPI platform profile done via function
+keys (e.g., Fn-L). This is marked upstream as an experimental feature.
+
+@item @code{profiles} (type: mixed-list)
+Map of PPD profiles states to TuneD profiles. It's supposed to be a
+list of pairs, pair members are supposed to be string. It defaults to
+@code{%default-tuned-ppd-settings-profiles}:
+
+@lisp
+'(("power-saver" . "powersave")
+ ("balanced" . "balanced")
+ ("performance" . "throughput-performance"))
+@end lisp
+
+Elements can be pairs or strings. Pair members can be either strings, gexps or
+file like objects. Strings are directly passed to the serializer. This can be
+an escape hatch in case the underlying syntax of the output file changes
+slightly and the Scheme API is not adequated in time. This way there is always
+a way to work around Scheme records.
+
+@item @code{battery} (type: mixed-list)
+Map of PPD battery states to TuneD profiles. It's supposed to be a list
+of pairs, pair members are supposed to be string. It defaults to
+@code{%default-tuned-ppd-settings-battery}:
+
+@lisp
+'(("balanced" . "balanced-battery"))
+@end lisp
+
+Elements can be pairs or strings. Pair members can be either strings, gexps or
+file like objects. Strings are directly passed to the serializer. This can be
+an escape hatch in case the underlying syntax of the output file changes
+slightly and the Scheme API is not adequated in time. This way there is always
+a way to work around Scheme records.
+
+@item @code{extra-content} (type: text-config)
+A list of file-like objects that are appended to the configuration file.
+
+@end table
+
+@end deftp
+
+
+@c %end of fragment
+@end defvar
+
@cindex zram
@cindex compressed swap
@cindex Compressed RAM-based block devices
diff --git a/gnu/services/linux.scm b/gnu/services/linux.scm
index 90693b77eb..2284741a65 100644
--- a/gnu/services/linux.scm
+++ b/gnu/services/linux.scm
@@ -8,6 +8,7 @@
;;; Copyright © 2023 Bruno Victal <[email protected]>
;;; Copyright © 2023 Felix Lechner <[email protected]>
;;; Copyright © 2025 Edouard Klein <[email protected]>
+;;; Copyright © 2026 Giacomo Leidi <[email protected]>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -30,13 +31,18 @@
#:use-module (guix records)
#:use-module (guix modules)
#:use-module (guix i18n)
+ #:use-module (guix packages)
#:use-module (guix ui)
#:use-module (gnu services)
#:use-module (gnu services admin)
#:use-module (gnu services base)
#:use-module (gnu services configuration)
+ #:use-module (gnu services dbus)
#:use-module (gnu services shepherd)
+ #:use-module (gnu system file-systems)
+ #:use-module (gnu packages base)
#:use-module (gnu packages linux)
+ #:use-module (gnu packages power)
#:use-module (gnu packages file-systems)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
@@ -45,6 +51,7 @@
#:use-module (srfi srfi-171)
#:use-module (ice-9 format)
#:use-module (ice-9 match)
+ #:use-module (ice-9 string-fun)
#:export (earlyoom-configuration
earlyoom-configuration?
earlyoom-configuration-earlyoom
@@ -97,6 +104,49 @@
rasdaemon-configuration-record?
rasdaemon-service-type
+ %default-tuned-configuration-recommend.conf
+ %default-tuned-ppd-settings-battery
+ %default-tuned-ppd-settings-profiles
+
+ tuned-configuration
+ tuned-configuration?
+ tuned-configuration-fields
+ tuned-configuration-tuned
+ tuned-configuration-auto-start?
+ tuned-configuration-power-profiles-daemon-support?
+ tuned-configuration-profiles
+ tuned-configuration-settings
+ tuned-configuration-ppd-settings
+ tuned-configuration-recommend.conf
+
+ tuned-settings
+ tuned-settings?
+ tuned-settings-fields
+ tuned-settings-daemon?
+ tuned-settings-dynamic-tuning?
+ tuned-settings-default-instance-priority
+ tuned-settings-recommend-command?
+ tuned-settings-sleep-interval
+ tuned-settings-update-interval
+ tuned-settings-profile-dirs
+ tuned-settings-extra-content
+
+ tuned-ppd-settings
+ tuned-ppd-settings?
+ tuned-ppd-settings-fields
+ tuned-ppd-settings-default
+ tuned-ppd-settings-battery-detection?
+ tuned-ppd-settings-sysfs-acpi-monitor?
+ tuned-ppd-settings-profiles
+ tuned-ppd-settings-battery
+ tuned-ppd-settings-extra-content
+
+ tuned-file-systems
+ tuned-activation
+ tuned-shepherd-services
+
+ tuned-service-type
+
zram-device-configuration
zram-device-configuration?
zram-device-configuration-size
@@ -550,6 +600,404 @@ the Linux @code{cachefiles} module.")
(description "Run @command{rasdaemon}, the RAS monitor")))
+;;;
+;;; TuneD.
+;;;
+
+(define (uglify-snake-case field-name)
+ "Serializes FIELD-NAME, a field name from @code{(gnu services
configuration)},
+to a snake case string representation of the field name. Trailing @code{?} in
+the name are dropped and @code{-} get replaced by @code{_}.
+
+For example the procedure would convert @code{'A-Field?} to
@code{\"a_field\"}."
+ (define str (symbol->string field-name))
+ (string-downcase
+ (string-replace-substring
+ (if (string-suffix? "?" str)
+ (string-drop-right str 1)
+ str)
+ "-" "_")))
+
+(define* (tuned-serialize-pair pair #:key (separator "="))
+ (define (valid? member)
+ (or (string? member)
+ (gexp? member)
+ (file-like? member)))
+ (match pair
+ (((? valid? key) . (? valid? value))
+ #~(string-append #$key #$separator #$value))
+ (_
+ (raise
+ (formatted-message
+ (G_ "pair members must contain only strings, gexps or file-like objects
+but ~a was found")
+ pair)))))
+
+(define* (tuned-ppd-serialize-mixed-list name value #:key (separator " = "))
+ (if (zero? (length value))
+ ""
+ #~(string-append "\n[" #$(uglify-snake-case name) "]\n"
+ (string-join
+ (list #$@(map tuned-serialize-pair value)) "\n")
+ "\n")))
+
+(define (mixed-list? value)
+ ;; Expected spec format:
+ ;; '(("name" . "value") "name=value")
+ (for-each
+ (lambda (el)
+ (cond ((string? el) el)
+ ((pair? el) (tuned-serialize-pair el))
+ (else
+ (raise
+ (formatted-message
+ (G_ "members must be either strings or pairs but ~a was
+found!")
+ el)))))
+ value)
+ #t)
+
+(define (tuned-ppd-serialize-string name value)
+ (format #f "~a=~a" (uglify-snake-case name) value))
+
+(define (tuned-ppd-serialize-boolean name value)
+ (format #f "~a=~a" (uglify-snake-case name) (if value "true" "false")))
+
+(define %default-tuned-ppd-settings-profiles
+ '(("power-saver" . "powersave")
+ ("balanced" . "balanced")
+ ("performance" . "throughput-performance")))
+
+(define %default-tuned-ppd-settings-battery
+ '(("balanced" . "balanced-battery")))
+
+(define-configuration tuned-ppd-settings
+ (default
+ (string "balanced")
+ "Default PPD profile.")
+ (battery-detection?
+ (boolean #t)
+ "Whether to enable battery detection.")
+ (sysfs-acpi-monitor?
+ (boolean #t)
+ "Whether to react to changes of ACPI platform profile done via function
keys
+(e.g., Fn-L). This is marked upstream as an experimental feature.")
+ (profiles
+ (mixed-list %default-tuned-ppd-settings-profiles)
+ "Map of PPD profiles states to TuneD profiles. It's supposed to be a list
of
+pairs, pair members are supposed to be string. It defaults to
+@code{%default-tuned-ppd-settings-profiles}:
+
+@lisp
+'((\"power-saver\" . \"powersave\")
+ (\"balanced\" . \"balanced\")
+ (\"performance\" . \"throughput-performance\"))
+@end lisp
+
+Elements can be pairs or strings. Pair members can be either strings, gexps or
+file like objects. Strings are directly passed to the serializer. This can be
+an escape hatch in case the underlying syntax of the output file changes
+slightly and the Scheme API is not adequated in time. This way there is always
+a way to work around Scheme records.")
+ (battery
+ (mixed-list %default-tuned-ppd-settings-battery)
+ "Map of PPD battery states to TuneD profiles. It's supposed to be a list of
+pairs, pair members are supposed to be string. It defaults to
+@code{%default-tuned-ppd-settings-battery}:
+
+@lisp
+'((\"balanced\" . \"balanced-battery\"))
+@end lisp
+
+Elements can be pairs or strings. Pair members can be either strings, gexps or
+file like objects. Strings are directly passed to the serializer. This can be
+an escape hatch in case the underlying syntax of the output file changes
+slightly and the Scheme API is not adequated in time. This way there is always
+a way to work around Scheme records.")
+ (extra-content
+ (text-config
+ (list (plain-file "tuned-ppd-settings-extra-content" "")))
+ "A list of file-like objects that are appended to the configuration file."
+ (serializer serialize-text-config))
+ (prefix tuned-ppd-))
+
+(define (serialize-tuned-ppd-settings config)
+ (define fields
+ (filter-configuration-fields
+ tuned-ppd-settings-fields
+ '(default battery-detection? sysfs-acpi-monitor? profiles battery
+ extra-content)))
+ (define getters
+ (map configuration-field-getter fields))
+ (define names
+ (map configuration-field-name fields))
+ (define serializers
+ (map configuration-field-serializer fields))
+ (define values
+ (map (match-lambda ((serializer name getter)
+ (serializer name (getter config))))
+ (zip serializers names getters)))
+
+ (match values
+ ((default battery-detection? sysfs-acpi-monitor? profiles battery
+ extra-content)
+
+ (mixed-text-file "ppd.conf"
+ "[main]\n"
+ (string-append default "\n")
+ (string-append battery-detection? "\n")
+ (string-append sysfs-acpi-monitor? "\n")
+ "\n"
+ profiles
+ battery
+ extra-content
+ "\n"))))
+
+(define (serialize-list-of-profile-dirs name value)
+ (if (zero? (length value))
+ ""
+ #~(string-append
+ #$(uglify-snake-case name) " = " (string-join (list #$@value) ","))))
+
+(define (list-of-profile-dirs? value)
+ (for-each
+ (lambda (el)
+ (unless (or (string? el) (file-like? el))
+ (raise
+ (formatted-message
+ (G_ "tuned-settings profile-dirs members must be either a string
+or a file-like object but ~a was found!")
+ el))))
+ value)
+ #t)
+
+(define tuned-serialize-boolean tuned-ppd-serialize-boolean)
+(define tuned-serialize-integer tuned-ppd-serialize-string)
+
+(define-configuration tuned-settings
+ (daemon?
+ (boolean #t)
+ "Whether to use daemon. Without daemon TuneD just applies tuning.")
+ (dynamic-tuning?
+ (boolean #f)
+ "Dynamically tune devices, if disabled only static tuning will be used.")
+ (default-instance-priority
+ (integer 0)
+ "Default priority assigned to instances.")
+ (recommend-command?
+ (boolean #t)
+ "Recommend functionality, if disabled @code{recommend} command will be not
+available in CLI, daemon will not parse @file{recommend.conf} but will return
+one hardcoded profile (by default @code{balanced}).")
+ (sleep-interval
+ (integer 1)
+ "How long to sleep before checking for events (in seconds),
+higher number means lower overhead but longer response time.")
+ (update-interval
+ (integer 10)
+ "Update interval for dynamic tunings (in seconds). It must be a multiple of
+the @code{sleep-interval}.")
+ (profile-dirs
+ (list-of-profile-dirs
+ (list (file-append tuned "/lib/tuned/profiles") "/etc/tuned/profiles"))
+ "List of strings or gexps representing directories to search for
+profiles. In case of collisions in profile names, the latter directory takes
+precedence."
+ (serializer serialize-list-of-profile-dirs))
+ (extra-content
+ (text-config
+ (list (plain-file "tuned-settings-extra-content" "")))
+ "A list of file-like objects that are appended to the configuration file."
+ (serializer serialize-text-config))
+ (prefix tuned-))
+
+(define (serialize-tuned-settings config)
+ (define fields
+ (filter-configuration-fields
+ tuned-settings-fields
+ '(daemon? dynamic-tuning? default-instance-priority
+ recommend-command? sleep-interval update-interval profile-dirs
+ extra-content)))
+ (define getters
+ (map configuration-field-getter fields))
+ (define names
+ (map configuration-field-name fields))
+ (define serializers
+ (map configuration-field-serializer fields))
+ (define values
+ (map (match-lambda ((serializer name getter)
+ (serializer name (getter config))))
+ (zip serializers names getters)))
+
+ (match values
+ ((daemon? dynamic-tuning? default-instance-priority
+ recommend-command? sleep-interval update-interval profile-dirs
+ extra-content)
+ (mixed-text-file
+ "tuned-main.conf"
+ (string-append daemon? "\n\n")
+ (string-append dynamic-tuning? "\n\n")
+ (string-append default-instance-priority "\n\n")
+ (string-append recommend-command? "\n\n")
+ (string-append sleep-interval "\n\n")
+ (string-append update-interval "\n\n")
+ profile-dirs
+ extra-content
+ "\n"))))
+
+(define (tuned-plugin? value)
+ (if (and (= 2 (length value))
+ (string? (first value))
+ (file-like? (second value)))
+ #t
+ (raise
+ (formatted-message
+ (G_ "tuned-configuration profiles members must be lists with two
+elements, the first being a string and the second a file-like object, but ~a
was
+found!")
+ value))))
+
+(define (list-of-tuned-plugins? value)
+ (list-of tuned-plugin?))
+
+(define %default-tuned-configuration-recommend.conf
+ (file-append tuned "/lib/tuned/recommend.d/50-tuned.conf"))
+
+(define-configuration/no-serialization tuned-configuration
+ (tuned
+ (package tuned)
+ "The TuneD package.")
+ (auto-start?
+ (boolean #t)
+ "Whether this service should be started automatically by the Shepherd. If
it
+is @code{#f} the service has to be started manually with @command{herd
start}.")
+ (power-profiles-daemon-support?
+ (boolean #f)
+ "Whether the power-profiles-daemon emulation layer should be
+enabled.")
+ (profiles
+ (list-of-tuned-plugins '())
+ "User provided profiles for TuneD. Each element of the list is supposed to
be
+a list where the first element is the name of the directory where plugin files
+will be placed under @file{/etc/tuned/profiles} and the second a file like
+object containing the plugin files:
+
+@lisp
+(list
+ (list \"plugin-name\"
+ (plain-file \"plugin.conf\" \"content\"))
+ (list \"other-plugin\"
+ (file-union \"plugin-data\"
+ (list (list \"other-plugin.conf\"
+ (plain-file \"other-plugin.conf\" \"content\"))
+ (list \"other-plugin.scm\"
+ (program-file \"other-plugin.scm\"
+ #~(display \"content\")))))))
+@end lisp")
+ (settings
+ (tuned-settings (tuned-settings))
+ "Configuration for TuneD.")
+ (ppd-settings
+ (tuned-ppd-settings (tuned-ppd-settings))
+ "Configuration for the @code{power-profiles-daemon} compatibility layer of
+TuneD.")
+ (recommend.conf
+ (file-like %default-tuned-configuration-recommend.conf)
+ "File like object containing the recommended profile configuration.
Defaults
+to @code{%default-tuned-configuration-recommend.conf}."))
+
+(define (tuned-file-systems config)
+ (list
+ (file-system
+ (device "none")
+ (mount-point "/run/tuned")
+ (type "ramfs")
+ (check? #f))))
+
+(define (tuned-activation config)
+ (match-record config <tuned-configuration>
+ (profiles settings ppd-settings recommend.conf)
+ #~(begin
+ (use-modules (guix build utils))
+ (let ((data-directory "/var/lib/tuned")
+ (config-directory "/etc/tuned"))
+ ;; Setup TuneD directories.
+ (for-each
+ (lambda (dir)
+ (mkdir-p dir)
+ (chmod dir #o755))
+ (list data-directory config-directory
+ ;; the directory where TuneD will look for kernel modules for
+ ;; plugins.
+ "/etc/tuned/modprobe.d"))
+ ;; Create plugins kernel modules configuration.
+ (invoke #$(file-append coreutils-minimal "/bin/touch")
+ "/etc/tuned/modprobe.d/tuned.conf")
+ ;; Generate and activate TuneD configuration files.
+ ;; TuneD needs to write in /etc/tuned, special-files-service-type
+ ;; creates a file union, so /etc/tuned is read-only and TuneD
crashes.
+ ;; activate-special-files creates a single symlink to the store for
+ ;; each file so TuneD doesn't notice and runs successfully.
+ (activate-special-files
+ '(("/etc/tuned/recommend.conf" #$recommend.conf)
+ ("/etc/tuned/profiles"
+ #$(file-union "tuned-profiles" profiles))
+ ("/etc/tuned/tuned-main.conf"
+ #$(serialize-tuned-settings settings))
+ ("/etc/tuned/ppd.conf"
+ #$(serialize-tuned-ppd-settings ppd-settings))))))))
+
+(define (tuned-shepherd-services config)
+ (match-record config <tuned-configuration>
+ (tuned auto-start? power-profiles-daemon-support?)
+ (append
+ (list
+ (shepherd-service
+ (documentation "TuneD daemon")
+ (provision '(tuned))
+ (requirement '(dbus-system user-processes udev))
+ (start #~(make-forkexec-constructor
+ '(#$(file-append tuned "/sbin/tuned"))
+ #:log-file "/var/log/tuned/tuned.log"))
+ (stop #~(make-kill-destructor))
+ (auto-start? auto-start?)))
+ (if power-profiles-daemon-support?
+ (list (shepherd-service
+ (documentation "TuneD power-profiles-daemon emulation daemon")
+ (provision '(tuned-ppd power-profiles-daemon))
+ (requirement '(dbus-system user-processes udev tuned))
+ (start
+ #~(make-forkexec-constructor
+ '(#$(file-append tuned "/sbin/tuned-ppd"))
+ #:log-file "/var/log/tuned/tuned-ppd.log"))
+ (stop #~(make-kill-destructor))
+ (auto-start? auto-start?)))
+ '()))))
+
+(define tuned-service-type
+ (let ((config->package
+ (compose list tuned-configuration-tuned)))
+ (service-type
+ (name 'tuned)
+ (extensions (list
+ (service-extension shepherd-root-service-type
+ tuned-shepherd-services)
+ (service-extension dbus-root-service-type
+ config->package)
+ (service-extension polkit-service-type
+ config->package)
+ (service-extension profile-service-type
+ config->package)
+ (service-extension file-system-service-type
+ tuned-file-systems)
+ (service-extension activation-service-type
+ tuned-activation)))
+ (default-value (tuned-configuration))
+ (description "Run the TuneD daemon. It is daemon that tunes system
settings
+dynamically. It does so by monitoring the usage of several system components
+periodically."))))
+
+
;;;
;;; Zram device
;;;