all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [bug#41180] [PATCH] Add cachefilesd service.
@ 2020-05-10 19:19 Jean-Baptiste Note
  2020-05-10 19:27 ` Jean-Baptiste Note
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Jean-Baptiste Note @ 2020-05-10 19:19 UTC (permalink / raw)
  To: 41180; +Cc: Mathieu Othacehe


[-- Attachment #1.1: Type: text/plain, Size: 2023 bytes --]


Dear guix developers, Mathieu,

Please find attached a first version of the cachefilesd service patch.
The second patch for documentation will be sent right after.

I have a few general newbie scheme questions:

- I gathered that #~ / #$ kinds of suspends evaluation / forces it -- is
  there documentation about this somewhere ?

- There's something that looks like a splat operator (only seen in
  conjuction with forcing evaluation in #$@) -- again i'd be interested
  in more documentation about this feature -- is this a guix-specific
  operator?

- I don't understand why there are ^L separating services in the scheme
  files -- is this necessary? A convention? What purpose does it serve?

Regarding the patch itself:

- i'm not entirely sure the service belongs to services/linux.scm

- documentation is hastily written. I have found no way to indent
  automatically the lisp code in the texi file, which is very painfull
  -- would there be an emacs solution for this?

- there are no automated tests (beyond what I have done by hand
  locally!), and there's no lint, so I don't really feel confident about
  it :) Are there tests for services to alleviate my fears?

- I've copied some other service for modprobing the required kernel
  modules before launching the daemon with a one-shot shepherd
  service. Frankly i'm not happy about this solution, it seems to me
  that it unnecessarily pollutes the shepherd configuration; maybe some
  other mechanism (graft?) adjusting the modprobe configuration could be
  better (better still, autoload the file). Any guidance would be nice
  (including, that this solution is sufficient for now :))

I had great fun writing this, it reminded me of writing cookbooks during
my 'Chef' days. I must confess that the Chef DSL embedded in ruby seemed
more concise, and that it provided a way to write a cookbook
'out-of-tree' which was kind of less daunting for newcomers; however
it's already amazing that you have this kind of functionality!

Kind regards,
Jean-Baptiste

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-gnu-Add-cachefilesd-service.patch --]
[-- Type: text/x-patch, Size: 9401 bytes --]

From 729d43d541e8dcb41b36a7522ec291b0c3f8dd14 Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Note <jean-baptiste.note@m4x.org>
Date: Sat, 9 May 2020 15:14:26 +0000
Subject: [PATCH 1/2] gnu: Add cachefilesd-service.

* doc/guix.texi (Linux Services): Add a new subsection and document the
new service and its configuration.
* gnu/services/linux.scm (cachefilesd-service-type): New type.
(cachefilesd-configuration): New type.
---
 gnu/services/linux.scm | 210 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 209 insertions(+), 1 deletion(-)

diff --git a/gnu/services/linux.scm b/gnu/services/linux.scm
index 12934c2084..810901e0ca 100644
--- a/gnu/services/linux.scm
+++ b/gnu/services/linux.scm
@@ -42,7 +42,11 @@
             earlyoom-configuration-send-notification-command
             earlyoom-service-type
 
-            kernel-module-loader-service-type))
+            kernel-module-loader-service-type
+
+            cachefilesd-configuration
+            cachefilesd-configuration?
+            cachefilesd-service-type))
 
 \f
 ;;;
@@ -177,3 +181,207 @@ representation."
    (compose concatenate)
    (extend append)
    (default-value '())))
+
+\f
+;;;
+;;; cachefilesd.
+;;;
+
+(define-record-type* <cachefilesd-configuration>
+  cachefilesd-configuration make-cachefilesd-configuration
+  cachefilesd-configuration?
+
+  ;; <package-path>
+  (cachefilesd           cachefilesd-configuration-cachefilesd
+                         (default cachefilesd))
+
+  ;; cmdline flags
+  ;; Boolean
+  (daemonic?             cachefilesd-configuration-daemonic?
+                         (default #t))
+
+  ;; string
+  (pid-file              cachefilesd-configuration-pid-file
+                         (default "/var/run/cachefilesd.pid"))
+
+  ;; Boolean
+  (debug?                cachefilesd-configuration-debug?
+                         (default #f))
+  ;; Boolean
+  (syslog?               cachefilesd-configuration-syslog?
+                         (default #t))
+  ;; Boolean
+  (culling-and-scanning? cachefilesd-configuration-culling-and-scanning?
+                         (default #t))
+
+  ;; configuration file contents
+  ;; String
+  (dir                   cachefilesd-configuration-dir
+                         (default "/var/cache/fscache"))
+
+  ;; String
+  (tag                   cachefilesd-configuration-tag
+                         (default "CacheFiles"))
+
+  ;; String
+  (secctx                cachefilesd-configuration-secctx
+                         (default #f))
+
+  ;; integers
+  (brun                  cachefilesd-configuration-brun
+                         (default 7))
+  (frun                  cachefilesd-configuration-frun
+                         (default 7))
+  (bcull                 cachefilesd-configuration-bcull
+                         (default 5))
+  (fcull                 cachefilesd-configuration-fcull
+                         (default 5))
+  (bstop                 cachefilesd-configuration-bstop
+                         (default 1))
+  (fstop                 cachefilesd-configuration-fstop
+                         (default 1))
+
+  ;; integer
+  (culltable             cachefilesd-configuration-culltable
+                         (default 12))
+
+  ;; integer / debug mask
+  (kernel-debug          cachefilesd-configuration-kernel-debug
+                         (default 0))
+
+  ;; boolean
+  (nocull?               cachefilesd-configuration-nocull?
+                         (default #f))
+  ;; Boolean
+  ;; XXX: This should really be handled in an orthogonal way, for instance as
+  ;; proposed in <https://bugs.gnu.org/27155>.  Keep it internal/undocumented
+  ;; for now.
+  (%auto-start?          cachefilesd-auto-start?
+                         (default #t)))
+
+(define (cachefilesd-configuration-file config)
+  "Return the cachefilesd configuration file corresponding to CONFIG."
+  (define secctx
+    (cachefilesd-configuration-dir config))
+
+  (computed-file
+   "cachefilesd.conf"
+   #~(begin
+       (use-modules (ice-9 match))
+       (call-with-output-file #$output
+         (lambda (port)
+           (display "# Generated by 'cachefilesd-service'.\n" port)
+           (format port "dir ~a\n" #$(cachefilesd-configuration-dir config))
+
+           (let ((secctx #$(cachefilesd-configuration-secctx config)))
+             (if secctx (format port "secctx ~a" secctx)))
+
+           ;; XXX factor this
+           (format port "brun ~a%\n"
+                   #$(number->string
+                      (cachefilesd-configuration-brun config)))
+           (format port "frun ~a%\n"
+                   #$(number->string
+                      (cachefilesd-configuration-frun config)))
+           (format port "bcull ~a%\n"
+                   #$(number->string
+                      (cachefilesd-configuration-bcull config)))
+           (format port "fcull ~a%\n"
+                   #$(number->string
+                      (cachefilesd-configuration-fcull config)))
+           (format port "bstop ~a%\n"
+                   #$(number->string
+                      (cachefilesd-configuration-bstop config)))
+           (format port "fstop ~a%\n"
+                   #$(number->string
+                      (cachefilesd-configuration-fstop config)))
+
+           (format port "tag ~a\n" #$(cachefilesd-configuration-tag config))
+
+           (format port "culltable ~a\n"
+                   #$(number->string
+                      (cachefilesd-configuration-culltable config)))
+
+           (if #$(cachefilesd-configuration-nocull? config)
+               (display "nocull\n" port))
+
+           (format port "debug ~a\n"
+                   #$(number->string
+                      (cachefilesd-configuration-kernel-debug config)))
+
+           #t)))))
+
+(define (cachefilesd-activation config)
+  "Return cachefilesd's activation GEXP for CONFIG."
+  (with-imported-modules '((guix build utils))
+    #~(begin
+        (use-modules (guix build utils))
+        ;; Make sure the cache directory and pid dir exists
+        (mkdir-p #$(cachefilesd-configuration-dir config))
+        (mkdir-p (dirname #$(cachefilesd-configuration-pid-file config))))))
+
+(define (cachefilesd-shepherd-service config)
+  "Return a <shepherd-service> for cachefilesd with CONFIG."
+
+  (define cachefilesdpath
+    (cachefilesd-configuration-cachefilesd config))
+  (define pid-file
+    (cachefilesd-configuration-pid-file config))
+  (define syslog?
+    (cachefilesd-configuration-syslog? config))
+  (define culling-and-scanning?
+    (cachefilesd-configuration-culling-and-scanning? config))
+  (define debug?
+    (cachefilesd-configuration-debug? config))
+
+  (define cachefilesd-command
+    #~(list #$(file-append cachefilesdpath "/sbin/cachefilesd")
+            #$@(if (cachefilesd-configuration-daemonic? config) '() '("-n"))
+            ;; XXX shepherd pid file handling: no idea how shepherd does it
+            ;; and if it's going to conflict with cachefilesd's
+            #$@(if debug? '("-d") '())
+            #$@(if syslog? '() '("-s"))
+            #$@(if culling-and-scanning? '() '("-N"))
+            "-p" #$pid-file
+            "-f" #$(cachefilesd-configuration-file config)))
+
+  (list (shepherd-service
+         (documentation "Start cachefilesd daemon.")
+         (requirement (append '(file-systems cachefiles-module)
+                              (if syslog? '(syslogd) '())))
+         (provision '(cachefilesd))
+         (start #~(make-forkexec-constructor #$cachefilesd-command
+                                             #:pid-file #$pid-file))
+         (stop #~(make-kill-destructor))
+         (auto-start? (cachefilesd-auto-start? config)))
+
+        (shepherd-service
+         (provision '(cachefiles-module))
+         (requirement '(file-systems))
+         (modules '((guix build utils)))
+         (documentation
+          "Load the cachefiles Linux kernel module.")
+         (start (with-imported-modules '((guix build utils))
+                  #~(lambda _
+                      ;; XXX: duplicated from networking
+                      ;; -- factor this into a modprobe command
+                      ;; XXX: We can't use 'load-linux-module*' here because it
+                      ;; expects a flat module directory.
+                      (setenv "LINUX_MODULE_DIRECTORY"
+                              "/run/booted-system/kernel/lib/modules")
+                      (invoke #$(file-append kmod "/bin/modprobe")
+                              "cachefiles"))))
+         (one-shot? #t))))
+
+(define cachefilesd-service-type
+  (service-type (name 'cachefilesd)
+                (description
+                 "Run the CacheFile backend daemon, @command{cachefilesd}.")
+                (extensions
+                 (list
+                  (service-extension shepherd-root-service-type
+                                     cachefilesd-shepherd-service)
+                  (service-extension activation-service-type
+                                     cachefilesd-activation)))
+                (compose concatenate)
+                (default-value (cachefilesd-configuration))))
-- 
2.26.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#41180] [PATCH] Add cachefilesd service.
  2020-05-10 19:19 [bug#41180] [PATCH] Add cachefilesd service Jean-Baptiste Note
@ 2020-05-10 19:27 ` Jean-Baptiste Note
  2020-05-11 15:06 ` Mathieu Othacehe
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Jean-Baptiste Note @ 2020-05-10 19:27 UTC (permalink / raw)
  To: 41180; +Cc: Mathieu Othacehe


[-- Attachment #1.1: Type: text/plain, Size: 23 bytes --]


Documentation patch.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0002-doc-Add-documentation-for-cachefilesd-service.patch --]
[-- Type: text/x-patch, Size: 1783 bytes --]

From b169047ad64996860e6eb154bb4d20ad80463b47 Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Note <jean-baptiste.note@m4x.org>
Date: Sun, 10 May 2020 18:43:08 +0000
Subject: [PATCH 2/2] doc: Add documentation for cachefilesd-service.

* doc/guix.texi (Linux Services): Add a new subsection and document the
cachefilesd service and its configuration.
---
 doc/guix.texi | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index 0cba0ee1ec..4aaec43739 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -25724,6 +25724,41 @@ parameters, can be done as follow:
 @end lisp
 @end deffn
 
+@cindex cachefilesd
+@cindex cachefiles
+@cindex fscache
+@subsubheading cachefilesd Service
+
+The cachefilesd service allows one to load start @code{cachefilesd} for
+caching network filesystem data on local disks.  This is especially
+useful for NFS and AFS shares, reducing read latency.
+
+@deffn {Scheme Variable} cachefilesd-service-type
+The service type for starting cachefilesd.  For example starting the
+cachefiles daemon can be done as follow:
+
+@lisp
+(use-modules (gnu) (gnu services))
+(use-package-modules linux)
+(use-service-modules linux)
+
+(operating-system
+  ...
+  (services
+    (cons*
+      (service cachefilesd-service-type
+        (cachefilesd-configuration
+          (dir "/var/cache/fscache") ; the default value
+          (syslog? #f)               ; don't require syslogd
+          (secctx "cachefiles_kernel_t")
+          (tag "mycache")
+          (brun 10)
+          (bcull 7)
+          (bstop 3)))
+       %base-services)))
+@end lisp
+@end deffn
+
 @node Miscellaneous Services
 @subsection Miscellaneous Services
 
-- 
2.26.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#41180] [PATCH] Add cachefilesd service.
  2020-05-10 19:19 [bug#41180] [PATCH] Add cachefilesd service Jean-Baptiste Note
  2020-05-10 19:27 ` Jean-Baptiste Note
@ 2020-05-11 15:06 ` Mathieu Othacehe
  2020-05-19 12:12 ` Mathieu Othacehe
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Mathieu Othacehe @ 2020-05-11 15:06 UTC (permalink / raw)
  To: Jean-Baptiste Note; +Cc: 41180


Hello Jean-Baptiste,

Thanks for this service!

> - I gathered that #~ / #$ kinds of suspends evaluation / forces it -- is
>   there documentation about this somewhere ?

#~ and #$ are related to the Gexp mechanism. It's documented here:
 https://guix.gnu.org/manual/en/html_node/G_002dExpressions.html.
 
> - There's something that looks like a splat operator (only seen in
>   conjuction with forcing evaluation in #$@) -- again i'd be interested
>   in more documentation about this feature -- is this a guix-specific
>   operator?

#$@ is a shortcut for ungexp-splicing. It's also documented in the link
above. It can be a bit puzzling at start, don't hesitate to ask some
help on #guix channel.
 
> - I don't understand why there are ^L separating services in the scheme
>   files -- is this necessary? A convention? What purpose does it serve?

Yes, see the "Pagination" section in
https://mumble.net/~campbell/scheme/style.txt. You can install
"emacs-page-break-lines" to replace it by cleaner lines.

> Regarding the patch itself:
>
> - i'm not entirely sure the service belongs to services/linux.scm

I think it's fine.

> - there are no automated tests (beyond what I have done by hand
>   locally!), and there's no lint, so I don't really feel confident about
>   it :) Are there tests for services to alleviate my fears?

