* Let the GRUB menu builder detect whether /boot is on a different

partition from /.  If so, copy the kernels and initrds to /boot and
  use paths relative to /boot in the GRUB configuration file.  This
  makes the boot.loader.grub.bootDevice option obsolete.  (Is there a
  way to mark obsolete options?)  It also makes it unnecessary to set
  boot.loader.grub.copyKernels, although that option is still
  available since it can speed up GRUB if the Nix store is very
  large.

svn path=/nixos/trunk/; revision=18998
This commit is contained in:
Eelco Dolstra 2009-12-16 18:57:02 +00:00
parent 8d588424d2
commit deb4f88c2c
3 changed files with 35 additions and 41 deletions

View file

@ -1,9 +1,6 @@
# This configuration has / on a LVM volume. Since Grub # This configuration has / on a LVM volume. Since Grub
# doesn't know about LVM, a separate /boot is therefore # doesn't know about LVM, a separate /boot is therefore
# needed. In particular you need to set "copyKernels" # needed.
# to tell NixOS to copy kernels and initrds from /nix/store
# to /boot, and "bootMount" to tell Grub the /boot device
# in Grub syntax (e.g. (hd0,0) for /dev/sda1).
# #
# In this example, labels are used for file systems and # In this example, labels are used for file systems and
# swap devices: "boot" might be /dev/sda1, "root" might be # swap devices: "boot" might be /dev/sda1, "root" might be
@ -12,12 +9,8 @@
# that / is on LVM; that's figured out automatically. # that / is on LVM; that's figured out automatically.
{ {
boot = { boot.loader.grub.device = "/dev/sda";
grubDevice = "/dev/sda"; boot.initrd.kernelModules = ["ata_piix"];
initrd.kernelModules = ["ata_piix"];
copyKernels = true;
bootMount = "(hd0,0)";
};
fileSystems = [ fileSystems = [
{ mountPoint = "/"; { mountPoint = "/";

View file

@ -12,8 +12,6 @@ fi
grubVersion="@version@" grubVersion="@version@"
defaultConfig="$1" defaultConfig="$1"
bootDevice="@bootDevice@"
if test -z "$bootDevice"; then bootDevice=/boot; fi
case "$grubVersion" in case "$grubVersion" in
1|2) 1|2)
@ -27,6 +25,20 @@ case "$grubVersion" in
esac esac
# Discover whether /boot is on the same filesystem as /. If not, then
# all kernels and initrds must be copied to /boot, and all paths in
# 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
bootRoot=/boot
copyKernels="@copyKernels@" # user can override in the NixOS config
else
bootRoot=
copyKernels=1
fi
prologue() { prologue() {
case "$grubVersion" in case "$grubVersion" in
1) 1)
@ -37,7 +49,7 @@ default @default@
timeout @timeout@ timeout @timeout@
GRUBEND GRUBEND
if test -n "@splashImage@"; then if test -n "@splashImage@"; then
echo "splashimage $bootDevice/background.xpm.gz" >> "$1" echo "splashimage $bootRoot/background.xpm.gz" >> "$1"
fi fi
;; ;;
2) 2)
@ -46,7 +58,7 @@ GRUBEND
# Automatically generated. DO NOT EDIT THIS FILE! # Automatically generated. DO NOT EDIT THIS FILE!
set default=@default@ set default=@default@
set timeout=@timeout@ set timeout=@timeout@
if loadfont $bootDevice/grub/unicode.pf2; then if loadfont $bootRoot/grub/unicode.pf2; then
set gfxmode=640x480 set gfxmode=640x480
insmod gfxterm insmod gfxterm
insmod vbe insmod vbe
@ -59,7 +71,7 @@ EOF
# if it doesn't match the video resolution. # if it doesn't match the video resolution.
cat >> "$1" <<EOF cat >> "$1" <<EOF
insmod png insmod png
if background_image $bootDevice/background.png; then if background_image $bootRoot/background.png; then
set color_normal=white/black set color_normal=white/black
set color_highlight=black/white set color_highlight=black/white
else else
@ -106,7 +118,8 @@ declare -A filesCopied
copyToKernelsDir() { copyToKernelsDir() {
local src="$1" local src="$1"
local dst="/boot/kernels/$(cleanName $src)" local p="kernels/$(cleanName $src)"
local dst="/boot/$p"
# Don't copy the file if $dst already exists. This means that we # Don't copy the file if $dst already exists. This means that we
# have to create $dst atomically to prevent partially copied # have to create $dst atomically to prevent partially copied
# kernels or initrd if this script is ever interrupted. # kernels or initrd if this script is ever interrupted.
@ -116,7 +129,7 @@ copyToKernelsDir() {
mv $dstTmp $dst mv $dstTmp $dst
fi fi
filesCopied[$dst]=1 filesCopied[$dst]=1
result=$dst result="$bootRoot/$p"
} }
@ -147,34 +160,27 @@ addEntry() {
1) 1)
cat > /boot/nixos-grub-config <<EOF cat > /boot/nixos-grub-config <<EOF
title Emergency boot title Emergency boot
kernel ${bootDevice:-/boot}/nixos-kernel systemConfig=$(readlink -f "$path") init=/boot/nixos-init $(cat "$path/kernel-params") kernel $bootRoot/nixos-kernel systemConfig=$(readlink -f "$path") init=/boot/nixos-init $(cat "$path/kernel-params")
initrd ${bootDevice:-/boot}/nixos-initrd initrd $bootRoot/nixos-initrd
EOF EOF
;; ;;
2) 2)
cat > /boot/nixos-grub-config <<EOF cat > /boot/nixos-grub-config <<EOF
menuentry "Emergency boot" { menuentry "Emergency boot" {
linux ${bootDevice:-/boot}/nixos-kernel systemConfig=$(readlink -f "$path") init=/boot/nixos-init $(cat "$path/kernel-params") linux $bootRoot/nixos-kernel systemConfig=$(readlink -f "$path") init=/boot/nixos-init $(cat "$path/kernel-params")
initrd ${bootDevice:-/boot}/initrd initrd $bootRoot/initrd
} }
EOF EOF
;; ;;
esac esac
fi fi
if test -n "@copyKernels@"; then if test -n "$copyKernels"; then
copyToKernelsDir $kernel; kernel=$result copyToKernelsDir $kernel; kernel=$result
copyToKernelsDir $initrd; initrd=$result copyToKernelsDir $initrd; initrd=$result
fi fi
if test -n "$bootDevice"; then local confName=$(cat $path/configuration-name 2>/dev/null)
kernel=$(echo $kernel | sed -e "s^/boot^$bootDevice^")
initrd=$(echo $initrd | sed -e "s^/boot^$bootDevice^")
fi
local confName=$(if test -e $path/configuration-name; then
cat $path/configuration-name;
fi)
if test -n "$confName"; then if test -n "$confName"; then
name="$confName $3" name="$confName $3"
fi fi
@ -199,7 +205,7 @@ GRUBEND
} }
if test -n "@copyKernels@"; then if test -n "$copyKernels"; then
mkdir -p /boot/kernels mkdir -p /boot/kernels
fi fi

