Patchwork [(4)] gnu: Add NFS related services. (minor improvements to documentation; Added test to ensure that pipefs mount/umount succeeded()

login
register
mail settings
Submitter John Darrington
Date Oct. 11, 2016, 6:37 a.m.
Message ID <1476167844-28068-1-git-send-email-jmd@gnu.org>
Download mbox | patch
Permalink /patch/16418/
State New
Headers show

Comments

John Darrington - Oct. 11, 2016, 6:37 a.m.
Yet another patch.  Here I check that the mount/umount succeeds by testing that 
/var/lib/nfs/pipefs is a member of the list returned by (mount-points).

Regarding Ludo's suggestion to use a filesystem extention a la elogind - I have
looked into that possibility, but so far as I can see using a service extension 
does not allow a "provision" field, so I don't know how to make the other services
dependent upon it.  Also I don't see from the elogind example how to specify an 
alternative mount point and then to pass that mount point to dependent services.
(I cannot imagine why anyone would want to do that, but hey - guix is supposed to
be hackable!)   I'd be happy to change it later if someone can explain how to do it.





* gnu/services/nfs.scm (pipefs-service-type): New Variable,
(gss-service-type): New Variable, (idmap-service-type) New Variable.

* doc/guix.texi (Network File system): New Node.
---
 doc/guix.texi        | 100 +++++++++++++++++++++++++++++++++++++--
 gnu/services/nfs.scm | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 225 insertions(+), 4 deletions(-)
Ludovic Courtès - Oct. 11, 2016, 8:30 p.m.
Hi,

John Darrington <jmd@gnu.org> skribis:

> Yet another patch.  Here I check that the mount/umount succeeds by testing that 
> /var/lib/nfs/pipefs is a member of the list returned by (mount-points).

OK.

> Regarding Ludo's suggestion to use a filesystem extention a la elogind - I have
> looked into that possibility, but so far as I can see using a service extension 
> does not allow a "provision" field, so I don't know how to make the other services
> dependent upon it.  Also I don't see from the elogind example how to specify an 
> alternative mount point and then to pass that mount point to dependent services.
> (I cannot imagine why anyone would want to do that, but hey - guix is supposed to
> be hackable!)   I'd be happy to change it later if someone can explain how to do it.

Yes, let’s keep it for later.

For future reference, as I wrote in
<https://lists.gnu.org/archive/html/guix-devel/2016-09/msg01096.html>,
the Shepherd service corresponding to the file system object would be
called ‘file-system-/var/lib/nfs/pipefs’.  This is the name you would
write in ‘requirement’.

>
>
>
>
> * gnu/services/nfs.scm (pipefs-service-type): New Variable,
> (gss-service-type): New Variable, (idmap-service-type) New Variable.
>
> * doc/guix.texi (Network File system): New Node.

No need to capitalize “node” and “variable.”

OK with this patch, thank you!

Ludo’.

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index 57821c5..1f6e0bb 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -221,6 +221,7 @@  Services
 * Database Services::           SQL databases.
 * Mail Services::               IMAP, POP3, SMTP, and all that.
 * Web Services::                Web servers.
+* Network File System::         NFS related services.
 * Miscellaneous Services::      Other services.
 
 Defining Services
@@ -7647,6 +7648,7 @@  declaration.
 * Database Services::           SQL databases.
 * Mail Services::               IMAP, POP3, SMTP, and all that.
 * Web Services::                Web servers.
+* Network File System::         NFS related services.
 * Miscellaneous Services::      Other services.
 @end menu
 
@@ -10366,14 +10368,21 @@  directories are created when the service is activated.
 
 @end deffn
 
-@node Miscellaneous Services
-@subsubsection Miscellaneous Services
+@node Network File System
+@subsubsection Network File System
+@cindex NFS
 
+The @code{(gnu services nfs)} module provides the following services,
+which are most commonly used in relation to mounting or exporting
+directory trees as @dfn{network file systems} (NFS).
 
 @subsubheading RPC Bind Service
 @cindex rpcbind
 
-The @code{(gnu services nfs)} module provides the following:
+The RPC Bind service provides a facility to map program numbers into
+universal addresses.
+Many NFS related services use this facility.  Hence it is automatically
+started when a dependent service starts.
 
 @defvr {Scheme Variable} rpcbind-service-type
 A service type  for the RPC portmapper daemon.
@@ -10394,6 +10403,91 @@  instance.
 @end table
 @end deftp
 
+
+@subsubheading Pipefs Pseudo File System
+@cindex pipefs
+@cindex rpc_pipefs
+
+The pipefs file system is used to transfer NFS related data
+between the kernel and user space programs.
+
+@defvr {Scheme Variable} pipefs-service-type
+A service type for the pipefs pseudo file system.
+@end defvr
+
+@deftp {Data Type} pipefs-configuration
+Data type representing the configuration of the pipefs pseudo file system service.
+This type has the following parameters:
+@table @asis
+@item @code{mount-point} (default: @code{"/var/lib/nfs/rpc_pipefs"})
+The directory to which the file system is to be attached.
+@end table
+@end deftp
+
+
+@subsubheading GSS Daemon Service
+@cindex GSSD
+@cindex GSS
+@cindex global security system
+
+The @dfn{global security system} (GSS) daemon provides strong security for RPC
+based protocols.
+Before exchanging RPC requests an RPC client must establish a security
+context.  Typically this is done using the Kerberos command @command{kinit}
+or automatically at login time using PAM services.
+
+@defvr {Scheme Variable} gss-service-type
+A service type for the Global Security System (GSS) daemon.
+@end defvr
+
+@deftp {Data Type} gss-configuration
+Data type representing the configuration of the GSS daemon service.
+This type has the following parameters:
+@table @asis
+@item @code{nfs-utils} (default: @code{nfs-utils})
+The package in which the @command{rpc.gssd} command is to be found.
+
+@item @code{pipefs-directory} (default: @code{"/var/lib/nfs/rpc_pipefs"})
+The directory where the pipefs file system is mounted.
+
+@end table
+@end deftp
+
+
+@subsubheading IDMAP Daemon Service
+@cindex idmapd
+@cindex name mapper
+
+The idmap daemon service provides mapping between user IDs and user names.
+Typically it is required in order to access file systems mounted via NFSv4.
+
+@defvr {Scheme Variable} idmap-service-type
+A service type for the Identity Mapper (IDMAP) daemon.
+@end defvr
+
+@deftp {Data Type} idmap-configuration
+Data type representing the configuration of the IDMAP daemon service.
+This type has the following parameters:
+@table @asis
+@item @code{nfs-utils} (default: @code{nfs-utils})
+The package in which the @command{rpc.idmapd} command is to be found.
+
+@item @code{pipefs-directory} (default: @code{"/var/lib/nfs/rpc_pipefs"})
+The directory where the pipefs file system is mounted.
+
+@item @code{domain} (default: @code{#f})
+The local NFSv4 domain name.
+This must be a string or @code{#f}.
+If it is @code{#f} then the daemon will use the host's fully qualified domain name.
+
+@end table
+@end deftp
+
+
+@node Miscellaneous Services
+@subsubsection Miscellaneous Services
+
+
 @cindex lirc
 @subsubheading Lirc Service
 
diff --git a/gnu/services/nfs.scm b/gnu/services/nfs.scm
index b1e1f53..8f58920 100644
--- a/gnu/services/nfs.scm
+++ b/gnu/services/nfs.scm
@@ -20,11 +20,31 @@ 
   #:use-module (gnu)
   #:use-module (gnu services shepherd)
   #:use-module (gnu packages onc-rpc)
+  #:use-module (gnu packages linux)
   #:use-module (guix)
   #:use-module (guix records)
+  #:use-module (ice-9 match)
+  #:use-module (gnu build file-systems)
   #:export (rpcbind-service-type
             rpcbind-configuration
-            rpcbind-configuration?))
+            rpcbind-configuration?
+
+            pipefs-service-type
+            pipefs-configuration
+            pipefs-configuration?
+
+            idmap-service-type
+            idmap-configuration
+            idmap-configuration?
+
+            gss-service-type
+            gss-configuration
+            gss-configuration?))
+
+
+(define default-pipefs-directory "/var/lib/nfs/rpc_pipefs")
+
+
 
 (define-record-type* <rpcbind-configuration>
   rpcbind-configuration make-rpcbind-configuration
@@ -52,3 +72,110 @@ 
 
       (start #~(make-forkexec-constructor #$rpcbind-command))
       (stop #~(make-kill-destructor))))))
+
+
+
+(define-record-type* <pipefs-configuration>
+  pipefs-configuration make-pipefs-configuration
+  pipefs-configuration?
+  (mount-point           pipefs-configuration-mount-point
+                         (default default-pipefs-directory)))
+
+(define pipefs-service-type
+  (shepherd-service-type
+   'pipefs
+   (lambda (config)
+     (define pipefs-directory (pipefs-configuration-mount-point config))
+
+     (shepherd-service
+      (documentation "Mount the pipefs pseudo filesystem.")
+      (provision '(rpc-pipefs))
+
+      (start #~(lambda ()
+                 (mkdir-p #$pipefs-directory)
+                 (mount "rpc_pipefs" #$pipefs-directory "rpc_pipefs")
+                 (member #$pipefs-directory (mount-points))))
+
+      (stop #~(lambda (pid . args)
+                (umount #$pipefs-directory MNT_DETACH)
+                (not (member #$pipefs-directory (mount-points)))))))))
+
+
+
+(define-record-type* <gss-configuration>
+  gss-configuration make-gss-configuration
+  gss-configuration?
+  (pipefs-directory            gss-configuration-pipefs-directory
+                         (default default-pipefs-directory))
+  (nfs-utils             gss-configuration-gss
+                         (default nfs-utils)))
+
+(define gss-service-type
+  (shepherd-service-type
+   'gss
+   (lambda (config)
+     (define nfs-utils
+       (gss-configuration-gss config))
+
+     (define pipefs-directory
+       (gss-configuration-pipefs-directory config))
+
+     (define gss-command
+       #~(list (string-append #$nfs-utils "/sbin/rpc.gssd") "-f"
+               "-p" #$pipefs-directory))
+
+     (shepherd-service
+      (documentation "Start the RPC GSS daemon.")
+      (requirement '(rpcbind-daemon rpc-pipefs))
+      (provision '(gss-daemon))
+
+      (start #~(make-forkexec-constructor #$gss-command))
+      (stop #~(make-kill-destructor))))))
+
+
+
+(define-record-type* <idmap-configuration>
+  idmap-configuration make-idmap-configuration
+  idmap-configuration?
+  (pipefs-directory            idmap-configuration-pipefs-directory
+                         (default default-pipefs-directory))
+  (domain                idmap-configuration-domain
+                           (default #f))
+  (nfs-utils             idmap-configuration-idmap
+                         (default nfs-utils)))
+
+(define idmap-service-type
+  (shepherd-service-type
+   'idmap
+   (lambda (config)
+
+     (define nfs-utils
+       (idmap-configuration-idmap config))
+
+     (define pipefs-directory
+       (idmap-configuration-pipefs-directory config))
+
+     (define domain (idmap-configuration-domain config))
+
+     (define (idmap-config-file config)
+       (plain-file "idmapd.conf"
+                   (string-append
+                    "\n[General]\n"
+                    (if domain
+                        (format #f "Domain = ~a\n" domain))
+                    "\n[Mapping]\n"
+                    "Nobody-User = nobody\n"
+                    "Nobody-Group = nogroup\n")))
+
+     (define idmap-command
+       #~(list (string-append #$nfs-utils "/sbin/rpc.idmapd") "-f"
+               "-p" #$pipefs-directory
+               "-c" #$(idmap-config-file config)))
+
+     (shepherd-service
+       (documentation "Start the RPC IDMAP daemon.")
+       (requirement '(rpcbind-daemon rpc-pipefs))
+       (provision '(idmap-daemon))
+       (start #~(make-forkexec-constructor #$idmap-command))
+       (stop #~(make-kill-destructor))))))
+