It would be nice to implement tests along with the new service
definition. You can have a look to (gnu tests cups) module for
instance. It tests the cups service by spawning a virtual-machine called
a "marionette". You could create a (gnu tests cachefilesd) doing a
similar job.

See "Running the Test Suite" in the info page for more details on how to
run the test suite.

> - I've copied some other service for modprobing the required kernel
>   modules before launching the daemon with a one-shot shepherd
>   service. Frankly i'm not happy about this solution, it seems to me
>   that it unnecessarily pollutes the shepherd configuration; maybe some
>   other mechanism (graft?) adjusting the modprobe configuration could be
>   better (better still, autoload the file). Any guidance would be nice
>   (including, that this solution is sufficient for now :))

The ideal would be that cachefilesd loads the appropriated module. If
this is not possible, we can discuss extending
kernel-module-loader-service-type service. But for now I guess it's ok.

I hope it answers your questions, I'll review the rest of the service
later on.

Thanks,

Mathieu




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#41180] [PATCH] Add cachefilesd service.
  2020-05-10 19:19 [bug#41180] [PATCH] Add cachefilesd service Jean-Baptiste Note
  2020-05-10 19:27 ` Jean-Baptiste Note
  2020-05-11 15:06 ` Mathieu Othacehe
@ 2020-05-19 12:12 ` Mathieu Othacehe
  2020-05-20 20:39   ` Jean-Baptiste Note
  2023-03-09 12:24 ` [bug#41180] [PATCH v2] gnu: services: Add cachefilesd service. (Closes: #41180) Felix Lechner via Guix-patches via
  2023-04-30  4:10 ` bug#41180: Closing in favor of Bug#63182 Felix Lechner via Guix-patches via
  4 siblings, 1 reply; 9+ messages in thread
From: Mathieu Othacehe @ 2020-05-19 12:12 UTC (permalink / raw)
  To: Jean-Baptiste Note; +Cc: 41180


Hello,

Overall, this looks nice! A few comments below. Note that you can merge
this patch with the documentation patch. It would also be nice to add
the associated system tests.

> +(define-record-type* <cachefilesd-configuration>
> +  cachefilesd-configuration make-cachefilesd-configuration
> +  cachefilesd-configuration?
> +
> +  ;; <package-path>
> +  (cachefilesd           cachefilesd-configuration-cachefilesd
> +                         (default cachefilesd))
> +

You could write something more concise here by removing empty lines and
adding the 'type' comment on the same line.

> +           (let ((secctx #$(cachefilesd-configuration-secctx config)))
> +             (if secctx (format port "secctx ~a" secctx)))

You can use 'when' for one arm if conditions.

> +
> +           ;; XXX factor this
> +           (format port "brun ~a%\n"
> +                   #$(number->string
> +                      (cachefilesd-configuration-brun config)))

It would indeed be nice to factor it, maybe by creating an association
table with the symbol name as CAR and the matching procedure as
CDR. Something like:

--8<---------------cut here---------------start------------->8---
'(("frun" . cachefilesd-configuration-frun)
  ("bcull" . cachefilesd-configuration-bcull))
--8<---------------cut here---------------end--------------->8---

then you could iterate on that list.

> +           (if #$(cachefilesd-configuration-nocull? config)
> +               (display "nocull\n" port))

Same as above. You can use 'when' or 'unless' instead of "(if test
stmt)".

> +        ;; Make sure the cache directory and pid dir exists

"dir" -> "directory".

> +            ;; XXX shepherd pid file handling: no idea how shepherd does it
> +            ;; and if it's going to conflict with cachefilesd's

Shepherd documentation says:

--8<---------------cut here---------------start------------->8---
     When PID-FILE is true, it must be the name of a PID file associated
     with the process being launched; the return value is the PID once
     that file has been created.  If PID-FILE does not show up in less
     than PID-FILE-TIMEOUT seconds, the service is considered as failing
     to start.
--8<---------------cut here---------------end--------------->8---

So I think you can remove this comment.

Thanks,

Mathieu




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#41180] [PATCH] Add cachefilesd service.
  2020-05-19 12:12 ` Mathieu Othacehe
@ 2020-05-20 20:39   ` Jean-Baptiste Note
  2020-05-23  6:44     ` Mathieu Othacehe
  2020-09-02 14:58     ` Mathieu Othacehe
  0 siblings, 2 replies; 9+ messages in thread
From: Jean-Baptiste Note @ 2020-05-20 20:39 UTC (permalink / raw)
  To: Mathieu Othacehe; +Cc: 41180

[-- Attachment #1: Type: text/plain, Size: 1346 bytes --]

Hi Mathieu,

Thanks a lot for taking so much time to help me out and review this
patch.

Following your previous mail, I'm currently writing a test. I may follow
NFS's tests rather than CUPS -- (some of) NFS' tests just checks from
within the marionette that the service has been started, while CUPS
verifies from the outside that an external service is correctly running.

While I do prefer the CUPS test -- verify at the "user level" that the
service is provided -- it seems very complex to me to test cachefilesd
at a high level with a binary decision and no false positive. Venues for
this could be:

- maybe an NFS mount with the fsc option when cachefilesd is not
  activated will fail -- I need to check that;

- or maybe mounting some NFS share with fsc, accessing it, and checking
  afterwards that the cache has been filled by cached data -- this is
  getting complex though, and probably not a clear-cut scenario.

I don't know how high you will set the bar and if a simple 'check that
the daemon is running' would be sufficient to you :)

Thanks a lot for the various documentation pointers and style
recommendation. I really appreciate all of this!

I will provide a comprehensive patch with your changes integrated, and a
test, as soon as i am happy with it -- or just give up writing the
perfect test.

Kind regards,
Jean-Baptiste

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#41180] [PATCH] Add cachefilesd service.
  2020-05-20 20:39   ` Jean-Baptiste Note
@ 2020-05-23  6:44     ` Mathieu Othacehe
  2020-09-02 14:58     ` Mathieu Othacehe
  1 sibling, 0 replies; 9+ messages in thread
From: Mathieu Othacehe @ 2020-05-23  6:44 UTC (permalink / raw)
  To: Jean-Baptiste Note; +Cc: 41180


Hello Jean-Baptiste,

> Thanks a lot for the various documentation pointers and style
> recommendation. I really appreciate all of this!
>
> I will provide a comprehensive patch with your changes integrated, and a
> test, as soon as i am happy with it -- or just give up writing the
> perfect test.

Great :) I think that checking that the module is loaded, and the
cachefilesd service is running is already a first step. You can also
check for some properties in the sysfs, but unless you're already there,
maybe you don't need to push much further!

Thanks,

Mathieu




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#41180] [PATCH] Add cachefilesd service.
  2020-05-20 20:39   ` Jean-Baptiste Note
  2020-05-23  6:44     ` Mathieu Othacehe
@ 2020-09-02 14:58     ` Mathieu Othacehe
  1 sibling, 0 replies; 9+ messages in thread
From: Mathieu Othacehe @ 2020-09-02 14:58 UTC (permalink / raw)
  To: Jean-Baptiste Note; +Cc: 41180


Hello Jean-Baptiste,

> Thanks a lot for the various documentation pointers and style
> recommendation. I really appreciate all of this!
>
> I will provide a comprehensive patch with your changes integrated, and a
> test, as soon as i am happy with it -- or just give up writing the
> perfect test.

Any progress on that one :)? Do not hesitate to ask some help here or on
#guix if needed.

Thanks,

Mathieu




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#41180] [PATCH v2] gnu: services: Add cachefilesd service. (Closes: #41180)
  2020-05-10 19:19 [bug#41180] [PATCH] Add cachefilesd service Jean-Baptiste Note
                   ` (2 preceding siblings ...)
  2020-05-19 12:12 ` Mathieu Othacehe
@ 2023-03-09 12:24 ` Felix Lechner via Guix-patches via
  2023-04-30  4:10 ` bug#41180: Closing in favor of Bug#63182 Felix Lechner via Guix-patches via
  4 siblings, 0 replies; 9+ messages in thread
From: Felix Lechner via Guix-patches via @ 2023-03-09 12:24 UTC (permalink / raw)
  To: 41180; +Cc: Bruno Victal, Felix Lechner

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 <mirai@makinata.eu>
---
 doc/guix.texi             |  90 +++++++++++++++++
 gnu/local.mk              |   1 +
 gnu/services/linux.scm    | 200 +++++++++++++++++++++++++++++++++++++-
 gnu/tests/cachefilesd.scm |  71 ++++++++++++++
 4 files changed, 361 insertions(+), 1 deletion(-)
 create mode 100644 gnu/tests/cachefilesd.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index 6671ba9305..c1a68707d2 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -113,6 +113,7 @@ Copyright @copyright{} 2022⁠–⁠2023 Bruno Victal@*
 Copyright @copyright{} 2022 Ivan Vilata-i-Balaguer@*
 Copyright @copyright{} 2023 Giacomo Leidi@*
 Copyright @copyright{} 2022 Antero Mejr@*
+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
@@ -37473,6 +37474,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 6c5a9ce024..a4e0e4ec55 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -759,6 +759,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 60e2093e1d..e581291a7b 100644
--- a/gnu/services/linux.scm
+++ b/gnu/services/linux.scm
@@ -5,6 +5,7 @@
 ;;; Copyright © 2021 raid5atemyhomework <raid5atemyhomework@protonmail.com>
 ;;; Copyright © 2021 B. Wilson <elaexuotee@wilsonb.com>
 ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz>
+;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -30,12 +31,14 @@ (define-module (gnu services linux)
   #:use-module (guix ui)
   #:use-module (gnu services)
   #:use-module (gnu services base)
+  #:use-module (gnu services configuration)
   #:use-module (gnu services shepherd)
   #:use-module (gnu packages linux)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-34)
   #:use-module (srfi srfi-35)
+  #:use-module (ice-9 format)
   #:use-module (ice-9 match)
   #:export (earlyoom-configuration
             earlyoom-configuration?
@@ -52,6 +55,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?
@@ -198,6 +223,179 @@ (define kernel-module-loader-service-type
    (extend append)
    (default-value '())))
 
+\f
+;;;
+;;; 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."
+   empty-serializer)
+
+  ;; command-line options
+  (debug-output?
+   (boolean #f)
+   "Print debugging output to stderr."
+   empty-serializer)
+
+  (use-syslog?
+   (boolean #t)
+   "Log to syslog facility instead of stdout."
+   empty-serializer)
+
+  ;; culling is part of the configuration file
+  ;; despite the name of the command-line option
+  (scan?
+   (boolean #t)
+   "Scan for cachable objects."
+   empty-serializer)
+
+  ;; sole required field in the configuration file
+  (cache-directory
+   maybe-string
+   "Location of the cache directory."
+   (make-option-serializer 'dir))
+
+  (cache-name
+   (maybe-string "CacheFiles")
+   "Name of cache (keep unique)."
+   (make-option-serializer 'tag))
+
+  (security-context
+   maybe-string
+   "SELinux security context."
+   (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."
+   (make-percentage-threshold-serializer 'brun))
+
+  (pause-culling-for-file-percentage
+   (maybe-non-negative-integer 7)
+   "Pause culling when available files exceed this percentage."
+   (make-percentage-threshold-serializer 'frun))
+
+  (resume-culling-for-block-percentage
+   (maybe-non-negative-integer 5)
+   "Start culling when available blocks drop below this percentage."
+   (make-percentage-threshold-serializer 'bcull))
+
+  (resume-culling-for-file-percentage
+   (maybe-non-negative-integer 5)
+   "Start culling when available files drop below this percentage."
+   (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."
+   (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."
+   (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."
+   (make-option-serializer 'culltable))
+
+  (cull?
+   (boolean #t)
+   "Create free space by culling (consumes system load)."
+   (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)."
+   empty-serializer)
+
+  (trace-function-exit-in-kernel-module?
+   (boolean #f)
+   "Trace function exit in the kernel module (for debugging)."
+   empty-serializer)
+
+  (trace-internal-checkpoints-in-kernel-module?
+   (boolean #f)
+   "Trace internal checkpoints in the kernel module (for debugging)."
+   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 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))))
+
 \f
 ;;;
 ;;; Reliability, Availability, and Serviceability (RAS) daemon
@@ -243,7 +441,7 @@ (define rasdaemon-service-type
 
 \f
 ;;;
-;;; Kernel module loader.
+;;; Zram device
 ;;;
 
 (define-record-type* <zram-device-configuration>
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 <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))))
-- 
2.39.1





^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#41180: Closing in favor of Bug#63182
  2020-05-10 19:19 [bug#41180] [PATCH] Add cachefilesd service Jean-Baptiste Note
                   ` (3 preceding siblings ...)
  2023-03-09 12:24 ` [bug#41180] [PATCH v2] gnu: services: Add cachefilesd service. (Closes: #41180) Felix Lechner via Guix-patches via
@ 2023-04-30  4:10 ` Felix Lechner via Guix-patches via
  4 siblings, 0 replies; 9+ messages in thread
From: Felix Lechner via Guix-patches via @ 2023-04-30  4:10 UTC (permalink / raw)
  To: 41180-done

Hi,

This bug is too old to trigger a CI job. The patch also needed
adjustments. Please check Bug#63182 for more progress.

Closing this bug. Thanks!

Kind regards
Felix




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-04-30  4:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-10 19:19 [bug#41180] [PATCH] Add cachefilesd service Jean-Baptiste Note
2020-05-10 19:27 ` Jean-Baptiste Note
2020-05-11 15:06 ` Mathieu Othacehe
2020-05-19 12:12 ` Mathieu Othacehe
2020-05-20 20:39   ` Jean-Baptiste Note
2020-05-23  6:44     ` Mathieu Othacehe
2020-09-02 14:58     ` Mathieu Othacehe
2023-03-09 12:24 ` [bug#41180] [PATCH v2] gnu: services: Add cachefilesd service. (Closes: #41180) Felix Lechner via Guix-patches via
2023-04-30  4:10 ` bug#41180: Closing in favor of Bug#63182 Felix Lechner via Guix-patches via

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.