From patchwork Sun May 28 23:36:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Felix Lechner X-Patchwork-Id: 50405 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 8C1C327BBE9; Mon, 29 May 2023 00:38:27 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id E42BB27BBE2 for ; Mon, 29 May 2023 00:38:23 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q3Pxc-0004Xc-FH; Sun, 28 May 2023 19:38:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q3Pxa-0004XG-LG for guix-patches@gnu.org; Sun, 28 May 2023 19:38:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1q3Pxa-0002X4-D8 for guix-patches@gnu.org; Sun, 28 May 2023 19:38:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1q3Pxa-0006fQ-8m for guix-patches@gnu.org; Sun, 28 May 2023 19:38:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63182] [PATCH v2] gnu: services: Add cachefilesd service. (Closes: #63182) References: In-Reply-To: Resent-From: Felix Lechner Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 28 May 2023 23:38:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63182 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63182@debbugs.gnu.org Cc: Bruno Victal , Felix Lechner Received: via spool by 63182-submit@debbugs.gnu.org id=B63182.168531702225540 (code B ref 63182); Sun, 28 May 2023 23:38:02 +0000 Received: (at 63182) by debbugs.gnu.org; 28 May 2023 23:37:02 +0000 Received: from localhost ([127.0.0.1]:56554 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1q3Pwa-0006dl-Ms for submit@debbugs.gnu.org; Sun, 28 May 2023 19:37:01 -0400 Received: from sail-ipv4.us-core.com ([208.82.101.137]:50846) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1q3PwY-0006dc-Tp for 63182@debbugs.gnu.org; Sun, 28 May 2023 19:37:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; s=2017; bh=0BBfkjZHe8pEgMh s7XlGjqIHaWhneL6Mci6VWXXxlU4=; h=date:subject:cc:to:from; d=lease-up.com; b=eqZBjOwFSEDyC1lsRbcyj+irRIJDFhWwl1ekQHl1SOyVhMb7E0IY q1bcfDqB5gfhBWTuYUC39En4aJHGY7HbXPylsM6bI60Bza7maTSpuWLJxumupwTvu9u3Mh Je/0G/+HK0vEt2I95GX/gKY+uj8XYzeA17+QcTuGaytMwV7+c= Received: by sail-ipv4.us-core.com (OpenSMTPD) with ESMTPSA id 52d48a06 (TLSv1.3:TLS_CHACHA20_POLY1305_SHA256:256:NO); Sun, 28 May 2023 23:36:58 +0000 (UTC) Received: from localhost (localhost [local]) by localhost (OpenSMTPD) with ESMTPA id 63786ea1; Sun, 28 May 2023 23:36:57 +0000 (UTC) Date: Sun, 28 May 2023 16:36:31 -0700 Message-Id: <26f0b6ed21a731525dd2dff5335f2017fcaa57a3.1685316939.git.felix.lechner@lease-up.com> X-Mailer: git-send-email 2.40.1 MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Felix Lechner X-ACL-Warn: , Felix Lechner via Guix-patches X-Patchwork-Original-From: Felix Lechner via Guix-patches via From: Felix Lechner Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches 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! Co-authored-by: Bruno Victal --- Rebased for changes in guix.texi. doc/guix.texi | 90 +++++++++++++++++ gnu/local.mk | 1 + gnu/services/linux.scm | 199 +++++++++++++++++++++++++++++++++++++- gnu/tests/cachefilesd.scm | 71 ++++++++++++++ 4 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 gnu/tests/cachefilesd.scm base-commit: d64d6ea2cf5a1be801be355031fb2cfa5901a92a diff --git a/doc/guix.texi b/doc/guix.texi index 31dc33fb97..304a61603d 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -115,6 +115,7 @@ Copyright @copyright{} 2023 Giacomo Leidi@* Copyright @copyright{} 2022 Antero Mejr@* Copyright @copyright{} 2023 Karl Hallsby@* Copyright @copyright{} 2023 Nathaniel Nicandro@* +Copyright @copyright{} 2023 Felix Lechner@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -38062,6 +38063,95 @@ parameters, can be done as follow: @end lisp @end defvar +@cindex cachefilesd +@cindex cachefiles +@cindex fscache +@subsubheading Cachefilesd Service + +The Cachefilesd service starts a daemon that caches network filesystem +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 started 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 Platform Reliability, Availability and Serviceability daemon @subsubheading Rasdaemon Service diff --git a/gnu/local.mk b/gnu/local.mk index 73370dcc78..8f419880f7 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -766,6 +766,7 @@ GNU_SYSTEM_MODULES = \ %D%/tests.scm \ %D%/tests/audio.scm \ %D%/tests/base.scm \ + %D%/tests/cachefilesd.scm \ %D%/tests/ci.scm \ %D%/tests/cups.scm \ %D%/tests/databases.scm \ diff --git a/gnu/services/linux.scm b/gnu/services/linux.scm index d105c42850..e42ef1ae97 100644 --- a/gnu/services/linux.scm +++ b/gnu/services/linux.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2021 B. Wilson ;;; Copyright © 2022 Josselin Poiret ;;; Copyright © 2023 Bruno Victal +;;; Copyright © 2023 Felix Lechner ;;; ;;; This file is part of GNU Guix. ;;; @@ -67,6 +68,28 @@ (define-module (gnu services linux) 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-record? @@ -306,6 +329,180 @@ (define kernel-module-loader-service-type (extend append) (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 for cachefilesd for CONFIG." + (match-record + config (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 FS-Cache backend daemon @command{cachefilesd}.") + (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 @@ -351,7 +548,7 @@ (define rasdaemon-service-type ;;; -;;; Kernel module loader. +;;; Zram device ;;; (define-record-type* diff --git a/gnu/tests/cachefilesd.scm b/gnu/tests/cachefilesd.scm new file mode 100644 index 0000000000..7f5d513067 --- /dev/null +++ b/gnu/tests/cachefilesd.scm @@ -0,0 +1,71 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2017 Peter Mikkelsen +;;; Copyright © 2022 Bruno Victal +;;; Copyright © 2023 Felix Lechner +;;; +;;; 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 . + +(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))))