mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-10-22 05:07:45 +03: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() {
|
fail() {
|
||||||
# If starting stage 2 failed, start an interactive shell.
|
# If starting stage 2 failed, start an interactive shell.
|
||||||
echo "Stage 2 failed, starting emergency shell..."
|
echo "Stage 2 failed, starting emergency shell..."
|
||||||
|
echo "(Stage 1 init script is $stage2Init)"
|
||||||
exec @staticShell@
|
exec @staticShell@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,12 +68,55 @@ udevtrigger
|
|||||||
udevsettle
|
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.
|
# Try to find and mount the root device.
|
||||||
mkdir /mnt
|
mkdir /mnt
|
||||||
mkdir /mnt/root
|
mkdir /mnt/root
|
||||||
|
|
||||||
echo "mounting the root device..."
|
|
||||||
|
|
||||||
if test -n "@autoDetectRootDevice@"; then
|
if test -n "@autoDetectRootDevice@"; then
|
||||||
|
|
||||||
# Look for the root device by label.
|
# Look for the root device by label.
|
||||||
@ -109,32 +153,36 @@ if test -n "@autoDetectRootDevice@"; then
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
# Hard-coded root device.
|
# Hard-coded root device(s).
|
||||||
rootDevice="@rootDevice@"
|
mountPoints=(@mountPoints@)
|
||||||
|
devices=(@devices@)
|
||||||
|
fsTypes=(@fsTypes@)
|
||||||
|
optionss=(@optionss@)
|
||||||
|
|
||||||
# Check the root device.
|
for ((n = 0; n < ${#mountPoints[*]}; n++)); do
|
||||||
fsck -C -a "$rootDevice"
|
mountPoint=${mountPoints[$n]}
|
||||||
fsckResult=$?
|
device=${devices[$n]}
|
||||||
|
fsType=${fsTypes[$n]}
|
||||||
|
options=${optionss[$n]}
|
||||||
|
|
||||||
if test $(($fsckResult | 2)) = $fsckResult; then
|
# !!! Really quick hack to support bind mounts, i.e., where
|
||||||
echo "fsck finished, rebooting..."
|
# the "device" should be taken relative to /mnt/root, not /.
|
||||||
sleep 3
|
# Assume that every device that doesn't start with /dev or
|
||||||
# reboot -f -d !!! don't have reboot yet
|
# LABEL= is a bind mount.
|
||||||
fail
|
case $device in
|
||||||
fi
|
/dev/*)
|
||||||
|
;;
|
||||||
|
LABEL=*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
device=/mnt/root$device
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if test $(($fsckResult | 4)) = $fsckResult; then
|
echo "mounting $device on $mountPoint..."
|
||||||
echo "$rootDevice has unrepaired errors, please fix them manually."
|
|
||||||
fail
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $fsckResult -ge 8; then
|
mountFS "$device" "$mountPoint" "$options"
|
||||||
echo "fsck on $rootDevice failed."
|
done
|
||||||
fail
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Mount read-writable.
|
|
||||||
mount -n -o rw "$rootDevice" /mnt/root || fail
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -148,8 +196,6 @@ mount --move . /
|
|||||||
umount /proc # cleanup
|
umount /proc # cleanup
|
||||||
umount /sys
|
umount /sys
|
||||||
|
|
||||||
echo "INIT = $stage2Init"
|
|
||||||
|
|
||||||
if test -z "$stage2Init"; then fail; fi
|
if test -z "$stage2Init"; then fail; fi
|
||||||
|
|
||||||
exec chroot . $stage2Init
|
exec chroot . $stage2Init
|
||||||
|
@ -10,8 +10,15 @@
|
|||||||
, # Whether to find root device automatically using its label.
|
, # Whether to find root device automatically using its label.
|
||||||
autoDetectRootDevice
|
autoDetectRootDevice
|
||||||
|
|
||||||
, # If not scanning, the root must be specified explicitly.
|
, # If not scanning, the root must be specified explicitly. Actually,
|
||||||
rootDevice
|
# 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.
|
# If scanning, we need a disk label.
|
||||||
, rootLabel
|
, rootLabel
|
||||||
@ -21,12 +28,23 @@
|
|||||||
stage2Init ? "/init"
|
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 {
|
substituteAll {
|
||||||
src = ./boot-stage-1-init.sh;
|
src = ./boot-stage-1-init.sh;
|
||||||
isExecutable = true;
|
isExecutable = true;
|
||||||
inherit staticShell modules modulesDir;
|
inherit staticShell modules modulesDir;
|
||||||
inherit autoDetectRootDevice;
|
inherit autoDetectRootDevice mountPoints devices fsTypes optionss;
|
||||||
rootDevice = if !autoDetectRootDevice then rootDevice else "";
|
|
||||||
rootLabel = if autoDetectRootDevice then rootLabel else "";
|
rootLabel = if autoDetectRootDevice then rootLabel else "";
|
||||||
path = [
|
path = [
|
||||||
staticTools
|
staticTools
|
||||||
|
@ -68,12 +68,10 @@ rec {
|
|||||||
inherit (pkgsDiet) module_init_tools;
|
inherit (pkgsDiet) module_init_tools;
|
||||||
inherit extraUtils;
|
inherit extraUtils;
|
||||||
autoDetectRootDevice = config.get ["boot" "autoDetectRootDevice"];
|
autoDetectRootDevice = config.get ["boot" "autoDetectRootDevice"];
|
||||||
rootDevice =
|
fileSystems =
|
||||||
let rootFS =
|
pkgs.lib.filter
|
||||||
(pkgs.library.findSingle (fs: fs.mountPoint == "/")
|
(fs: fs.mountPoint == "/" || (fs ? neededForBoot && fs.neededForBoot))
|
||||||
(abort "No root mount point declared.")
|
(config.get ["fileSystems"]);
|
||||||
(config.get ["fileSystems"]));
|
|
||||||
in if rootFS ? device then rootFS.device else "LABEL=" + rootFS.label;
|
|
||||||
rootLabel = config.get ["boot" "rootLabel"];
|
rootLabel = config.get ["boot" "rootLabel"];
|
||||||
inherit stage2Init;
|
inherit stage2Init;
|
||||||
modulesDir = modulesClosure;
|
modulesDir = modulesClosure;
|
||||||
|
Loading…
Reference in New Issue
Block a user