Merge pull request #79532 from NixOS/fix-predictable-ifnames-in-initrd

nixos/stage-1: fix predictable interface names in initrd
This commit is contained in:
Maximilian Bosch 2020-03-02 17:14:06 +01:00 committed by GitHub
commit 70325e63d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 39 deletions

View File

@ -6,7 +6,11 @@ let
cfg = config.boot.initrd.network;
dhcpinterfaces = lib.attrNames (lib.filterAttrs (iface: v: v.useDHCP == true) (config.networking.interfaces or {}));
dhcpInterfaces = lib.attrNames (lib.filterAttrs (iface: v: v.useDHCP == true) (config.networking.interfaces or {}));
doDhcp = config.networking.useDHCP || dhcpInterfaces != [];
dhcpIfShellExpr = if config.networking.useDHCP
then "$(ls /sys/class/net/ | grep -v ^lo$)"
else lib.concatMapStringsSep " " lib.escapeShellArg dhcpInterfaces;
udhcpcScript = pkgs.writeScript "udhcp-script"
''
@ -62,6 +66,16 @@ in
'';
};
boot.initrd.network.flushBeforeStage2 = mkOption {
type = types.bool;
default = true;
description = ''
Whether to clear the configuration of the interfaces that were set up in
the initrd right before stage 2 takes over. Stage 2 will do the regular network
configuration based on the NixOS networking options.
'';
};
boot.initrd.network.udhcpc.extraArgs = mkOption {
default = [];
type = types.listOf types.str;
@ -89,49 +103,45 @@ in
boot.initrd.kernelModules = [ "af_packet" ];
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.mkinitcpio-nfs-utils}/bin/ipconfig
copy_bin_and_libs ${pkgs.klibc}/lib/klibc/bin.static/ipconfig
'';
boot.initrd.preLVMCommands = mkBefore (
# Search for interface definitions in command line.
''
ifaces=""
for o in $(cat /proc/cmdline); do
case $o in
ip=*)
ipconfig $o && hasNetwork=1
ipconfig $o && ifaces="$ifaces $(echo $o | cut -d: -f6)"
;;
esac
done
''
# Otherwise, use DHCP.
+ optionalString (config.networking.useDHCP || dhcpinterfaces != []) ''
if [ -z "$hasNetwork" ]; then
+ optionalString doDhcp ''
# Bring up all interfaces.
for iface in ${dhcpIfShellExpr}; do
echo "bringing up network interface $iface..."
ip link set "$iface" up && ifaces="$ifaces $iface"
done
# Bring up all interfaces.
for iface in $(ls /sys/class/net/); do
echo "bringing up network interface $iface..."
ip link set "$iface" up
done
# Acquire DHCP leases.
for iface in ${ if config.networking.useDHCP then
"$(ls /sys/class/net/ | grep -v ^lo$)"
else
lib.concatMapStringsSep " " lib.escapeShellArg dhcpinterfaces
}; do
echo "acquiring IP address via DHCP on $iface..."
udhcpc --quit --now -i $iface -O staticroutes --script ${udhcpcScript} ${udhcpcArgs} && hasNetwork=1
done
fi
# Acquire DHCP leases.
for iface in ${dhcpIfShellExpr}; do
echo "acquiring IP address via DHCP on $iface..."
udhcpc --quit --now -i $iface -O staticroutes --script ${udhcpcScript} ${udhcpcArgs}
done
''
+ ''
if [ -n "$hasNetwork" ]; then
echo "networking is up!"
${cfg.postCommands}
fi
'');
+ cfg.postCommands);
boot.initrd.postMountCommands = mkIf cfg.flushBeforeStage2 ''
for iface in $ifaces; do
ip address flush "$iface"
ip link down "$iface"
done
'';
};

View File

