diff --git a/modules/stage-2.nix b/modules/stage-2.nix index 58fe241f..b9cb8cfb 100644 --- a/modules/stage-2.nix +++ b/modules/stage-2.nix @@ -1,14 +1,24 @@ { config, lib, pkgs, ... }: +# FIXME: Add hook for mounting, right now it's hardcoded to only mount "/". +# (This'll allow complex schemes like LVM) +# FIXME: Move udev stuff out. + +let + rootfs = config.fileSystems."/".device; +in with import ./initrd-order.nix; { - mobile.boot.stage-1.init = lib.mkOrder SWITCH_ROOT_INIT '' + mobile.boot.stage-1.init = + lib.mkOrder SWITCH_ROOT_INIT '' set -x - targetRoot=/mnt - _fs_id() { - blkid | grep ' LABEL="'"$1"'" ' | cut -d':' -f1 - } + # FIXME : udev stuff out of here... + systemd-udevd --daemon + udevadm trigger --action=add + udevadm settle + + targetRoot=/mnt _init_path() { local _system="" @@ -40,18 +50,8 @@ with import ./initrd-order.nix; echo "$_system/init" } - _fs_id NIXOS_SD - _fs_id NIXOS_BOOT - # FIXME : LESS FLIMSY! mkdir -p $targetRoot - mount $(_fs_id NIXOS_SD) $targetRoot - - # mkdir -p $targetRoot/boot - # mount $(_fs_id NIXOS_BOOT) $targetRoot/boot - - # mount "$(blkid | grep ' LABEL="'"NIXOS_SD"'" ' | cut -d':' -f1)" /mnt - # mkdir -p /mnt/boot/ - # mount "$(blkid | grep ' LABEL="'"NIXOS_BOOT"'" ' | cut -d':' -f1)" /mnt/boot + mount "${rootfs}" $targetRoot echo "" echo "***" @@ -61,12 +61,17 @@ with import ./initrd-order.nix; echo "***" echo "" - for mp in /proc /sys /dev /run; do mkdir -m 0755 -p $targetRoot/$mp mount --move $mp $targetRoot/$mp done + # TODO : hook "AT" switch root + + # FIXME : udev stuff out of here... + # Stop udevd. + udevadm control --exit + exec env -i $(type -P switch_root) $targetRoot $(_init_path) ''; diff --git a/systems/initrd.nix b/systems/initrd.nix index 132cdeca..f819a1fc 100644 --- a/systems/initrd.nix +++ b/systems/initrd.nix @@ -11,8 +11,18 @@ lib, mkExtraUtils, + + # FIXME : udev specifics + runCommandNoCC, + udev, + pkgs }: +# FIXME: get the udev specifics out of here. +# The main issue is how `udevRules` needs a reference to `extraUtils`. +# This means that `extraUtils` should be a build product of stage-1 in +# system.build, that we can refer to when required. + let inherit (lib) optionals flatten; @@ -24,11 +34,74 @@ let busybox ] ++ optionals (stage-1 ? extraUtils) stage-1.extraUtils + ++ [{ + package = runCommandNoCC "empty" {} "mkdir -p $out"; + extraCommand = + let + inherit (pkgs) udev; + in + '' + # Copy udev. + copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd + copy_bin_and_libs ${udev}/bin/udevadm + for BIN in ${udev}/lib/udev/*_id; do + copy_bin_and_libs $BIN + done + '' + ; + }] ; }; shell = "${extraUtils}/bin/ash"; + udevRules = runCommandNoCC "udev-rules" { + allowedReferences = [ extraUtils ]; + preferLocalBuild = true; + } '' + mkdir -p $out + + echo 'ENV{LD_LIBRARY_PATH}="${extraUtils}/lib"' > $out/00-env.rules + + cp -v ${udev}/lib/udev/rules.d/60-cdrom_id.rules $out/ + cp -v ${udev}/lib/udev/rules.d/60-persistent-storage.rules $out/ + cp -v ${udev}/lib/udev/rules.d/80-drivers.rules $out/ + cp -v ${pkgs.lvm2}/lib/udev/rules.d/*.rules $out/ + + for i in $out/*.rules; do + substituteInPlace $i \ + --replace ata_id ${extraUtils}/bin/ata_id \ + --replace scsi_id ${extraUtils}/bin/scsi_id \ + --replace cdrom_id ${extraUtils}/bin/cdrom_id \ + --replace ${pkgs.coreutils}/bin/basename ${extraUtils}/bin/basename \ + --replace ${pkgs.utillinux}/bin/blkid ${extraUtils}/bin/blkid \ + --replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \ + --replace ${pkgs.mdadm}/sbin ${extraUtils}/sbin \ + --replace ${pkgs.bash}/bin/sh ${extraUtils}/bin/sh \ + --replace ${udev}/bin/udevadm ${extraUtils}/bin/udevadm + done + + # Work around a bug in QEMU, which doesn't implement the "READ + # DISC INFORMATION" SCSI command: + # https://bugzilla.redhat.com/show_bug.cgi?id=609049 + # As a result, `cdrom_id' doesn't print + # ID_CDROM_MEDIA_TRACK_COUNT_DATA, which in turn prevents the + # /dev/disk/by-label symlinks from being created. We need these + # in the NixOS installation CD, so use ID_CDROM_MEDIA in the + # corresponding udev rules for now. This was the behaviour in + # udev <= 154. See also + # http://www.spinics.net/lists/hotplug/msg03935.html + substituteInPlace $out/60-persistent-storage.rules \ + --replace ID_CDROM_MEDIA_TRACK_COUNT_DATA ID_CDROM_MEDIA + ''; # */ + + # Just to keep track of this bit. + udevFragment = '' + mkdir -p /etc/udev + + ln -sfn ${udevRules} /etc/udev/rules.d + ''; + stage1 = writeScript "stage1" '' #!${shell} @@ -41,6 +114,7 @@ let ln -sv ${shell} /bin/sh # ---- stage-1.init START ---- + ${udevFragment} ${stage-1.init} # ---- stage-1.init END ---- '';