Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce new disk partitioning scheme #478

Merged
merged 1 commit into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
# Devices #
###########

PrivateDevices = true;
# PrivateDevices = true;
# DeviceAllow=/dev/null

##########
Expand Down
161 changes: 161 additions & 0 deletions modules/disko/disko-ab-partitions.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
unbel13ver marked this conversation as resolved.
Show resolved Hide resolved
# SPDX-License-Identifier: Apache-2.0
#
# This partition scheme contains three common partitions and ZFS pool.
# Some partitions are duplicated for the future AB SWupdate implementation.
#
# First three partitions are related to the boot process:
# - boot : Bootloader partition
# - ESP-A : (500M) Kernel and initrd
# - ESP-B : (500M)
#
# ZFS datasets do not necessary need to have specified size and can be
# allocated dynamically. Quotas only restrict the maximum size of
# datasets, but do not reserve the space in the pool.
# The ZFS pool contains next datasets:
# - root-A : (30G) Root FS
# - root-B : (30G)
# - vm-storage-A : (30G) Possible standalone pre-built VM images are stored here
# - vm-storage-B : (30G)
# - reserved-A : (10G) Reserved dataset, no use
# - reserved-B : (10G)
# - gp-storage : (50G) General purpose storage for some common insecure cases
# - recovery : (no quota) Recovery factory image is stored here
# - storagevm: (no quota) Dataset is meant to be used for StorageVM
{pkgs, ...}: {
#TODO Probably the 'networking.hostId' should be set
# somewhere else instead.
networking.hostId = "8425e349";
unbel13ver marked this conversation as resolved.
Show resolved Hide resolved
disko = {
memSize = 4096;
extraPostVM = ''
${pkgs.zstd}/bin/zstd --compress $out/*raw
rm $out/*raw
'';
extraRootModules = ["zfs"];
devices = {
disk.disk1 = {
type = "disk";
imageSize = "15G";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "1M";
type = "EF02";
unbel13ver marked this conversation as resolved.
Show resolved Hide resolved
priority = 1; # Needs to be first partition
brianmcgillion marked this conversation as resolved.
Show resolved Hide resolved
};
esp_a = {
name = "ESP_A";
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"umask=0077"
"nofail"
];
};
};
esp_b = {
name = "ESP_B";
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountOptions = [
"umask=0077"
"nofail"
];
};
};
zfs_1 = {
size = "100%";
content = {
type = "zfs";
pool = "zfspool";
};
};
};
};
};
zpool = {
zfspool = {
type = "zpool";
rootFsOptions = {
mountpoint = "none";
acltype = "posixacl";
};
datasets = {
"root_a" = {
type = "zfs_fs";
mountpoint = "/";
options = {
mountpoint = "/";
quota = "30G";
};
};
"vm_storage_a" = {
type = "zfs_fs";
options = {
mountpoint = "/vm_storage";
quota = "30G";
};
};
"reserved_a" = {
type = "zfs_fs";
options = {
mountpoint = "none";
quota = "10G";
};
};
"root_b" = {
type = "zfs_fs";
options = {
mountpoint = "none";
quota = "30G";
};
};
"vm_storage_b" = {
type = "zfs_fs";
options = {
mountpoint = "none";
quota = "30G";
};
};
"reserved_b" = {
type = "zfs_fs";
options = {
mountpoint = "none";
quota = "10G";
};
};
"gp_storage" = {
type = "zfs_fs";
options = {
mountpoint = "/gp_storage";
quota = "50G";
};
};
"recovery" = {
type = "zfs_fs";
options = {
mountpoint = "none";
};
};
"storagevm" = {
type = "zfs_fs";
options = {
mountpoint = "/storagevm";
};
};
};
};
};
};
};
}
36 changes: 36 additions & 0 deletions modules/disko/disko-zfs-postboot.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{pkgs, ...}: let
postBootCmds = ''
set -xeuo pipefail

# Check which physical disk is used by ZFS
ZFS_POOLNAME=$(${pkgs.zfs}/bin/zpool list | ${pkgs.gnugrep}/bin/grep -v NAME | ${pkgs.gawk}/bin/awk '{print $1}')
ZFS_LOCATION=$(${pkgs.zfs}/bin/zpool status -P | ${pkgs.gnugrep}/bin/grep dev | ${pkgs.gawk}/bin/awk '{print $1}')

# Get the actual device path
P_DEVPATH=$(readlink -f "$ZFS_LOCATION")

# Extract the partition number using regex
if [[ "$P_DEVPATH" =~ [0-9]+$ ]]; then
PARTNUM=$(echo "$P_DEVPATH" | ${pkgs.gnugrep}/bin/grep -o '[0-9]*$')
PARENT_DISK=$(echo "$P_DEVPATH" | ${pkgs.gnused}/bin/sed 's/[0-9]*$//')
else
echo "No partition number found in device path: $P_DEVPATH"
fi

# Fix GPT first
${pkgs.gptfdisk}/bin/sgdisk "$PARENT_DISK" -e

# Call partprobe to update kernel's partitions
${pkgs.parted}/bin/partprobe

# Extend the partition to use unallocated space
${pkgs.parted}/bin/parted -s -a opt "$PARENT_DISK" "resizepart $PARTNUM 100%"

# Extend ZFS pool to use newly allocated space
${pkgs.zfs}/bin/zpool online -e "$ZFS_POOLNAME" "$ZFS_LOCATION"
'';
in {
boot.postBootCommands = postBootCmds;
}
6 changes: 6 additions & 0 deletions modules/disko/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@
./disko-basic-partition-v1.nix
./disko-basic-postboot.nix
];

disko-ab-partitions-v1.imports = [
inputs.disko.nixosModules.disko
./disko-ab-partitions.nix
./disko-zfs-postboot.nix
];
};
}
3 changes: 3 additions & 0 deletions modules/hardware/x86_64-generic/x86_64-linux.nix
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ in {
initrd.availableKernelModules = [
"nvme"
"uas"
"zfs"
];
loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
};
supportedFilesystems = ["zfs"];
kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
};
};
}
8 changes: 4 additions & 4 deletions targets/laptop/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
targets = [
# Laptop Debug configurations
(laptop-configuration "lenovo-x1-carbon-gen10" "debug" [
self.nixosModules.disko-basic-partition-v1
self.nixosModules.disko-ab-partitions-v1
{
ghaf = {
hardware.definition.configFile = "/lenovo-x1/definitions/x1-gen10.nix";
Expand All @@ -23,7 +23,7 @@
}
])
(laptop-configuration "lenovo-x1-carbon-gen11" "debug" [
self.nixosModules.disko-basic-partition-v1
self.nixosModules.disko-ab-partitions-v1
{
ghaf = {
hardware.definition.configFile = "/lenovo-x1/definitions/x1-gen11.nix";
Expand Down Expand Up @@ -52,7 +52,7 @@

# Laptop Release configurations
(laptop-configuration "lenovo-x1-carbon-gen10" "release" [
self.nixosModules.disko-basic-partition-v1
self.nixosModules.disko-ab-partitions-v1
{
ghaf = {
hardware.definition.configFile = "/lenovo-x1/definitions/x1-gen10.nix";
Expand All @@ -61,7 +61,7 @@
}
])
(laptop-configuration "lenovo-x1-carbon-gen11" "release" [
self.nixosModules.disko-basic-partition-v1
self.nixosModules.disko-ab-partitions-v1
{
ghaf = {
hardware.definition.configFile = "/lenovo-x1/definitions/x1-gen11.nix";
Expand Down