diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 4e7f62fc8f5..5ae3f4bd6e6 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -172,6 +172,10 @@ with lib; (mkRenamedOptionModule [ "services" "locate" "period" ] [ "services" "locate" "interval" ]) (mkRemovedOptionModule [ "services" "locate" "includeStore" ] "Use services.locate.prunePaths" ) + # nfs + (mkRenamedOptionModule [ "services" "nfs" "lockdPort" ] [ "services" "nfs" "server" "lockdPort" ]) + (mkRenamedOptionModule [ "services" "nfs" "statdPort" ] [ "services" "nfs" "server" "statdPort" ]) + # Options that are obsolete and have no replacement. (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "") (mkRemovedOptionModule [ "programs" "bash" "enable" ] "") diff --git a/nixos/modules/services/network-filesystems/nfsd.nix b/nixos/modules/services/network-filesystems/nfsd.nix index ddc7258ce0b..4fafb7a1fdb 100644 --- a/nixos/modules/services/network-filesystems/nfsd.nix +++ b/nixos/modules/services/network-filesystems/nfsd.nix @@ -20,6 +20,7 @@ in server = { enable = mkOption { + type = types.bool; default = false; description = '' Whether to enable the kernel's NFS server. @@ -27,6 +28,7 @@ in }; exports = mkOption { + type = types.lines; default = ""; description = '' Contents of the /etc/exports file. See @@ -36,6 +38,7 @@ in }; hostName = mkOption { + type = types.nullOr types.str; default = null; description = '' Hostname or address on which NFS requests will be accepted. @@ -46,6 +49,7 @@ in }; nproc = mkOption { + type = types.int; default = 8; description = '' Number of NFS server threads. Defaults to the recommended value of 8. @@ -53,11 +57,13 @@ in }; createMountPoints = mkOption { + type = types.bool; default = false; description = "Whether to create the mount points in the exports file at startup time."; }; mountdPort = mkOption { + type = types.nullOr types.int; default = null; example = 4002; description = '' @@ -66,11 +72,26 @@ in }; lockdPort = mkOption { - default = 0; + type = types.nullOr types.int; + default = null; + example = 4001; description = '' - Fix the lockd port number. This can help setting firewall rules for NFS. + Use a fixed port for the NFS lock manager kernel module + (lockd/nlockmgr). This is useful if the + NFS server is behind a firewall. ''; }; + + statdPort = mkOption { + type = types.nullOr types.int; + default = null; + example = 4000; + description = '' + Use a fixed port for rpc.statd. This is + useful if the NFS server is behind a firewall. + ''; + }; + }; }; @@ -82,61 +103,42 @@ in config = mkIf cfg.enable { + services.nfs.extraConfig = '' + [nfsd] + threads=${toString cfg.nproc} + ${optionalString (cfg.hostName != null) "host=${cfg.hostName}"} + + [mountd] + ${optionalString (cfg.mountdPort != null) "port=${toString cfg.mountdPort}"} + + [statd] + ${optionalString (cfg.statdPort != null) "port=${toString cfg.statdPort}"} + + [lockd] + ${optionalString (cfg.lockdPort != null) '' + port=${toString cfg.lockdPort} + udp-port=${toString cfg.lockdPort} + ''} + ''; + services.rpcbind.enable = true; boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd - environment.systemPackages = [ pkgs.nfs-utils ]; - environment.etc.exports.source = exports; - boot.kernelModules = [ "nfsd" ]; - - systemd.services.nfsd = - { description = "NFS Server"; - + systemd.services.nfs-server = + { enable = true; wantedBy = [ "multi-user.target" ]; - - requires = [ "rpcbind.service" "mountd.service" ]; - after = [ "rpcbind.service" "mountd.service" "idmapd.service" ]; - before = [ "statd.service" ]; - - path = [ pkgs.nfs-utils ]; - - script = - '' - # Create a state directory required by NFSv4. - mkdir -p /var/lib/nfs/v4recovery - - ${pkgs.procps}/sbin/sysctl -w fs.nfs.nlm_tcpport=${builtins.toString cfg.lockdPort} - ${pkgs.procps}/sbin/sysctl -w fs.nfs.nlm_udpport=${builtins.toString cfg.lockdPort} - - rpc.nfsd \ - ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} \ - ${builtins.toString cfg.nproc} - ''; - - postStop = "rpc.nfsd 0"; - - serviceConfig.Type = "oneshot"; - serviceConfig.RemainAfterExit = true; }; - systemd.services.mountd = - { description = "NFSv3 Mount Daemon"; - - requires = [ "rpcbind.service" ]; - after = [ "rpcbind.service" "local-fs.target" ]; - - path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ]; + systemd.services.nfs-mountd = + { enable = true; + path = [ pkgs.nfs-utils ]; + restartTriggers = [ exports ]; preStart = '' - mkdir -p /var/lib/nfs - touch /var/lib/nfs/rmtab - - mountpoint -q /proc/fs/nfsd || mount -t nfsd none /proc/fs/nfsd - ${optionalString cfg.createMountPoints '' # create export directories: @@ -149,15 +151,6 @@ in exportfs -rav ''; - - restartTriggers = [ exports ]; - - serviceConfig.Type = "forking"; - serviceConfig.ExecStart = '' - @${pkgs.nfs-utils}/sbin/rpc.mountd rpc.mountd \ - ${if cfg.mountdPort != null then "-p ${toString cfg.mountdPort}" else ""} - ''; - serviceConfig.Restart = "always"; }; }; diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix index e9a7ccc721a..692034c0e37 100644 --- a/nixos/modules/tasks/filesystems/nfs.nix +++ b/nixos/modules/tasks/filesystems/nfs.nix @@ -24,6 +24,8 @@ let Method = nsswitch ''; + nfsConfFile = pkgs.writeText "nfs.conf" cfg.extraConfig; + cfg = config.services.nfs; in @@ -32,23 +34,12 @@ in ###### interface options = { - services.nfs = { - statdPort = mkOption { - default = null; - example = 4000; + extraConfig = mkOption { + type = types.lines; + default = ""; description = '' - Use a fixed port for rpc.statd. This is - useful if the NFS server is behind a firewall. - ''; - }; - lockdPort = mkOption { - default = null; - example = 4001; - description = '' - Use a fixed port for the NFS lock manager kernel module - (lockd/nlockmgr). This is useful if the - NFS server is behind a firewall. + Extra nfs-utils configuration. ''; }; }; @@ -62,69 +53,44 @@ in system.fsPackages = [ pkgs.nfs-utils ]; - boot.extraModprobeConfig = mkIf (cfg.lockdPort != null) '' - options lockd nlm_udpport=${toString cfg.lockdPort} nlm_tcpport=${toString cfg.lockdPort} - ''; - - boot.kernelModules = [ "sunrpc" ]; - boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; - # FIXME: should use upstream units from nfs-utils. + systemd.packages = [ pkgs.nfs-utils ]; + systemd.generator-packages = [ pkgs.nfs-utils ]; - systemd.services.statd = - { description = "NFSv3 Network Status Monitor"; + environment.etc = { + "idmapd.conf".source = idmapdConfFile; + "nfs.conf".source = nfsConfFile; + }; - path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ]; - - wants = [ "remote-fs-pre.target" ]; - before = [ "remote-fs-pre.target" ]; - wantedBy = [ "remote-fs.target" ]; - requires = [ "basic.target" "rpcbind.service" ]; - after = [ "basic.target" "rpcbind.service" ]; - - unitConfig.DefaultDependencies = false; # don't stop during shutdown - - preStart = - '' - mkdir -p ${nfsStateDir}/sm - mkdir -p ${nfsStateDir}/sm.bak - sm-notify -d - ''; - - serviceConfig.Type = "forking"; - serviceConfig.ExecStart = '' - @${pkgs.nfs-utils}/sbin/rpc.statd rpc.statd --no-notify \ - ${if cfg.statdPort != null then "-p ${toString cfg.statdPort}" else ""} - ''; - serviceConfig.Restart = "always"; + systemd.services.nfs-blkmap = + { restartTriggers = [ nfsConfFile ]; }; - systemd.services.idmapd = - { description = "NFSv4 ID Mapping Daemon"; + systemd.targets.nfs-client = + { wantedBy = [ "multi-user.target" "remote-fs.target" ]; + }; - path = [ pkgs.sysvtools pkgs.utillinux ]; + systemd.services.nfs-idmapd = + { restartTriggers = [ idmapdConfFile ]; + }; - wants = [ "remote-fs-pre.target" ]; - before = [ "remote-fs-pre.target" ]; - wantedBy = [ "remote-fs.target" ]; - requires = [ "rpcbind.service" ]; - after = [ "rpcbind.service" ]; + systemd.services.nfs-mountd = + { restartTriggers = [ nfsConfFile ]; + enable = mkDefault false; + }; - preStart = - '' - mkdir -p ${rpcMountpoint} - mount -t rpc_pipefs rpc_pipefs ${rpcMountpoint} - ''; + systemd.services.nfs-server = + { restartTriggers = [ nfsConfFile ]; + enable = mkDefault false; + }; - postStop = - '' - umount ${rpcMountpoint} - ''; + systemd.services.rpc-gssd = + { restartTriggers = [ nfsConfFile ]; + }; - serviceConfig.Type = "forking"; - serviceConfig.ExecStart = "@${pkgs.nfs-utils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}"; - serviceConfig.Restart = "always"; + systemd.services.rpc-statd = + { restartTriggers = [ nfsConfFile ]; }; };