@ -210,6 +210,8 @@ done
# Create device nodes in /dev.
@preDeviceCommands@
echo "running udev..."
mkdir -p /etc/systemd
ln -sfn @linkUnits@ /etc/systemd/network
mkdir -p /etc/udev
ln -sfn @udevRules@ /etc/udev/rules.d
mkdir -p /dev/.mdadm
@ -266,7 +268,7 @@ checkFS() {
return 0
fi
# Device might be already mounted manually
# Device might be already mounted manually
# e.g. NBD-device or the host filesystem of the file which contains encrypted root fs
if mount | grep -q "^$device on "; then
echo "skip checking already mounted $device"
@ -351,7 +353,7 @@ mountFS() {
elif [ "$fsType" = f2fs ]; then
echo "resizing $device..."
fsck.f2fs -fp "$device"
resize.f2fs "$device"
resize.f2fs "$device"
fi
;;
esac

View File

@ -120,6 +120,7 @@ let
# Copy udev.
copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd
copy_bin_and_libs ${udev}/lib/systemd/systemd-sysctl
copy_bin_and_libs ${udev}/bin/udevadm
for BIN in ${udev}/lib/udev/*_id; do
copy_bin_and_libs $BIN
@ -198,6 +199,14 @@ let
''; # */
linkUnits = pkgs.runCommand "link-units" {
allowedReferences = [ extraUtils ];
preferLocalBuild = true;
} ''
mkdir -p $out
cp -v ${udev}/lib/systemd/network/*.link $out/
'';
udevRules = pkgs.runCommand "udev-rules" {
allowedReferences = [ extraUtils ];
preferLocalBuild = true;
@ -208,7 +217,9 @@ let
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/75-net-description.rules $out/
cp -v ${udev}/lib/udev/rules.d/80-drivers.rules $out/
cp -v ${udev}/lib/udev/rules.d/80-net-setup-link.rules $out/
cp -v ${pkgs.lvm2}/lib/udev/rules.d/*.rules $out/
${config.boot.initrd.extraUdevRulesCommands}
@ -222,7 +233,7 @@ let
--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
--replace ${udev} ${extraUtils}
done
# Work around a bug in QEMU, which doesn't implement the "READ
@ -257,7 +268,7 @@ let
${pkgs.buildPackages.busybox}/bin/ash -n $target
'';
inherit udevRules extraUtils modulesClosure;
inherit linkUnits udevRules extraUtils modulesClosure;
inherit (config.boot) resumeDevice;

View File

@ -1,4 +1,4 @@
import ./make-test-python.nix ({ pkgs, ...} : {
import ./make-test-python.nix ({ pkgs, lib, ...} : {
name = "initrd-network";
meta.maintainers = [ pkgs.stdenv.lib.maintainers.eelco ];
@ -8,15 +8,26 @@ import ./make-test-python.nix ({ pkgs, ...} : {
boot.initrd.network.enable = true;
boot.initrd.network.postCommands =
''
ip addr show
ip route show
ip addr | grep 10.0.2.15 || exit 1
ping -c1 10.0.2.2 || exit 1
'';
# Check if cleanup was done correctly
boot.initrd.postMountCommands = lib.mkAfter
''
ip addr show
ip route show
ip addr | grep 10.0.2.15 && exit 1
ping -c1 10.0.2.2 && exit 1
'';
};
testScript =
''
start_all()
machine.wait_for_unit("multi-user.target")
machine.succeed("ip link >&2")
machine.succeed("ip addr show >&2")
machine.succeed("ip route show >&2")
'';
})

View File

@ -17,6 +17,12 @@ in pkgs.lib.listToAttrs (pkgs.lib.crossLists (predictable: withNetworkd: {
networking.useNetworkd = withNetworkd;
networking.dhcpcd.enable = !withNetworkd;
networking.useDHCP = !withNetworkd;
# Check if predictable interface names are working in stage-1
boot.initrd.postDeviceCommands = ''
ip link
ip link show eth0 ${if predictable then "&&" else "||"} exit 1
'';
};
testScript = ''

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, linuxHeaders, perl }:
{ lib, stdenv, fetchurl, linuxHeaders, perl }:
let
commonMakeFlags = [
@ -9,11 +9,11 @@ in
stdenv.mkDerivation rec {
pname = "klibc";
version = "2.0.4";
version = "2.0.7";
src = fetchurl {
url = "mirror://kernel/linux/libs/klibc/2.0/klibc-${version}.tar.xz";
sha256 = "7f9a0850586def7cf4faeeb75e5d0f66e613674c524f6e77b0f4d93a26c801cb";
sha256 = "08li3aj9bvzabrih98jdxi3m19h85cp53s8cr7cqad42r8vjdvxb";
};
patches = [ ./no-reinstall-kernel-headers.patch ];
@ -35,7 +35,6 @@ stdenv.mkDerivation rec {
dir=$out/lib/klibc/bin.static
mkdir $dir
cp $(find $(find . -name static) -type f ! -name "*.g" -a ! -name ".*") $dir/
cp usr/dash/sh $dir/
for file in ${linuxHeaders}/include/*; do
ln -sv $file $out/lib/klibc/include
@ -43,6 +42,10 @@ stdenv.mkDerivation rec {
'';
meta = {
platforms = [ "x86_64-linux" ];
description = "Minimalistic libc subset for initramfs usage";
homepage = "https://kernel.org/pub/linux/libs/klibc/";
maintainers = with lib.maintainers; [ fpletz ];
license = lib.licenses.bsd3;
platforms = lib.platforms.linux;
};
}

View File

@ -5,7 +5,7 @@ diff -Naur klibc-2.0.3-orig/scripts/Kbuild.install klibc-2.0.3/scripts/Kbuild.in
$(Q)mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include
$(Q)mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)lib
$(Q)mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)bin
- $(Q)$(MAKE) -C $(KLIBCKERNELSRC) ARCH=$(KLIBCARCH) INSTALL_HDR_PATH=$(INSTALLROOT)$(INSTALLDIR)/$(KCROSS) headers_install
- $(Q)cp -rfL $(KLIBCKERNELSRC)/include/. $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include/.
$(Q)cp -rf usr/include/. $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include/.
$(Q)chmod -R a+rX $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include
$(Q)$(install-data) $(srctree)/klcc/klcc.1 $(INSTALLROOT)$(mandir)/man1/$(KCROSS)klcc.1