diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index 734dba49dd4..249a6e8b2ab 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -413,6 +413,8 @@ sub shutdown { sub crash { my ($self) = @_; return unless $self->{booted}; + + $self->log("forced crash"); $self->sendMonitorCommand("quit"); diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index ba6b901b961..ccf147e2f4f 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -74,44 +74,64 @@ in ###### implementation - config = - mkAssert - (cfg.client.enable || cfg.server.enable -> config.services.portmap.enable) " - Please enable portmap (services.portmap.enable) to use nfsd. - " { + config = { - services.portmap.enable = mkAlways (cfg.client.enable || cfg.server.enable); + services.portmap.enable = cfg.client.enable || cfg.server.enable; + + environment.systemPackages = mkIf cfg.server.enable [ pkgs.nfsUtils ]; environment.etc = mkIf cfg.server.enable (singleton { source = exports; target = "exports"; }); + boot.kernelModules = mkIf cfg.server.enable [ "nfsd" ]; + jobs = optionalAttrs cfg.server.enable { nfsd = { description = "Kernel NFS server"; - startOn = "started portmap"; - stopOn = "stopped statd"; + startOn = "started networking"; + + path = [ pkgs.nfsUtils ]; preStart = '' - export PATH=${pkgs.nfsUtils}/sbin:$PATH - mkdir -p /var/lib/nfs - + start portmap || true + start mountd || true + # Create a state directory required by NFSv4. mkdir -p /var/lib/nfs/v4recovery - # exports file is ${exports} - # keep this comment so that this job is restarted whenever exports changes! - ${pkgs.nfsUtils}/sbin/exportfs -ra - - # rpc.nfsd needs the kernel support - ${config.system.sbin.modprobe}/sbin/modprobe nfsd || true + rpc.nfsd \ + ${if cfg.server.hostName != null then "-H ${cfg.server.hostName}" else ""} \ + ${builtins.toString cfg.server.nproc} + ''; - ${pkgs.sysvtools}/bin/mountpoint -q /proc/fs/nfsd \ - || ${pkgs.utillinux}/bin/mount -t nfsd none /proc/fs/nfsd + postStop = "rpc.nfsd 0"; + + postStart = + '' + start statd || true + ''; + }; + } + + // optionalAttrs cfg.server.enable + { mountd = + { description = "Kernel NFS server - mount daemon"; + + path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; + + preStart = + '' + start portmap || true + + mkdir -p /var/lib/nfs + touch /var/lib/nfs/rmtab + + mountpoint -q /proc/fs/nfsd || mount -t nfsd none /proc/fs/nfsd ${optionalString cfg.server.createMountPoints '' @@ -123,25 +143,14 @@ in '' } - ${pkgs.nfsUtils}/sbin/rpc.nfsd \ - ${if cfg.server.hostName != null then "-H ${cfg.server.hostName}" else ""} \ - ${builtins.toString cfg.server.nproc} + # exports file is ${exports} + # keep this comment so that this job is restarted whenever exports changes! + exportfs -ra ''; - postStop = "${pkgs.nfsUtils}/sbin/rpc.nfsd 0"; - }; - } - - // optionalAttrs cfg.server.enable - { mountd = - { description = "Kernel NFS server - mount daemon"; - - startOn = "started nfsd"; - stopOn = "stopped statd"; - daemonType = "fork"; - exec = "${pkgs.nfsUtils}/sbin/rpc.mountd -f /etc/exports"; + exec = "rpc.mountd -f /etc/exports"; }; } @@ -149,24 +158,22 @@ in { statd = { description = "Kernel NFS server - Network Status Monitor"; - startOn = if cfg.server.enable then - "started mountd and started nfsd" - else - "started portmap"; - stopOn = "stopping nfsd"; + path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; + + stopOn = "never"; # needed during shutdown preStart = '' + start portmap || true mkdir -p /var/lib/nfs mkdir -p /var/lib/nfs/sm mkdir -p /var/lib/nfs/sm.bak + sm-notify -d ''; daemonType = "fork"; - exec = "${pkgs.nfsUtils}/sbin/rpc.statd --no-notify"; - - postStart = "${pkgs.nfsUtils}/sbin/sm-notify -d"; + exec = "rpc.statd --no-notify"; }; }; diff --git a/modules/services/networking/portmap.nix b/modules/services/networking/portmap.nix index 3d887b7729d..a6d799ec377 100644 --- a/modules/services/networking/portmap.nix +++ b/modules/services/networking/portmap.nix @@ -71,7 +71,7 @@ in startOn = "started network-interfaces"; stopOn = "never"; - daemonType = "fork"; + daemonType = "fork"; # needed during shutdown path = [ portmap pkgs.netcat ]; diff --git a/tests/nfs.nix b/tests/nfs.nix index e8da5ce6770..413578ec8ff 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -8,7 +8,7 @@ let [ { mountPoint = "/data"; device = "server:/data"; fsType = "nfs"; - options = "bootwait"; + options = "bootwait,vers=3"; } ]; }; @@ -34,11 +34,9 @@ in testScript = '' - startAll; + $server->waitForJob("nfsd"); - $server->waitForJob("nfs-kernel-nfsd"); - $server->waitForJob("nfs-kernel-mountd"); - $server->waitForJob("nfs-kernel-statd"); + startAll; $client1->waitForJob("tty1"); # depends on filesystems $client1->succeed("echo bla > /data/foo"); @@ -48,15 +46,11 @@ in $client2->succeed("echo bla > /data/bar"); $server->succeed("test -e /data/bar"); - # Test whether restarting the ‘nfs-kernel-exports’ job works - # correctly. In Upstart 0.6.7 this fails because the jobs that - # depend on ‘nfs-kernel-exports’ are stopped but not restarted. - $server->succeed("restart nfs-kernel-exports"); - $client2->succeed("echo bla >> /data/bar"); + # Test whether restarting ‘nfsd’ works correctly. + $server->succeed("stop nfsd; start nfsd"); + $client2->succeed("echo bla >> /data/bar"); # will take 90 seconds due to the NFS grace period - # Test whether we can get a lock. !!! This step takes about 90 - # seconds because the NFS server waits that long after booting - # before accepting new locks. + # Test whether we can get a lock. $client2->succeed("time flock -n -s /data/lock true"); # Test locking: client 1 acquires an exclusive lock, so client 2 @@ -78,9 +72,7 @@ in $client1->succeed("touch /data/xyzzy"); $client1->fail("time flock -n -s /data/lock true"); - # Test whether unmounting during shutdown happens quickly. This - # requires portmap and statd to keep running during the - # shutdown. + # Test whether unmounting during shutdown happens quickly. my $t1 = time; $client1->shutdown; my $duration = time - $t1;