summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi85
-rw-r--r--gnu/services/base.scm121
2 files changed, 200 insertions, 6 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index bb52cf713f..00737850fd 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4177,10 +4177,91 @@ tool suite.)
 the ``message of the day''.
 @end deffn
 
-@deffn {Monadic Procedure} nscd-service [#:glibc glibc]
-Return a service that runs libc's name service cache daemon (nscd).
+@cindex name service cache daemon
+@cindex nscd
+@deffn {Monadic Procedure} nscd-service [@var{config}] [#:glibc glibc]
+Return a service that runs libc's name service cache daemon (nscd) with the
+given @var{config}---an @code{<nscd-configuration>} object.
 @end deffn
 
+@defvr {Scheme Variable} %nscd-default-configuration
+This is the default @code{<nscd-configuration>} value (see below) used
+by @code{nscd-service}.  This uses the caches defined by
+@var{%nscd-default-caches}; see below.
+@end defvr
+
+@deftp {Data Type} nscd-configuration
+This is the type representing the name service cache daemon (nscd)
+configuration.
+
+@table @asis
+
+@item @code{log-file} (default: @code{"/var/log/nscd.log"})
+Name of nscd's log file.  This is where debugging output goes when
+@code{debug-level} is strictly positive.
+
+@item @code{debug-level} (default: @code{0})
+Integer denoting the debugging levels.  Higher numbers mean more
+debugging output is logged.
+
+@item @code{caches} (default: @var{%nscd-default-caches})
+List of @code{<nscd-cache>} objects denoting things to be cached; see
+below.
+
+@end table
+@end deftp
+
+@deftp {Data Type} nscd-cache
+Data type representing a cache database of nscd and its parameters.
+
+@table @asis
+
+@item @code{database}
+This is a symbol representing the name of the database to be cached.
+Valid values are @code{passwd}, @code{group}, @code{hosts}, and
+@code{services}, which designate the corresponding NSS database
+(@pxref{NSS Basics,,, libc, The GNU C Library Reference Manual}).
+
+@item @code{positive-time-to-live}
+@itemx @code{negative-time-to-live} (default: @code{20})
+A number representing the number of seconds during which a positive or
+negative lookup result remains in cache.
+
+@item @code{check-files?} (default: @code{#t})
+Whether to check for updates of the files corresponding to
+@var{database}.
+
+For instance, when @var{database} is @code{hosts}, setting this flag
+instructs nscd to check for updates in @file{/etc/hosts} and to take
+them into account.
+
+@item @code{persistent?} (default: @code{#t})
+Whether the cache should be stored persistently on disk.
+
+@item @code{shared?} (default: @code{#t})
+Whether the cache should be shared among users.
+
+@item @code{max-database-size} (default: 32@tie{}MiB)
+Maximum size in bytes of the database cache.
+
+@c XXX: 'suggested-size' and 'auto-propagate?' seem to be expert
+@c settings, so leave them out.
+
+@end table
+@end deftp
+
+@defvr {Scheme Variable} %nscd-default-caches
+List of @code{<nscd-cache>} objects used by default by
+@code{nscd-configuration} (see above.)
+
+It enables persistent and aggressive caching of service and host name
+lookups.  The latter provides better host name lookup performance,
+resilience in the face of unreliable name servers, and also better
+privacy---often the result of host name lookups is in local cache, so
+external name servers do not even need to be queried.
+@end defvr
+
+
 @deffn {Monadic Procedure} syslog-service
 Return a service that runs @code{syslogd} with reasonable default
 settings.
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 712222bdde..95edba6e7c 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -33,8 +33,10 @@
                 #:select (mount-flags->bit-mask))
   #:use-module (guix gexp)
   #:use-module (guix monads)
+  #:use-module (guix records)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-26)
+  #:use-module (ice-9 match)
   #:use-module (ice-9 format)
   #:export (root-file-system-service
             file-system-service
@@ -46,6 +48,16 @@
             console-font-service
             udev-service
             mingetty-service
+
+            %nscd-default-caches
+            %nscd-default-configuration
+
+            nscd-configuration
+            nscd-configuration?
+
+            nscd-cache
+            nscd-cache?
+
             nscd-service
             syslog-service
             guix-service
@@ -374,9 +386,110 @@ the ``message of the day''."
                                #:allow-empty-passwords? allow-empty-passwords?
                                #:motd motd)))))))
 
-(define* (nscd-service #:key (glibc (canonical-package glibc)))
-  "Return a service that runs libc's name service cache daemon (nscd)."
-  (with-monad %store-monad
+(define-record-type* <nscd-configuration> nscd-configuration
+  make-nscd-configuration
+  nscd-configuration?
+  (log-file    nscd-configuration-log-file        ;string
+               (default "/var/log/nscd.log"))
+  (debug-level nscd-debug-level                   ;integer
+               (default 0))
+  ;; TODO: See nscd.conf in glibc for other options to add.
+  (caches     nscd-configuration-caches           ;list of <nscd-cache>
+              (default %nscd-default-caches)))
+
+(define-record-type* <nscd-cache> nscd-cache make-nscd-cache
+  nscd-cache?
+  (database              nscd-cache-database)              ;symbol
+  (positive-time-to-live nscd-cache-positive-time-to-live) ;integer
+  (negative-time-to-live nscd-cache-negative-time-to-live
+                         (default 20))             ;integer
+  (suggested-size        nscd-cache-suggested-size ;integer ("default module
+                                                   ;of hash table")
+                         (default 211))
+  (check-files?          nscd-cache-check-files?  ;Boolean
+                         (default #t))
+  (persistent?           nscd-cache-persistent?   ;Boolean
+                         (default #t))
+  (shared?               nscd-cache-shared?       ;Boolean
+                         (default #t))
+  (max-database-size     nscd-cache-max-database-size ;integer
+                         (default (* 32 (expt 2 20))))
+  (auto-propagate?       nscd-cache-auto-propagate? ;Boolean
+                         (default #t)))
+
+(define %nscd-default-caches
+  ;; Caches that we want to enable by default.  Note that when providing an
+  ;; empty nscd.conf, all caches are disabled.
+  (list (nscd-cache (database 'hosts)
+
+                    ;; Aggressively cache the host name cache to improve
+                    ;; privacy and resilience.
+                    (positive-time-to-live (* 3600 12))
+                    (negative-time-to-live 20)
+                    (persistent? #t))
+
+        (nscd-cache (database 'services)
+
+                    ;; Services are unlikely to change, so we can be even more
+                    ;; aggressive.
+                    (positive-time-to-live (* 3600 24))
+                    (negative-time-to-live 3600)
+                    (check-files? #t)             ;check /etc/services changes
+                    (persistent? #t))))
+
+(define %nscd-default-configuration
+  ;; Default nscd configuration.
+  (nscd-configuration))
+
+(define (nscd.conf-file config)
+  "Return the @file{nscd.conf} configuration file for @var{config}, an
+@code{<nscd-configuration>} object."
+  (define cache->config
+    (match-lambda
+     (($ <nscd-cache> (= symbol->string database)
+                      positive-ttl negative-ttl size check-files?
+                      persistent? shared? max-size propagate?)
+      (string-append "\nenable-cache\t" database "\tyes\n"
+
+                     "positive-time-to-live\t" database "\t"
+                     (number->string positive-ttl) "\n"
+                     "negative-time-to-live\t" database "\t"
+                     (number->string negative-ttl) "\n"
+                     "suggested-size\t" database "\t"
+                     (number->string size) "\n"
+                     "check-files\t" database "\t"
+                     (if check-files? "yes\n" "no\n")
+                     "persistent\t" database "\t"
+                     (if persistent? "yes\n" "no\n")
+                     "shared\t" database "\t"
+                     (if shared? "yes\n" "no\n")
+                     "max-db-size\t" database "\t"
+                     (number->string max-size) "\n"
+                     "auto-propagate\t" database "\t"
+                     (if propagate? "yes\n" "no\n")))))
+
+  (match config
+    (($ <nscd-configuration> log-file debug-level caches)
+     (text-file "nscd.conf"
+                (string-append "\
+# Configuration of libc's name service cache daemon (nscd).\n\n"
+                               (if log-file
+                                   (string-append "logfile\t" log-file)
+                                   "")
+                               "\n"
+                               (if debug-level
+                                   (string-append "debug-level\t"
+                                                  (number->string debug-level))
+                                   "")
+                               "\n"
+                               (string-concatenate
+                                (map cache->config caches)))))))
+
+(define* (nscd-service #:optional (config %nscd-default-configuration)
+                       #:key (glibc (canonical-package glibc)))
+  "Return a service that runs libc's name service cache daemon (nscd) with the
+given @var{config}---an @code{<nscd-configuration>} object."
+  (mlet %store-monad ((nscd.conf (nscd.conf-file config)))
     (return (service
              (documentation "Run libc's name service cache daemon (nscd).")
              (provision '(nscd))
@@ -388,7 +501,7 @@ the ``message of the day''."
 
              (start #~(make-forkexec-constructor
                        (list (string-append #$glibc "/sbin/nscd")
-                             "-f" "/dev/null" "--foreground")))
+                             "-f" #$nscd.conf "--foreground")))
              (stop #~(make-kill-destructor))
 
              (respawn? #f)))))