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

EFI partition isn't mirrored #41

Open
qdm12 opened this issue Jul 31, 2019 · 6 comments
Open

EFI partition isn't mirrored #41

qdm12 opened this issue Jul 31, 2019 · 6 comments

Comments

@qdm12
Copy link

qdm12 commented Jul 31, 2019

Hi there,

First of all, thanks for the nice program, it takes out a lot of headaches 👍
I can see my root is mirrored on two of my drives with ZFS, but what about /mnt/efi? It does not seem to be mirrorred. So this would mean that removing one of the two drives could make (50% chance) the system unbootable. Is there a way to mirror (or other) the boot partition as well?

Thanks!

@danboid
Copy link
Owner

danboid commented Jul 31, 2019

Hi Quentin!

alez does not currently support mirroring the UEFI partition, so yes, what you say is a potential pitfall. The upcoming release of Proxmox supports this (under Debian 10) so it'd be interesting to see how they've implemented this.

@johnramsden has more experience with Linux ZFS on UEFI. Our answer to this question needs to be added to the README until we do add support for this.

@johnramsden
Copy link
Collaborator

Easiest way would probably be just setting up a systemd service which is triggered upon the kernel changing, the files could then be rsync'd to the other partition.

This can be done by using a similar pattern to what is detailed in 'EFI system partition - Using systemd'.

Or, a pacman hook might be more suitable since it supports globbing, which I don't believe systemd path monitoring does.

If you end up setting this up yourself, and testing it, it could make a good first PR which I'd be happy to review. I might get around to it at some point, but right now I don't have the time to add the feature.

@johnramsden johnramsden changed the title Is the EFI partition mirrored? EFI partition isn't mirrored Aug 1, 2019
@qdm12
Copy link
Author

qdm12 commented Aug 6, 2019

I'll look into it. I may also do a PR for native encryption for the root partition. Also (out of the topic, sorry) why do you support only mirror and not raidzN? I could look into it perhaps and add the missing dialog menus.

@johnramsden
Copy link
Collaborator

No reason in particular other than increased complexity. raidz would be a good addition, you could open an issue for that and we'll add it to the list of enhancements.

@johnramsden
Copy link
Collaborator

@qdm12 Regarding your question in #39 (comment)


If you are using BIOS, so [[ "${install_type}" =~ ^(b|B)$ ]], bios_partitioning is done, and is passed a block device.

ALEZ/alez.sh

Lines 458 to 459 in 05ebf9d

if [[ "${install_type}" =~ ^(b|B)$ ]]; then
bios_partitioning "$blkdev" | dialog --programbox 10 70

bios_partitioning creates GPT partitions, partition one being a BIOS partition, and partition two being the system partition for the zpool. This will be called for each disc that will be mirrored.

ALEZ/alez.sh

Lines 111 to 123 in 05ebf9d

bios_partitioning(){
echo -e "GPT BIOS partitioning ${1}...\n"
zap_partition "${1}"
echo "Creating BIOS boot partition"
sgdisk --new=1:0:+2M --typecode=1:EF02 "${1}"
echo "Creating system partition"
sgdisk --new=2:0:-"${free_space}"M --typecode=2:BF00 "${1}"
echo "Set legacy BIOS boot flag"
sgdisk -A 2:set:2 "${1}"
}

The install_grub function should be called to install grub to each disc.

ALEZ/alez.sh

Line 637 in 05ebf9d

install_grub "${grubdisk}" | dialog --progressbox 30 70


If you're using UEFI, so [[ "${install_type}" =~ ^(u|U)$ ]], a size is decided for the ESP, and it it passed along with the block device to the uefi_partitioning function.

ALEZ/alez.sh

Lines 460 to 470 in 05ebf9d

