1
1
mirror of https://github.com/NixOS/mobile-nixos.git synced 2024-12-15 11:03:37 +03:00
mobile-nixos/modules/initrd-logs.nix

107 lines
3.2 KiB
Nix
Raw Normal View History

{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkMerge mkOption optionalString types;
inherit (config.system.build) extraUtils;
cfg = config.mobile.boot.stage-1.bootlog;
in
{
options.mobile.boot.stage-1.bootlog = {
enable = mkOption {
type = types.bool;
default = true;
description = ''
Enables bootlogd logging multiplexer.
'';
};
kmsg = mkOption {
type = types.bool;
default = false;
description = ''
Enables logging to /dev/kmsg.
Note that this may render switching to stage-2 inoperable.
'';
};
};
config.mobile.boot.stage-1 = mkMerge [
(mkIf cfg.kmsg {
# This is a bit buggy:
# * fast burst of \n-delimited output will not work as expected
# * `printk.devkmsg=on` is required on the kernel cmdline for better results
# A better implementation would be to have a binary who's sole purpose is to
# duplicate the stdout/stderr to /dev/kmsg while still outputting them to
# stdout/stderr as they do currently.
#
# Reminder: redirecting to kmsg is useful *mainly* for getting data through
# console_ramoops on devices without serial and without any other means to
# get the initial data out.
earlyInitScripts = ''
${extraUtils}/bin/mknod /.kmsg c 1 11
exec > /.kmsg 2>&1
'';
})
(mkIf cfg.enable {
earlyInitScripts = ''
(
export LD_LIBRARY_PATH="${extraUtils}/lib"
export PATH="${extraUtils}/bin"
echo "Prepping to launch bootlog..."
# I'd really like *not* to prep mounts here, but bootlogd requires them.
# If we wait, we'll lose even more output.
echo "(Preparing /dev for /dev/pts)"
mkdir -p /dev
mount -t devtmpfs devtmpfs /dev
echo "(Preparing /dev/pts to identify console)"
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
bootlogd &
# Ugh, bootlogd takes a bit of time to be ready.
# Let's not drop logs
sleep 0.5
)
echo "Early logging started..."
echo
echo "***************************************"
echo "* Continuing with stage-1... *"
echo "***************************************"
echo
'';
tasks = [
(pkgs.writeText "bootlogd-task.rb" ''
class Tasks::KickstartBootlogd < SingletonTask
def initialize()
add_dependency(:Target, :Environment)
add_dependency(:Mount, "/proc")
add_dependency(:Mount, "/dev")
add_dependency(:Mount, "/run")
add_dependency(:Mount, "/dev/pts")
Targets[:Devices].add_dependency(:Task, self)
end
def run()
# bootlogd is already waiting for the file to appear.
FileUtils.mkdir_p("/run/log/")
File.write("/run/log/stage-1.log", "")
end
end
'')
];
extraUtils = with pkgs; [
{ package = bootlogd; }
];
})
];
config.boot.postBootCommands = mkIf cfg.enable ''
echo "Quitting bootlogd"
${pkgs.procps}/bin/pkill -x bootlogd
'';
}