1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.nfs.server; 8 9 exports = pkgs.writeText "exports" cfg.exports; 10 11in 12 13{ 14 imports = [ 15 (mkRenamedOptionModule [ "services" "nfs" "lockdPort" ] [ "services" "nfs" "server" "lockdPort" ]) 16 (mkRenamedOptionModule [ "services" "nfs" "statdPort" ] [ "services" "nfs" "server" "statdPort" ]) 17 ]; 18 19 ###### interface 20 21 options = { 22 23 services.nfs = { 24 25 server = { 26 enable = mkOption { 27 type = types.bool; 28 default = false; 29 description = '' 30 Whether to enable the kernel's NFS server. 31 ''; 32 }; 33 34 extraNfsdConfig = mkOption { 35 type = types.str; 36 default = ""; 37 description = '' 38 Extra configuration options for the [nfsd] section of /etc/nfs.conf. 39 ''; 40 }; 41 42 exports = mkOption { 43 type = types.lines; 44 default = ""; 45 description = '' 46 Contents of the /etc/exports file. See 47 <citerefentry><refentrytitle>exports</refentrytitle> 48 <manvolnum>5</manvolnum></citerefentry> for the format. 49 ''; 50 }; 51 52 hostName = mkOption { 53 type = types.nullOr types.str; 54 default = null; 55 description = '' 56 Hostname or address on which NFS requests will be accepted. 57 Default is all. See the <option>-H</option> option in 58 <citerefentry><refentrytitle>nfsd</refentrytitle> 59 <manvolnum>8</manvolnum></citerefentry>. 60 ''; 61 }; 62 63 nproc = mkOption { 64 type = types.int; 65 default = 8; 66 description = '' 67 Number of NFS server threads. Defaults to the recommended value of 8. 68 ''; 69 }; 70 71 createMountPoints = mkOption { 72 type = types.bool; 73 default = false; 74 description = "Whether to create the mount points in the exports file at startup time."; 75 }; 76 77 mountdPort = mkOption { 78 type = types.nullOr types.int; 79 default = null; 80 example = 4002; 81 description = '' 82 Use fixed port for rpc.mountd, useful if server is behind firewall. 83 ''; 84 }; 85 86 lockdPort = mkOption { 87 type = types.nullOr types.int; 88 default = null; 89 example = 4001; 90 description = '' 91 Use a fixed port for the NFS lock manager kernel module 92 (<literal>lockd/nlockmgr</literal>). This is useful if the 93 NFS server is behind a firewall. 94 ''; 95 }; 96 97 statdPort = mkOption { 98 type = types.nullOr types.int; 99 default = null; 100 example = 4000; 101 description = '' 102 Use a fixed port for <command>rpc.statd</command>. This is 103 useful if the NFS server is behind a firewall. 104 ''; 105 }; 106 107 }; 108 109 }; 110 111 }; 112 113 114 ###### implementation 115 116 config = mkIf cfg.enable { 117 118 services.nfs.extraConfig = '' 119 [nfsd] 120 threads=${toString cfg.nproc} 121 ${optionalString (cfg.hostName != null) "host=${cfg.hostName}"} 122 ${cfg.extraNfsdConfig} 123 124 [mountd] 125 ${optionalString (cfg.mountdPort != null) "port=${toString cfg.mountdPort}"} 126 127 [statd] 128 ${optionalString (cfg.statdPort != null) "port=${toString cfg.statdPort}"} 129 130 [lockd] 131 ${optionalString (cfg.lockdPort != null) '' 132 port=${toString cfg.lockdPort} 133 udp-port=${toString cfg.lockdPort} 134 ''} 135 ''; 136 137 services.rpcbind.enable = true; 138 139 boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd 140 141 environment.etc.exports.source = exports; 142 143 systemd.services.nfs-server = 144 { enable = true; 145 wantedBy = [ "multi-user.target" ]; 146 147 preStart = 148 '' 149 mkdir -p /var/lib/nfs/v4recovery 150 ''; 151 }; 152 153 systemd.services.nfs-mountd = 154 { enable = true; 155 restartTriggers = [ exports ]; 156 157 preStart = 158 '' 159 mkdir -p /var/lib/nfs 160 161 ${optionalString cfg.createMountPoints 162 '' 163 # create export directories: 164 # skip comments, take first col which may either be a quoted 165 # "foo bar" or just foo (-> man export) 166 sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \ 167 | xargs -d '\n' mkdir -p 168 '' 169 } 170 ''; 171 }; 172 173 }; 174 175}