diff --git a/prophecy/propdata.nix b/prophecy/propdata.nix index ba19e14..a72189e 100644 --- a/prophecy/propdata.nix +++ b/prophecy/propdata.nix @@ -11,56 +11,74 @@ let t = g * 1000; ki = 1024; _8ki = 8 * ki; - vdev_size = lib.pipe (14 * t) [ - # 14TB - (n: n * 0.99) # leave 1% unused - builtins.floor # convert back to int - (n: (n / _8ki) * _8ki) # round to multiple of 8KiB - ]; - vdev_size_ki = vdev_size / ki; - md_partition_size = lib.pipe vdev_size [ - (n: n / 2) # only using raid0 pairs currently - # from man md(4): "between 64K and 128K is lost when a device in incorporated into an MD array" - (n: n + (128 * ki)) - ]; - md_partition_size_ki = md_partition_size / ki; + safe_size = size: + lib.pipe size [ + (n: n * 0.99) # leave 1% unused + (n: n / (4*ki)) # convert to sectors + builtins.floor # integer number of sectors + (n: n * (4*ki)) # convert to bytes + ] + ; + # I have drives that are 8TB, 10TB, and 14TB. By partitioning the 14TB into 8 + 2 + 4 and the 10TB into 8 + 2, I can create a vdevs across a bunch of 8TB, 2TB, and 4TB partitions + slabsMin = { + slabA = { idx = 0; sizeT = 8; }; + slabB = { idx = 1; sizeT = 2; }; + slabC = { idx = 2; sizeT = 4; }; + }; + slabs = lib.mapAttrs (name: value: + value // rec { + inherit name; + sizeBytes = safe_size (value.sizeT * t); + sizeKi = sizeBytes / ki; + partitionConfig = { + size = "${builtins.toString sizeKi}K"; + type = fs_type_zfs; + priority = 1000 + value.idx; + }; + } + ) slabsMin; + slapParts = lib.mapAttrs (_: v: v.partitionConfig) slabs; + # slabs = { + # _8 = rec { + # idx = 0; + # letter = "slabA"; + # size_bytes = safe_size (8 * t); + # size_ki = size_bytes / ki; + # }; + # _2 = rec { + # idx = 1; + # letter = "slabB"; + # size_bytes = safe_size (2 * t); + # size_ki = size_bytes / ki; + # }; + # _4 = rec { + # idx = 2; + # letter = "slabC"; + # size_bytes = safe_size (4 * t); + # size_ki = size_bytes / ki; + # }; + # }; + # slab_size_8t = safe_size (8 * t); + # slab_size_2t = safe_size (2 * t); + # slab_size_4t = safe_size (4 * t); path_prefix = "/dev/disk/by-id/"; - # each 8TB + # 8TB seagate_1 = "ata-ST8000DM004-2U9188_ZR115511"; seagate_2 = "ata-ST8000DM004-2U9188_ZR11FWPR"; - seagate_gaming = [ + seagates = [ seagate_1 seagate_2 ]; - # each 10TB + # 10TB easystore_1 = "ata-WDC_WD100EMAZ-00WJTA0_1EGEP22N"; easystore_2 = "ata-WDC_WD100EMAZ-00WJTA0_1EGLWXMZ"; easystores_10 = [ easystore_1 easystore_2 ]; - fs_type_raid = "fd00"; # Linux RAID - fs_type_zfs = "a504"; # FreeBSD ZFS - split_config = md_name: { - type = "disk"; - content = { - type = "gpt"; - partitions.mdadm = { - size = "${builtins.toString md_partition_size_ki}K"; - type = fs_type_raid; - content = { - type = "mdraid"; - name = md_name; - }; - }; - }; - }; - md_name_seagate = "propdata-seagates-combiner"; - md_name_easystore = "propdata-easystores-combiner"; - poolname = "propdata"; - # each 14TB + # 14TB easystores_14 = vaculib.listOfLines { } '' - ata-WDC_WD140EDFZ-11A0VA0_Y5J3929C + # unused, previously nothing ata-WDC_WD140EDGZ-11B2DA2_2BHRSN3F ata-WDC_WD140EDGZ-11B2DA2_2CG19ERP ata-WDC_WD140EDGZ-11B2DA2_2CG4ZYSN @@ -70,90 +88,141 @@ let ata-WDC_WD140EDGZ-11B2DA2_3WH4KX0P ata-WDC_WD140EDGZ-11B2DA2_3WJ4XRUJ ata-WDC_WD140EDGZ-11B2DA2_3WK2HBDP + + # unused, previously cold spare for emanlooc + ata-WDC_WD140EDFZ-11A0VA0_Y5J3929C + + # previously the emanlooc pool + ata-WDC_WD140EDFZ-11A0VA0_9LG7AUEG + ata-WDC_WD140EDFZ-11A0VA0_9LG8247A + ata-WDC_WD140EDFZ-11A0VA0_9LG8475A + ata-WDC_WD140EDFZ-11A0VA0_9LG872WA + ata-WDC_WD140EDFZ-11A0VA0_9MG7KBWA + ata-WDC_WD140EDFZ-11A0VA0_Y5J31ZAC + ata-WDC_WD140EDFZ-11A0VA0_Y5J333UC + ata-WDC_WD140EDFZ-11A0VA0_Y5J3V54C ''; - easystore_14_configs = lib.pipe easystores_14 [ - (map (name: { - name = "easystore14_${lib.last (lib.splitString "_" name)}"; + easystores_14_spare = lib.singleton (lib.head easystores_14); + easystores_14_active = lib.tail easystores_14; + fs_type_zfs = "a504"; # FreeBSD ZFS + poolname = "propdata"; + + mk_configs = { groupName, drives, partitions }: + builtins.listToAttrs (map (name: { + name = "${groupName}_${lib.last (lib.splitString "_" name)}}"; value = { type = "disk"; device = path_prefix + name; content = { type = "gpt"; - partitions.main = { - size = "${builtins.toString vdev_size_ki}K"; - type = fs_type_zfs; - content = { - type = "zfs"; - pool = poolname; - }; - }; + inherit partitions; }; }; - })) - builtins.listToAttrs - ]; - md_config = { - type = "mdadm"; - level = 0; - content = { - type = "zfs"; - pool = poolname; - }; - }; + }) drives) + ; + + # each 14TB + # easystore_14_configs = lib.pipe easystores_14 [ + # (map (name: { + # name = "easystore14_${lib.last (lib.splitString "_" name)}"; + # value = { + # type = "disk"; + # device = path_prefix + name; + # content = { + # type = "gpt"; + # partitions.main = { + # size = "${builtins.toString vdev_size_ki}K"; + # type = fs_type_zfs; + # content = { + # type = "zfs"; + # pool = poolname; + # }; + # }; + # }; + # }; + # })) + # builtins.listToAttrs + # ]; in { imports = [ inputs.disko.nixosModules.default ]; options.vacu.prophecy = lib.mapAttrs (_: vaculib.mkOutOption) { inherit - vdev_size - md_partition_size easystores_10 easystores_14 - seagate_gaming + seagates ; }; - config.disko.enableConfig = false; - config.disko.checkScripts = true; - config.disko.rootMountPoint = "/"; - config.disko.devices.disk = { - seagate1 = (split_config md_name_seagate) // { - device = path_prefix + seagate_1; + config.disko = { + enableConfig = false; + checkScripts = true; + rootMountPoint = "/"; + devices.disk = {} + // mk_configs { + groupName = "easystore14"; + drives = easystores_14; + partitions = { + inherit (slapParts) slabA slabB slabC; + }; + } + // mk_configs { + groupName = "easystore10"; + drives = easystores_10; + partitions = { + inherit (slapParts) slabA slabB; + }; + } + // mk_configs { + groupName = "seagate8"; + drives = seagates; + partitions = { + inherit (slapParts) slabA; + }; + } + ; + devices.zpool."${poolname}" = { + type = "zpool"; + options = { + ashift = "12"; + comment = "Shelvacu's, for prophecy server"; # comment is limited to 32 characters + failmode = "continue"; + }; + rootFsOptions = { + acltype = "posix"; + atime = "off"; + compression = "zstd"; + devices = "off"; + dedup = "on"; + dnodesize = "auto"; + encryption = "on"; + keyformat = "hex"; + keylocation = "file:///var/log/propdata-encryption-key.hex.txt"; + exec = "off"; + redundant_metadata = "most"; + xattr = "sa"; + }; + # mode = "raidz3"; + mode = { + type = "topology"; + vdev = [ + # slabA + { + mode = "raidz3"; + members = map (drive: path_prefix+drive+"-part1") (seagates ++ easystores_10 ++ easystores_14_active); + } + # slabB + { + mode = "raidz3"; + members = map (drive: path_prefix+drive+"-part2") (easystores_10 ++ easystores_14_active); + } + # slabC + { + mode = "raidz3"; + members = map (drive: path_prefix+drive+"-part3") easystores_14_active; + } + ]; + spare = easystores_14_spare; + }; }; - seagate2 = (split_config md_name_seagate) // { - device = path_prefix + seagate_2; - }; - easystoreEMAZ1 = (split_config md_name_easystore) // { - device = path_prefix + easystore_1; - }; - easystoreEMAZ2 = (split_config md_name_easystore) // { - device = path_prefix + easystore_2; - }; - } // easystore_14_configs; - config.disko.devices.mdadm = { - "${md_name_seagate}" = md_config; - "${md_name_easystore}" = md_config; - }; - config.disko.devices.zpool."${poolname}" = { - type = "zpool"; - options = { - ashift = "12"; - comment = "Shelvacu's, for prophecy server"; # comment is limited to 32 characters - failmode = "continue"; - }; - rootFsOptions = { - acltype = "posix"; - atime = "off"; - compression = "zstd"; - devices = "off"; - dedup = "on"; - dnodesize = "auto"; - encryption = "on"; - keyformat = "hex"; - keylocation = "file:///var/log/propdata-encryption-key.hex.txt"; - exec = "off"; - redundant_metadata = "most"; - xattr = "sa"; - }; - mode = "raidz3"; }; }