mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-10 23:13:56 +00:00
* Allow multiple file systems to be mounted in stage 1 (i.e., from the
initrd). This is useful if /nix (which is necessary for stage 2) is on a different file system than /. svn path=/nixos/trunk/; revision=7862
This commit is contained in:
parent
923348b490
commit
8cf1eceb0a
@ -3,6 +3,7 @@
|
||||
fail() {
|
||||
# If starting stage 2 failed, start an interactive shell.
|
||||
echo "Stage 2 failed, starting emergency shell..."
|
||||
echo "(Stage 1 init script is $stage2Init)"
|
||||
exec @staticShell@
|
||||
}
|
||||
|
||||
@ -67,12 +68,55 @@ udevtrigger
|
||||
udevsettle
|
||||
|
||||
|
||||
# Function for mounting a file system.
|
||||
mountFS() {
|
||||
local device="$1"
|
||||
local mountPoint="$2"
|
||||
local options="$3"
|
||||
|
||||
# Check the root device, if .
|
||||
mustCheck=
|
||||
if test -b "$device"; then
|
||||
mustCheck=1
|
||||
else
|
||||
case $device in
|
||||
LABEL=*)
|
||||
mustCheck=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if test -n "$mustCheck"; then
|
||||
fsck -C -a "$device"
|
||||
fsckResult=$?
|
||||
|
||||
if test $(($fsckResult | 2)) = $fsckResult; then
|
||||
echo "fsck finished, rebooting..."
|
||||
sleep 3
|
||||
# reboot -f -d !!! don't have reboot yet
|
||||
fail
|
||||
fi
|
||||
|
||||
if test $(($fsckResult | 4)) = $fsckResult; then
|
||||
echo "$device has unrepaired errors, please fix them manually."
|
||||
fail
|
||||
fi
|
||||
|
||||
if test $fsckResult -ge 8; then
|
||||
echo "fsck on $device failed."
|
||||
fail
|
||||
fi
|
||||
fi
|
||||
|
||||
# Mount read-writable.
|
||||
mount -n -o "$options" "$device" /mnt/root$mountPoint || fail
|
||||
}
|
||||
|
||||
|
||||
# Try to find and mount the root device.
|
||||
mkdir /mnt
|
||||
mkdir /mnt/root
|
||||
|
||||
echo "mounting the root device..."
|
||||
|
||||
if test -n "@autoDetectRootDevice@"; then
|
||||
|
||||
# Look for the root device by label.
|
||||
@ -109,33 +153,37 @@ if test -n "@autoDetectRootDevice@"; then
|
||||
|
||||
else
|
||||
|
||||
# Hard-coded root device.
|
||||
rootDevice="@rootDevice@"
|
||||
# Hard-coded root device(s).
|
||||
mountPoints=(@mountPoints@)
|
||||
devices=(@devices@)
|
||||
fsTypes=(@fsTypes@)
|
||||
optionss=(@optionss@)
|
||||
|
||||
# Check the root device.
|
||||
fsck -C -a "$rootDevice"
|
||||
fsckResult=$?
|
||||
for ((n = 0; n < ${#mountPoints[*]}; n++)); do
|
||||
mountPoint=${mountPoints[$n]}
|
||||
device=${devices[$n]}
|
||||
fsType=${fsTypes[$n]}
|
||||
options=${optionss[$n]}
|
||||
|
||||
if test $(($fsckResult | 2)) = $fsckResult; then
|
||||
echo "fsck finished, rebooting..."
|
||||
sleep 3
|
||||
# reboot -f -d !!! don't have reboot yet
|
||||
fail
|
||||
fi
|
||||
# !!! Really quick hack to support bind mounts, i.e., where
|
||||
# the "device" should be taken relative to /mnt/root, not /.
|
||||
# Assume that every device that doesn't start with /dev or
|
||||
# LABEL= is a bind mount.
|
||||
case $device in
|
||||
/dev/*)
|
||||
;;
|
||||
LABEL=*)
|
||||
;;
|
||||
*)
|
||||
device=/mnt/root$device
|
||||
;;
|
||||
esac
|
||||
|
||||
if test $(($fsckResult | 4)) = $fsckResult; then
|
||||
echo "$rootDevice has unrepaired errors, please fix them manually."
|
||||
fail
|
||||
fi
|
||||
|
||||
if test $fsckResult -ge 8; then
|
||||
echo "fsck on $rootDevice failed."
|
||||
fail
|
||||
fi
|
||||
|
||||
# Mount read-writable.
|
||||
mount -n -o rw "$rootDevice" /mnt/root || fail
|
||||
echo "mounting $device on $mountPoint..."
|
||||
|
||||
mountFS "$device" "$mountPoint" "$options"
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@ -148,8 +196,6 @@ mount --move . /
|
||||
umount /proc # cleanup
|
||||
umount /sys
|
||||
|
||||
echo "INIT = $stage2Init"
|
||||
|
||||
if test -z "$stage2Init"; then fail; fi
|
||||
|
||||
exec chroot . $stage2Init
|
||||
|
@ -10,8 +10,15 @@
|
||||
, # Whether to find root device automatically using its label.
|
||||
autoDetectRootDevice
|
||||
|
||||
, # If not scanning, the root must be specified explicitly.
|
||||
rootDevice
|
||||
, # If not scanning, the root must be specified explicitly. Actually,
|
||||
# stage 1 can mount multiple file systems. This is necessary if,
|
||||
# for instance, /nix (necessary for stage 2) is on a different file
|
||||
# system than /.
|
||||
#
|
||||
# This is a list of {mountPoint, device|label} attribute sets, i.e.,
|
||||
# the format used by the fileSystems configuration option. There
|
||||
# must at least be a file system for the / mount point in this list.
|
||||
fileSystems ? []
|
||||
|
||||
# If scanning, we need a disk label.
|
||||
, rootLabel
|
||||
@ -21,12 +28,23 @@
|
||||
stage2Init ? "/init"
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
# !!! use XML; copy&pasted from upstart-jobs/filesystems.nix.
|
||||
mountPoints = map (fs: fs.mountPoint) fileSystems;
|
||||
devices = map (fs: if fs ? device then fs.device else "LABEL=" + fs.label) fileSystems;
|
||||
fsTypes = map (fs: if fs ? fsType then fs.fsType else "auto") fileSystems;
|
||||
optionss = map (fs: if fs ? options then fs.options else "defaults") fileSystems;
|
||||
|
||||
in
|
||||
|
||||
assert autoDetectRootDevice -> mountPoints != [];
|
||||
|
||||
substituteAll {
|
||||
src = ./boot-stage-1-init.sh;
|
||||
isExecutable = true;
|
||||
inherit staticShell modules modulesDir;
|
||||
inherit autoDetectRootDevice;
|
||||
rootDevice = if !autoDetectRootDevice then rootDevice else "";
|
||||
inherit autoDetectRootDevice mountPoints devices fsTypes optionss;
|
||||
rootLabel = if autoDetectRootDevice then rootLabel else "";
|
||||
path = [
|
||||
staticTools
|
||||
|
@ -68,12 +68,10 @@ rec {
|
||||
inherit (pkgsDiet) module_init_tools;
|
||||
inherit extraUtils;
|
||||
autoDetectRootDevice = config.get ["boot" "autoDetectRootDevice"];
|
||||
rootDevice =
|
||||
let rootFS =
|
||||
(pkgs.library.findSingle (fs: fs.mountPoint == "/")
|
||||
(abort "No root mount point declared.")
|
||||
(config.get ["fileSystems"]));
|
||||
in if rootFS ? device then rootFS.device else "LABEL=" + rootFS.label;
|
||||
fileSystems =
|
||||
pkgs.lib.filter
|
||||
(fs: fs.mountPoint == "/" || (fs ? neededForBoot && fs.neededForBoot))
|
||||
(config.get ["fileSystems"]);
|
||||
rootLabel = config.get ["boot" "rootLabel"];
|
||||
inherit stage2Init;
|
||||
modulesDir = modulesClosure;
|
||||
|
Loading…
Reference in New Issue
Block a user