nixos/xen: simplify package options

Signed-off-by: Fernando Rodrigues <alpha@sigmasquadron.net>
This commit is contained in:
Fernando Rodrigues 2024-10-05 21:23:57 +00:00
parent f5e6e7ac2a
commit 251dc99c70
No known key found for this signature in database
GPG key ID: CC3AE2EA00000000

View file

@ -8,6 +8,35 @@
}: }:
let let
inherit (builtins) readFile;
inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule mkIf;
inherit (lib.options)
mkOption
mkEnableOption
literalExpression
mkPackageOption
;
inherit (lib.types)
listOf
str
ints
lines
enum
path
submodule
addCheck
float
bool
int
nullOr
;
inherit (lib.lists) optional optionals;
inherit (lib.strings) hasSuffix optionalString;
inherit (lib.meta) getExe;
inherit (lib.attrsets) optionalAttrs;
inherit (lib.trivial) boolToString;
inherit (lib.teams.xen) members;
cfg = config.virtualisation.xen; cfg = config.virtualisation.xen;
xenBootBuilder = pkgs.writeShellApplication { xenBootBuilder = pkgs.writeShellApplication {
@ -22,7 +51,7 @@ let
gnused gnused
jq jq
]) ])
++ lib.lists.optionals (cfg.efi.bootBuilderVerbosity == "info") ( ++ optionals (cfg.efi.bootBuilderVerbosity == "info") (
with pkgs; with pkgs;
[ [
bat bat
@ -36,12 +65,12 @@ let
# We disable SC2016 because we don't want to expand the regexes in the sed commands. # We disable SC2016 because we don't want to expand the regexes in the sed commands.
excludeShellChecks = [ "SC2016" ]; excludeShellChecks = [ "SC2016" ];
text = builtins.readFile ./xen-boot-builder.sh; text = readFile ./xen-boot-builder.sh;
}; };
in in
{ {
imports = with lib.modules; [ imports = [
(mkRemovedOptionModule (mkRemovedOptionModule
[ [
"virtualisation" "virtualisation"
@ -123,59 +152,33 @@ in
options.virtualisation.xen = { options.virtualisation.xen = {
enable = lib.options.mkEnableOption "the Xen Project Hypervisor, a virtualisation technology defined as a *type-1 hypervisor*, which allows multiple virtual machines, known as *domains*, to run concurrently on the physical machine. NixOS runs as the privileged *Domain 0*. This option requires a reboot into a Xen kernel to take effect"; enable = mkEnableOption "the Xen Project Hypervisor, a virtualisation technology defined as a *type-1 hypervisor*, which allows multiple virtual machines, known as *domains*, to run concurrently on the physical machine. NixOS runs as the privileged *Domain 0*. This option requires a reboot into a Xen kernel to take effect";
debug = lib.options.mkEnableOption "Xen debug features for Domain 0. This option enables some hidden debugging tests and features, and should not be used in production"; debug = mkEnableOption "Xen debug features for Domain 0. This option enables some hidden debugging tests and features, and should not be used in production";
trace = lib.options.mkOption { trace = mkOption {
type = lib.types.bool; type = bool;
default = cfg.debug; default = cfg.debug;
defaultText = lib.options.literalExpression "false"; defaultText = literalExpression "false";
example = true; example = true;
description = "Whether to enable Xen debug tracing and logging for Domain 0."; description = "Whether to enable Xen debug tracing and logging for Domain 0.";
}; };
package = lib.options.mkOption { package = mkPackageOption pkgs "Xen Hypervisor" { default = [ "xen" ]; };
type = lib.types.package;
default = pkgs.xen;
defaultText = lib.options.literalExpression "pkgs.xen";
example = lib.options.literalExpression "pkgs.xen-slim";
description = ''
The package used for Xen Project Hypervisor.
'';
relatedPackages = [
"xen"
"xen-slim"
];
};
qemu = { qemu = {
package = lib.options.mkOption { package = mkPackageOption pkgs "QEMU (with Xen Hypervisor support)" {
type = lib.types.package; default = [ "qemu_xen" ];
default = pkgs.xen;
defaultText = lib.options.literalExpression "pkgs.xen";
example = lib.options.literalExpression "pkgs.qemu_xen";
description = ''
The package with QEMU binaries that runs in Domain 0
and virtualises the unprivileged domains.
'';
relatedPackages = [
"xen"
{
name = "qemu_xen";
comment = "For use with `pkgs.xen-slim`.";
}
];
}; };
pidFile = lib.options.mkOption { pidFile = mkOption {
type = lib.types.path; type = path;
default = "/run/xen/qemu-dom0.pid"; default = "/run/xen/qemu-dom0.pid";
example = "/var/run/xen/qemu-dom0.pid"; example = "/var/run/xen/qemu-dom0.pid";
description = "Path to the QEMU PID file."; description = "Path to the QEMU PID file.";
}; };
}; };
bootParams = lib.options.mkOption { bootParams = mkOption {
default = [ ]; default = [ ];
example = '' example = ''
[ [
@ -184,7 +187,7 @@ in
"vga=ask" "vga=ask"
] ]
''; '';
type = lib.types.listOf lib.types.str; type = listOf str;
description = '' description = ''
Xen Command Line parameters passed to Domain 0 at boot time. Xen Command Line parameters passed to Domain 0 at boot time.
Note: these are different from `boot.kernelParams`. See Note: these are different from `boot.kernelParams`. See
@ -193,8 +196,8 @@ in
}; };
efi = { efi = {
bootBuilderVerbosity = lib.options.mkOption { bootBuilderVerbosity = mkOption {
type = lib.types.enum [ type = enum [
"default" "default"
"info" "info"
"debug" "debug"
@ -218,11 +221,11 @@ in
''; '';
}; };
path = lib.options.mkOption { path = mkOption {
type = lib.types.path; type = path;
default = "${cfg.package.boot}/${cfg.package.efi}"; default = "${cfg.package.boot}/${cfg.package.efi}";
defaultText = lib.options.literalExpression "\${config.virtualisation.xen.package.boot}/\${config.virtualisation.xen.package.efi}"; defaultText = literalExpression "\${config.virtualisation.xen.package.boot}/\${config.virtualisation.xen.package.efi}";
example = lib.options.literalExpression "\${config.virtualisation.xen.package}/boot/efi/efi/nixos/xen-\${config.virtualisation.xen.package.version}.efi"; example = literalExpression "\${config.virtualisation.xen.package}/boot/efi/efi/nixos/xen-\${config.virtualisation.xen.package.version}.efi";
description = '' description = ''
Path to xen.efi. `pkgs.xen` is patched to install the xen.efi file Path to xen.efi. `pkgs.xen` is patched to install the xen.efi file
on `$boot/boot/xen.efi`, but an unpatched Xen build may install it on `$boot/boot/xen.efi`, but an unpatched Xen build may install it
@ -234,10 +237,10 @@ in
}; };
dom0Resources = { dom0Resources = {
maxVCPUs = lib.options.mkOption { maxVCPUs = mkOption {
default = 0; default = 0;
example = 4; example = 4;
type = lib.types.ints.unsigned; type = ints.unsigned;
description = '' description = ''
Amount of virtual CPU cores allocated to Domain 0 on boot. Amount of virtual CPU cores allocated to Domain 0 on boot.
If set to 0, all cores are assigned to Domain 0, and If set to 0, all cores are assigned to Domain 0, and
@ -245,10 +248,10 @@ in
''; '';
}; };
memory = lib.options.mkOption { memory = mkOption {
default = 0; default = 0;
example = 512; example = 512;
type = lib.types.ints.unsigned; type = ints.unsigned;
description = '' description = ''
Amount of memory (in MiB) allocated to Domain 0 on boot. Amount of memory (in MiB) allocated to Domain 0 on boot.
If set to 0, all memory is assigned to Domain 0, and If set to 0, all memory is assigned to Domain 0, and
@ -256,11 +259,11 @@ in
''; '';
}; };
maxMemory = lib.options.mkOption { maxMemory = mkOption {
default = cfg.dom0Resources.memory; default = cfg.dom0Resources.memory;
defaultText = lib.options.literalExpression "config.virtualisation.xen.dom0Resources.memory"; defaultText = literalExpression "config.virtualisation.xen.dom0Resources.memory";
example = 1024; example = 1024;
type = lib.types.ints.unsigned; type = ints.unsigned;
description = '' description = ''
Maximum amount of memory (in MiB) that Domain 0 can Maximum amount of memory (in MiB) that Domain 0 can
dynamically allocate to itself. Does nothing if set dynamically allocate to itself. Does nothing if set
@ -271,8 +274,8 @@ in
}; };
domains = { domains = {
extraConfig = lib.options.mkOption { extraConfig = mkOption {
type = lib.types.lines; type = lines;
default = ""; default = "";
example = '' example = ''
XENDOMAINS_SAVE=/persist/xen/save XENDOMAINS_SAVE=/persist/xen/save
@ -288,28 +291,28 @@ in
}; };
store = { store = {
path = lib.options.mkOption { path = mkOption {
type = lib.types.path; type = path;
default = "${cfg.package}/bin/oxenstored"; default = "${cfg.package}/bin/oxenstored";
defaultText = lib.options.literalExpression "\${config.virtualisation.xen.package}/bin/oxenstored"; defaultText = literalExpression "\${config.virtualisation.xen.package}/bin/oxenstored";
example = lib.options.literalExpression "\${config.virtualisation.xen.package}/bin/xenstored"; example = literalExpression "\${config.virtualisation.xen.package}/bin/xenstored";
description = '' description = ''
Path to the Xen Store Daemon. This option is useful to Path to the Xen Store Daemon. This option is useful to
switch between the legacy C-based Xen Store Daemon, and switch between the legacy C-based Xen Store Daemon, and
the newer OCaml-based Xen Store Daemon, `oxenstored`. the newer OCaml-based Xen Store Daemon, `oxenstored`.
''; '';
}; };
type = lib.options.mkOption { type = mkOption {
type = lib.types.enum [ type = enum [
"c" "c"
"ocaml" "ocaml"
]; ];
default = if (lib.strings.hasSuffix "oxenstored" cfg.store.path) then "ocaml" else "c"; default = if (hasSuffix "oxenstored" cfg.store.path) then "ocaml" else "c";
internal = true; internal = true;
readOnly = true; readOnly = true;
description = "Helper internal option that determines the type of the Xen Store Daemon based on cfg.store.path."; description = "Helper internal option that determines the type of the Xen Store Daemon based on cfg.store.path.";
}; };
settings = lib.options.mkOption { settings = mkOption {
default = { }; default = { };
example = { example = {
enableMerge = false; enableMerge = false;
@ -324,34 +327,34 @@ in
The OCaml-based Xen Store Daemon configuration. This The OCaml-based Xen Store Daemon configuration. This
option does nothing with the C-based `xenstored`. option does nothing with the C-based `xenstored`.
''; '';
type = lib.types.submodule { type = submodule {
options = { options = {
pidFile = lib.options.mkOption { pidFile = mkOption {
default = "/run/xen/xenstored.pid"; default = "/run/xen/xenstored.pid";
example = "/var/run/xen/xenstored.pid"; example = "/var/run/xen/xenstored.pid";
type = lib.types.path; type = path;
description = "Path to the Xen Store Daemon PID file."; description = "Path to the Xen Store Daemon PID file.";
}; };
testEAGAIN = lib.options.mkOption { testEAGAIN = mkOption {
default = cfg.debug; default = cfg.debug;
defaultText = lib.options.literalExpression "config.virtualisation.xen.debug"; defaultText = literalExpression "config.virtualisation.xen.debug";
example = true; example = true;
type = lib.types.bool; type = bool;
visible = false; visible = false;
description = "Randomly fail a transaction with EAGAIN. This option is used for debugging purposes only."; description = "Randomly fail a transaction with EAGAIN. This option is used for debugging purposes only.";
}; };
enableMerge = lib.options.mkOption { enableMerge = mkOption {
default = true; default = true;
example = false; example = false;
type = lib.types.bool; type = bool;
description = "Whether to enable transaction merge support."; description = "Whether to enable transaction merge support.";
}; };
conflict = { conflict = {
burstLimit = lib.options.mkOption { burstLimit = mkOption {
default = 5.0; default = 5.0;
example = 15.0; example = 15.0;
type = lib.types.addCheck ( type = addCheck (
lib.types.float float
// { // {
name = "nonnegativeFloat"; name = "nonnegativeFloat";
description = "nonnegative floating point number, meaning >=0"; description = "nonnegative floating point number, meaning >=0";
@ -369,12 +372,12 @@ in
domain's requests are ignored. domain's requests are ignored.
''; '';
}; };
maxHistorySeconds = lib.options.mkOption { maxHistorySeconds = mkOption {
default = 5.0e-2; default = 5.0e-2;
example = 1.0; example = 1.0;
type = lib.types.addCheck ( type = addCheck (float // { description = "nonnegative floating point number, meaning >=0"; }) (
lib.types.float // { description = "nonnegative floating point number, meaning >=0"; } n: n >= 0
) (n: n >= 0); );
description = '' description = ''
Limits applied to domains whose writes cause other domains' transaction Limits applied to domains whose writes cause other domains' transaction
commits to fail. Must include decimal point. commits to fail. Must include decimal point.
@ -384,10 +387,10 @@ in
is the minimum pause-time during which a domain will be ignored. is the minimum pause-time during which a domain will be ignored.
''; '';
}; };
rateLimitIsAggregate = lib.options.mkOption { rateLimitIsAggregate = mkOption {
default = true; default = true;
example = false; example = false;
type = lib.types.bool; type = bool;
description = '' description = ''
If the conflict.rateLimitIsAggregate option is `true`, then after each If the conflict.rateLimitIsAggregate option is `true`, then after each
tick one point of conflict-credit is given to just one domain: the tick one point of conflict-credit is given to just one domain: the
@ -408,16 +411,16 @@ in
}; };
}; };
perms = { perms = {
enable = lib.options.mkOption { enable = mkOption {
default = true; default = true;
example = false; example = false;
type = lib.types.bool; type = bool;
description = "Whether to enable the node permission system."; description = "Whether to enable the node permission system.";
}; };
enableWatch = lib.options.mkOption { enableWatch = mkOption {
default = true; default = true;
example = false; example = false;
type = lib.types.bool; type = bool;
description = '' description = ''
Whether to enable the watch permission system. Whether to enable the watch permission system.
@ -432,144 +435,142 @@ in
}; };
}; };
quota = { quota = {
enable = lib.options.mkOption { enable = mkOption {
default = true; default = true;
example = false; example = false;
type = lib.types.bool; type = bool;
description = "Whether to enable the quota system."; description = "Whether to enable the quota system.";
}; };
maxEntity = lib.options.mkOption { maxEntity = mkOption {
default = 1000; default = 1000;
example = 1024; example = 1024;
type = lib.types.ints.positive; type = ints.positive;
description = "Entity limit for transactions."; description = "Entity limit for transactions.";
}; };
maxSize = lib.options.mkOption { maxSize = mkOption {
default = 2048; default = 2048;
example = 4096; example = 4096;
type = lib.types.ints.positive; type = ints.positive;
description = "Size limit for transactions."; description = "Size limit for transactions.";
}; };
maxWatch = lib.options.mkOption { maxWatch = mkOption {
default = 100; default = 100;
example = 256; example = 256;
type = lib.types.ints.positive; type = ints.positive;
description = "Maximum number of watches by the Xenstore Watchdog."; description = "Maximum number of watches by the Xenstore Watchdog.";
}; };
transaction = lib.options.mkOption { transaction = mkOption {
default = 10; default = 10;
example = 50; example = 50;
type = lib.types.ints.positive; type = ints.positive;
description = "Maximum number of transactions."; description = "Maximum number of transactions.";
}; };
maxRequests = lib.options.mkOption { maxRequests = mkOption {
default = 1024; default = 1024;
example = 1024; example = 1024;
type = lib.types.ints.positive; type = ints.positive;
description = "Maximum number of requests per transaction."; description = "Maximum number of requests per transaction.";
}; };
maxPath = lib.options.mkOption { maxPath = mkOption {
default = 1024; default = 1024;
example = 1024; example = 1024;
type = lib.types.ints.positive; type = ints.positive;
description = "Path limit for the quota system."; description = "Path limit for the quota system.";
}; };
maxOutstanding = lib.options.mkOption { maxOutstanding = mkOption {
default = 1024; default = 1024;
example = 1024; example = 1024;
type = lib.types.ints.positive; type = ints.positive;
description = "Maximum outstanding requests, i.e. in-flight requests / domain."; description = "Maximum outstanding requests, i.e. in-flight requests / domain.";
}; };
maxWatchEvents = lib.options.mkOption { maxWatchEvents = mkOption {
default = 1024; default = 1024;
example = 2048; example = 2048;
type = lib.types.ints.positive; type = ints.positive;
description = "Maximum number of outstanding watch events per watch."; description = "Maximum number of outstanding watch events per watch.";
}; };
}; };
persistent = lib.options.mkOption { persistent = mkOption {
default = false; default = false;
example = true; example = true;
type = lib.types.bool; type = bool;
description = "Whether to activate the filed base backend."; description = "Whether to activate the filed base backend.";
}; };
xenstored = { xenstored = {
log = { log = {
file = lib.options.mkOption { file = mkOption {
default = "/var/log/xen/xenstored.log"; default = "/var/log/xen/xenstored.log";
example = "/dev/null"; example = "/dev/null";
type = lib.types.path; type = path;
description = "Path to the Xen Store log file."; description = "Path to the Xen Store log file.";
}; };
level = lib.options.mkOption { level = mkOption {
default = if cfg.trace then "debug" else null; default = if cfg.trace then "debug" else null;
defaultText = lib.options.literalExpression "if (config.virtualisation.xen.trace == true) then \"debug\" else null"; defaultText = literalExpression "if (config.virtualisation.xen.trace == true) then \"debug\" else null";
example = "error"; example = "error";
type = lib.types.nullOr ( type = nullOr (enum [
lib.types.enum [ "debug"
"debug" "info"
"info" "warn"
"warn" "error"
"error" ]);
]
);
description = "Logging level for the Xen Store."; description = "Logging level for the Xen Store.";
}; };
# The hidden options below have no upstream documentation whatsoever. # The hidden options below have no upstream documentation whatsoever.
# The nb* options appear to alter the log rotation behaviour, and # The nb* options appear to alter the log rotation behaviour, and
# the specialOps option appears to affect the Xenbus logging logic. # the specialOps option appears to affect the Xenbus logging logic.
nbFiles = lib.options.mkOption { nbFiles = mkOption {
default = 10; default = 10;
example = 16; example = 16;
type = lib.types.int; type = int;
visible = false; visible = false;
description = "Set `xenstored-log-nb-files`."; description = "Set `xenstored-log-nb-files`.";
}; };
}; };
accessLog = { accessLog = {
file = lib.options.mkOption { file = mkOption {
default = "/var/log/xen/xenstored-access.log"; default = "/var/log/xen/xenstored-access.log";
example = "/var/log/security/xenstored-access.log"; example = "/var/log/security/xenstored-access.log";
type = lib.types.path; type = path;
description = "Path to the Xen Store access log file."; description = "Path to the Xen Store access log file.";
}; };
nbLines = lib.options.mkOption { nbLines = mkOption {
default = 13215; default = 13215;
example = 16384; example = 16384;
type = lib.types.int; type = int;
visible = false; visible = false;
description = "Set `access-log-nb-lines`."; description = "Set `access-log-nb-lines`.";
}; };
nbChars = lib.options.mkOption { nbChars = mkOption {
default = 180; default = 180;
example = 256; example = 256;
type = lib.types.int; type = int;
visible = false; visible = false;
description = "Set `acesss-log-nb-chars`."; description = "Set `acesss-log-nb-chars`.";
}; };
specialOps = lib.options.mkOption { specialOps = mkOption {
default = false; default = false;
example = true; example = true;
type = lib.types.bool; type = bool;
visible = false; visible = false;
description = "Set `access-log-special-ops`."; description = "Set `access-log-special-ops`.";
}; };
}; };
xenfs = { xenfs = {
kva = lib.options.mkOption { kva = mkOption {
default = "/proc/xen/xsd_kva"; default = "/proc/xen/xsd_kva";
example = cfg.store.settings.xenstored.xenfs.kva; example = cfg.store.settings.xenstored.xenfs.kva;
type = lib.types.path; type = path;
visible = false; visible = false;
description = '' description = ''
Path to the Xen Store Daemon KVA location inside the XenFS pseudo-filesystem. Path to the Xen Store Daemon KVA location inside the XenFS pseudo-filesystem.
While it is possible to alter this value, some drivers may be hardcoded to follow the default paths. While it is possible to alter this value, some drivers may be hardcoded to follow the default paths.
''; '';
}; };
port = lib.options.mkOption { port = mkOption {
default = "/proc/xen/xsd_port"; default = "/proc/xen/xsd_port";
example = cfg.store.settings.xenstored.xenfs.port; example = cfg.store.settings.xenstored.xenfs.port;
type = lib.types.path; type = path;
visible = false; visible = false;
description = '' description = ''
Path to the Xen Store Daemon userspace port inside the XenFS pseudo-filesystem. Path to the Xen Store Daemon userspace port inside the XenFS pseudo-filesystem.
@ -578,11 +579,11 @@ in
}; };
}; };
}; };
ringScanInterval = lib.options.mkOption { ringScanInterval = mkOption {
default = 20; default = 20;
example = 30; example = 30;
type = lib.types.addCheck ( type = addCheck (
lib.types.int int
// { // {
name = "nonzeroInt"; name = "nonzeroInt";
description = "nonzero signed integer, meaning !=0"; description = "nonzero signed integer, meaning !=0";
@ -602,7 +603,7 @@ in
## Implementation ## ## Implementation ##
config = lib.modules.mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [
{ {
assertion = pkgs.stdenv.hostPlatform.isx86_64; assertion = pkgs.stdenv.hostPlatform.isx86_64;
@ -639,18 +640,18 @@ in
]; ];
virtualisation.xen.bootParams = virtualisation.xen.bootParams =
lib.lists.optionals cfg.trace [ optionals cfg.trace [
"loglvl=all" "loglvl=all"
"guest_loglvl=all" "guest_loglvl=all"
] ]
++ ++
lib.lists.optional (cfg.dom0Resources.memory != 0) optional (cfg.dom0Resources.memory != 0)
"dom0_mem=${toString cfg.dom0Resources.memory}M${ "dom0_mem=${toString cfg.dom0Resources.memory}M${
lib.strings.optionalString ( optionalString (
cfg.dom0Resources.memory != cfg.dom0Resources.maxMemory cfg.dom0Resources.memory != cfg.dom0Resources.maxMemory
) ",max:${toString cfg.dom0Resources.maxMemory}M" ) ",max:${toString cfg.dom0Resources.maxMemory}M"
}" }"
++ lib.lists.optional ( ++ optional (
cfg.dom0Resources.maxVCPUs != 0 cfg.dom0Resources.maxVCPUs != 0
) "dom0_max_vcpus=${toString cfg.dom0Resources.maxVCPUs}"; ) "dom0_max_vcpus=${toString cfg.dom0Resources.maxVCPUs}";
@ -701,7 +702,7 @@ in
# See the `xenBootBuilder` script in the main `let...in` statement of this file. # See the `xenBootBuilder` script in the main `let...in` statement of this file.
loader.systemd-boot.extraInstallCommands = '' loader.systemd-boot.extraInstallCommands = ''
${lib.meta.getExe xenBootBuilder} ${cfg.efi.bootBuilderVerbosity} ${getExe xenBootBuilder} ${cfg.efi.bootBuilderVerbosity}
''; '';
}; };
@ -744,7 +745,7 @@ in
XENSTORED="${cfg.store.path}" XENSTORED="${cfg.store.path}"
QEMU_XEN="${cfg.qemu.package}/${cfg.qemu.package.qemu-system-i386}" QEMU_XEN="${cfg.qemu.package}/${cfg.qemu.package.qemu-system-i386}"
${lib.strings.optionalString cfg.trace '' ${optionalString cfg.trace ''
XENSTORED_TRACE=yes XENSTORED_TRACE=yes
XENCONSOLED_TRACE=all XENCONSOLED_TRACE=all
''} ''}
@ -756,10 +757,10 @@ in
''; '';
} }
# The OCaml-based Xen Store Daemon requires /etc/xen/oxenstored.conf to start. # The OCaml-based Xen Store Daemon requires /etc/xen/oxenstored.conf to start.
// lib.attrsets.optionalAttrs (cfg.store.type == "ocaml") { // optionalAttrs (cfg.store.type == "ocaml") {
"xen/oxenstored.conf".text = '' "xen/oxenstored.conf".text = ''
pid-file = ${cfg.store.settings.pidFile} pid-file = ${cfg.store.settings.pidFile}
test-eagain = ${lib.trivial.boolToString cfg.store.settings.testEAGAIN} test-eagain = ${boolToString cfg.store.settings.testEAGAIN}
merge-activate = ${toString cfg.store.settings.enableMerge} merge-activate = ${toString cfg.store.settings.enableMerge}
conflict-burst-limit = ${toString cfg.store.settings.conflict.burstLimit} conflict-burst-limit = ${toString cfg.store.settings.conflict.burstLimit}
conflict-max-history-seconds = ${toString cfg.store.settings.conflict.maxHistorySeconds} conflict-max-history-seconds = ${toString cfg.store.settings.conflict.maxHistorySeconds}
@ -775,7 +776,7 @@ in
quota-path-max = ${toString cfg.store.settings.quota.maxPath} quota-path-max = ${toString cfg.store.settings.quota.maxPath}
quota-maxoutstanding = ${toString cfg.store.settings.quota.maxOutstanding} quota-maxoutstanding = ${toString cfg.store.settings.quota.maxOutstanding}
quota-maxwatchevents = ${toString cfg.store.settings.quota.maxWatchEvents} quota-maxwatchevents = ${toString cfg.store.settings.quota.maxWatchEvents}
persistent = ${lib.trivial.boolToString cfg.store.settings.persistent} persistent = ${boolToString cfg.store.settings.persistent}
xenstored-log-file = ${cfg.store.settings.xenstored.log.file} xenstored-log-file = ${cfg.store.settings.xenstored.log.file}
xenstored-log-level = ${ xenstored-log-level = ${
if isNull cfg.store.settings.xenstored.log.level then if isNull cfg.store.settings.xenstored.log.level then
@ -787,7 +788,7 @@ in
access-log-file = ${cfg.store.settings.xenstored.accessLog.file} access-log-file = ${cfg.store.settings.xenstored.accessLog.file}
access-log-nb-lines = ${toString cfg.store.settings.xenstored.accessLog.nbLines} access-log-nb-lines = ${toString cfg.store.settings.xenstored.accessLog.nbLines}
acesss-log-nb-chars = ${toString cfg.store.settings.xenstored.accessLog.nbChars} acesss-log-nb-chars = ${toString cfg.store.settings.xenstored.accessLog.nbChars}
access-log-special-ops = ${lib.trivial.boolToString cfg.store.settings.xenstored.accessLog.specialOps} access-log-special-ops = ${boolToString cfg.store.settings.xenstored.accessLog.specialOps}
ring-scan-interval = ${toString cfg.store.settings.ringScanInterval} ring-scan-interval = ${toString cfg.store.settings.ringScanInterval}
xenstored-kva = ${cfg.store.settings.xenstored.xenfs.kva} xenstored-kva = ${cfg.store.settings.xenstored.xenfs.kva}
xenstored-port = ${cfg.store.settings.xenstored.xenfs.port} xenstored-port = ${cfg.store.settings.xenstored.xenfs.port}
@ -870,5 +871,5 @@ in
}; };
}; };
}; };
meta.maintainers = lib.teams.xen.members; meta.maintainers = members;
} }