nixos/binfmt: Add option to use static emulators when available
The fixBinary flag will be enabled if a static emulator is in use.
This commit is contained in:
parent
4658a06076
commit
b8c1ef98e4
@ -296,6 +296,10 @@ let
|
||||
in {
|
||||
emulatorAvailable = pkgs: (selectEmulator pkgs) != null;
|
||||
|
||||
# whether final.emulator pkgs.pkgsStatic works
|
||||
staticEmulatorAvailable = pkgs: final.emulatorAvailable pkgs
|
||||
&& (final.isLinux || final.isWasi || final.isMmix);
|
||||
|
||||
emulator = pkgs:
|
||||
if (final.emulatorAvailable pkgs)
|
||||
then selectEmulator pkgs
|
||||
|
@ -96,6 +96,7 @@ lib.runTests (
|
||||
canExecute = null;
|
||||
emulator = null;
|
||||
emulatorAvailable = null;
|
||||
staticEmulatorAvailable = null;
|
||||
isCompatible = null;
|
||||
}?${platformAttrName};
|
||||
};
|
||||
|
@ -28,8 +28,6 @@ let
|
||||
''
|
||||
else interpreter;
|
||||
|
||||
getEmulator = system: (lib.systems.elaborate { inherit system; }).emulator pkgs;
|
||||
getQemuArch = system: (lib.systems.elaborate { inherit system; }).qemuArch;
|
||||
|
||||
# Mapping of systems to “magicOrExtension” and “mask”. Mostly taken from:
|
||||
# - https://github.com/cleverca22/nixos-configs/blob/master/qemu.nix
|
||||
@ -280,28 +278,50 @@ in {
|
||||
'';
|
||||
type = types.listOf (types.enum (builtins.attrNames magics));
|
||||
};
|
||||
|
||||
preferStaticEmulators = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to use static emulators when available.
|
||||
|
||||
This enables the kernel to preload the emulator binaries when
|
||||
the binfmt registrations are added, obviating the need to make
|
||||
the emulator binaries available inside chroots and chroot-like
|
||||
sandboxes.
|
||||
'';
|
||||
type = types.bool;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
assertions = lib.mapAttrsToList (name: reg: {
|
||||
assertion = reg.fixBinary -> !reg.wrapInterpreterInShell;
|
||||
message = "boot.binfmt.registrations.\"${name}\" cannot have fixBinary when the interpreter is invoked through a shell.";
|
||||
}) cfg.registrations;
|
||||
|
||||
boot.binfmt.registrations = builtins.listToAttrs (map (system: assert system != pkgs.stdenv.hostPlatform.system; {
|
||||
name = system;
|
||||
value = { config, ... }: let
|
||||
interpreter = getEmulator system;
|
||||
qemuArch = getQemuArch system;
|
||||
elaborated = lib.systems.elaborate { inherit system; };
|
||||
useStaticEmulator = cfg.preferStaticEmulators && elaborated.staticEmulatorAvailable pkgs;
|
||||
interpreter = elaborated.emulator (if useStaticEmulator then pkgs.pkgsStatic else pkgs);
|
||||
|
||||
inherit (elaborated) qemuArch;
|
||||
isQemu = "qemu-${qemuArch}" == baseNameOf interpreter;
|
||||
|
||||
preserveArgvZero = "qemu-${qemuArch}" == baseNameOf interpreter;
|
||||
interpreterReg = let
|
||||
wrapperName = "qemu-${qemuArch}-binfmt-P";
|
||||
wrapper = pkgs.wrapQemuBinfmtP wrapperName interpreter;
|
||||
in
|
||||
if preserveArgvZero then "${wrapper}/bin/${wrapperName}"
|
||||
if isQemu && !useStaticEmulator then "${wrapper}/bin/${wrapperName}"
|
||||
else interpreter;
|
||||
in ({
|
||||
preserveArgvZero = mkDefault preserveArgvZero;
|
||||
preserveArgvZero = mkDefault isQemu;
|
||||
|
||||
interpreter = mkDefault interpreterReg;
|
||||
wrapInterpreterInShell = mkDefault (!config.preserveArgvZero);
|
||||
fixBinary = mkDefault useStaticEmulator;
|
||||
wrapInterpreterInShell = mkDefault (!config.preserveArgvZero && !config.fixBinary);
|
||||
interpreterSandboxPath = mkDefault (dirOf (dirOf config.interpreter));
|
||||
} // (magics.${system} or (throw "Cannot create binfmt registration for system ${system}")));
|
||||
}) cfg.emulatedSystems);
|
||||
|
Loading…
Reference in New Issue
Block a user