* Use normal, dynamically linked binaries for e2fsck, lvm etc. in the
initrd instead of a mix of dietlibc, klibc and static-glibc based binaries. This works by copying what we need from Glibc into the initrd and using patchelf to set the ELF interpreter and RPATH correctly. The resulting initrd is about 500 KB smaller, but more importantly, it's much easier to maintain - all those dietlibc/klibc/static-glibc builds frequently cause build problems. svn path=/nixos/branches/fix-style/; revision=14178
This commit is contained in:
parent
6c703347a8
commit
38e8cf175f
@ -1,7 +1,9 @@
|
|||||||
#! @staticShell@
|
#! @shell@
|
||||||
|
|
||||||
targetRoot=/mnt/root
|
targetRoot=/mnt/root
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH=@extraUtils@/lib
|
||||||
|
|
||||||
|
|
||||||
errorDialog() {
|
errorDialog() {
|
||||||
timeout=15
|
timeout=15
|
||||||
@ -14,13 +16,13 @@ errorDialog() {
|
|||||||
read -t $timeout reply
|
read -t $timeout reply
|
||||||
case $reply in
|
case $reply in
|
||||||
f)
|
f)
|
||||||
exec @staticShell@;;
|
exec @shell@;;
|
||||||
i)
|
i)
|
||||||
echo
|
echo
|
||||||
echo "Quit interactive shell with exit status of"
|
echo "Quit interactive shell with exit status of"
|
||||||
echo " 0 : to continue"
|
echo " 0 : to continue"
|
||||||
echo " non-zero : to get this dialog again"
|
echo " non-zero : to get this dialog again"
|
||||||
@staticShell@ || fail
|
@shell@ || fail
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo continuing ignoring error;;
|
echo continuing ignoring error;;
|
||||||
@ -299,7 +301,6 @@ umount /proc
|
|||||||
exec run-init "$targetRoot" "$stage2Init"
|
exec run-init "$targetRoot" "$stage2Init"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo $1 failed running "$stage2Init"
|
echo "$1: failed running $stage2Init"
|
||||||
echo "It's your last chance to fix things manually without rebooting"
|
echo "Dropping into a root shell..."
|
||||||
echo "finally switching to interactive shell pid 1"
|
export $stage2Init; exec @shell@
|
||||||
export $stage2Init; exec @staticShell@
|
|
||||||
|
@ -13,26 +13,6 @@ in
|
|||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
pkgsDiet = import "${pkgs.path}/top-level/all-packages.nix" {
|
|
||||||
system = pkgs.stdenv.system;
|
|
||||||
bootStdenv = pkgs.useDietLibC pkgs.stdenv;
|
|
||||||
};
|
|
||||||
|
|
||||||
pkgsKlibc = import "${pkgs.path}/top-level/all-packages.nix" {
|
|
||||||
system = pkgs.stdenv.system;
|
|
||||||
bootStdenv = pkgs.useKlibc pkgs.stdenv pkgs.klibc;
|
|
||||||
};
|
|
||||||
|
|
||||||
pkgsStatic = import "${pkgs.path}/top-level/all-packages.nix" {
|
|
||||||
system = pkgs.stdenv.system;
|
|
||||||
bootStdenv = pkgs.makeStaticBinaries pkgs.stdenv;
|
|
||||||
};
|
|
||||||
|
|
||||||
stdenvLinuxStuff = import "${pkgs.path}/stdenv/linux" {
|
|
||||||
system = pkgs.stdenv.system;
|
|
||||||
allPackages = import "${pkgs.path}/top-level/all-packages.nix";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
# Determine the set of modules that we need to mount the root FS.
|
# Determine the set of modules that we need to mount the root FS.
|
||||||
modulesClosure = pkgs.makeModulesClosure {
|
modulesClosure = pkgs.makeModulesClosure {
|
||||||
@ -44,41 +24,82 @@ rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
udev = pkgsKlibc.udev;
|
# Some additional utilities needed in stage 1, like mount, lvm, fsck
|
||||||
|
# etc. We don't want to bring in all of those packages, so we just
|
||||||
|
# copy what we need. Instead of using statically linked binaries,
|
||||||
# Some additional utilities needed in stage 1, notably mount. We
|
# we just copy what we need from Glibc and use patchelf to make it
|
||||||
# don't want to bring in all of util-linux, so we just copy what we
|
# work.
|
||||||
# need.
|
|
||||||
extraUtils = pkgs.runCommand "extra-utils"
|
extraUtils = pkgs.runCommand "extra-utils"
|
||||||
{ buildInputs = [pkgs.nukeReferences];
|
{ buildInputs = [pkgs.nukeReferences];
|
||||||
inherit (pkgsStatic) utillinux;
|
devicemapper = if config.boot.initrd.lvm then pkgs.devicemapper else null;
|
||||||
inherit udev;
|
lvm2 = if config.boot.initrd.lvm then pkgs.lvm2 else null;
|
||||||
e2fsprogs = pkgsDiet.e2fsprogs;
|
allowedReferences = ["out"]; # prevent accidents like glibc being included in the initrd
|
||||||
devicemapper =
|
|
||||||
if config.boot.initrd.lvm
|
|
||||||
then assert pkgs.devicemapper.enableStatic; pkgs.devicemapper
|
|
||||||
else null;
|
|
||||||
lvm2 =
|
|
||||||
if config.boot.initrd.lvm
|
|
||||||
then assert pkgs.lvm2.enableStatic; pkgs.lvm2
|
|
||||||
else null;
|
|
||||||
allowedReferences = []; # prevent accidents like glibc being included in the initrd
|
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
ensureDir $out/bin
|
ensureDir $out/bin
|
||||||
if test -n "$devicemapper"; then
|
ensureDir $out/lib
|
||||||
cp $devicemapper/sbin/dmsetup.static $out/bin/dmsetup
|
|
||||||
cp $lvm2/sbin/lvm.static $out/bin/lvm
|
# Copy what we need from Glibc.
|
||||||
fi
|
cp -p ${pkgs.glibc}/lib/ld-linux*.so.2 $out/lib
|
||||||
cp $utillinux/bin/mount $utillinux/bin/umount $utillinux/sbin/pivot_root $out/bin
|
cp -p ${pkgs.glibc}/lib/libc.so.* $out/lib
|
||||||
cp -pd $e2fsprogs/sbin/fsck $e2fsprogs/sbin/e2fsck $e2fsprogs/sbin/tune2fs $out/bin
|
cp -p ${pkgs.glibc}/lib/libpthread.so.* $out/lib
|
||||||
|
cp -p ${pkgs.glibc}/lib/librt.so.* $out/lib
|
||||||
|
cp -p ${pkgs.glibc}/lib/libdl.so.* $out/lib
|
||||||
|
|
||||||
|
# Copy some utillinux stuff.
|
||||||
|
cp ${pkgs.utillinux}/bin/mount ${pkgs.utillinux}/bin/umount ${pkgs.utillinux}/sbin/pivot_root $out/bin
|
||||||
|
|
||||||
|
# Copy e2fsck and friends.
|
||||||
|
cp ${pkgs.e2fsprogs}/sbin/e2fsck $out/bin
|
||||||
|
cp ${pkgs.e2fsprogs}/sbin/tune2fs $out/bin
|
||||||
|
cp ${pkgs.e2fsprogs}/sbin/fsck $out/bin
|
||||||
ln -s e2fsck $out/bin/fsck.ext2
|
ln -s e2fsck $out/bin/fsck.ext2
|
||||||
ln -s e2fsck $out/bin/fsck.ext3
|
ln -s e2fsck $out/bin/fsck.ext3
|
||||||
ln -s e2fsck $out/bin/fsck.ext4
|
ln -s e2fsck $out/bin/fsck.ext4
|
||||||
cp $udev/sbin/udevd $udev/sbin/udevadm $out/bin
|
|
||||||
cp $udev/lib/udev/*_id $out/bin
|
cp -pd ${pkgs.e2fsprogs}/lib/lib*.so.* $out/lib
|
||||||
for i in $out/bin/*; do if ! test -L $i; then nuke-refs $i; fi; done
|
|
||||||
|
# Copy devicemapper and lvm, if we need it.
|
||||||
|
if test -n "$devicemapper"; then
|
||||||
|
cp $devicemapper/sbin/dmsetup $out/bin/dmsetup
|
||||||
|
cp $devicemapper/lib/libdevmapper.so.*.* $out/lib
|
||||||
|
cp $lvm2/sbin/lvm $out/bin/lvm
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy udev.
|
||||||
|
cp ${pkgs.udev}/sbin/udevd ${pkgs.udev}/sbin/udevadm $out/bin
|
||||||
|
cp ${pkgs.udev}/lib/udev/*_id $out/bin
|
||||||
|
cp ${pkgs.udev}/lib/libvolume_id.so.* $out/lib
|
||||||
|
|
||||||
|
# Copy bash.
|
||||||
|
cp ${pkgs.bash}/bin/bash $out/bin
|
||||||
|
ln -s bash $out/bin/sh
|
||||||
|
|
||||||
|
# Run patchelf to make the programs refer to the copied libraries.
|
||||||
|
for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done
|
||||||
|
|
||||||
|
for i in $out/bin/*; do
|
||||||
|
if ! test -L $i; then
|
||||||
|
echo "patching $i..."
|
||||||
|
patchelf --set-interpreter $out/lib/ld-linux*.so.2 --set-rpath $out/lib $i || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Make sure that the patchelf'ed binaries still work.
|
||||||
|
echo "testing patched programs..."
|
||||||
|
$out/bin/bash --version
|
||||||
|
export LD_LIBRARY_PATH=$out/lib
|
||||||
|
$out/bin/mount --version
|
||||||
|
$out/bin/umount --version
|
||||||
|
$out/bin/e2fsck -V
|
||||||
|
$out/bin/tune2fs 2> /dev/null | grep "tune2fs "
|
||||||
|
$out/bin/fsck -N
|
||||||
|
$out/bin/udevadm --version
|
||||||
|
$out/bin/vol_id 2>&1 | grep "no device"
|
||||||
|
if test -n "$devicemapper"; then
|
||||||
|
$out/bin/dmsetup --version | grep "version:"
|
||||||
|
LVM_SYSTEM_DIR=$out $out/bin/lvm 2>&1 | grep "LVM"
|
||||||
|
fi
|
||||||
''; # */
|
''; # */
|
||||||
|
|
||||||
|
|
||||||
@ -94,7 +115,7 @@ rec {
|
|||||||
name = "udev-rules";
|
name = "udev-rules";
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
ensureDir $out
|
ensureDir $out
|
||||||
cp ${udev}/*/udev/rules.d/60-persistent-storage.rules $out/
|
cp ${pkgs.udev}/*/udev/rules.d/60-persistent-storage.rules $out/
|
||||||
substituteInPlace $out/60-persistent-storage.rules \
|
substituteInPlace $out/60-persistent-storage.rules \
|
||||||
--replace ata_id ${extraUtils}/bin/ata_id \
|
--replace ata_id ${extraUtils}/bin/ata_id \
|
||||||
--replace usb_id ${extraUtils}/bin/usb_id \
|
--replace usb_id ${extraUtils}/bin/usb_id \
|
||||||
@ -117,11 +138,11 @@ rec {
|
|||||||
bootStage1 = pkgs.substituteAll {
|
bootStage1 = pkgs.substituteAll {
|
||||||
src = ./boot-stage-1-init.sh;
|
src = ./boot-stage-1-init.sh;
|
||||||
|
|
||||||
|
shell = "${extraUtils}/bin/bash";
|
||||||
|
|
||||||
isExecutable = true;
|
isExecutable = true;
|
||||||
|
|
||||||
staticShell = stdenvLinuxStuff.bootstrapTools.bash;
|
inherit modulesClosure udevConf extraUtils;
|
||||||
|
|
||||||
inherit modulesClosure udevConf;
|
|
||||||
|
|
||||||
inherit (config.boot) isLiveCD resumeDevice;
|
inherit (config.boot) isLiveCD resumeDevice;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user