diff options
Diffstat (limited to 'nixos/modules/services/networking/multipath.nix')
-rw-r--r-- | nixos/modules/services/networking/multipath.nix | 559 |
1 files changed, 0 insertions, 559 deletions
diff --git a/nixos/modules/services/networking/multipath.nix b/nixos/modules/services/networking/multipath.nix deleted file mode 100644 index acbb7862a54..00000000000 --- a/nixos/modules/services/networking/multipath.nix +++ /dev/null @@ -1,559 +0,0 @@ -{ config, lib, pkgs, ... }: with lib; - -# See http://christophe.varoqui.free.fr/usage.html and -# https://github.com/opensvc/multipath-tools/blob/master/multipath/multipath.conf.5 - -let - cfg = config.services.multipath; - - indentLines = n: str: concatStringsSep "\n" ( - map (line: "${fixedWidthString n " " " "}${line}") ( - filter ( x: x != "" ) ( splitString "\n" str ) - ) - ); - - addCheckDesc = desc: elemType: check: types.addCheck elemType check - // { description = "${elemType.description} (with check: ${desc})"; }; - hexChars = stringToCharacters "0123456789abcdef"; - isHexString = s: all (c: elem c hexChars) (stringToCharacters (toLower s)); - hexStr = addCheckDesc "hexadecimal string" types.str isHexString; - -in { - - options.services.multipath = with types; { - - enable = mkEnableOption "the device mapper multipath (DM-MP) daemon"; - - package = mkOption { - type = package; - description = "multipath-tools package to use"; - default = pkgs.multipath-tools; - defaultText = "pkgs.multipath-tools"; - }; - - devices = mkOption { - default = [ ]; - example = literalExpression '' - [ - { - vendor = "\"COMPELNT\""; - product = "\"Compellent Vol\""; - path_checker = "tur"; - no_path_retry = "queue"; - max_sectors_kb = 256; - }, ... - ] - ''; - description = '' - This option allows you to define arrays for use in multipath - groups. - ''; - type = listOf (submodule { - imports = [ (mkRemovedOptionModule [ "retain_attached_hw_handler" ]) ]; - - options = { - - vendor = mkOption { - type = str; - example = "COMPELNT"; - description = "Regular expression to match the vendor name"; - }; - - product = mkOption { - type = str; - example = "Compellent Vol"; - description = "Regular expression to match the product name"; - }; - - revision = mkOption { - type = nullOr str; - default = null; - description = "Regular expression to match the product revision"; - }; - - product_blacklist = mkOption { - type = nullOr str; - default = null; - description = "Products with the given vendor matching this string are blacklisted"; - }; - - alias_prefix = mkOption { - type = nullOr str; - default = null; - description = "The user_friendly_names prefix to use for this device type, instead of the default mpath"; - }; - - vpd_vendor = mkOption { - type = nullOr str; - default = null; - description = "The vendor specific vpd page information, using the vpd page abbreviation"; - }; - - hardware_handler = mkOption { - type = nullOr (enum [ "emc" "rdac" "hp_sw" "alua" "ana" ]); - default = null; - description = "The hardware handler to use for this device type"; - }; - - # Optional arguments - path_grouping_policy = mkOption { - type = nullOr (enum [ "failover" "multibus" "group_by_serial" "group_by_prio" "group_by_node_name" ]); - default = null; # real default: "failover" - description = "The default path grouping policy to apply to unspecified multipaths"; - }; - - uid_attribute = mkOption { - type = nullOr str; - default = null; - description = "The udev attribute providing a unique path identifier (WWID)"; - }; - - getuid_callout = mkOption { - type = nullOr str; - default = null; - description = '' - (Superseded by uid_attribute) The default program and args to callout - to obtain a unique path identifier. Should be specified with an absolute path. - ''; - }; - - path_selector = mkOption { - type = nullOr (enum [ - ''"round-robin 0"'' - ''"queue-length 0"'' - ''"service-time 0"'' - ''"historical-service-time 0"'' - ]); - default = null; # real default: "service-time 0" - description = "The default path selector algorithm to use; they are offered by the kernel multipath target"; - }; - - path_checker = mkOption { - type = enum [ "readsector0" "tur" "emc_clariion" "hp_sw" "rdac" "directio" "cciss_tur" "none" ]; - default = "tur"; - description = "The default method used to determine the paths state"; - }; - - prio = mkOption { - type = nullOr (enum [ - "none" "const" "sysfs" "emc" "alua" "ontap" "rdac" "hp_sw" "hds" - "random" "weightedpath" "path_latency" "ana" "datacore" "iet" - ]); - default = null; # real default: "const" - description = "The name of the path priority routine"; - }; - - prio_args = mkOption { - type = nullOr str; - default = null; - description = "Arguments to pass to to the prio function"; - }; - - features = mkOption { - type = nullOr str; - default = null; - description = "Specify any device-mapper features to be used"; - }; - - failback = mkOption { - type = nullOr str; - default = null; # real default: "manual" - description = "Tell multipathd how to manage path group failback. Quote integers as strings"; - }; - - rr_weight = mkOption { - type = nullOr (enum [ "priorities" "uniform" ]); - default = null; # real default: "uniform" - description = '' - If set to priorities the multipath configurator will assign path weights - as "path prio * rr_min_io". - ''; - }; - - no_path_retry = mkOption { - type = nullOr str; - default = null; # real default: "fail" - description = "Specify what to do when all paths are down. Quote integers as strings"; - }; - - rr_min_io = mkOption { - type = nullOr int; - default = null; # real default: 1000 - description = '' - Number of I/O requests to route to a path before switching to the next in the - same path group. This is only for Block I/O (BIO) based multipath and - only apply to round-robin path_selector. - ''; - }; - - rr_min_io_rq = mkOption { - type = nullOr int; - default = null; # real default: 1 - description = '' - Number of I/O requests to route to a path before switching to the next in the - same path group. This is only for Request based multipath and - only apply to round-robin path_selector. - ''; - }; - - fast_io_fail_tmo = mkOption { - type = nullOr str; - default = null; # real default: 5 - description = '' - Specify the number of seconds the SCSI layer will wait after a problem has been - detected on a FC remote port before failing I/O to devices on that remote port. - This should be smaller than dev_loss_tmo. Setting this to "off" will disable - the timeout. Quote integers as strings. - ''; - }; - - dev_loss_tmo = mkOption { - type = nullOr str; - default = null; # real default: 600 - description = '' - Specify the number of seconds the SCSI layer will wait after a problem has - been detected on a FC remote port before removing it from the system. This - can be set to "infinity" which sets it to the max value of 2147483647 - seconds, or 68 years. It will be automatically adjusted to the overall - retry interval no_path_retry * polling_interval - if a number of retries is given with no_path_retry and the - overall retry interval is longer than the specified dev_loss_tmo value. - The Linux kernel will cap this value to 600 if fast_io_fail_tmo - is not set. - ''; - }; - - flush_on_last_del = mkOption { - type = nullOr (enum [ "yes" "no" ]); - default = null; # real default: "no" - description = '' - If set to "yes" multipathd will disable queueing when the last path to a - device has been deleted. - ''; - }; - - user_friendly_names = mkOption { - type = nullOr (enum [ "yes" "no" ]); - default = null; # real default: "no" - description = '' - If set to "yes", using the bindings file /etc/multipath/bindings - to assign a persistent and unique alias to the multipath, in the - form of mpath. If set to "no" use the WWID as the alias. In either - case this be will be overridden by any specific aliases in the - multipaths section. - ''; - }; - - detect_prio = mkOption { - type = nullOr (enum [ "yes" "no" ]); - default = null; # real default: "yes" - description = '' - If set to "yes", multipath will try to detect if the device supports - SCSI-3 ALUA. If so, the device will automatically use the sysfs - prioritizer if the required sysf attributes access_state and - preferred_path are supported, or the alua prioritizer if not. If set - to "no", the prioritizer will be selected as usual. - ''; - }; - - detect_checker = mkOption { - type = nullOr (enum [ "yes" "no" ]); - default = null; # real default: "yes" - description = '' - If set to "yes", multipath will try to detect if the device supports - SCSI-3 ALUA. If so, the device will automatically use the tur checker. - If set to "no", the checker will be selected as usual. - ''; - }; - - deferred_remove = mkOption { - type = nullOr (enum [ "yes" "no" ]); - default = null; # real default: "no" - description = '' - If set to "yes", multipathd will do a deferred remove instead of a - regular remove when the last path device has been deleted. This means - that if the multipath device is still in use, it will be freed when - the last user closes it. If path is added to the multipath device - before the last user closes it, the deferred remove will be canceled. - ''; - }; - - san_path_err_threshold = mkOption { - type = nullOr str; - default = null; - description = '' - If set to a value greater than 0, multipathd will watch paths and check - how many times a path has been failed due to errors.If the number of - failures on a particular path is greater then the san_path_err_threshold, - then the path will not reinstate till san_path_err_recovery_time. These - path failures should occur within a san_path_err_forget_rate checks, if - not we will consider the path is good enough to reinstantate. - ''; - }; - - san_path_err_forget_rate = mkOption { - type = nullOr str; - default = null; - description = '' - If set to a value greater than 0, multipathd will check whether the path - failures has exceeded the san_path_err_threshold within this many checks - i.e san_path_err_forget_rate. If so we will not reinstante the path till - san_path_err_recovery_time. - ''; - }; - - san_path_err_recovery_time = mkOption { - type = nullOr str; - default = null; - description = '' - If set to a value greater than 0, multipathd will make sure that when - path failures has exceeded the san_path_err_threshold within - san_path_err_forget_rate then the path will be placed in failed state - for san_path_err_recovery_time duration. Once san_path_err_recovery_time - has timeout we will reinstante the failed path. san_path_err_recovery_time - value should be in secs. - ''; - }; - - marginal_path_err_sample_time = mkOption { - type = nullOr int; - default = null; - description = "One of the four parameters of supporting path check based on accounting IO error such as intermittent error"; - }; - - marginal_path_err_rate_threshold = mkOption { - type = nullOr int; - default = null; - description = "The error rate threshold as a permillage (1/1000)"; - }; - - marginal_path_err_recheck_gap_time = mkOption { - type = nullOr str; - default = null; - description = "One of the four parameters of supporting path check based on accounting IO error such as intermittent error"; - }; - - marginal_path_double_failed_time = mkOption { - type = nullOr str; - default = null; - description = "One of the four parameters of supporting path check based on accounting IO error such as intermittent error"; - }; - - delay_watch_checks = mkOption { - type = nullOr str; - default = null; - description = "This option is deprecated, and mapped to san_path_err_forget_rate"; - }; - - delay_wait_checks = mkOption { - type = nullOr str; - default = null; - description = "This option is deprecated, and mapped to san_path_err_recovery_time"; - }; - - skip_kpartx = mkOption { - type = nullOr (enum [ "yes" "no" ]); - default = null; # real default: "no" - description = "If set to yes, kpartx will not automatically create partitions on the device"; - }; - - max_sectors_kb = mkOption { - type = nullOr int; - default = null; - description = "Sets the max_sectors_kb device parameter on all path devices and the multipath device to the specified value"; - }; - - ghost_delay = mkOption { - type = nullOr int; - default = null; - description = "Sets the number of seconds that multipath will wait after creating a device with only ghost paths before marking it ready for use in systemd"; - }; - - all_tg_pt = mkOption { - type = nullOr str; - default = null; - description = "Set the 'all targets ports' flag when registering keys with mpathpersist"; - }; - - }; - }); - }; - - defaults = mkOption { - type = nullOr str; - default = null; - description = '' - This section defines default values for attributes which are used - whenever no values are given in the appropriate device or multipath - sections. - ''; - }; - - blacklist = mkOption { - type = nullOr str; - default = null; - description = '' - This section defines which devices should be excluded from the - multipath topology discovery. - ''; - }; - - blacklist_exceptions = mkOption { - type = nullOr str; - default = null; - description = '' - This section defines which devices should be included in the - multipath topology discovery, despite being listed in the - blacklist section. - ''; - }; - - overrides = mkOption { - type = nullOr str; - default = null; - description = '' - This section defines values for attributes that should override the - device-specific settings for all devices. - ''; - }; - - extraConfig = mkOption { - type = nullOr str; - default = null; - description = "Lines to append to default multipath.conf"; - }; - - extraConfigFile = mkOption { - type = nullOr str; - default = null; - description = "Append an additional file's contents to /etc/multipath.conf"; - }; - - pathGroups = mkOption { - example = literalExpression '' - [ - { - wwid = "360080e500043b35c0123456789abcdef"; - alias = 10001234; - array = "bigarray.example.com"; - fsType = "zfs"; # optional - options = "ro"; # optional - }, ... - ] - ''; - description = '' - This option allows you to define multipath groups as described - in http://christophe.varoqui.free.fr/usage.html. - ''; - type = listOf (submodule { - options = { - - alias = mkOption { - type = int; - example = 1001234; - description = "The name of the multipath device"; - }; - - wwid = mkOption { - type = hexStr; - example = "360080e500043b35c0123456789abcdef"; - description = "The identifier for the multipath device"; - }; - - array = mkOption { - type = str; - default = null; - example = "bigarray.example.com"; - description = "The DNS name of the storage array"; - }; - - fsType = mkOption { - type = nullOr str; - default = null; - example = "zfs"; - description = "Type of the filesystem"; - }; - - options = mkOption { - type = nullOr str; - default = null; - example = "ro"; - description = "Options used to mount the file system"; - }; - - }; - }); - }; - - }; - - config = mkIf cfg.enable { - environment.etc."multipath.conf".text = - let - inherit (cfg) defaults blacklist blacklist_exceptions overrides; - - mkDeviceBlock = cfg: let - nonNullCfg = lib.filterAttrs (k: v: v != null) cfg; - attrs = lib.mapAttrsToList (name: value: " ${name} ${toString value}") nonNullCfg; - in '' - device { - ${lib.concatStringsSep "\n" attrs} - } - ''; - devices = lib.concatMapStringsSep "\n" mkDeviceBlock cfg.devices; - - mkMultipathBlock = m: '' - multipath { - wwid ${m.wwid} - alias ${toString m.alias} - } - ''; - multipaths = lib.concatMapStringsSep "\n" mkMultipathBlock cfg.pathGroups; - - in '' - devices { - ${indentLines 2 devices} - } - - ${optionalString (!isNull defaults) '' - defaults { - ${indentLines 2 defaults} - multipath_dir ${cfg.package}/lib/multipath - } - ''} - ${optionalString (!isNull blacklist) '' - blacklist { - ${indentLines 2 blacklist} - } - ''} - ${optionalString (!isNull blacklist_exceptions) '' - blacklist_exceptions { - ${indentLines 2 blacklist_exceptions} - } - ''} - ${optionalString (!isNull overrides) '' - overrides { - ${indentLines 2 overrides} - } - ''} - multipaths { - ${indentLines 2 multipaths} - } - ''; - - systemd.packages = [ cfg.package ]; - - environment.systemPackages = [ cfg.package ]; - boot.kernelModules = [ "dm-multipath" "dm-service-time" ]; - - # We do not have systemd in stage-1 boot so must invoke `multipathd` - # with the `-1` argument which disables systemd calls. Invoke `multipath` - # to display the multipath mappings in the output of `journalctl -b`. - boot.initrd.kernelModules = [ "dm-multipath" "dm-service-time" ]; - boot.initrd.postDeviceCommands = '' - modprobe -a dm-multipath dm-service-time - multipathd -s - (set -x && sleep 1 && multipath -ll) - ''; - }; -} |