else
esp_size=512
if [[ "${bootloader}" =~ ^(s|S) ]]; then
msg="Enter the size of the esp (512 or greater in MiB),\n1024 or greater recommended to hold multiple kernels"
esp_size=$(dialog --stdout --clear --title "UEFI partition size" --inputbox "${msg}" $HEIGHT $WIDTH "2048")
while [ "$esp_size" -lt "512" ]; do
esp_size=$(dialog --stdout --clear --title "UEFI partition size" --inputbox "${msg}" $HEIGHT $WIDTH "2048")
done
fi
uefi_partitioning "$blkdev" "${esp_size}" | dialog --programbox 10 70
fi

In the uefi_partitioning, an EFI partition is created along with a system partition for a zpool device.

ALEZ/alez.sh

Lines 125 to 135 in 05ebf9d

uefi_partitioning(){
echo -e "GPT UEFI partitioning ${1}...\n"
zap_partition "${1}"
echo "Creating EFI partition"
sgdisk --new=1:1M:+"${2}"M --typecode=1:EF00 "${1}"
echo "Creating system partition"
sgdisk --new=2:0:-"${free_space}"M --typecode=2:BF00 "${1}"
}

Right now this will be created for each device, but only one will be selected to be used since no mirroring is occurring.

ALEZ/alez.sh

Lines 575 to 593 in 05ebf9d

msg="Enter the number of the partition above that you want to use for an esp.\n\n"
msg+="If you used alez to create your partitions,\nyou likely want the one ending with -part1"
# This shellcheck exception is necessary to keep the partinfo variable unquoted.
# Adding quotes around ${partinfo} here breaks the esp dialog command.
# shellcheck disable=SC2086
esp=$(dialog --stdout --clear --title "Install type" \
--menu "$msg" \
$HEIGHT $WIDTH "$(( 2 + ptcount))" ${partinfo})
efi_partition="${partids[$esp]}"
mkfs.fat -F 32 "${efi_partition}"| dialog --progressbox 10 70
mkdir -p "${installdir}${esp_mountpoint}" "${installdir}/boot"
mount "${efi_partition}" "${installdir}${esp_mountpoint}"
if [[ "${bootloader}" =~ ^(s|S)$ ]]; then
mkdir -p "${installdir}${esp_mountpoint}/env/zedenv-default"
mount --bind "${installdir}${esp_mountpoint}/env/zedenv-default" "${installdir}/boot"
fi

If systemd-boot is used, install_sdboot it's called with the ESP mountpoint, otherwise install_grub_efi is called.

ALEZ/alez.sh

Lines 644 to 648 in 05ebf9d

if [[ "${bootloader}" =~ ^(s|S)$ ]]; then
install_sdboot "${esp_mountpoint}"
else
install_grub_efi "${esp_mountpoint}"
fi


For UEFI, EFI entries need to be created, bootctl, or
grub-install should create those entries but I'm not sure what will happen if installation happens to more than one ESP. I imagine you will just have more than one UEFI entry.

For GRUB, the zpool is actually holding the kernels, and ${zroot}/boot/grub holds grub.cfg so not much will not need mirroring.

See

ALEZ/alez.sh

Line 527 in 05ebf9d

echo "Creating datasets..."

For systemd-boot, the files are actually kept on the ESP, with the kernels kept in ${esp_mountpoint}/env/zedenv-${boot_env}, and that directory is bind-mounted to /boot.

ALEZ/alez.sh

Lines 590 to 593 in 05ebf9d

if [[ "${bootloader}" =~ ^(s|S)$ ]]; then
mkdir -p "${installdir}${esp_mountpoint}/env/zedenv-default"
mount --bind "${installdir}${esp_mountpoint}/env/zedenv-default" "${installdir}/boot"
fi

Therefore you will likely want to mount the second ESP add an alternate location and just update it after each kernel update or configuration update. To keep the configuration in sync you probably want to just synchronize the entire ESP after every kernel upgrade, or use a filesystem watcher and synchronize the configuration whenever it changes.


Hope that helps.

@qdm12
Copy link
Author

qdm12 commented Aug 10, 2019

Hi John and thanks for the very detailed explanation! I will see what I can do with it.

I am testing my current changes in (hyper-v) VMs for now, maybe we can already do a PR for the encryption and raidzN first and do a boot related PR afterwards. Thanks again for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants