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 {
|
in {
|
||||||
emulatorAvailable = pkgs: (selectEmulator pkgs) != null;
|
emulatorAvailable = pkgs: (selectEmulator pkgs) != null;
|
||||||
|
|
||||||
|
# whether final.emulator pkgs.pkgsStatic works
|
||||||
|
staticEmulatorAvailable = pkgs: final.emulatorAvailable pkgs
|
||||||
|
&& (final.isLinux || final.isWasi || final.isMmix);
|
||||||
|
|
||||||
emulator = pkgs:
|
emulator = pkgs:
|
||||||
if (final.emulatorAvailable pkgs)
|
if (final.emulatorAvailable pkgs)
|
||||||
then selectEmulator pkgs
|
then selectEmulator pkgs
|
||||||
|
@ -96,6 +96,7 @@ lib.runTests (
|
|||||||
canExecute = null;
|
canExecute = null;
|
||||||
emulator = null;
|
emulator = null;
|
||||||
emulatorAvailable = null;
|
emulatorAvailable = null;
|
||||||
|
staticEmulatorAvailable = null;
|
||||||
isCompatible = null;
|
isCompatible = null;
|
||||||
}?${platformAttrName};
|
}?${platformAttrName};
|
||||||
};
|
};
|
||||||
|
@ -28,8 +28,6 @@ let
|
|||||||
''
|
''
|
||||||
else interpreter;
|
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:
|
# Mapping of systems to “magicOrExtension” and “mask”. Mostly taken from:
|
||||||
# - https://github.com/cleverca22/nixos-configs/blob/master/qemu.nix
|
# - https://github.com/cleverca22/nixos-configs/blob/master/qemu.nix
|
||||||
@ -280,28 +278,50 @@ in {
|
|||||||
'';
|
'';
|
||||||
type = types.listOf (types.enum (builtins.attrNames magics));
|
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 = {
|
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; {
|
boot.binfmt.registrations = builtins.listToAttrs (map (system: assert system != pkgs.stdenv.hostPlatform.system; {
|
||||||
name = system;
|
name = system;
|
||||||
value = { config, ... }: let
|
value = { config, ... }: let
|
||||||
interpreter = getEmulator system;
|
elaborated = lib.systems.elaborate { inherit system; };
|
||||||
qemuArch = getQemuArch 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
|
interpreterReg = let
|
||||||
wrapperName = "qemu-${qemuArch}-binfmt-P";
|
wrapperName = "qemu-${qemuArch}-binfmt-P";
|
||||||
wrapper = pkgs.wrapQemuBinfmtP wrapperName interpreter;
|
wrapper = pkgs.wrapQemuBinfmtP wrapperName interpreter;
|
||||||
in
|
in
|
||||||
if preserveArgvZero then "${wrapper}/bin/${wrapperName}"
|
if isQemu && !useStaticEmulator then "${wrapper}/bin/${wrapperName}"
|
||||||
else interpreter;
|
else interpreter;
|
||||||
in ({
|
in ({
|
||||||
preserveArgvZero = mkDefault preserveArgvZero;
|
preserveArgvZero = mkDefault isQemu;
|
||||||
|
|
||||||
interpreter = mkDefault interpreterReg;
|
interpreter = mkDefault interpreterReg;
|
||||||
wrapInterpreterInShell = mkDefault (!config.preserveArgvZero);
|
fixBinary = mkDefault useStaticEmulator;
|
||||||
|
wrapInterpreterInShell = mkDefault (!config.preserveArgvZero && !config.fixBinary);
|
||||||
interpreterSandboxPath = mkDefault (dirOf (dirOf config.interpreter));
|
interpreterSandboxPath = mkDefault (dirOf (dirOf config.interpreter));
|
||||||
} // (magics.${system} or (throw "Cannot create binfmt registration for system ${system}")));
|
} // (magics.${system} or (throw "Cannot create binfmt registration for system ${system}")));
|
||||||
}) cfg.emulatedSystems);
|
}) cfg.emulatedSystems);
|
||||||
|
Loading…
Reference in New Issue
Block a user