johnramsden/zectl

increase possible number of boot envs

eoli3n opened this issue · 4 comments

Creating a separated /boot with ext4 would improve his management when creating boot envs.

Bind mount

That's what you explain in : https://github.com/johnramsden/zectl/blob/master/docs/plugins/systemdboot.md#alternate-mountpoint

  • esp : VFAT 500M
  • bind mounting /boot to esp/env/org.zectl-default.

With this, you're limited to 6 or 7 boot environments, until /boot gets full.
Impossible to tweak because VFAT doesn't support {hard|sym}links.

Separated esp and /boot
  • esp : VFAT 50M
  • /boot : ext4 450M

EFI launch bootloader from esp then systemd-boot knows how to read ext4 and find kernel and initramfs.
You could then use hardlinks, it would increase the number of boot environments, isn't it ?

The problem of that solution is that it would not match existing classic configurations, user would need to manually create that special partition layout.

But if he does, would you add a test in zectl ->
if /boot is ext4, use hardlink instead of simple copy ?

Personally to avoid running out of space I have a 2 GB partition for my ESP.

Unless I'm mistaken, what you detailed above should just work with the existing implementation. The ext4 partition could be the bind mounted partition, there's nothing that specifies you need to use a fat partition.

I'm confused what you mean about copying, I don't understand how hardlinks would help. Are you saying we could hardlink multiple kernels if they're the same kernel? If so it would also only really help if the kernels were identical. It would also add a fair bit of complexity, and as a result extra failure modes. We would have to have some way of detecting when a kernel upgrade is going to occur, and in that case we would have to unlink the hard link, and allow the kernel upgrade to happen with the new kernel.

It's an interesting idea, but unless I'm misunderstanding what you meant, since we don't have a way of detecting when an upgrade occurs this isn't realistically doable.

If you do manage to get it working with an ext4 partition, let me know, it might be worth adding some instructions to the documentation.

It should work yes, but zectl will duplicate kernel/initramfs for each boot envs.

Are you saying we could hardlink multiple kernels if they're the same kernel?

I mean that yes, but you don't need to manage the "if" part. I don't understand why you says that it adds complexity, it's as simple as a copy.
Maybe you misunderstand what hardlinking is : https://en.wikipedia.org/wiki/Hard_link

For now, when you use zectl create you do

cp -r esp/env/zectl-default esp/env/zectl-bootenv1

But you could

# Test if /boot is ext4
if [[ $(df --output="fstype" /boot | sed '1d') == "ext4" ]]
then
   # If it does, use hardlink
    mkdir -p esp/env/zectl-bootenv1
    for file in $(ls /boot)
    do
        ln /boot/$file esp/env/zectl-bootenv1/$file
    done
else
    # Else fallback to a simple copy
    cp -r esp/env/zectl-default esp/env/zectl-bootenv1
fi

When you hardlink, the file descriptor target the same data on the disk. If a system update override current kernel, the hardlinked data in zectl-bootenv1 will still refer to previous datas.
Also, if you create multiple boot envs, with the same kernel/initramfs, each hardlink will refer to the same data.

The reason this doesn't work is then the files would be modified when either upgrade. If we hardlink kernel0 to kernel1, and update kernel1, both will be upgraded.

For example:

echo "test L0" > f0
ln f0 f1

cat f0 f1
test L0
test L0

echo "test L1" > f1

cat f0 f1
test L1
test L1

So i was the one who misunderstood how hardlinks work :) Sorry for that.
What i described is cp --reflink but ext4 doesnt support that.
So yes, hard to implement as systemd-boot can't read anything else than nocow fs.