View file

@ -13,7 +13,7 @@ let
inherit (pkgs) bash; inherit (pkgs) bash;
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep]; path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
inherit (config.boot.loader.grub) copyKernels extraEntries extraEntriesBeforeNixOS inherit (config.boot.loader.grub) copyKernels extraEntries extraEntriesBeforeNixOS
splashImage bootDevice configurationLimit version default timeout; splashImage configurationLimit version default timeout;
}; };
in in
@ -53,15 +53,10 @@ in
''; '';
}; };
# !!! How can we mark options as obsolete?
bootDevice = mkOption { bootDevice = mkOption {
default = ""; default = "";
example = "(hd0,0)"; description = "Obsolete.";
description = ''
If the system partition may be wiped on reinstall, it is better
to have /boot on a small partition. To do it, we need to explain
to GRUB where the kernels live. Specify the partition here (in
GRUB notation).
'';
}; };
configurationName = mkOption { configurationName = mkOption {
@ -121,8 +116,8 @@ in
default = false; default = false;
description = '' description = ''
Whether the GRUB menu builder should copy kernels and initial Whether the GRUB menu builder should copy kernels and initial
ramdisks to /boot. This is necessary when /nix is on a ramdisks to /boot. This is done automatically if /boot is
different file system than /boot. on a different partition than /.
''; '';
}; };