Fix kernel crash caused by absent root device

This commit is contained in:
Ihor Antonov 2018-05-09 10:15:16 -04:00 committed by Tuomas Tynkkynen
parent e4777ae2d8
commit 08ebd830a5
4 changed files with 28 additions and 33 deletions

View File

@ -8,7 +8,7 @@ in {
imports = [ ../../../modules/virtualisation/amazon-image.nix ]; imports = [ ../../../modules/virtualisation/amazon-image.nix ];
# Required to avoid kernel panics on KVM instances where nvme volume availability can get delayed # Required to provide good EBS experience,
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html#timeout-nvme-ebs-volumes # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html#timeout-nvme-ebs-volumes
# TODO change value to 4294967295 when kernel is updated to 4.15 or later # TODO change value to 4294967295 when kernel is updated to 4.15 or later
config.boot.kernelParams = [ "nvme_core.io_timeout=255" ]; config.boot.kernelParams = [ "nvme_core.io_timeout=255" ];

View File

@ -30,7 +30,7 @@ with lib;
boot.initrd.postDeviceCommands = '' boot.initrd.postDeviceCommands = ''
rootDevice="${config.fileSystems."/".device}" rootDevice="${config.fileSystems."/".device}"
if [ -e "$rootDevice" ]; then if waitDevice "$rootDevice"; then
rootDevice="$(readlink -f "$rootDevice")" rootDevice="$(readlink -f "$rootDevice")"
parentDevice="$rootDevice" parentDevice="$rootDevice"
while [ "''${parentDevice%[0-9]}" != "''${parentDevice}" ]; do while [ "''${parentDevice%[0-9]}" != "''${parentDevice}" ]; do

View File

@ -74,6 +74,32 @@ ln -s /proc/mounts /etc/mtab # to shut up mke2fs
touch /etc/udev/hwdb.bin # to shut up udev touch /etc/udev/hwdb.bin # to shut up udev
touch /etc/initrd-release touch /etc/initrd-release
# Function for waiting a device to appear.
waitDevice() {
local device="$1"
# USB storage devices tend to appear with some delay. It would be
# great if we had a way to synchronously wait for them, but
# alas... So just wait for a few seconds for the device to
# appear.
if test ! -e $device; then
echo -n "waiting for device $device to appear..."
try=20
while [ $try -gt 0 ]; do
sleep 1
# also re-try lvm activation now that new block devices might have appeared
lvm vgchange -ay
# and tell udev to create nodes for the new LVs
udevadm trigger --action=add
if test -e $device; then break; fi
echo -n "."
try=$((try - 1))
done
echo
[ $try -ne 0 ]
fi
}
# Mount special file systems. # Mount special file systems.
specialMount() { specialMount() {
local device="$1" local device="$1"
@ -377,31 +403,7 @@ lustrateRoot () {
exec 4>&- exec 4>&-
} }
# Function for waiting a device to appear.
waitDevice() {
local device="$1"
# USB storage devices tend to appear with some delay. It would be
# great if we had a way to synchronously wait for them, but
# alas... So just wait for a few seconds for the device to
# appear.
if test ! -e $device; then
echo -n "waiting for device $device to appear..."
try=20
while [ $try -gt 0 ]; do
sleep 1
# also re-try lvm activation now that new block devices might have appeared
lvm vgchange -ay
# and tell udev to create nodes for the new LVs
udevadm trigger --action=add
if test -e $device; then break; fi
echo -n "."
try=$((try - 1))
done
echo
[ $try -ne 0 ]
fi
}
# Try to resume - all modules are loaded now. # Try to resume - all modules are loaded now.

View File

@ -48,13 +48,6 @@ let cfg = config.ec2; in
boot.loader.grub.extraPerEntryConfig = mkIf (!cfg.hvm) "root (hd0)"; boot.loader.grub.extraPerEntryConfig = mkIf (!cfg.hvm) "root (hd0)";
boot.loader.timeout = 0; boot.loader.timeout = 0;
boot.initrd.postDeviceCommands =
''
# Force udev to exit to prevent random "Device or resource busy
# while trying to open /dev/xvda" errors from fsck.
udevadm control --exit || true
'';
boot.initrd.network.enable = true; boot.initrd.network.enable = true;
# Mount all formatted ephemeral disks and activate all swap devices. # Mount all formatted ephemeral disks and activate all swap devices.