services: Add cachefilesd service.

Thanks to Bruno Victal "mirai" for cooperating on this patch and for
generously sharing a wealth of insights about Guix services.

Thanks to Jean-Baptiste Note for an early version of this service!

* doc/guix.texi (Linux Services)[Cachefilesd Service]: New heading.
* gnu/services/linux.scm (serialize-string, non-negative-integer?)
(serialize-non-negative-integer, string, non-negative-integer)
(make-option-serializer, make-percentage-threshold-serializer): New
procedures.
(cachefilesd-configuration): New record type.
(cachefilesd-service-type): New variable.
* gnu/tests/cachefilesd.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.

Co-authored-by: Bruno Victal <mirai@makinata.eu>
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Felix Lechner 2023-05-28 16:36:31 -07:00 committed by Ludovic Courtès
parent 48d06aee7b
commit b8ee6b8a59
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
4 changed files with 359 additions and 1 deletions

View file

@ -117,6 +117,7 @@ Copyright @copyright{} 2023 Karl Hallsby@*
Copyright @copyright{} 2023 Nathaniel Nicandro@* Copyright @copyright{} 2023 Nathaniel Nicandro@*
Copyright @copyright{} 2023 Tanguy Le Carrour@* Copyright @copyright{} 2023 Tanguy Le Carrour@*
Copyright @copyright{} 2023 Brian Cully@* Copyright @copyright{} 2023 Brian Cully@*
Copyright @copyright{} 2023 Felix Lechner@*
Permission is granted to copy, distribute and/or modify this document Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or under the terms of the GNU Free Documentation License, Version 1.3 or
@ -38659,6 +38660,94 @@ parameters, can be done as follow:
@end lisp @end lisp
@end defvar @end defvar
@subsubheading Cachefilesd Service
@cindex cachefilesd
@cindex fscache, file system caching (Linux)
The Cachefilesd service starts a daemon that caches network file system
data locally. It is especially useful for NFS and AFS shares, where it
reduces latencies for repeated access when reading files.
The daemon can be configured as follows:
@lisp
(service cachefilesd-service-type
(cachefilesd-configuration
(cache-directory "/var/cache/fscache")))
@end lisp
@defvar cachefilesd-service-type
The service type for starting @command{cachefilesd}. The value for this
service type is a @code{cachefilesd-configuration}, whose only required
field is @var{cache-directory}.
@end defvar
@c %start of fragment
@deftp {Data Type} cachefilesd-configuration
Available @code{cachefilesd-configuration} fields are:
@table @asis
@item @code{cachefilesd} (default: @code{cachefilesd}) (type: file-like)
The cachefilesd package to use.
@item @code{debug-output?} (default: @code{#f}) (type: boolean)
Print debugging output to stderr.
@item @code{use-syslog?} (default: @code{#t}) (type: boolean)
Log to syslog facility instead of stdout.
@item @code{scan?} (default: @code{#t}) (type: boolean)
Scan for cachable objects.
@item @code{cache-directory} (type: maybe-string)
Location of the cache directory.
@item @code{cache-name} (default: @code{"CacheFiles"}) (type: maybe-string)
Name of cache (keep unique).
@item @code{security-context} (type: maybe-string)
SELinux security context.
@item @code{pause-culling-for-block-percentage} (default: @code{7}) (type: maybe-non-negative-integer)
Pause culling when available blocks exceed this percentage.
@item @code{pause-culling-for-file-percentage} (default: @code{7}) (type: maybe-non-negative-integer)
Pause culling when available files exceed this percentage.
@item @code{resume-culling-for-block-percentage} (default: @code{5}) (type: maybe-non-negative-integer)
Start culling when available blocks drop below this percentage.
@item @code{resume-culling-for-file-percentage} (default: @code{5}) (type: maybe-non-negative-integer)
Start culling when available files drop below this percentage.
@item @code{pause-caching-for-block-percentage} (default: @code{1}) (type: maybe-non-negative-integer)
Pause further allocations when available blocks drop below this
percentage.
@item @code{pause-caching-for-file-percentage} (default: @code{1}) (type: maybe-non-negative-integer)
Pause further allocations when available files drop below this
percentage.
@item @code{log2-table-size} (default: @code{12}) (type: maybe-non-negative-integer)
Size of tables holding cullable objects in logarithm of base 2.
@item @code{cull?} (default: @code{#t}) (type: boolean)
Create free space by culling (consumes system load).
@item @code{trace-function-entry-in-kernel-module?} (default: @code{#f}) (type: boolean)
Trace function entry in the kernel module (for debugging).
@item @code{trace-function-exit-in-kernel-module?} (default: @code{#f}) (type: boolean)
Trace function exit in the kernel module (for debugging).
@item @code{trace-internal-checkpoints-in-kernel-module?} (default: @code{#f}) (type: boolean)
Trace internal checkpoints in the kernel module (for debugging).
@end table
@end deftp
@c %end of fragment
@cindex rasdaemon @cindex rasdaemon
@cindex Platform Reliability, Availability and Serviceability daemon @cindex Platform Reliability, Availability and Serviceability daemon
@subsubheading Rasdaemon Service @subsubheading Rasdaemon Service

View file

@ -770,6 +770,7 @@ GNU_SYSTEM_MODULES = \
%D%/tests.scm \ %D%/tests.scm \
%D%/tests/audio.scm \ %D%/tests/audio.scm \
%D%/tests/base.scm \ %D%/tests/base.scm \
%D%/tests/cachefilesd.scm \
%D%/tests/ci.scm \ %D%/tests/ci.scm \
%D%/tests/cups.scm \ %D%/tests/cups.scm \
%D%/tests/databases.scm \ %D%/tests/databases.scm \

View file

@ -6,6 +6,7 @@
;;; Copyright © 2021 B. Wilson <elaexuotee@wilsonb.com> ;;; Copyright © 2021 B. Wilson <elaexuotee@wilsonb.com>
;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz> ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz>
;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu> ;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu>
;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -67,6 +68,28 @@ (define-module (gnu services linux)
kernel-module-loader-service-type kernel-module-loader-service-type
cachefilesd-configuration
cachefilesd-configuration?
cachefilesd-configuration-cachefilesd
cachefilesd-configuration-debug-output?
cachefilesd-configuration-use-syslog?
cachefilesd-configuration-scan?
cachefilesd-configuration-cache-directory
cachefilesd-configuration-cache-name
cachefilesd-configuration-security-context
cachefilesd-configuration-pause-culling-for-block-percentage
cachefilesd-configuration-pause-culling-for-file-percentage
cachefilesd-configuration-resume-culling-for-block-percentage
cachefilesd-configuration-resume-culling-for-file-percentage
cachefilesd-configuration-pause-caching-for-block-percentage
cachefilesd-configuration-pause-caching-for-file-percentage
cachefilesd-configuration-log2-table-size
cachefilesd-configuration-cull?
cachefilesd-configuration-trace-function-entry-in-kernel-module
cachefilesd-configuration-trace-function-exit-in-kernel-module
cachefilesd-configuration-trace-internal-checkpoints-in-kernel-module
cachefilesd-service-type
rasdaemon-configuration rasdaemon-configuration
rasdaemon-configuration? rasdaemon-configuration?
rasdaemon-configuration-record? rasdaemon-configuration-record?
@ -306,6 +329,180 @@ (define kernel-module-loader-service-type
(extend append) (extend append)
(default-value '()))) (default-value '())))
;;;
;;; Cachefilesd, an FS-Cache daemon
;;;
(define (serialize-string variable-symbol value)
#~(format #f "~a ~a~%" #$(symbol->string variable-symbol) #$value))
(define-maybe string)
(define (non-negative-integer? val)
(and (exact-integer? val) (not (negative? val))))
(define (serialize-non-negative-integer variable-symbol value)
#~(format #f "~a ~d~%" #$(symbol->string variable-symbol) #$value))
(define-maybe non-negative-integer)
(define (make-option-serializer option-symbol)
(lambda (variable-symbol text)
(if (maybe-value-set? text)
#~(format #f "~a ~a~%" #$(symbol->string option-symbol) #$text)
"")))
(define (make-percentage-threshold-serializer threshold-symbol)
(lambda (variable-symbol percentage)
(if (maybe-value-set? percentage)
#~(format #f "~a ~a%~%" #$(symbol->string threshold-symbol) #$percentage)
"")))
(define-configuration cachefilesd-configuration
(cachefilesd
(file-like cachefilesd)
"The cachefilesd package to use."
(serializer empty-serializer))
;; command-line options
(debug-output?
(boolean #f)
"Print debugging output to stderr."
(serializer empty-serializer))
(use-syslog?
(boolean #t)
"Log to syslog facility instead of stdout."
(serializer empty-serializer))
;; culling is part of the configuration file
;; despite the name of the command-line option
(scan?
(boolean #t)
"Scan for cachable objects."
(serializer empty-serializer))
;; sole required field in the configuration file
(cache-directory
maybe-string
"Location of the cache directory."
(serializer (make-option-serializer 'dir)))
(cache-name
(maybe-string "CacheFiles")
"Name of cache (keep unique)."
(serializer (make-option-serializer 'tag)))
(security-context
maybe-string
"SELinux security context."
(serializer (make-option-serializer 'secctx)))
;; percentage thresholds in the configuration file
(pause-culling-for-block-percentage
(maybe-non-negative-integer 7)
"Pause culling when available blocks exceed this percentage."
(serializer (make-percentage-threshold-serializer 'brun)))
(pause-culling-for-file-percentage
(maybe-non-negative-integer 7)
"Pause culling when available files exceed this percentage."
(serializer (make-percentage-threshold-serializer 'frun)))
(resume-culling-for-block-percentage
(maybe-non-negative-integer 5)
"Start culling when available blocks drop below this percentage."
(serializer (make-percentage-threshold-serializer 'bcull)))
(resume-culling-for-file-percentage
(maybe-non-negative-integer 5)
"Start culling when available files drop below this percentage."
(serializer (make-percentage-threshold-serializer 'fcull)))
(pause-caching-for-block-percentage
(maybe-non-negative-integer 1)
"Pause further allocations when available blocks drop below this percentage."
(serializer (make-percentage-threshold-serializer 'bstop)))
(pause-caching-for-file-percentage
(maybe-non-negative-integer 1)
"Pause further allocations when available files drop below this percentage."
(serializer (make-percentage-threshold-serializer 'fstop)))
;; run time optimizations in the configuration file
(log2-table-size
(maybe-non-negative-integer 12)
"Size of tables holding cullable objects in logarithm of base 2."
(serializer (make-option-serializer 'culltable)))
(cull?
(boolean #t)
"Create free space by culling (consumes system load)."
(serializer
(lambda (variable-symbol value)
(if value "" "nocull\n"))))
;; kernel module debugging in the configuration file
(trace-function-entry-in-kernel-module?
(boolean #f)
"Trace function entry in the kernel module (for debugging)."
(serializer empty-serializer))
(trace-function-exit-in-kernel-module?
(boolean #f)
"Trace function exit in the kernel module (for debugging)."
(serializer empty-serializer))
(trace-internal-checkpoints-in-kernel-module?
(boolean #f)
"Trace internal checkpoints in the kernel module (for debugging)."
(serializer empty-serializer)))
(define (serialize-cachefilesd-configuration configuration)
(mixed-text-file
"cachefilesd.conf"
(serialize-configuration configuration cachefilesd-configuration-fields)))
(define (cachefilesd-shepherd-service config)
"Return a list of <shepherd-service> for cachefilesd for CONFIG."
(match-record
config <cachefilesd-configuration> (cachefilesd
debug-output?
use-syslog?
scan?
cache-directory)
(let ((configuration-file (serialize-cachefilesd-configuration config)))
(shepherd-service
(documentation "Run the cachefilesd daemon for FS-Cache.")
(provision '(cachefilesd))
(requirement (append '(file-systems)
(if use-syslog? '(syslogd) '())))
(start #~(begin
(and=> #$(maybe-value cache-directory) mkdir-p)
(make-forkexec-constructor
`(#$(file-append cachefilesd "/sbin/cachefilesd")
;; do not detach
"-n"
#$@(if debug-output? '("-d") '())
#$@(if use-syslog? '() '("-s"))
#$@(if scan? '() '("-N"))
"-f" #$configuration-file))))
(stop #~(make-kill-destructor))))))
(define cachefilesd-service-type
(service-type
(name 'cachefilesd)
(description
"Run the file system cache daemon @command{cachefilesd}, which relies on
the Linux @code{cachefiles} module.")
(extensions
(list (service-extension kernel-module-loader-service-type
(const '("cachefiles")))
(service-extension shepherd-root-service-type
(compose list cachefilesd-shepherd-service))))
(default-value (cachefilesd-configuration))))
;;; ;;;
;;; Reliability, Availability, and Serviceability (RAS) daemon ;;; Reliability, Availability, and Serviceability (RAS) daemon
@ -351,7 +548,7 @@ (define rasdaemon-service-type
;;; ;;;
;;; Kernel module loader. ;;; Zram device
;;; ;;;
(define-record-type* <zram-device-configuration> (define-record-type* <zram-device-configuration>

71
gnu/tests/cachefilesd.scm Normal file
View file

@ -0,0 +1,71 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Peter Mikkelsen <petermikkelsen10@gmail.com>
;;; Copyright © 2022 Bruno Victal <mirai@makinata.eu>
;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu tests cachefilesd)
#:use-module (gnu tests)
#:use-module (gnu system)
#:use-module (gnu system vm)
#:use-module (gnu services)
#:use-module (gnu services linux)
#:use-module (guix gexp)
#:export (%test-cachefilesd))
(define %cachefilesd-os
(simple-operating-system
(service cachefilesd-service-type
(cachefilesd-configuration
(cache-directory "/var/cache/fscache")))))
(define (run-cachefilesd-test)
"Run tests in %cachefilesd-os, which has cachefilesd running."
(define os
(marionette-operating-system
%cachefilesd-os
#:imported-modules '((gnu services herd))))
(define vm
(virtual-machine os))
(define test
(with-imported-modules '((gnu build marionette))
#~(begin
(use-modules (srfi srfi-64)
(gnu build marionette))
(define marionette
(make-marionette (list #$vm)))
(test-runner-current (system-test-runner #$output))
(test-begin "cachefilesd")
(test-assert "service is running"
(marionette-eval
'(begin
(use-modules (gnu services herd))
(start-service 'cachefilesd))
marionette))
(test-end))))
(gexp->derivation "cachefilesd-test" test))
(define %test-cachefilesd
(system-test
(name "cachefilesd")
(description "Test that the cachefilesd runs when started.")
(value (run-cachefilesd-test))))