summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoan V. C. <codeberg-hn80@joanvc.cat>2026-03-20 09:42:50 +0100
committerEfraim Flashner <efraim@flashner.co.il>2026-05-20 11:37:30 +0300
commit3b7fd1e76698559f8575ffeeed116673bd00ade1 (patch)
treee49b166727766800ed1005bd4baf792f667c1ec5
parent5912f01e976480b50c18c65f8236a998fc7db7f9 (diff)
gnu: services: Add btrfs-scrub-service-type.
* gnu/services/linux.scm (btrfs-scrub-configuration): New configuration record. (btrfs-scrub-service-type): New service type with custom actions. (fstrim-/shepherd-calendar-event?): Refactor to avoid name collisions. * doc/guix.texi: Add service documentation. Change-Id: I04747914591a80cd535d2f79d35e08f68081b2fc Signed-off-by: Joan Vilardaga Castro <codeberg-hn80@joanvc.cat> Signed-off-by: Efraim Flashner <efraim@flashner.co.il>
-rw-r--r--doc/guix.texi76
-rw-r--r--gnu/services/linux.scm135
2 files changed, 208 insertions, 3 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 8d45ed1f43b..debe9b48a77 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -151,6 +151,7 @@ Copyright @copyright{} 2025 Noé Lopez@*
151Copyright @copyright{} 2026 David Elsing@* 151Copyright @copyright{} 2026 David Elsing@*
152Copyright @copyright{} 2026 Nguyễn Gia Phong@* 152Copyright @copyright{} 2026 Nguyễn Gia Phong@*
153Copyright @copyright{} 2026 Yarl Baudig@* 153Copyright @copyright{} 2026 Yarl Baudig@*
154Copyright @copyright{} 2026 Joan Vilardaga Castro@*
154 155
155Permission is granted to copy, distribute and/or modify this document 156Permission is granted to copy, distribute and/or modify this document
156under the terms of the GNU Free Documentation License, Version 1.3 or 157under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -45888,6 +45889,81 @@ mount.
45888@end table 45889@end table
45889@end deftp 45890@end deftp
45890 45891
45892@subsubheading btrfs-scrub Service
45893@cindex btrfs-scrub service
45894@cindex solid state drives, periodic trim
45895@cindex solid state drives, trim
45896
45897@c This was copied from the btrfs-scrub manpage, with some Texinfo touch-ups.
45898@quotation Information
45899Scrub is a validation pass over all filesystem data and metadata that
45900detects data checksum errors, basic super block errors, basic metadata
45901block header errors, and disk read errors.
45902
45903Scrub is done on a per-device base, if a device is specified to
45904@command{btrfs scrub start}, then only that device will be
45905scrubbed. Although btrfs will also try to read other device to find a
45906good copy, if the mirror on that specified device failed to be read or
45907pass verification.
45908
45909If a path of btrfs is specified to @command{btrfs scrub start}, btrfs
45910will scrub all devices in parallel.
45911
45912On filesystems that use replicated block group profiles (e.g. RAID1),
45913read-write scrub will also automatically repair any damage by copying
45914verified good data from one of the other replicas.
45915
45916Such automatic repair is also carried out when reading metadata or data
45917from a read-write mounted filesystem.
45918@end quotation
45919
45920@defvar btrfs-scrub-service-type
45921Type for a service that periodically runs @command{btrfs-scrub} on a
45922certain device, whose value must be an
45923@code{<btrfs-scrub-configuration>} object. The service can be
45924instantiated in its default configuration with:
45925
45926@lisp
45927;; This will scrub the root (@file{/}) filesystem.
45928(service btrfs-scrub-service-type)
45929
45930;; This will scrub the @file{/gnu/store} filesystem (assuming it's a
45931;; different filesystem from @file{/}).
45932
45933(service btrfs-scrub-service-type
45934 (btrfs-scrub-configuration
45935 (to-scrub "/gnu/store")))
45936@end lisp
45937@end defvar
45938
45939@c %start of fragment
45940
45941@deftp {Data Type} btrfs-scrub-configuration
45942Available @code{btrfs-scrub-configuration} fields are:
45943
45944@table @asis
45945@item @code{package} (default: @code{btrfs-progs}) (type: file-like)
45946The package providing the @command{btrfs} command.
45947
45948@item @code{schedule} (default: @code{"0 0 1-7 * 0"}) (type: Shepherd calendar event)
45949Schedule for launching @command{btrfs-scrub}, expressed as a string in
45950traditional cron syntax or as a gexp evaluating to a Shepherd calendar
45951event (@pxref{Timers,,, shepherd, The GNU Shepherd Manual}). By default
45952this is set to run the 1st Sunday of the month, at 00:00.
45953
45954@item @code{to-scrub} (default: @code{"/"}) (type: maybe-string)
45955Device to scrub. It will scrub the root (@file{/}) if not given.
45956
45957@item @code{extra-arguments} (type: maybe-list-of-strings)
45958Extra options to append to @command{btrfs scrub start} (run @samp{man
45959btrfs-scrub.8} for more information). Keep in mind that, by definition,
45960this service uses the @option{-B} flag (do not background and print
45961scrub statistics when finished).
45962
45963@end table
45964
45965@end deftp
45966
45891@cindex oom 45967@cindex oom
45892@cindex out of memory killer 45968@cindex out of memory killer
45893@cindex earlyoom 45969@cindex earlyoom
diff --git a/gnu/services/linux.scm b/gnu/services/linux.scm
index 2284741a659..f6e74b60ff5 100644
--- a/gnu/services/linux.scm
+++ b/gnu/services/linux.scm
@@ -9,6 +9,7 @@
9;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com> 9;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
10;;; Copyright © 2025 Edouard Klein <edk@beaver-labs.com> 10;;; Copyright © 2025 Edouard Klein <edk@beaver-labs.com>
11;;; Copyright © 2026 Giacomo Leidi <therewasa@fishinthecalculator.me> 11;;; Copyright © 2026 Giacomo Leidi <therewasa@fishinthecalculator.me>
12;;; Copyright © 2026 Joan Vilardaga Castro <codeberg-hn80@joanvc.cat>
12;;; 13;;;
13;;; This file is part of GNU Guix. 14;;; This file is part of GNU Guix.
14;;; 15;;;
@@ -52,7 +53,10 @@
52 #:use-module (ice-9 format) 53 #:use-module (ice-9 format)
53 #:use-module (ice-9 match) 54 #:use-module (ice-9 match)
54 #:use-module (ice-9 string-fun) 55 #:use-module (ice-9 string-fun)
55 #:export (earlyoom-configuration 56 #:export (btrfs-scrub-configuration
57 btrfs-scrub-service-type
58
59 earlyoom-configuration
56 earlyoom-configuration? 60 earlyoom-configuration?
57 earlyoom-configuration-earlyoom 61 earlyoom-configuration-earlyoom
58 earlyoom-configuration-minimum-available-memory 62 earlyoom-configuration-minimum-available-memory
@@ -161,6 +165,131 @@
161 165
162 166
163;;; 167;;;
168;;; BTRFS scrub.
169;;;
170
171(define (btrfs-scrub-shepherd-calendar-event? x)
172 (or (string? x) (gexp? x)))
173
174(define-maybe string (prefix btrfs-scrub-))
175
176(define-maybe list-of-strings (prefix btrfs-scrub-))
177
178(define (btrfs-scrub-serialize-string field-name value)
179 (if (maybe-value-set? value)
180 (list value) '()))
181
182(define (btrfs-scrub-serialize-list-of-string field-name value)
183 (if (maybe-value-set? value)
184 value '()))
185
186(define-configuration btrfs-scrub-configuration
187 (package
188 (file-like btrfs-progs)
189 "The package providing the @command{btrfs} command." empty-serializer)
190 (schedule (btrfs-scrub-shepherd-calendar-event "0 0 1-7 * 0")
191 "Schedule for launching @command{btrfs-scrub}, expressed as a string in
192traditional cron syntax or as a gexp evaluating to a Shepherd calendar
193event (@pxref{Timers,,, shepherd, The GNU Shepherd Manual}). By default this
194is set to run the 1st Sunday of the month, at 00:00."
195 empty-serializer)
196 ;; The following are btrfs-scrub-related options.
197 (to-scrub (maybe-string "/")
198 "Device to scrub. It will scrub the root (\"/\") if not given.")
199 (extra-arguments maybe-list-of-strings
200 "Extra options to append to @command{btrfs scrub start}
201 (run @samp{man btrfs-scrub} for more information). Keep in mind that,
202 by default, this service uses the @option{-B} flag (do not background and
203 print scrub statistics when finished).")
204 (prefix btrfs-scrub-))
205
206(define (serialize-btrfs-scrub-configuration config)
207 (list-transduce (compose (base-transducer config) tconcatenate)
208 rcons
209 btrfs-scrub-configuration-fields))
210
211
212(define (btrfs-scrub-template-action-procedure btrfs-bin cmd-args to-scrub)
213 "Template procedure to call the btrfs command, print it's outputs and return
214it's exit code. Taken from
215https://www.gnu.org/software/guile/manual/html_node/Processes.html#index-spawn"
216 #~(lambda (_ . args)
217 (let* ((stdout-in-out (pipe)) (stderr-in-out (pipe))
218 (argv (append (list #$btrfs-bin) '#$cmd-args '(#$to-scrub)))
219 (pid (spawn #$btrfs-bin argv
220 #:output (cdr stdout-in-out)
221 #:error (cdr stderr-in-out))))
222 (close-port (cdr stdout-in-out))
223 (close-port (cdr stderr-in-out))
224 (display (get-string-all (car stdout-in-out)))
225 ;; Redirect stderr to stdout to make it printable for "herd"
226 (display (get-string-all (car stderr-in-out)))
227 (close-port (car stdout-in-out))
228 (close-port (car stderr-in-out))
229 (let* ((status (waitpid pid)) (exit-val (status:exit-val (cdr status))))
230 (= EXIT_SUCCESS exit-val)))))
231
232
233(define (btrfs-scrub-status-action-procedure btrfs-bin to-scrub)
234 "Return a procedure to check the status of the current BTRFS scrub."
235 (btrfs-scrub-template-action-procedure btrfs-bin '("scrub" "status") to-scrub))
236
237(define (btrfs-scrub-cancel-action-procedure btrfs-bin to-scrub)
238 "Return a procedure to always cancel the current BTRFS scrub."
239 (btrfs-scrub-template-action-procedure btrfs-bin '("scrub" "cancel") to-scrub))
240
241(define (btrfs-scrub-extra-actions btrfs-bin to-scrub)
242 (list shepherd-trigger-action
243 (shepherd-action (name 'scrub-status)
244 (documentation
245 "Print the status of the scrubing process.")
246 (procedure (btrfs-scrub-status-action-procedure
247 btrfs-bin
248 to-scrub)))
249 (shepherd-action (name 'cancel)
250 (documentation
251 "Cancel the current scrub (it's an alias for stop).")
252 (procedure (btrfs-scrub-cancel-action-procedure
253 btrfs-bin
254 to-scrub)))))
255
256
257(define (btrfs-scrub-shepherd-services config)
258 (match-record config <btrfs-scrub-configuration>
259 (package schedule to-scrub)
260 (let ((btrfs-bin (file-append package "/bin/btrfs")))
261 (list (shepherd-service
262 (provision (list (string->symbol (string-append "btrfs-scrub-" to-scrub))))
263 (requirement '(user-processes))
264 (modules '((shepherd service timer)
265 (ice-9 popen)
266 (ice-9 textual-ports)))
267 (start #~(make-timer-constructor
268 #$(if (string? schedule)
269 #~(cron-string->calendar-event #$schedule)
270 schedule)
271 (command (list #$btrfs-bin
272 "scrub"
273 "start"
274 "-B"
275 #$@(serialize-btrfs-scrub-configuration config)))
276 #:wait-for-termination? #t))
277 (stop (btrfs-scrub-cancel-action-procedure btrfs-bin to-scrub))
278 (documentation "Periodically run the 'btrfs-scrub' command.")
279 (actions (btrfs-scrub-extra-actions btrfs-bin to-scrub)))))))
280
281
282(define btrfs-scrub-service-type
283 (service-type (name 'btrfs-scrub)
284 (extensions (list (service-extension
285 shepherd-root-service-type
286 btrfs-scrub-shepherd-services)))
287 (description
288 "Verify the block checksums of a BTRFS filesystem.")
289 (default-value (btrfs-scrub-configuration))))
290
291
292;;;
164;;; Early OOM daemon. 293;;; Early OOM daemon.
165;;; 294;;;
166 295
@@ -251,7 +380,7 @@ representation."
251;;; fstrim 380;;; fstrim
252;;; 381;;;
253 382
254(define (shepherd-calendar-event? x) 383(define (fstrim-shepherd-calendar-event? x)
255 (or (string? x) (gexp? x))) 384 (or (string? x) (gexp? x)))
256 385
257(define-maybe list-of-strings (prefix fstrim-)) 386(define-maybe list-of-strings (prefix fstrim-))
@@ -271,7 +400,7 @@ representation."
271 "The package providing the @command{fstrim} command." 400 "The package providing the @command{fstrim} command."
272 empty-serializer) 401 empty-serializer)
273 (schedule 402 (schedule
274 (shepherd-calendar-event "0 0 * * 0") 403 (fstrim-shepherd-calendar-event "0 0 * * 0")
275 "Schedule for launching @command{fstrim}, expressed as a string in 404 "Schedule for launching @command{fstrim}, expressed as a string in
276traditional cron syntax or as a gexp evaluating to a Shepherd calendar 405traditional cron syntax or as a gexp evaluating to a Shepherd calendar
277event (@pxref{Timers,,, shepherd, The GNU Shepherd Manual}). By default this 406event (@pxref{Timers,,, shepherd, The GNU Shepherd Manual}). By default this