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
 ;;;

Reply via email to