From dbadf6e9c20bacb54a8d3df442f4e0069224a111 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 4 Jun 2010 14:22:11 +0000 Subject: [PATCH 01/45] =?UTF-8?q?*=20Use=20mountall=20to=20mount=20all=20f?= =?UTF-8?q?ilesystems=20and=20activate=20all=20swap=20devices=20=20=20duri?= =?UTF-8?q?ng=20boot.=20=20Mountall=20ensures=20that=20these=20are=20done?= =?UTF-8?q?=20in=20the=20right=20=20=20order.=20=20It's=20informed=20by=20?= =?UTF-8?q?udev=20about=20devices=20becoming=20available.=20=20It=20=20=20?= =?UTF-8?q?emits=20some=20Upstart=20events=20upon=20reaching=20certain=20s?= =?UTF-8?q?tates,=20in=20=20=20particular=20=E2=80=98local-filesystems?= =?UTF-8?q?=E2=80=99=20after=20all=20local=20filesystems=20have=20been=20?= =?UTF-8?q?=20=20mounted=20successfully,=20=E2=80=98remote-filesystems?= =?UTF-8?q?=E2=80=99=20after=20all=20network=20=20=20filesystems=20have=20?= =?UTF-8?q?been=20mounted,=20and=20=E2=80=98filesystem=E2=80=99=20(sic)=20?= =?UTF-8?q?when=20all=20=20=20filesystems=20have=20been=20mounted.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, if a filesystem fails to mount or doesn't exist, then the mingettys won't start and the boot will appear to hang. This is because mountall doesn't emit an event for failing filesystems and waits indefinitely for the filesystems to become available. * The ‘filesystems’ and ‘swap’ Upstart jobs are gone. (Support for encrypted swap devices is temporarily gone.) * Generate a proper /etc/fstab from the ‘fileSystems’ and ‘swapDevices’ options. svn path=/nixos/branches/boot-order/; revision=22148 --- modules/services/ttys/mingetty.nix | 2 +- modules/tasks/filesystems.nix | 142 ++++++++--------------------- modules/tasks/swap.nix | 75 ++------------- 3 files changed, 45 insertions(+), 174 deletions(-) diff --git a/modules/services/ttys/mingetty.nix b/modules/services/ttys/mingetty.nix index 445fdcd78ed..8299580a8cf 100644 --- a/modules/services/ttys/mingetty.nix +++ b/modules/services/ttys/mingetty.nix @@ -55,7 +55,7 @@ with pkgs.lib; # Generate a separate job for each tty. jobs = listToAttrs (map (tty: nameValuePair tty { - startOn = "started udev"; + startOn = "started udev and local-filesystems"; exec = "${pkgs.mingetty}/sbin/mingetty --loginprog=${pkgs.shadow}/bin/login --noclear ${tty}"; diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index d42a4449edc..791ecccf4c8 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -2,108 +2,6 @@ with pkgs.lib; -let - - fileSystems = config.fileSystems; - mount = config.system.sbin.mount; - - task = - '' - PATH=${pkgs.e2fsprogs}/sbin:${pkgs.utillinuxng}/sbin:$PATH - - newDevices=1 - - # If we mount any file system, we repeat this loop, because new - # mount opportunities may have become available (such as images - # for loopback mounts). - - while test -n "$newDevices"; do - newDevices= - - ${flip concatMapStrings fileSystems (fs: '' - for dummy in x; do # make `continue' work - mountPoint='${fs.mountPoint}' - device='${if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}"}' - fsType='${fs.fsType}' - - # A device is a pseudo-device (i.e. not an actual device - # node) if it's not an absolute path (e.g. an NFS server - # such as machine:/path), if it starts with // (a CIFS FS), - # a known pseudo filesystem (such as tmpfs), or the device - # is a directory (e.g. a bind mount). - isPseudo= - test "''${device:0:1}" != / -o "''${device:0:2}" = // -o "$fsType" = "tmpfs" \ - -o -d "$device" && isPseudo=1 - - if ! test -n "$isPseudo" -o -e "$device"; then - echo "skipping $device, doesn't exist (yet)" - continue - fi - - # !!! quick hack: if the mount point is already mounted, try - # a remount to change the options but nothing else. - if cat /proc/mounts | grep -F -q " $mountPoint "; then - if test "''${device:0:2}" != //; then - echo "remounting $device on $mountPoint" - ${mount}/bin/mount -t "$fsType" \ - -o remount,"${fs.options}" \ - "$device" "$mountPoint" || true - fi - continue - fi - - # If $device is already mounted somewhere else, unmount it first. - # !!! Note: we use /etc/mtab, not /proc/mounts, because mtab - # contains more accurate info when using loop devices. - - if test -z "$isPseudo"; then - - device=$(readlink -f "$device") - - prevMountPoint=$( - cat /etc/mtab \ - | grep "^$device " \ - | sed 's|^[^ ]\+ \+\([^ ]\+\).*|\1|' \ - ) - - if test "$prevMountPoint" = "$mountPoint"; then - echo "remounting $device on $mountPoint" - ${mount}/bin/mount -t "$fsType" \ - -o remount,"${fs.options}" \ - "$device" "$mountPoint" || true - continue - fi - - if test -n "$prevMountPoint"; then - echo "unmount $device from $prevMountPoint" - ${mount}/bin/umount "$prevMountPoint" || true - fi - - fi - - echo "mounting $device on $mountPoint" - - # !!! should do something with the result; also prevent repeated fscks. - if test -z "$isPseudo"; then - fsck -a "$device" || true - fi - - ${optionalString fs.autocreate - '' - mkdir -p "$mountPoint" - '' - } - - if ${mount}/bin/mount -t "$fsType" -o "${fs.options}" "$device" "$mountPoint"; then - newDevices=1 - fi - done - '')} - done - ''; - -in - { ###### interface @@ -221,12 +119,44 @@ in config = { # Add the mount helpers to the system path so that `mount' can find them. - environment.systemPackages = [pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils]; + environment.systemPackages = [ pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils pkgs.mountall ]; - jobs.filesystems = - { startOn = [ "new-devices" "ip-up" ]; + environment.etc = singleton + { source = pkgs.writeText "fstab" + '' + # This is a generated file. Do not edit! - script = task; + # Filesystems. + ${flip concatMapStrings config.fileSystems (fs: + (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") + + " " + fs.mountPoint + + " " + fs.fsType + + " " + fs.options + + " 0" + + " " + (if fs.mountPoint == "/" then "1" else "2") + + "\n" + )} + + # Swap devices. + ${flip concatMapStrings config.swapDevices (sw: + "${sw.device} none swap\n" + )} + ''; + target = "fstab"; + }; + + jobs.mountall = + { startOn = "started udev"; + + script = + '' + exec > /dev/console 2>&1 + export PATH=${config.system.sbin.mount}/bin:${pkgs.utillinux}/sbin:$PATH + ${pkgs.mountall}/sbin/mountall --verbose --debug + echo DONE + ''; + + extraConfig = "console owner"; task = true; }; diff --git a/modules/tasks/swap.nix b/modules/tasks/swap.nix index ab81185532e..a3f241fc8c5 100644 --- a/modules/tasks/swap.nix +++ b/modules/tasks/swap.nix @@ -2,12 +2,6 @@ with pkgs.lib; -let - - inherit (pkgs) cryptsetup utillinux; - -in - { ###### interface @@ -36,37 +30,31 @@ in options = {config, options, ...}: { options = { + device = mkOption { example = "/dev/sda3"; type = types.string; - description = '' - Path of the device. - ''; + description = "Path of the device."; }; label = mkOption { example = "swap"; type = types.string; - description = " + description = '' Label of the device. Can be used instead of device. - "; + ''; }; cipher = mkOption { default = false; example = true; type = types.bool; - description = " - Cipher the swap device to protect swapped data. This option + description = '' + Encrypt the swap device to protect swapped data. This option does not work with labels. - "; + ''; }; - command = mkOption { - description = " - Command used to activate the swap device. - "; - }; }; config = { @@ -75,59 +63,12 @@ in "/dev/disk/by-label/${config.label}" else mkNotdef; - - command = '' - if test -e "${config.device}"; then - ${if config.cipher then '' - plainDevice="${config.device}" - name="crypt$(echo "$plainDevice" | sed -e 's,/,.,g')" - device="/dev/mapper/$name" - if ! test -e "$device"; then - ${cryptsetup}/sbin/cryptsetup -c aes -s 128 -d /dev/urandom create "$name" "$plainDevice" - ${utillinux}/sbin/mkswap -f "$device" || true - fi - '' - else '' - device="${config.device}" - '' - } - device=$(readlink -f "$device") - # Add new swap devices. - if echo $unused | grep -q "^$device\$"; then - unused="$(echo $unused | grep -v "^$device\$" || true)" - else - ${utillinux}/sbin/swapon "$device" || true - fi - fi - ''; }; - + }; }; }; - ###### implementation - - config = { - - jobs.swap = - { task = true; - - startOn = ["startup" "new-devices"]; - - script = - '' - unused="$(sed '1d; s/ .*//' /proc/swaps)" - - ${toString (map (x: x.command) config.swapDevices)} - - # Remove remaining swap devices. - test -n "$unused" && ${utillinux}/sbin/swapoff $unused || true - ''; - }; - - }; - } From 5702557a65c32661944a2b9f8f08509a3b3a3d4f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 4 Jun 2010 15:35:32 +0000 Subject: [PATCH 02/45] * Put e2fsprogs etc. in mountall's $PATH so that fsck works. svn path=/nixos/branches/boot-order/; revision=22151 --- modules/config/system-path.nix | 2 -- modules/tasks/filesystems.nix | 13 +++++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/modules/config/system-path.nix b/modules/config/system-path.nix index d9074732418..7e04af21997 100644 --- a/modules/config/system-path.nix +++ b/modules/config/system-path.nix @@ -22,7 +22,6 @@ let pkgs.cpio pkgs.curl pkgs.diffutils - pkgs.e2fsprogs pkgs.eject # HAL depends on it anyway pkgs.findutils pkgs.gawk @@ -44,7 +43,6 @@ let pkgs.pciutils pkgs.perl pkgs.procps - pkgs.reiserfsprogs pkgs.rsync pkgs.seccure pkgs.strace diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 791ecccf4c8..387a093ee69 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -2,6 +2,13 @@ with pkgs.lib; +let + + # Packages that provide fsck backends. + fsPackages = [ pkgs.e2fsprogs pkgs.reiserfsprogs ]; + +in + { ###### interface @@ -119,7 +126,9 @@ with pkgs.lib; config = { # Add the mount helpers to the system path so that `mount' can find them. - environment.systemPackages = [ pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils pkgs.mountall ]; + environment.systemPackages = + [ pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils pkgs.mountall ] + ++ fsPackages; environment.etc = singleton { source = pkgs.writeText "fstab" @@ -151,7 +160,7 @@ with pkgs.lib; script = '' exec > /dev/console 2>&1 - export PATH=${config.system.sbin.mount}/bin:${pkgs.utillinux}/sbin:$PATH + export PATH=${config.system.sbin.mount}/bin:${makeSearchPath "sbin" ([pkgs.utillinux] ++ fsPackages)}:$PATH ${pkgs.mountall}/sbin/mountall --verbose --debug echo DONE ''; From 629078824740451e90b9b1d8865661882ac84b94 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Jun 2010 12:15:55 +0000 Subject: [PATCH 03/45] * If mountall fails to mount all filesystems, start an emergency shell to allow the user to fix or ignore the problem. svn path=/nixos/branches/boot-order/; revision=22165 --- modules/services/ttys/mingetty.nix | 2 +- modules/tasks/filesystems.nix | 56 ++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/modules/services/ttys/mingetty.nix b/modules/services/ttys/mingetty.nix index 8299580a8cf..239231b3699 100644 --- a/modules/services/ttys/mingetty.nix +++ b/modules/services/ttys/mingetty.nix @@ -55,7 +55,7 @@ with pkgs.lib; # Generate a separate job for each tty. jobs = listToAttrs (map (tty: nameValuePair tty { - startOn = "started udev and local-filesystems"; + startOn = "started udev and filesystem"; exec = "${pkgs.mingetty}/sbin/mingetty --loginprog=${pkgs.shadow}/bin/login --noclear ${tty}"; diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 387a093ee69..81e7446ff83 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -157,17 +157,67 @@ in jobs.mountall = { startOn = "started udev"; + task = true; + script = '' exec > /dev/console 2>&1 + echo "mounting filesystems..." export PATH=${config.system.sbin.mount}/bin:${makeSearchPath "sbin" ([pkgs.utillinux] ++ fsPackages)}:$PATH - ${pkgs.mountall}/sbin/mountall --verbose --debug - echo DONE + ${pkgs.mountall}/sbin/mountall ''; + }; + + # The `mount-failed' event is emitted synchronously, but we don't + # want `mountall' to wait for the emergency shell. So use this + # intermediate job to make the event asynchronous. + jobs.mountFailed = + { name = "mount-failed"; + task = true; + startOn = "mount-failed"; + script = + '' + start --no-wait emergency-shell \ + DEVICE="$DEVICE" MOUNTPOINT="$MOUNTPOINT" + ''; + }; + + jobs.emergencyShell = + { name = "emergency-shell"; + + task = true; + + stopOn = "filesystem"; extraConfig = "console owner"; - task = true; + script = + '' + exec < /dev/console > /dev/console 2>&1 + + cat <>> + + The filesystem \`$DEVICE' could not be mounted on \`$MOUNTPOINT'. + + Please do one of the following: + + - Repair the filesystem (\`fsck $DEVICE') and exit the emergency + shell to resume booting. + + - Ignore any failed filesystems and continue booting by running + \`initctl emit filesystem'. + + - Remove the failed filesystem from the system configuration in + /etc/nixos/configuration.nix and run \`nixos-rebuild switch'. + + EOF + + ${pkgs.shadow}/bin/login root || false + + initctl start --no-wait mountall + ''; }; }; From 085a47c88a0622c6e0132a5798c118f961038bf9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Jun 2010 12:16:59 +0000 Subject: [PATCH 04/45] * Bind mounts should have filesystem type "none" to prevent an invocation of "fsck.auto" at boot time. svn path=/nixos/branches/boot-order/; revision=22166 --- modules/virtualisation/qemu-vm.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 6e4e372c1bf..1c725d946f5 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -212,6 +212,7 @@ in } { mountPoint = "/nix/store"; device = "/hostfs/nix/store"; + fsType = "none"; options = "bind"; neededForBoot = true; } From 48fdc931a4ee497979db40f57f3bccca57bf889c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Jun 2010 12:39:50 +0000 Subject: [PATCH 05/45] * Run udevtrigger in a separate job. This speeds up booting because it allows the `mountall' task to start mounting filesystems as soon as udev is running and devices become available (i.e. it doesn't have to wait for all devices). This means that some jobs should depend on "stopped udevtrigger" instead of "started udev". svn path=/nixos/branches/boot-order/; revision=22167 --- modules/services/hardware/udev.nix | 11 ++++++++--- modules/services/x11/xserver.nix | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/services/hardware/udev.nix b/modules/services/hardware/udev.nix index d5955f88fbd..f730e0c1f17 100644 --- a/modules/services/hardware/udev.nix +++ b/modules/services/hardware/udev.nix @@ -185,8 +185,14 @@ in daemonType = "fork"; exec = "${udev}/sbin/udevd --daemon"; + }; - postStart = + jobs.udevtrigger = + { startOn = "started udev"; + + task = true; + + script = '' # Let udev create device nodes for all modules that have already # been loaded into the kernel (or for which support is built into @@ -200,9 +206,8 @@ in initctl emit -n new-devices ''; - }; - + }; } diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index a5a4c908bef..97c96ef8be9 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -408,7 +408,7 @@ in optional (elem "virtualbox" driverNames) kernelPackages.virtualboxGuestAdditions; jobs.xserver = - { startOn = if cfg.autorun then "started udev and started hal" else ""; + { startOn = if cfg.autorun then "filesystem and stopped udevtrigger and started hal" else ""; environment = { FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup From 23cc979f61882cd2fc75758e0419a4cde4666b81 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jun 2010 10:06:00 +0000 Subject: [PATCH 06/45] * Run `swapoff -a' during shutdown. Otherwise filesystems containing swapfiles cannot be unmounted or even remounted read-only. * In the remount, pass `-t none' to get a more informative error message if the filesystem is in use. svn path=/nixos/branches/boot-order/; revision=22179 --- modules/system/upstart-events/shutdown.nix | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/system/upstart-events/shutdown.nix b/modules/system/upstart-events/shutdown.nix index 9db5fafa46c..368886a6302 100644 --- a/modules/system/upstart-events/shutdown.nix +++ b/modules/system/upstart-events/shutdown.nix @@ -63,6 +63,10 @@ with pkgs.lib; # Set the hardware clock to the system time. echo "setting the hardware clock..." hwclock --systohc --utc + + + # Stop all swap devices. + swapoff -a # Unmount helper functions. @@ -99,7 +103,7 @@ with pkgs.lib; # `-i' is to workaround a bug in mount.cifs (it # doesn't recognise the `remount' option, and # instead mounts the FS again). - mount -n -i -o remount,ro "$mp" + mount -t none -n -i -o remount,ro none "$mp" # Note: don't use `umount -f'; it's very buggy. # (For instance, when applied to a bind-mount it @@ -118,8 +122,8 @@ with pkgs.lib; fi done done - - + + # Final sync. sync From 7c3ae9e716fac68645d3595a457a3d155049ade6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jun 2010 11:52:16 +0000 Subject: [PATCH 07/45] * During shutdown, warn explicitly about filesystems that could not be unmounted or remounted read-only. * Don't try to unmount / or /nix/store. svn path=/nixos/branches/boot-order/; revision=22181 --- modules/system/upstart-events/shutdown.nix | 52 +++++++++------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/modules/system/upstart-events/shutdown.nix b/modules/system/upstart-events/shutdown.nix index 368886a6302..283782fb4d1 100644 --- a/modules/system/upstart-events/shutdown.nix +++ b/modules/system/upstart-events/shutdown.nix @@ -69,31 +69,19 @@ with pkgs.lib; swapoff -a - # Unmount helper functions. - getMountPoints() { - cat /proc/mounts \ - | grep -v '^rootfs' \ - | sed 's|^[^ ]\+ \+\([^ ]\+\).*|\1|' \ - | grep -v '/proc\|/sys\|/dev' - } - - getDevice() { - local mountPoint=$1 - cat /proc/mounts \ - | grep -v '^rootfs' \ - | grep "^[^ ]\+ \+$mountPoint \+" \ - | sed 's|^\([^ ]\+\).*|\1|' - } - # Unmount file systems. We repeat this until no more file systems # can be unmounted. This is to handle loopback devices, file # systems mounted on other file systems and so on. tryAgain=1 while test -n "$tryAgain"; do tryAgain= - - for mp in $(getMountPoints); do - device=$(getDevice $mp) + failed= # list of mount points that couldn't be unmounted/remounted + + cp /proc/mounts /dev/.mounts # don't read /proc/mounts while it's changing + exec 4< /dev/.mounts + while read -u 4 device mp fstype options rest; do + if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /var/run/nscd ]; then continue; fi + echo "unmounting $mp..." # We need to remount,ro before attempting any @@ -103,27 +91,31 @@ with pkgs.lib; # `-i' is to workaround a bug in mount.cifs (it # doesn't recognise the `remount' option, and # instead mounts the FS again). - mount -t none -n -i -o remount,ro none "$mp" + success= + if mount -t "$fstype" -n -i -o remount,ro "device" "$mp"; then success=1; fi # Note: don't use `umount -f'; it's very buggy. # (For instance, when applied to a bind-mount it # unmounts the target of the bind-mount.) !!! But # we should use `-f' for NFS. - if umount -n "$mp"; then - if test "$mp" != /; then tryAgain=1; fi - fi - - # Hack: work around a bug in mount (mount -o remount on a - # loop device forgets the loop=/dev/loopN entry in - # /etc/mtab). - if echo "$device" | grep -q '/dev/loop'; then - echo "removing loop device $device..." - losetup -d "$device" + if [ "$mp" != / -a "$mp" != /nix/store ]; then + if umount -n "$mp"; then success=1; tryAgain=1; fi fi + + if [ -z "$success" ]; then failed="$failed $mp"; fi done done + # Warn about filesystems that could not be unmounted or + # remounted read-only. + if [ -n "$failed" ]; then + echo "warning: the following filesystems could not be unmounted:" + for mp in $failed; do echo " $mp"; done + sleep 5 + fi + + # Final sync. sync From 3eac0038003818a5a91a82da9039a5119ae292fa Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jun 2010 12:48:16 +0000 Subject: [PATCH 08/45] * Maintain /var/log/wtmp correctly during boot/shutdown. svn path=/nixos/branches/boot-order/; revision=22182 --- modules/system/boot/stage-2-init.sh | 2 ++ modules/system/upstart-events/runlevel.nix | 9 +++++++++ modules/system/upstart-events/shutdown.nix | 8 ++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index de9b136d02a..69c67de6e3a 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -134,9 +134,11 @@ export MODULE_DIR=@kernel@/lib/modules/ # Run any user-specified commands. @shell@ @postBootCommands@ + # For debugging Upstart. #@shell@ --login < /dev/console > /dev/console 2>&1 & + # Start Upstart's init. echo "starting Upstart..." PATH=/var/run/current-system/upstart/sbin exec init diff --git a/modules/system/upstart-events/runlevel.nix b/modules/system/upstart-events/runlevel.nix index 96864594509..10d108d9f40 100644 --- a/modules/system/upstart-events/runlevel.nix +++ b/modules/system/upstart-events/runlevel.nix @@ -4,6 +4,15 @@ with pkgs.lib; { + # After booting, go to runlevel 2. (NixOS doesn't really use + # runlevels, but this keeps wtmp happy.) + jobs.boot = + { name = "boot"; + startOn = "startup"; + task = true; + script = "telinit 2"; + }; + jobs.runlevel = { name = "runlevel"; diff --git a/modules/system/upstart-events/shutdown.nix b/modules/system/upstart-events/shutdown.nix index 283782fb4d1..2aad17cd1ac 100644 --- a/modules/system/upstart-events/shutdown.nix +++ b/modules/system/upstart-events/shutdown.nix @@ -58,8 +58,12 @@ with pkgs.lib; initctl emit -n startup exit 0 fi - - + + + # Write a shutdown record to wtmp while /var/log is still writable. + reboot --wtmp-only + + # Set the hardware clock to the system time. echo "setting the hardware clock..." hwclock --systohc --utc From a9e8bf6491ed3d0f618b5fbbaef6c58781d996a2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jun 2010 16:01:31 +0000 Subject: [PATCH 09/45] * nfsd: run rpc.nfsd from the pre-start script since it's not actually a daemon (it just starts some kernel threads). In the post-stop script, stop the kernel threads. * exportfs: fix the createMountPoints option. * Mount the nfsd filesystem on /proc/fs/nfsd because mountd prefers this. svn path=/nixos/branches/boot-order/; revision=22187 --- .../services/network-filesystems/nfs-kernel.nix | 16 ++++++++++++---- modules/tasks/filesystems.nix | 4 +--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index d28aef0ed52..1baa0305183 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -8,6 +8,8 @@ let cfg = config.services.nfsKernel; + exports = pkgs.writeText "exports" cfg.server.exports; + in { @@ -82,7 +84,7 @@ in }); environment.etc = mkIf cfg.server.enable (singleton - { source = pkgs.writeText "exports" cfg.server.exports; + { source = exports; target = "exports"; }); @@ -100,19 +102,23 @@ in '' export PATH=${pkgs.nfsUtils}/sbin:$PATH mkdir -p /var/lib/nfs + ${config.system.sbin.modprobe}/sbin/modprobe nfsd || true + ${pkgs.sysvtools}/bin/mountpoint -q /proc/fs/nfsd \ + || ${config.system.sbin.mount}/bin/mount -t nfsd none /proc/fs/nfsd + ${optionalString cfg.server.createMountPoints '' # create export directories: # skip comments, take first col which may either be a quoted # "foo bar" or just foo (-> man export) - sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${cfg.server.exports} \ + sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \ | xargs -d '\n' mkdir -p '' } - # exports file is ${cfg.server.exports} + # exports file is ${exports} # keep this comment so that this job is restarted whenever exports changes! exportfs -ra ''; @@ -128,7 +134,9 @@ in startOn = "started nfs-kernel-exports and started portmap"; stopOn = "stopping nfs-kernel-exports"; - exec = "${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.server.hostName != null then "-H ${cfg.server.hostName}" else ""} ${builtins.toString cfg.server.nproc}"; + preStart = "${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.server.hostName != null then "-H ${cfg.server.hostName}" else ""} ${builtins.toString cfg.server.nproc}"; + + postStop = "${pkgs.nfsUtils}/sbin/rpc.nfsd 0"; }; } diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 81e7446ff83..fe231d94ec8 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -142,7 +142,7 @@ in + " " + fs.fsType + " " + fs.options + " 0" - + " " + (if fs.mountPoint == "/" then "1" else "2") + + " " + (if fs.fsType == "none" then "0" else if fs.mountPoint == "/" then "1" else "2") + "\n" )} @@ -187,8 +187,6 @@ in task = true; - stopOn = "filesystem"; - extraConfig = "console owner"; script = From 2678f947fb5d094fe65e13660625e7cae5bdfd1a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jun 2010 16:02:22 +0000 Subject: [PATCH 10/45] * Add a test for the NFS server/client. svn path=/nixos/branches/boot-order/; revision=22188 --- tests/default.nix | 1 + tests/nfs.nix | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/nfs.nix diff --git a/tests/default.nix b/tests/default.nix index dfccce3851c..015eb071a15 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -12,6 +12,7 @@ with import ../lib/testing.nix { inherit nixpkgs services system; }; kde4 = makeTest (import ./kde4.nix); login = makeTest (import ./login.nix); nat = makeTest (import ./nat.nix); + nfs = makeTest (import ./nfs.nix); openssh = makeTest (import ./openssh.nix); portmap = makeTest (import ./portmap.nix); proxy = makeTest (import ./proxy.nix); diff --git a/tests/nfs.nix b/tests/nfs.nix new file mode 100644 index 00000000000..b0739ab92ab --- /dev/null +++ b/tests/nfs.nix @@ -0,0 +1,47 @@ +{ pkgs, ... }: + +{ + + nodes = + { client = + { config, pkgs, ... }: + { services.nfsKernel.client.enable = true; + fileSystems = pkgs.lib.mkOverride 50 {} + [ { mountPoint = "/data"; + device = "server:/data"; + fsType = "nfs"; + options = "bootwait"; + } + ]; + }; + + server = + { config, pkgs, ... }: + { services.nfsKernel.server.enable = true; + services.nfsKernel.server.exports = + '' + /data 192.168.1.0/255.255.255.0(rw,no_root_squash) + ''; + services.nfsKernel.server.createMountPoints = true; + }; + }; + + testScript = + '' + startAll; + + $server->waitForJob("nfs-kernel-nfsd"); + $server->waitForJob("nfs-kernel-mountd"); + $server->waitForJob("nfs-kernel-statd"); + + $client->waitForJob("nfs-kernel-statd"); + + $client->waitForJob("tty1"); # depends on filesystems + + $client->succeed("echo bar > /data/foo"); + $server->succeed("test -e /data/foo"); + + $client->shutdown; + ''; + +} From 5ddaf9b963cfe0819788846c6d90d514a93e09ec Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jun 2010 16:14:41 +0000 Subject: [PATCH 11/45] * Set `services.nfsKernel.client.enable' automatically if there is a filesystem with type "nfs" or "nfs4". svn path=/nixos/branches/boot-order/; revision=22189 --- modules/services/network-filesystems/nfs-kernel.nix | 2 +- tests/nfs.nix | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index 1baa0305183..2a9f78e7d2f 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -21,7 +21,7 @@ in services.nfsKernel = { client.enable = mkOption { - default = false; + default = any (fs: fs.fsType == "nfs" || fs.fsType == "nfs4") config.fileSystems; description = '' Whether to enable the kernel's NFS client daemons. ''; diff --git a/tests/nfs.nix b/tests/nfs.nix index b0739ab92ab..91a1005da94 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -5,8 +5,7 @@ nodes = { client = { config, pkgs, ... }: - { services.nfsKernel.client.enable = true; - fileSystems = pkgs.lib.mkOverride 50 {} + { fileSystems = pkgs.lib.mkOverride 50 {} [ { mountPoint = "/data"; device = "server:/data"; fsType = "nfs"; From c1ecdf708ffe6cc0c49a4b918bf20386e8afc032 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 10:51:05 +0000 Subject: [PATCH 12/45] * Put the hostname of the VM in the window title. svn path=/nixos/branches/boot-order/; revision=22191 --- modules/virtualisation/qemu-vm.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 1c725d946f5..2f554a591a8 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -123,7 +123,9 @@ let # -no-kvm-irqchip is needed to prevent the CIFS mount from # hanging the VM on x86_64. - exec ${pkgs.qemu_kvm}/bin/qemu-system-x86_64 -m ${toString config.virtualisation.memorySize} \ + exec ${pkgs.qemu_kvm}/bin/qemu-system-x86_64 \ + -name ${vmName} \ + -m ${toString config.virtualisation.memorySize} \ -no-kvm-irqchip \ -net nic,vlan=0,model=virtio -net user,vlan=0 -smb / \ -drive file=$NIX_DISK_IMAGE,if=virtio,boot=on,werror=report \ From d837ae49141abb62368f749cb003966773414d52 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 11:15:25 +0000 Subject: [PATCH 13/45] * portmap: don't use the -f flag to ensure that when the job reaches the "started" state, portmap is actually up. svn path=/nixos/branches/boot-order/; revision=22192 --- modules/services/networking/portmap.nix | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/services/networking/portmap.nix b/modules/services/networking/portmap.nix index 62d1c459f10..eead1c52ff0 100644 --- a/modules/services/networking/portmap.nix +++ b/modules/services/networking/portmap.nix @@ -54,7 +54,7 @@ in users.extraUsers = singleton { name = "portmap"; inherit uid; - description = "portmap daemon user"; + description = "Portmap daemon user"; home = "/var/empty"; }; @@ -66,14 +66,15 @@ in jobs.portmap = { description = "ONC RPC portmap"; - startOn = "ip-up"; + startOn = "started network-interfaces"; + + daemonType = "fork"; exec = '' - ${portmap}/sbin/portmap -f \ - ${if config.services.portmap.chroot == "" - then "" - else "-t \"${config.services.portmap.chroot}\""} \ + ${portmap}/sbin/portmap \ + ${optionalString (config.services.portmap.chroot != "") + "-t '${config.services.portmap.chroot}'"} \ ${if config.services.portmap.verbose then "-v" else ""} ''; }; From 156ba2def2b7734eaff34b84f5b4d3544ab13f89 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 13:15:15 +0000 Subject: [PATCH 14/45] * Don't use the "kvm-clock" clock source because it's unreliable. When starting multiple VMs, some will have perfectly synchronised clocks, while others will have their clocks run much slower (say, a factor of 5). svn path=/nixos/branches/boot-order/; revision=22195 --- modules/virtualisation/qemu-vm.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 2f554a591a8..6f8deebc69a 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -169,6 +169,9 @@ in boot.initrd.postDeviceCommands = '' + # Workaround for massive clock drift with the "kvm-clock" clock source. + echo hpet > /sys/devices/system/clocksource/clocksource0/current_clocksource + # Set up networking. Needed for CIFS mounting. ifconfig eth0 up 10.0.2.15 From 645ed8d3b46c839040c543a23f5be3d87e511a76 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 13:18:01 +0000 Subject: [PATCH 15/45] * Start NFS daemons in the right order as described in the nfs-utils README (i.e. for the server: exportfs, mountd, statd, nfsd, sm-notify; for the client: statd / sm-notify before mountall). This is important to allow locking to work correctly. svn path=/nixos/branches/boot-order/; revision=22196 --- .../network-filesystems/nfs-kernel.nix | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index 2a9f78e7d2f..f249b79357a 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -146,8 +146,8 @@ in description = "Kernel NFS server - mount daemon"; - startOn = "started nfs-kernel-nfsd and started portmap"; - stopOn = "stopping nfs-kernel-exports"; + startOn = "starting nfs-kernel-nfsd and started portmap"; + stopOn = "stopped nfs-kernel-nfsd"; exec = "${pkgs.nfsUtils}/sbin/rpc.mountd -F -f /etc/exports"; }; @@ -159,15 +159,32 @@ in description = "Kernel NFS server - Network Status Monitor"; - startOn = "${if cfg.server.enable then "started nfs-kernel-nfsd and " else ""} started portmap"; - stopOn = "stopping nfs-kernel-exports"; + startOn = "${if cfg.server.enable then "starting nfs-kernel-nfsd and " else ""} started portmap"; + stopOn = if cfg.server.enable then "stopped nfs-kernel-nfsd" else "starting shutdown"; preStart = '' mkdir -p /var/lib/nfs + mkdir -p /var/lib/nfs/sm + mkdir -p /var/lib/nfs/sm.bak ''; - exec = "${pkgs.nfsUtils}/sbin/rpc.statd -F"; + exec = "${pkgs.nfsUtils}/sbin/rpc.statd --foreground --no-notify"; + }; + } + + // optionalAttrs (cfg.client.enable || cfg.server.enable) + { nfs_kernel_sm_notify = + { name = "nfs-kernel-sm-notify"; + + description = "Kernel NFS server - Reboot notification"; + + startOn = "started nfs-kernel-statd" + + (if cfg.client.enable then " and starting mountall" else ""); + + task = true; + + exec = "${pkgs.nfsUtils}/sbin/sm-notify -d"; }; }; From 6e27ce8e8eba4f1734f78a39e91d34f91cf44bfa Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 13:18:49 +0000 Subject: [PATCH 16/45] * Test whether distributed locking works on NFS. svn path=/nixos/branches/boot-order/; revision=22197 --- tests/nfs.nix | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/tests/nfs.nix b/tests/nfs.nix index 91a1005da94..367a5bf3ab3 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -1,18 +1,25 @@ { pkgs, ... }: +let + + client = + { config, pkgs, ... }: + { fileSystems = pkgs.lib.mkOverride 50 {} + [ { mountPoint = "/data"; + device = "server:/data"; + fsType = "nfs"; + options = "bootwait"; + } + ]; + }; + +in + { nodes = - { client = - { config, pkgs, ... }: - { fileSystems = pkgs.lib.mkOverride 50 {} - [ { mountPoint = "/data"; - device = "server:/data"; - fsType = "nfs"; - options = "bootwait"; - } - ]; - }; + { client1 = client; + client2 = client; server = { config, pkgs, ... }: @@ -33,14 +40,24 @@ $server->waitForJob("nfs-kernel-mountd"); $server->waitForJob("nfs-kernel-statd"); - $client->waitForJob("nfs-kernel-statd"); - - $client->waitForJob("tty1"); # depends on filesystems - - $client->succeed("echo bar > /data/foo"); + $client1->waitForJob("tty1"); # depends on filesystems + $client1->succeed("echo bla > /data/foo"); $server->succeed("test -e /data/foo"); - $client->shutdown; + $client2->waitForJob("tty1"); # depends on filesystems + $client2->succeed("echo bla > /data/bar"); + $server->succeed("test -e /data/bar"); + + # 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. + $client2->succeed("time flock -n -s /data/lock true >&2"); + + # Test locking: client 1 acquires an exclusive lock, so client 2 + # should then fail to acquire a shared lock. + $client1->succeed("flock -x /data/lock -c 'touch locked; sleep 100000' &"); + $client1->waitForFile("locked"); + $client2->fail("flock -n -s /data/lock true"); ''; } From 94088e9b4865cf10981b69b6922fe8d70e16187b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 13:45:51 +0000 Subject: [PATCH 17/45] * Daemonise mountd/statd. svn path=/nixos/branches/boot-order/; revision=22198 --- modules/services/network-filesystems/nfs-kernel.nix | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index f249b79357a..c3974881f0a 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -149,7 +149,9 @@ in startOn = "starting nfs-kernel-nfsd and started portmap"; stopOn = "stopped nfs-kernel-nfsd"; - exec = "${pkgs.nfsUtils}/sbin/rpc.mountd -F -f /etc/exports"; + daemonType = "fork"; + + exec = "${pkgs.nfsUtils}/sbin/rpc.mountd -f /etc/exports"; }; } @@ -169,7 +171,9 @@ in mkdir -p /var/lib/nfs/sm.bak ''; - exec = "${pkgs.nfsUtils}/sbin/rpc.statd --foreground --no-notify"; + daemonType = "fork"; + + exec = "${pkgs.nfsUtils}/sbin/rpc.statd --no-notify"; }; } From b56b4c22d5ac3b453aafd25c927a17244219c88f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 13:46:18 +0000 Subject: [PATCH 18/45] * Test whether clients release their locks when they reboot. svn path=/nixos/branches/boot-order/; revision=22199 --- tests/nfs.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/nfs.nix b/tests/nfs.nix index 367a5bf3ab3..4a0ffe9a0d6 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -58,6 +58,12 @@ in $client1->succeed("flock -x /data/lock -c 'touch locked; sleep 100000' &"); $client1->waitForFile("locked"); $client2->fail("flock -n -s /data/lock true"); + + # Test whether client 2 obtains the lock if we reset client 1. + $client2->succeed("flock -s /data/lock -c 'echo acquired; touch locked' >&2 &"); + $client1->crash; + $client1->start; + $client2->waitForFile("locked"); ''; } From 483c322a6235e358563ce3db9057bb840cf85fd7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 13:46:52 +0000 Subject: [PATCH 19/45] * mustFail -> fail. * Added a function to crash a VM. svn path=/nixos/branches/boot-order/; revision=22200 --- lib/test-driver/Machine.pm | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index 5ff7bf6cea1..e0792ac928d 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -294,7 +294,7 @@ sub waitUntilFails { } -sub mustFail { +sub fail { my ($self, $command) = @_; my ($status, $out) = $self->execute($command); die "command `$command' unexpectedly succeeded" @@ -302,6 +302,11 @@ sub mustFail { } +sub mustFail { + fail @_; +} + + # Wait for an Upstart job to reach the "running" state. sub waitForJob { my ($self, $jobName) = @_; @@ -360,6 +365,16 @@ sub shutdown { } +sub crash { + my ($self) = @_; + return unless $self->{booted}; + + $self->sendMonitorCommand("quit"); + + $self->waitForShutdown; +} + + # Make the machine unreachable by shutting down eth1 (the multicast # interface used to talk to the other VMs). We keep eth0 up so that # the test driver can continue to talk to the machine. From e519b0652a0fd17a9aca6240ef017f10e23cc27e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 15:11:46 +0000 Subject: [PATCH 20/45] * Test whether locks survive a reboot of the server. svn path=/nixos/branches/boot-order/; revision=22201 --- tests/nfs.nix | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/nfs.nix b/tests/nfs.nix index 4a0ffe9a0d6..1e021eb10c1 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -51,7 +51,7 @@ in # 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. - $client2->succeed("time flock -n -s /data/lock true >&2"); + $client2->succeed("time flock -n -s /data/lock true"); # Test locking: client 1 acquires an exclusive lock, so client 2 # should then fail to acquire a shared lock. @@ -60,10 +60,17 @@ in $client2->fail("flock -n -s /data/lock true"); # Test whether client 2 obtains the lock if we reset client 1. - $client2->succeed("flock -s /data/lock -c 'echo acquired; touch locked' >&2 &"); + $client2->succeed("flock -x /data/lock -c 'echo acquired; touch locked; sleep 100000' >&2 &"); $client1->crash; $client1->start; $client2->waitForFile("locked"); + + # Test whether locks survive a reboot of the server. + $client1->waitForJob("tty1"); # depends on filesystems + $server->shutdown; + $server->start; + $client1->succeed("touch /data/xyzzy"); + $client1->fail("time flock -n -s /data/lock true"); ''; } From a5c433696cabd9e1f75e03b1de2df4de8b51acf2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jun 2010 22:29:06 +0000 Subject: [PATCH 21/45] * Put all of /var/run (not just /var/run/nscd) on a tmpfs to simplify shutdown. (Portmap and statd are needed during shutdown to unmount NFS volumes but have open files in /var/run.) * In the shutdown job, don't kill PIDs belonging to Upstart jobs that are still running. If they don't stop on the "starting shutdown" event, then they're needed during shutdown (such as portmap and statd). * NFS test: test whether the shutdown quickly unmounts NFS volumes (i.e. whether portmap and statd are still running). svn path=/nixos/branches/boot-order/; revision=22204 --- .../services/network-filesystems/nfs-kernel.nix | 2 +- modules/services/networking/portmap.nix | 1 + modules/system/activation/activation-script.nix | 11 ----------- modules/system/boot/stage-2-init.sh | 10 ++++++++++ modules/system/upstart-events/shutdown.nix | 17 +++++++++++------ tests/nfs.nix | 8 ++++++++ 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index c3974881f0a..e9c42237e0d 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -162,7 +162,7 @@ in description = "Kernel NFS server - Network Status Monitor"; startOn = "${if cfg.server.enable then "starting nfs-kernel-nfsd and " else ""} started portmap"; - stopOn = if cfg.server.enable then "stopped nfs-kernel-nfsd" else "starting shutdown"; + stopOn = "never"; preStart = '' diff --git a/modules/services/networking/portmap.nix b/modules/services/networking/portmap.nix index eead1c52ff0..9c0d559f867 100644 --- a/modules/services/networking/portmap.nix +++ b/modules/services/networking/portmap.nix @@ -67,6 +67,7 @@ in { description = "ONC RPC portmap"; startOn = "started network-interfaces"; + stopOn = "never"; daemonType = "fork"; diff --git a/modules/system/activation/activation-script.nix b/modules/system/activation/activation-script.nix index 5327740c631..637f2503466 100644 --- a/modules/system/activation/activation-script.nix +++ b/modules/system/activation/activation-script.nix @@ -75,7 +75,6 @@ let var = fullDepEntry '' # Various log/runtime directories. - mkdir -m 0755 -p /var/run touch /var/run/utmp # must exist chgrp ${toString config.ids.gids.utmp} /var/run/utmp @@ -84,16 +83,6 @@ let mkdir -m 0755 -p /var/run/nix/current-load # for distributed builds mkdir -m 0700 -p /var/run/nix/remote-stores - # Use a tmpfs for /var/run/nscd to ensure that / or /var can be - # unmounted or at least remounted read-only during shutdown. - # (Upstart 0.6 apparently uses nscd to do some name lookups, - # resulting in it holding some mmap mapping to deleted files in - # /var/run/nscd.) - if [ ! -e /var/run/nscd ]; then - mkdir -p /var/run/nscd - ${pkgs.utillinux}/bin/mount -t tmpfs -o "mode=755" none /var/run/nscd - fi - mkdir -m 0755 -p /var/log mkdir -m 0755 -p /var/log/upstart diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 69c67de6e3a..201c539bb6b 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -109,6 +109,16 @@ rm -rf /var/log/upstart rm -rf /nix/var/nix/chroots # recreated in activate-configuration.sh +# Use a tmpfs for /var/run to ensure that / or /var can be unmounted +# or at least remounted read-only during shutdown. (Upstart 0.6 +# apparently uses nscd to do some name lookups, resulting in it +# holding some mmap mapping to deleted files in /var/run/nscd. +# Similarly, portmap and statd have open files in /var/run and are +# needed during shutdown to unmount NFS volumes.) +mkdir -m 0755 -p /var/run +mount -t tmpfs -o "mode=755" none /var/run + + # Clear the resume device. if test -n "$resumeDevice"; then mkswap "$resumeDevice" || echo 'Failed to clear saved image.' diff --git a/modules/system/upstart-events/shutdown.nix b/modules/system/upstart-events/shutdown.nix index 2aad17cd1ac..1b2b63cd9c0 100644 --- a/modules/system/upstart-events/shutdown.nix +++ b/modules/system/upstart-events/shutdown.nix @@ -37,14 +37,19 @@ with pkgs.lib; sync - # Kill all remaining processes except init and this one. + # Kill all remaining processes except init, this one and any + # Upstart jobs that don't stop on the "starting shutdown" + # event, as these are necessary to complete the shutdown. + omittedPids=$(initctl list | sed -e 's/.*process \([0-9]\+\)/-o \1/;t;d') + #echo "saved PIDs: $omittedPids" + echo "sending the TERM signal to all processes..." - kill -TERM -1 + ${pkgs.sysvtools}/bin/killall5 -15 $job $omittedPids sleep 1 # wait briefly echo "sending the KILL signal to all processes..." - kill -KILL -1 + ${pkgs.sysvtools}/bin/killall5 -9 $job $omittedPids # If maintenance mode is requested, start a root shell, and @@ -71,8 +76,8 @@ with pkgs.lib; # Stop all swap devices. swapoff -a - - + + # Unmount file systems. We repeat this until no more file systems # can be unmounted. This is to handle loopback devices, file # systems mounted on other file systems and so on. @@ -84,7 +89,7 @@ with pkgs.lib; cp /proc/mounts /dev/.mounts # don't read /proc/mounts while it's changing exec 4< /dev/.mounts while read -u 4 device mp fstype options rest; do - if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /var/run/nscd ]; then continue; fi + if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /var/run ]; then continue; fi echo "unmounting $mp..." diff --git a/tests/nfs.nix b/tests/nfs.nix index 1e021eb10c1..f8d1cf951f3 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -71,6 +71,14 @@ in $server->start; $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. + my $t1 = time; + $client1->shutdown; + my $duration = time - $t1; + die "shutdown took too long ($duration seconds)" if $duration > 30; ''; } From 03f77ca82bb792abc77f7b8f968122e5cadf2f81 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 13 Jun 2010 20:59:49 +0000 Subject: [PATCH 22/45] * PostgreSQL / MySQL: depend on the "filesystem" event. svn path=/nixos/branches/boot-order/; revision=22247 --- modules/services/databases/mysql.nix | 2 +- modules/services/databases/postgresql.nix | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/services/databases/mysql.nix b/modules/services/databases/mysql.nix index 19c0bcc418a..9c97a15d751 100644 --- a/modules/services/databases/mysql.nix +++ b/modules/services/databases/mysql.nix @@ -100,7 +100,7 @@ in jobs.mysql = { description = "MySQL server"; - startOn = "started network-interfaces"; + startOn = "filesystem"; preStart = '' diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index ae6ac463dad..38d2568613e 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -28,9 +28,6 @@ let postgresql = postgresqlAndPlugins pkgs.postgresql; - startDependency = if config.services.gw6c.enable then - "gw6c" else "network-interfaces"; - run = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} postgres"; flags = optional cfg.enableTCPIP "-i"; @@ -120,10 +117,10 @@ in default = []; example = "pkgs.postgis"; # of course don't use a string here! description = '' - When this list contains elemnts a new store path is created. - Postgresql and the elments are symlinked into it. Then pg_config, + When this list contains elements a new store path is created. + PostgreSQL and the elments are symlinked into it. Then pg_config, postgres and pc_ctl are copied to make them use the new - $out/lib directory as pkglibdir. This make it possible to use postgis + $out/lib directory as pkglibdir. This makes it possible to use postgis without patching the .sql files which reference $libdir/postgis-1.5. ''; # Note: the duplication of executables is about 4MB size. @@ -160,7 +157,7 @@ in jobs.postgresql = { description = "PostgreSQL server"; - startOn = "started ${startDependency}"; + startOn = "filesystem"; environment = { TZ = config.time.timeZone; From e2dbfbdcf49380f3b972b65a64032c0e3b135373 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 13 Jun 2010 23:36:55 +0000 Subject: [PATCH 23/45] =?UTF-8?q?*=20Use=20writeback=20caching=20for=20vir?= =?UTF-8?q?tual=20disks=20instead=20of=20writethrough=20=20=20caching.=20?= =?UTF-8?q?=20This=20makes=20a=20huge=20performance=20difference=20(e.g.?= =?UTF-8?q?=20from=204=20MB/s=20=20=20`dd'=20throughput=20to=20140=20MB/s?= =?UTF-8?q?=20on=20the=20Hydra=20machines).=20=20As=20the=20QEMU=20=20=20m?= =?UTF-8?q?anual=20says:=20"Some=20block=20drivers=20perform=20badly=20wit?= =?UTF-8?q?h=20=20=20=E2=80=98cache=3Dwritethrough=E2=80=99,=20most=20nota?= =?UTF-8?q?bly,=20qcow2."?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/nixos/branches/boot-order/; revision=22248 --- modules/virtualisation/qemu-vm.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 6f8deebc69a..1cae5fef7c8 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -128,7 +128,7 @@ let -m ${toString config.virtualisation.memorySize} \ -no-kvm-irqchip \ -net nic,vlan=0,model=virtio -net user,vlan=0 -smb / \ - -drive file=$NIX_DISK_IMAGE,if=virtio,boot=on,werror=report \ + -drive file=$NIX_DISK_IMAGE,if=virtio,boot=on,cache=writeback,werror=report \ -kernel ${config.system.build.toplevel}/kernel \ -initrd ${config.system.build.toplevel}/initrd \ ${qemuGraphics} \ From 46ac1375a74112ee842fc208733b26d0541f2e28 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Jun 2010 16:15:17 +0000 Subject: [PATCH 24/45] * Don't use -smb and -no-kvm-irqchip. Maybe this makes VM builds more reliable. svn path=/nixos/branches/boot-order/; revision=22280 --- lib/test-driver/Machine.pm | 1 + modules/virtualisation/qemu-vm.nix | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index e0792ac928d..c7da5b1ecad 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -113,6 +113,7 @@ sub start { dup2(fileno($serialC), fileno(STDOUT)); dup2(fileno($serialC), fileno(STDERR)); $ENV{TMPDIR} = $self->{stateDir}; + $ENV{USE_TMPDIR} = 1; $ENV{QEMU_OPTS} = "-nographic -no-reboot -redir tcp:65535::514 -monitor unix:./monitor"; $ENV{QEMU_KERNEL_PARAMS} = "hostTmpDir=$ENV{TMPDIR}"; chdir $self->{stateDir} or die; diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 1cae5fef7c8..46462bbc6cc 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -113,21 +113,28 @@ let '' #! ${pkgs.stdenv.shell} - export PATH=${pkgs.samba}/sbin:$PATH - - NIX_DISK_IMAGE=''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}} + NIX_DISK_IMAGE=$(readlink -f ''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}}) if ! test -e "$NIX_DISK_IMAGE"; then - ${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" ${toString config.virtualisation.diskSize}M || exit 1 + ${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" \ + ${toString config.virtualisation.diskSize}M || exit 1 fi - - # -no-kvm-irqchip is needed to prevent the CIFS mount from - # hanging the VM on x86_64. + + # Start Samba (which wants to put its socket and config files in TMPDIR). + if [ -z "$TMPDIR" -o -z "$USE_TMPDIR" ]; then + TMPDIR=$(mktemp -d nix-vm-smbd.XXXXXXXXXX --tmpdir) + fi + cd $TMPDIR + + ${pkgs.vmTools.startSamba} + + # Start QEMU. exec ${pkgs.qemu_kvm}/bin/qemu-system-x86_64 \ -name ${vmName} \ -m ${toString config.virtualisation.memorySize} \ - -no-kvm-irqchip \ - -net nic,vlan=0,model=virtio -net user,vlan=0 -smb / \ + -net nic,vlan=0,model=virtio \ + -chardev socket,id=samba,path=./samba \ + -net user,vlan=0,guestfwd=tcp:10.0.2.4:139-chardev:samba \ -drive file=$NIX_DISK_IMAGE,if=virtio,boot=on,cache=writeback,werror=report \ -kernel ${config.system.build.toplevel}/kernel \ -initrd ${config.system.build.toplevel}/initrd \ From eab5aff8d0e1978675defa6d6c3fbb1f5876f994 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Jun 2010 18:00:56 +0000 Subject: [PATCH 25/45] * Drop the -no-kvm-irqchip flag here as well. svn path=/nixos/branches/boot-order/; revision=22281 --- lib/test-driver/Machine.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index c7da5b1ecad..77ff1734247 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -28,7 +28,7 @@ sub new { if (!$startCommand) { # !!! merge with qemu-vm.nix. $startCommand = - "qemu-system-x86_64 -m 384 -no-kvm-irqchip " . + "qemu-system-x86_64 -m 384 " . "-net nic,model=virtio -net user \$QEMU_OPTS "; $startCommand .= "-drive file=" . Cwd::abs_path($args->{hda}) . ",if=virtio,boot=on,werror=report " if defined $args->{hda}; From 69c71754041d0a4eaf807d1a1f33ea6852e04cd2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jun 2010 22:16:43 +0000 Subject: [PATCH 26/45] * During shutdown, don't unmount mount points that don't exist (in the current namespace). This prevents warnings about the aufs/tmpfs mounts from the initrd used by the installation CD. svn path=/nixos/branches/boot-order/; revision=22299 --- modules/system/upstart-events/shutdown.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/system/upstart-events/shutdown.nix b/modules/system/upstart-events/shutdown.nix index 1b2b63cd9c0..b7a004724be 100644 --- a/modules/system/upstart-events/shutdown.nix +++ b/modules/system/upstart-events/shutdown.nix @@ -89,7 +89,10 @@ with pkgs.lib; cp /proc/mounts /dev/.mounts # don't read /proc/mounts while it's changing exec 4< /dev/.mounts while read -u 4 device mp fstype options rest; do - if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /var/run ]; then continue; fi + # Skip various special filesystems. Non-existent + # mount points are typically tmpfs/aufs mounts from + # the initrd. + if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /var/run -o ! -e "$mp" ]; then continue; fi echo "unmounting $mp..." From a65b5ec81c699b21fc635ce909332dcda4346027 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jun 2010 22:18:26 +0000 Subject: [PATCH 27/45] * Added an option boot.loader.grub.extraConfig to add commands to grub.cfg before the menu entries. (This could also be done using `extraEntriesBeforeNixOS', but then you can't have entries *after* the main entry anymore.) * In the installer test, redirect GRUB output to the serial port. svn path=/nixos/branches/boot-order/; revision=22300 --- modules/installer/grub/grub-menu-builder.sh | 4 ++++ modules/installer/grub/grub.nix | 12 +++++++++++- tests/installer.nix | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/installer/grub/grub-menu-builder.sh b/modules/installer/grub/grub-menu-builder.sh index cf2041002e7..ecb69ceb263 100644 --- a/modules/installer/grub/grub-menu-builder.sh +++ b/modules/installer/grub/grub-menu-builder.sh @@ -216,6 +216,10 @@ extraEntries=`cat <> $tmp <> $tmp fi diff --git a/modules/installer/grub/grub.nix b/modules/installer/grub/grub.nix index 4217e0d481c..40c2ca60675 100644 --- a/modules/installer/grub/grub.nix +++ b/modules/installer/grub/grub.nix @@ -12,7 +12,8 @@ let inherit grub; inherit (pkgs) bash; path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep]; - inherit (config.boot.loader.grub) copyKernels extraEntries extraEntriesBeforeNixOS + inherit (config.boot.loader.grub) copyKernels + extraConfig extraEntries extraEntriesBeforeNixOS splashImage configurationLimit version default timeout; }; @@ -67,6 +68,15 @@ in ''; }; + extraConfig = mkOption { + default = ""; + example = "serial; terminal_output.serial"; + description = '' + Additional GRUB commands inserted in the configuration file + just before the menu entries. + ''; + }; + extraEntries = mkOption { default = ""; example = '' diff --git a/tests/installer.nix b/tests/installer.nix index a15b5587511..1f9ada808b2 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -40,6 +40,7 @@ let boot.loader.grub.version = 2; boot.loader.grub.device = "/dev/vda"; + boot.loader.grub.extraConfig = "serial; terminal_output.serial"; boot.initrd.kernelModules = [ "ext3" ]; fileSystems = [ ${fileSystems} ]; From ac22e5369fae1632b33ce86e53bf6f1f602c30dd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 18 Jun 2010 13:21:01 +0000 Subject: [PATCH 28/45] * Prevent tests from accessing the host's network accidentally. For instance, `nixos-rebuild' in the installer test does a `nix-pull' from nixos.org. svn path=/nixos/branches/boot-order/; revision=22325 --- modules/testing/test-instrumentation.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 5e62c698f27..dd61e68d9d1 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -80,6 +80,10 @@ in # serial port). services.syslogd.extraConfig = "*.*,kern.none /dev/ttyS0"; + # Prevent tests from accessing the Internet. + networking.defaultGateway = mkOverride 50 {} ""; + networking.nameservers = mkOverride 50 {} [ ]; + }; } From cf7e902283af830b3221da8b853753ab1ebbd1e5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 18 Jun 2010 15:30:36 +0000 Subject: [PATCH 29/45] * Intercept SIGCHLD to prevent accept() from waiting forever if QEMU dies before connecting to the monitor. svn path=/nixos/branches/boot-order/; revision=22328 --- lib/test-driver/Machine.pm | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index 77ff1734247..b5989d54076 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -121,10 +121,6 @@ sub start { die; } - # Wait until QEMU connects to the monitor. - accept($self->{monitor}, $monitorS) or die; - $self->waitForMonitorPrompt; - # Process serial line output. close $serialC; @@ -132,9 +128,9 @@ sub start { sub processSerialOutput { my ($self, $serialP) = @_; - $/ = "\r\n"; while (<$serialP>) { chomp; + s/\r$//; print STDERR $self->name, "# $_\n"; $self->{connectedQueue}->enqueue(1) if $_ eq "===UP==="; } @@ -142,7 +138,17 @@ sub start { $self->{connectedQueue}->enqueue(1); } - $self->log("vm running as pid $pid"); + # Wait until QEMU connects to the monitor. + eval { + local $SIG{CHLD} = sub { die "QEMU died prematurely\n"; }; + accept($self->{monitor}, $monitorS) or die; + }; + die "$@" if $@; + + $self->waitForMonitorPrompt; + + $self->log("QEMU running (pid $pid)"); + $self->{pid} = $pid; $self->{booted} = 1; } From 200a8b9a56ec3bf84cc6e023fcc1e1e98f2905cc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 18 Jun 2010 18:53:13 +0000 Subject: [PATCH 30/45] * Change the priority to make the NAT and Bittorrent tests work. svn path=/nixos/branches/boot-order/; revision=22329 --- modules/testing/test-instrumentation.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index dd61e68d9d1..84671028ba0 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -81,8 +81,8 @@ in services.syslogd.extraConfig = "*.*,kern.none /dev/ttyS0"; # Prevent tests from accessing the Internet. - networking.defaultGateway = mkOverride 50 {} ""; - networking.nameservers = mkOverride 50 {} [ ]; + networking.defaultGateway = mkOverride 200 {} ""; + networking.nameservers = mkOverride 200 {} [ ]; }; From 7eb7e8d732df6cab760f5c78d7230dcb876be824 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 18 Jun 2010 19:14:33 +0000 Subject: [PATCH 31/45] * Enable some tests. svn path=/nixos/branches/boot-order/; revision=22330 --- release.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release.nix b/release.nix index 10f9362ec87..1b013b9db36 100644 --- a/release.nix +++ b/release.nix @@ -156,6 +156,8 @@ let installer.swraid = t.installer.swraid.test; kde4 = t.kde4.test; login = t.login.test; + nat = t.nat.test; + nfs = t.nfs.test; openssh = t.openssh.test; proxy = t.proxy.test; quake3 = t.quake3.test; From 363806e89ba1e638b0459a2eb8b30bad8189d370 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 18 Jun 2010 19:31:02 +0000 Subject: [PATCH 32/45] * To establish the connection to the root shell in the guest, let the guest connect to a Unix domain socket on the host rather than the other way around. The former is a QEMU feature (guestfwd to a socket) while the latter requires a patch (which we can now get rid of). svn path=/nixos/branches/boot-order/; revision=22331 --- lib/test-driver/Machine.pm | 50 +++++++++++------------- lib/test-driver/test-driver.pl | 3 -- modules/testing/test-instrumentation.nix | 10 ++--- modules/virtualisation/qemu-vm.nix | 2 +- 4 files changed, 26 insertions(+), 39 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index b5989d54076..c18e0e33162 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -2,7 +2,6 @@ package Machine; use strict; use threads; -use Thread::Queue; use Socket; use IO::Handle; use POSIX qw(dup2); @@ -51,7 +50,6 @@ sub new { booted => 0, pid => 0, connected => 0, - connectedQueue => Thread::Queue->new(), socket => undef, stateDir => "$tmpDir/$name", monitor => undef, @@ -101,6 +99,14 @@ sub start { bind($monitorS, sockaddr_un($monitorPath)) or die "cannot bind monitor socket: $!"; listen($monitorS, 1) or die; + # Create a Unix domain socket to which the root shell in the guest will connect. + my $shellPath = $self->{stateDir} . "/shell"; + unlink $shellPath; + my $shellS; + socket($shellS, PF_UNIX, SOCK_STREAM, 0) or die; + bind($shellS, sockaddr_un($shellPath)) or die "cannot bind shell socket: $!"; + listen($shellS, 1) or die; + # Start the VM. my $pid = fork(); die if $pid == -1; @@ -108,13 +114,15 @@ sub start { if ($pid == 0) { close $serialP; close $monitorS; + close $shellS; open NUL, "{stateDir}; $ENV{USE_TMPDIR} = 1; - $ENV{QEMU_OPTS} = "-nographic -no-reboot -redir tcp:65535::514 -monitor unix:./monitor"; + $ENV{QEMU_OPTS} = "-nographic -no-reboot -monitor unix:./monitor -chardev socket,id=shell,path=./shell"; + $ENV{QEMU_NET_OPTS} = "guestfwd=tcp:10.0.2.6:23-chardev:shell"; $ENV{QEMU_KERNEL_PARAMS} = "hostTmpDir=$ENV{TMPDIR}"; chdir $self->{stateDir} or die; exec $self->{startCommand}; @@ -132,16 +140,20 @@ sub start { chomp; s/\r$//; print STDERR $self->name, "# $_\n"; - $self->{connectedQueue}->enqueue(1) if $_ eq "===UP==="; } - # If the child dies, wake up connect(). - $self->{connectedQueue}->enqueue(1); } - # Wait until QEMU connects to the monitor. eval { local $SIG{CHLD} = sub { die "QEMU died prematurely\n"; }; + + # Wait until QEMU connects to the monitor. accept($self->{monitor}, $monitorS) or die; + + # Wait until QEMU connects to the root shell socket. QEMU + # does so immediately; this doesn't mean that the root shell + # has connected yet inside the guest. + accept($self->{socket}, $shellS) or die; + $self->{socket}->autoflush(1); }; die "$@" if $@; @@ -197,27 +209,9 @@ sub connect { $self->start; - # Wait until the processQemuOutput thread signals that the machine - # is up. - retry sub { - return 1 if $self->{connectedQueue}->dequeue_nb(); - }; - - retry sub { - $self->log("trying to connect"); - my $socket = new IO::Handle; - $self->{socket} = $socket; - socket($socket, PF_UNIX, SOCK_STREAM, 0) or die; - connect($socket, sockaddr_un($self->{stateDir} . "/65535.socket")) or die; - $socket->autoflush(1); - print $socket "echo hello\n" or next; - flush $socket; - my $line = readline($socket); - chomp $line; - return 1 if $line eq "hello"; - }; - - $self->log("connected"); + my $line = readline $self->{socket} or die; + $self->log("connected to guest root shell"); + $self->{connected} = 1; } diff --git a/lib/test-driver/test-driver.pl b/lib/test-driver/test-driver.pl index 98666d6c775..ad1af5a6fbf 100644 --- a/lib/test-driver/test-driver.pl +++ b/lib/test-driver/test-driver.pl @@ -74,6 +74,3 @@ END { runTests; - - -print STDERR "DONE\n"; diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 84671028ba0..2515edf6192 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -13,6 +13,7 @@ let '' #! ${pkgs.perl}/bin/perl $SIG{CHLD} = 'DEFAULT'; + print "\n"; exec "/bin/sh"; ''; @@ -25,12 +26,6 @@ in jobs.backdoor = { startOn = "started network-interfaces"; - preStart = - '' - echo "guest running" > /dev/ttyS0 - echo "===UP===" > dev/ttyS0 - ''; - script = '' export USER=root @@ -39,7 +34,8 @@ in export GCOV_PREFIX=/tmp/coverage-data source /etc/profile cd /tmp - exec ${pkgs.socat}/bin/socat tcp-listen:514,fork exec:${rootShell} 2> /dev/ttyS0 + echo "connecting to host..." > /dev/ttyS0 + exec ${pkgs.socat}/bin/socat tcp:10.0.2.6:23 exec:${rootShell} 2> /dev/ttyS0 ''; }; diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 46462bbc6cc..e054b537d43 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -134,7 +134,7 @@ let -m ${toString config.virtualisation.memorySize} \ -net nic,vlan=0,model=virtio \ -chardev socket,id=samba,path=./samba \ - -net user,vlan=0,guestfwd=tcp:10.0.2.4:139-chardev:samba \ + -net user,vlan=0,guestfwd=tcp:10.0.2.4:139-chardev:samba''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \ -drive file=$NIX_DISK_IMAGE,if=virtio,boot=on,cache=writeback,werror=report \ -kernel ${config.system.build.toplevel}/kernel \ -initrd ${config.system.build.toplevel}/initrd \ From 411139148df295dd9d620d9fc4f073d1af2c862d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 19 Jun 2010 21:57:20 +0000 Subject: [PATCH 33/45] * Put a timeout on the call to readline. svn path=/nixos/branches/boot-order/; revision=22338 --- lib/test-driver/Machine.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index c18e0e33162..46fbf6d60cd 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -209,9 +209,12 @@ sub connect { $self->start; - my $line = readline $self->{socket} or die; + local $SIG{ALRM} = sub { die "timed out waiting for the guest to connect\n"; }; + alarm 300; + readline $self->{socket} or die; + alarm 0; + $self->log("connected to guest root shell"); - $self->{connected} = 1; } From 20a88efffa6a69b97a293b3a923c052501a964d7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 20 Jun 2010 15:33:44 +0000 Subject: [PATCH 34/45] * Fix networking in the installer test. * If connecting to the host fails in the guest, then shutdown immediately. svn path=/nixos/branches/boot-order/; revision=22341 --- lib/test-driver/Machine.pm | 2 +- modules/testing/test-instrumentation.nix | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index 46fbf6d60cd..9f5971d70a1 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -28,7 +28,7 @@ sub new { # !!! merge with qemu-vm.nix. $startCommand = "qemu-system-x86_64 -m 384 " . - "-net nic,model=virtio -net user \$QEMU_OPTS "; + "-net nic,model=virtio -net user,\$QEMU_NET_OPTS \$QEMU_OPTS "; $startCommand .= "-drive file=" . Cwd::abs_path($args->{hda}) . ",if=virtio,boot=on,werror=report " if defined $args->{hda}; $startCommand .= "-cdrom $args->{cdrom} " diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 2515edf6192..655cda31ed6 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -24,7 +24,8 @@ in config = { jobs.backdoor = - { startOn = "started network-interfaces"; + { startOn = "ip-up"; + stopOn = "never"; script = '' @@ -35,10 +36,12 @@ in source /etc/profile cd /tmp echo "connecting to host..." > /dev/ttyS0 - exec ${pkgs.socat}/bin/socat tcp:10.0.2.6:23 exec:${rootShell} 2> /dev/ttyS0 + ${pkgs.socat}/bin/socat tcp:10.0.2.6:23 exec:${rootShell} 2> /dev/ttyS0 || poweroff -f ''; + + respawn = false; }; - + boot.postBootCommands = '' # Panic on out-of-memory conditions rather than letting the From 1371f4e6c8107cd7d7945fa8c0fe714963d26949 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 20 Jun 2010 16:05:15 +0000 Subject: [PATCH 35/45] * Apparantly GRUB 2 cannot boot from a software RAID partition, so use a separate /boot. svn path=/nixos/branches/boot-order/; revision=22344 --- tests/installer.nix | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/installer.nix b/tests/installer.nix index 1f9ada808b2..8577e5b76cd 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -291,21 +291,25 @@ in { '' $machine->mustSucceed( "parted /dev/vda mklabel msdos", - "parted /dev/vda -- mkpart primary 1M 1000M", # md0 (root), first device - "parted /dev/vda -- mkpart primary 1024M 2024M", # md0 (root), second device - "parted /dev/vda -- mkpart primary 2048M 2548M", # md1 (swap), first device - "parted /dev/vda -- mkpart primary 2560M 3060M", # md1 (swap), second device + "parted /dev/vda -- mkpart primary ext2 1M 30MB", # /boot + "parted /dev/vda -- mkpart extended 30M -1s", # extended partition + "parted /dev/vda -- mkpart logical 30M 1000M", # md0 (root), first device + "parted /dev/vda -- mkpart logical 1024M 2000M", # md0 (root), second device + "parted /dev/vda -- mkpart logical 2048M 2548M", # md1 (swap), first device + "parted /dev/vda -- mkpart logical 2560M 3060M", # md1 (swap), second device "udevadm settle", - # Note that GRUB2 doesn't work with version 1.2 metadata. - "mdadm --create --force /dev/md0 --metadata 0.90 --level=raid1 --raid-devices=2 /dev/vda1 /dev/vda2", - "mdadm --create --force /dev/md1 --metadata 1.2 --level=raid1 --raid-devices=2 /dev/vda3 /dev/vda4", + "mdadm --create --force /dev/md0 --metadata 1.2 --level=raid1 --raid-devices=2 /dev/vda5 /dev/vda6", + "mdadm --create --force /dev/md1 --metadata 1.2 --level=raid1 --raid-devices=2 /dev/vda7 /dev/vda8", "mkswap -f /dev/md1 -L swap", "swapon -L swap", "mkfs.ext3 -L nixos /dev/md0", "mount LABEL=nixos /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir /mnt/boot", + "mount LABEL=boot /mnt/boot", ); ''; - fileSystems = rootFS; + fileSystems = rootFS + bootFS; }; } From eab091cc119cdc89060b123ac81d78263319078f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 20 Jun 2010 16:15:30 +0000 Subject: [PATCH 36/45] * Remove some redundant calls to `udevadm settle'. svn path=/nixos/branches/boot-order/; revision=22345 --- tests/installer.nix | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/installer.nix b/tests/installer.nix index 8577e5b76cd..bfecca48cc0 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -219,9 +219,7 @@ in { '' $machine->mustSucceed( "parted /dev/vda mklabel msdos", - "udevadm settle", "parted /dev/vda -- mkpart primary linux-swap 1M 1024M", - "udevadm settle", "parted /dev/vda -- mkpart primary ext2 1024M -1s", "udevadm settle", "mkswap /dev/vda1 -L swap", @@ -241,9 +239,7 @@ in { $machine->mustSucceed( "parted /dev/vda mklabel msdos", "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot - "udevadm settle", "parted /dev/vda -- mkpart primary linux-swap 50MB 1024M", - "udevadm settle", "parted /dev/vda -- mkpart primary ext2 1024M -1s", # / "udevadm settle", "mkswap /dev/vda2 -L swap", @@ -266,11 +262,8 @@ in { $machine->mustSucceed( "parted /dev/vda mklabel msdos", "parted /dev/vda -- mkpart primary 1M 2048M", # first PV - "udevadm settle", "parted /dev/vda -- set 1 lvm on", - "udevadm settle", "parted /dev/vda -- mkpart primary 2048M -1s", # second PV - "udevadm settle", "parted /dev/vda -- set 2 lvm on", "udevadm settle", "pvcreate /dev/vda1 /dev/vda2", From 593a110c4715a21a6973bf76a1ef1df30b2611d9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 20 Jun 2010 19:22:23 +0000 Subject: [PATCH 37/45] * Make sure that kernel log messages appear in the VM output. The comment was incorrect - when klogd is running, kernel messages no longer appear on the serial port. svn path=/nixos/branches/boot-order/; revision=22346 --- modules/testing/test-instrumentation.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 655cda31ed6..268a208e7fa 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -74,10 +74,8 @@ in # `xwininfo' is used by the test driver to query open windows. environment.systemPackages = [ pkgs.xorg.xwininfo ]; - # Send all of /var/log/messages to the serial port (except for - # kernel messages through klogd, which already appear on the - # serial port). - services.syslogd.extraConfig = "*.*,kern.none /dev/ttyS0"; + # Send all of /var/log/messages to the serial port. + services.syslogd.extraConfig = "*.* /dev/ttyS0"; # Prevent tests from accessing the Internet. networking.defaultGateway = mkOverride 200 {} ""; From 061ea1674fec3adfe9cf07aebc1452534dc2885d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 20 Jun 2010 20:52:42 +0000 Subject: [PATCH 38/45] * Increase the CIFS timeout here as well. svn path=/nixos/branches/boot-order/; revision=22348 --- modules/testing/test-instrumentation.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 268a208e7fa..b70c6e03f27 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -81,6 +81,13 @@ in networking.defaultGateway = mkOverride 200 {} ""; networking.nameservers = mkOverride 200 {} [ ]; + # Apply a patch to the kernel to increase the 15s CIFS timeout. + nixpkgs.config.packageOverrides = pkgs: { + linux = pkgs.linux.override (orig: { + kernelPatches = orig.kernelPatches ++ [ pkgs.kernelPatches.cifs_timeout ]; + }); + }; + }; } From d43d321e864cad2ac5ff6ae7633166925d2a2125 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 20 Jun 2010 20:54:31 +0000 Subject: [PATCH 39/45] * Sync with the trunk. svn path=/nixos/branches/boot-order/; revision=22349 --- modules/installer/grub/grub-menu-builder.sh | 2 +- modules/services/mail/postfix.nix | 10 +++++++++- modules/services/misc/nix-daemon.nix | 4 ++++ modules/services/printing/cupsd.nix | 13 ++++++++++--- modules/system/boot/stage-2-init.sh | 8 +++++++- modules/system/upstart/upstart.nix | 7 +++++-- tests/subversion.nix | 2 +- 7 files changed, 37 insertions(+), 9 deletions(-) diff --git a/modules/installer/grub/grub-menu-builder.sh b/modules/installer/grub/grub-menu-builder.sh index ecb69ceb263..f23184b0a06 100644 --- a/modules/installer/grub/grub-menu-builder.sh +++ b/modules/installer/grub/grub-menu-builder.sh @@ -30,7 +30,7 @@ esac # the GRUB config file must be relative to the root of the /boot # filesystem. `$bootRoot' is the path to be prepended to paths under # /boot. -if [ "$(stat -f -c '%i' /)" = "$(stat -f -c '%i' /boot)" ]; then +if [ "$(stat -c '%D' /.)" = "$(stat -c '%D' /boot/.)" ]; then bootRoot=/boot copyKernels="@copyKernels@" # user can override in the NixOS config else diff --git a/modules/services/mail/postfix.nix b/modules/services/mail/postfix.nix index 939260632c9..03c77885d06 100644 --- a/modules/services/mail/postfix.nix +++ b/modules/services/mail/postfix.nix @@ -287,7 +287,15 @@ in daemonType = "none"; - respawn = false; + respawn = true; + + script = '' + while ${pkgs.procps}/bin/ps `${pkgs.coreutils}/bin/cat /var/postfix/queue/pid/master.pid` | + grep -q postfix + do + ${pkgs.coreutils}/bin/sleep 1m + done + ''; preStart = '' diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index a9a0bc70f1e..fcdcc8fb299 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -162,6 +162,10 @@ in internal = true; default = ""; merge = mergeStringOption; + example = '' + export NIX_TARGET_LOAD=$(( 3 * $(${pkgs.coreutils}/bin/nproc) / 2 )) + export NIX_MAX_PARALLELIZATION=$NIX_TARGET_LOAD + ''; description = " Environment variables used by Nix. "; diff --git a/modules/services/printing/cupsd.nix b/modules/services/printing/cupsd.nix index 40760ec8af5..0ac52fe1038 100644 --- a/modules/services/printing/cupsd.nix +++ b/modules/services/printing/cupsd.nix @@ -106,6 +106,11 @@ in services.dbus.packages = [cups]; + # cups uses libusb to talk to printers, and does not use the + # linux kernel driver. If the driver is not in a black list, it + # gets loaded, and then cups cannot access the printers. + boot.blacklistedKernelModules = [ "usblp" ]; + environment.etc = [ # CUPS expects the following files in its ServerRoot. { source = "${cups}/etc/cups/mime.convs"; @@ -122,15 +127,17 @@ in startOn = "started network-interfaces"; stopOn = "stopping network-interfaces"; + environment = { + # Cups scripts for printing (psto...) require awk, sed, grep, ... + PATH = "${config.system.path}/bin"; + }; + preStart = '' mkdir -m 0755 -p ${logDir} mkdir -m 0700 -p /var/cache/cups mkdir -m 0700 -p /var/spool/cups mkdir -m 0755 -p ${cfg.tempDir} - - # Make USB printers show up. - ${modprobe}/sbin/modprobe usblp || true ''; exec = "${cups}/sbin/cupsd -c ${pkgs.writeText "cupsd.conf" cfg.cupsdConf} -F"; diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 201c539bb6b..aaf135fe51a 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -131,9 +131,15 @@ echo "running activation script..." @activateConfiguration@ "$systemConfig" -# Record the boot configuration. !!! Should this be a GC root? +# Record the boot configuration. if test -n "$systemConfig"; then ln -sfn "$systemConfig" /var/run/booted-system + + # Prevent the booted system form being garbage-collected + # If it weren't a gcroot, if we were running a different kernel, + # switched system, and garbage collected all, we could not load + # kernel modules anymore. + ln -sfn /var/run/booted-system /nix/var/nix/gcroots/booted-system fi diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 3110f376eec..cb3975e694c 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -21,6 +21,7 @@ let makeJob = job: let + hasMain = job.script != "" || job.exec != ""; jobText = let log = "/var/log/upstart/${job.name}"; in @@ -77,12 +78,14 @@ let ${optionalString job.task "task"} ${optionalString (!job.task && job.respawn) "respawn"} - ${optionalString (job.preStop != "") '' + ${ # preStop is run only if there is exec or script. + # (upstart 0.6.5, job.c:562) + optionalString (job.preStop != "") (assert hasMain; '' pre-stop script exec >> ${log} 2>&1 ${job.preStop} end script - ''} + '')} ${optionalString (job.postStop != "") '' post-stop script diff --git a/tests/subversion.nix b/tests/subversion.nix index 5354a40452b..d43e369b437 100644 --- a/tests/subversion.nix +++ b/tests/subversion.nix @@ -19,7 +19,7 @@ let # To build the kernel with coverage instrumentation, we need a # special patch to make coverage data available under /proc. - kernel = pkgs.kernel.override (orig: { + linux = pkgs.linux.override (orig: { stdenv = cleanupBuildTree (keepBuildTree orig.stdenv); extraConfig = '' From 6c6710b85a71964c117aff278cb9c074cb0163ad Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 21 Jun 2010 22:00:48 +0000 Subject: [PATCH 40/45] svn path=/nixos/branches/boot-order/; revision=22367 --- lib/make-iso9660-image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/make-iso9660-image.sh b/lib/make-iso9660-image.sh index 01b0fafa112..c6996e8db9a 100644 --- a/lib/make-iso9660-image.sh +++ b/lib/make-iso9660-image.sh @@ -54,7 +54,7 @@ done # Also include a manifest of the closures in a format suitable for # nix-store --load-db. -if [ -n "$object"; ]; then +if [ -n "$object" ]; then printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration echo "nix-path-registration=nix-path-registration" >> pathlist fi From 2e5387ac492493b60a12ce587c8cf6a4b8bf733d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 23 Jun 2010 09:59:26 +0000 Subject: [PATCH 41/45] * Fix evaluation of the manual. svn path=/nixos/branches/boot-order/; revision=22392 --- release.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.nix b/release.nix index 1b013b9db36..983b16f96d7 100644 --- a/release.nix +++ b/release.nix @@ -111,7 +111,7 @@ let options = (import lib/eval-config.nix { inherit nixpkgs; - modules = [ ]; + modules = [ { fileSystems = []; } ]; }).options; revision = with nixosSrc; if rev == 1234 then "HEAD" else toString rev; From 1f97de224f24d232d2c46a7c349cfcd3dd849de2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 23 Jun 2010 10:41:37 +0000 Subject: [PATCH 42/45] svn path=/nixos/branches/boot-order/; revision=22395 --- release.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release.nix b/release.nix index 983b16f96d7..204a636568d 100644 --- a/release.nix +++ b/release.nix @@ -113,8 +113,8 @@ let inherit nixpkgs; modules = [ { fileSystems = []; } ]; }).options; - revision = with nixosSrc; - if rev == 1234 then "HEAD" else toString rev; + revision = + if nixosSrc.rev == 1234 then "HEAD" else toString nixosSrc.rev; }; From 4225181fa11c49bf0cf732f6539840a778b06d1b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 5 Jul 2010 09:28:22 +0000 Subject: [PATCH 43/45] =?UTF-8?q?*=20Ensure=20that=20the=20=E2=80=98mount-?= =?UTF-8?q?failed=E2=80=99=20and=20=E2=80=98emergency-shell=E2=80=99=20tas?= =?UTF-8?q?ks=20don't=20get=20=20=20started=20by=20=E2=80=98switch-to-conf?= =?UTF-8?q?iguration.sh=E2=80=99.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/nixos/branches/boot-order/; revision=22473 --- modules/tasks/filesystems.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index fe231d94ec8..7d53824d050 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -177,6 +177,7 @@ in startOn = "mount-failed"; script = '' + [ -n "$MOUNTPOINT" ] || exit 0 start --no-wait emergency-shell \ DEVICE="$DEVICE" MOUNTPOINT="$MOUNTPOINT" ''; @@ -191,6 +192,8 @@ in script = '' + [ -n "$MOUNTPOINT" ] || exit 0 + exec < /dev/console > /dev/console 2>&1 cat < Date: Mon, 5 Jul 2010 14:33:11 +0000 Subject: [PATCH 44/45] * Use config.system.build.grub rather than pkgs.grub to get the right GRUB when version 2 is enabled. svn path=/nixos/branches/boot-order/; revision=22479 --- modules/services/x11/display-managers/kdm.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix index 15553ba386b..a88b34dc5ac 100644 --- a/modules/services/x11/display-managers/kdm.nix +++ b/modules/services/x11/display-managers/kdm.nix @@ -94,7 +94,9 @@ in config = mkIf cfg.enable { services.xserver.displayManager.job = - { execCmd = "PATH=${pkgs.grub}/sbin:$PATH exec ${kdebase_workspace}/bin/kdm -config ${kdmrc} -nodaemon"; + { execCmd = + (optionalString (config.system.boot.loader.id == "grub") "PATH=${config.system.build.grub}/sbin:$PATH ") + + "exec ${kdebase_workspace}/bin/kdm -config ${kdmrc} -nodaemon"; logsXsession = true; }; From bb2d97770e99310da64d862b08db71ec92702be8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 6 Jul 2010 09:01:15 +0000 Subject: [PATCH 45/45] * Move the swap module to config/ because it doesn't provide a task anymore. Activating swap devices is now handled by the mountall task. svn path=/nixos/branches/boot-order/; revision=22489 --- modules/{tasks => config}/swap.nix | 0 modules/module-list.nix | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename modules/{tasks => config}/swap.nix (100%) diff --git a/modules/tasks/swap.nix b/modules/config/swap.nix similarity index 100% rename from modules/tasks/swap.nix rename to modules/config/swap.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 841a6b11a5f..7bc98858506 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -7,6 +7,7 @@ ./config/no-x-libs.nix ./config/nsswitch.nix ./config/power-management.nix + ./config/swap.nix ./config/system-path.nix ./config/timezone.nix ./config/unix-odbc-drivers.nix @@ -152,7 +153,6 @@ ./tasks/kbd.nix ./tasks/lvm.nix ./tasks/network-interfaces.nix - ./tasks/swap.nix ./tasks/swraid.nix ./tasks/tty-backgrounds.nix ]