Skip to content

increase the boot partition to 256 MB #3027

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ader1990
Copy link
Contributor

@ader1990 ader1990 commented Jun 18, 2025

increase the boot partition to 256 MB

The boot partition is currently 128 MB, and reaching a usage size that is approaching soon 50+1% when Flatcar is freshly installed. During the upgrade process, the Flatcar upgrade workflow will put the new initrd in the /boot partition, thus using more space (almost doubling the used space).

Let's make this used space calculation with a more mathematical description.
Example of du output:

du -sh /boot/**/**
2.8M    /boot/EFI/boot
1.0K    /boot/boot/grub
1.8M    /boot/flatcar/grub
59M     /boot/flatcar/vmlinuz-a
683K    /boot/xen/pvboot-x86_64.elf

/boot partition contains the following data:

  • grub/efi/xen files - these will not change during the upgrade process - size GRUB_FILES_SIZE ~ 5 MB
  • initial initrd size - size INITRD_PART_A_SIZE ~ 59MB

When an upgrade is made, the boot partition size increases with the new intird size INITRD_PART_B_SIZE, currently at 59MB.

So, after an upgrade, we have: GRUB_FILES_SIZE + INITRD_PART_A_SIZE + INITRD_PART_B_SIZE ~= 5 + 59 + 59 ~= 123 MB size. Very close to 128 MB.

Doubling the boot partition will solve the future issue.

I consider that making the boot partition bigger is a more elegant and simpler solution than going with the quite complicated way presented here:
https://hackmd.io/@flatcar/H1MDJuu7lg
There are security implications with the moving approach, as for example, the verity hash workflow is changed, thus the security profile changes.

The downside of this approach would be that, after some time, the upgrade of the older versions won't work anymore, but by the time it becomes an issue, the whole global fleet should be replaced with new Flatcar. Same as with cgroups issue, we can stop the upgrade with an error message if the /boot won't have enough space for existing setups.

How to use

[ describe what reviewers need to do in order to validate this PR ]

Testing done

[Describe the testing you have done before submitting this PR. Please include both the commands you issued as well as the output you got.]

  • Changelog entries added in the respective changelog/ directory (user-facing change, bug fix, security fix, update)
  • Inspected CI output for image differences: /boot and /usr size, packages, list files for any missing binaries, kernel modules, config files, kernel modules, etc.

@chewi
Copy link
Contributor

chewi commented Jun 18, 2025

I'm slightly confused about what you're proposing. The first part sounds like existing deployments would be resized on upgrade. That's essential, given how close we are to the limit right now. On the other hand, you've only changed the disk layout here, and you also say that older systems won't be upgradeable anymore.

I did do an earlier write-up of the potential solutions, and resizing the partition was one of them. Sorry for not sharing that more widely. Assuming you did mean to resize on upgrade, here is what I wrote:


Resize the EFI-SYSTEM partition by shrinking USR

The USR partitions are currently only using about 50% of their 1GB size. These partitions are read-only, so some of this could be given to EFI-SYSTEM. See the current disk layout.

Method

  1. When upgrading from USR-B into USR-A…
  2. Shift the EFI-SYSTEM, BIOS-BOOT, USR-A boundaries to make EFI-SYSTEM bigger.
  3. Restore BIOS-BOOT using GRUB.
  4. Install USR-A as usual but with a temporarily smaller size.
  5. When later upgrading from USR-A into USR-B…
  6. Shift the USR-A, USR-B boundary to make them the same size.
  7. Install USR-B as usual.

Pros

  • Probably the easiest to pull off.
  • Resizes the partitions with no other changes.

Cons

  • Resizing partitions is always risky.
    • There is probably no way to make this safe on legacy BIOS systems. Can we write the BIOS-BOOT data in the new location before really modifying the partition table?
    • Even on UEFI systems, it may not be entirely safe.
  • Users are still stuck with the old bootloader unless further steps are taken.

I was told this approach was too risky. The space issue aside, we also want to be able to update the bootloader and have a dynamic configuration for better security and more flexibility going forwards. Most of my proposal is really about that, and actually moving the kernel is a relatively small change on top.

If the concern is security, then I believe what I have proposed actually makes things more secure than what we have right now. Existing BIOS deployments are arguably slightly less secure, but those were never particularly secure to begin with.

If the concern is the ability to actually pull the plan off, then I already have most of it working. Forgive my bias here, but I think the end result is quite nice.

Copy link

github-actions bot commented Jun 18, 2025

Test report for 4384.0.0+nightly-20250702-2100 / amd64 arm64

Platforms tested : qemu_uefi-amd64 qemu_update-amd64 qemu_uefi-arm64 qemu_update-arm64

ok bpf.execsnoop 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok bpf.local-gadget 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.basic 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.cloudinit.basic 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.cloudinit.multipart-mime 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.cloudinit.script 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.disk.raid0.data 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.disk.raid0.root 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.disk.raid1.data 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.disk.raid1.root 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.etcd-member.discovery 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.etcd-member.etcdctlv3 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.etcd-member.v2-backup-restore 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.filesystem 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.flannel.udp 🟢 Succeeded: qemu_uefi-amd64 (1)

ok cl.flannel.vxlan 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.instantiated.enable-unit 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.kargs 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.luks 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.oem.indirect 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.oem.indirect.new 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.oem.regular 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.oem.regular.new 🟢 Succeeded: qemu_uefi-amd64 (2); qemu_uefi-arm64 (1) ❌ Failed: qemu_uefi-amd64 (1)

                Diagnostic output for qemu_uefi-amd64, run 1
    L1: " Error: _oem.go:199: Couldn_t reboot machine: machine __dc58b225-f7e4-4a83-9781-c21c0a5275e6__ failed basic checks: some systemd units failed:"
    L2: "??? ldconfig.service loaded failed failed Rebuild Dynamic Linker Cache"
    L3: "status: "
    L4: "journal:-- No entries --"
    L5: "harness.go:614: Found systemd unit failed to start (?[0;1;39mldconfig.service?[0m - Rebuild Dynamic Linker Cache.  ) on machine dc58b225-f7e4-4a83-9781-c21c0a5275e6 console_"
    L6: " "
    L7: "  "

ok cl.ignition.oem.reuse 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.oem.wipe 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.partition_on_boot_disk 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.symlink 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.translation 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v1.btrfsroot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v1.ext4root 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v1.groups 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v1.once 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v1.sethostname 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v1.users 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v1.xfsroot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v2.btrfsroot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v2.ext4root 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v2.users 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v2.xfsroot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v2_1.ext4checkexisting 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v2_1.swap 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.ignition.v2_1.vfat 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.install.cloudinit 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.internet 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.locksmith.cluster 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.network.initramfs.second-boot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.network.iptables 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.network.listeners 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.network.nftables 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.network.wireguard 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.omaha.ping 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.osreset.ignition-rerun 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.overlay.cleanup 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.swap_activation 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.sysext.boot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.sysext.fallbackdownload # SKIP 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tang.nonroot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tang.root 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.toolbox.dnf-install 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tpm.eventlog 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tpm.nonroot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tpm.root 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tpm.root-cryptenroll 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tpm.root-cryptenroll-pcr-noupdate 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.tpm.root-cryptenroll-pcr-withupdate 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.update.badverity 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.update.payload 🟢 Succeeded: qemu_update-amd64 (2); qemu_update-arm64 (1) ❌ Failed: qemu_update-amd64 (1)

                Diagnostic output for qemu_update-amd64, run 1
    L1: " Error: _cluster.go:125: Created symlink _/etc/systemd/system/locksmithd.service_ ??? _/dev/null_."
    L2: "update.go:371: Triggering update_engine"
    L3: "update.go:390: Rebooting test machine"
    L4: "update.go:371: Triggering update_engine"
    L5: "update.go:390: Rebooting test machine"
    L6: "update.go:393: reboot failed: machine __ed978a67-d673-454f-b5df-1f2f1fed0172__ failed basic checks: some systemd units failed:"
    L7: "??? ldconfig.service loaded failed failed Rebuild Dynamic Linker Cache"
    L8: "status: "
    L9: "journal:-- No entries --_"
    L10: " "
    L11: "  "

ok cl.update.reboot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.users.shells 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok cl.verity 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.auth.verify 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.ignition.groups 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.ignition.once 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (2) ❌ Failed: qemu_uefi-arm64 (1)

                Diagnostic output for qemu_uefi-arm64, run 1
    L1: "  "
    L2: " Error: _execution.go:140: Couldn_t reboot machine: machine __ab256607-96dc-4355-87ad-4f4886474e41__ failed basic checks: some systemd units failed:"
    L3: "??? ldconfig.service loaded failed failed Rebuild Dynamic Linker Cache"
    L4: "status: "
    L5: "journal:-- No entries --"
    L6: "harness.go:614: Found systemd unit failed to start (?[0;1;39mldconfig.service?[0m - Rebuild Dynamic Linker Cache.  ) on machine ab256607-96dc-4355-87ad-4f4886474e41 console_"
    L7: " "

ok coreos.ignition.resource.local 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.ignition.resource.remote 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.ignition.resource.s3.versioned 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.ignition.security.tls 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.ignition.sethostname 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.ignition.systemd.enable-service 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.locksmith.reboot 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.locksmith.tls 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.selinux.boolean 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.selinux.enforce 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.tls.fetch-urls 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok coreos.update.badusr 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok devcontainer.docker 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok devcontainer.systemd-nspawn 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.btrfs-storage 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.containerd-restart 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.enable-service.sysext 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.lib-coreos-dockerd-compat 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.network-openbsd-nc 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.selinux 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok docker.userns 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok extra-test.[first_dual].cl.update.docker-btrfs-compat 🟢 Succeeded: qemu_update-amd64 (1, 2); qemu_update-arm64 (2) ❌ Failed: qemu_update-arm64 (1)

                Diagnostic output for qemu_update-arm64, run 1
    L1: "  "
    L2: " Error: _cluster.go:125: Created symlink /etc/systemd/system/locksmithd.service ??? /dev/null."
    L3: "cluster.go:125: Unable to find image _alpine:latest_ locally"
    L4: "cluster.go:125: latest: Pulling from library/alpine"
    L5: "cluster.go:125: d69d4d41cfe2: Pulling fs layer"
    L6: "cluster.go:125: d69d4d41cfe2: Verifying Checksum"
    L7: "cluster.go:125: d69d4d41cfe2: Download complete"
    L8: "cluster.go:125: d69d4d41cfe2: Pull complete"
    L9: "cluster.go:125: Digest: sha256:8a1f59ffb675680d47db6337b49d22281a139e9d709335b492be023728e11715"
    L10: "cluster.go:125: Status: Downloaded newer image for alpine:latest"
    L11: "update.go:371: Triggering update_engine"
    L12: "update.go:390: Rebooting test machine"
    L13: "update.go:371: Triggering update_engine"
    L14: "update.go:390: Rebooting test machine"
    L15: "update.go:393: reboot failed: machine __59fe8446-0c0f-445c-b383-80d4df2a4d9d__ failed basic checks: some systemd units failed:"
    L16: "??? ldconfig.service loaded failed failed Rebuild Dynamic Linker Cache"
    L17: "status: "
    L18: "journal:-- No entries --"
    L19: "harness.go:614: Found systemd unit failed to start (?[0;1;39mldconfig.service?[0m - Rebuild Dynamic Linker Cache.  ) on machine 59fe8446-0c0f-445c-b383-80d4df2a4d9d console_"
    L20: " "

ok extra-test.[first_dual].cl.update.payload 🟢 Succeeded: qemu_update-amd64 (2); qemu_update-arm64 (1, 2) ❌ Failed: qemu_update-amd64 (1)

                Diagnostic output for qemu_update-amd64, run 1
    L1: " Error: _cluster.go:125: Created symlink /etc/systemd/system/locksmithd.service ??? /dev/null."
    L2: "update.go:371: Triggering update_engine"
    L3: "update.go:390: Rebooting test machine"
    L4: "update.go:371: Triggering update_engine"
    L5: "update.go:390: Rebooting test machine"
    L6: "update.go:393: reboot failed: machine __1db8d385-f005-46fc-b367-6de04218cc81__ failed basic checks: some systemd units failed:"
    L7: "??? ldconfig.service loaded failed failed Rebuild Dynamic Linker Cache"
    L8: "status: "
    L9: "journal:-- No entries --_"
    L10: " "
    L11: "  "

ok kubeadm.v1.31.8.calico.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.31.8.cilium.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.31.8.flannel.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.32.4.calico.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.32.4.cilium.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.32.4.flannel.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.33.0.calico.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.33.0.cilium.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok kubeadm.v1.33.0.flannel.base 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok linux.nfs.v3 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok linux.nfs.v4 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok linux.ntp 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok misc.fips 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok packages 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok sysext.custom-docker.sysext 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok sysext.custom-oem 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok sysext.disable-containerd 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok sysext.disable-docker 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok sysext.simple 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok systemd.journal.remote 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok systemd.journal.user 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

ok systemd.sysusers.gshadow 🟢 Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)

@ader1990
Copy link
Contributor Author

Just to make thing clear: this is the only change I am proposing. As a consequence, the older systems can be upgraded as long as their /boot partition space still allows it. The older systems do not get any sort of partition changes, the WORKFLOW DOES NOT change, this is the only change to all Flatcar repositories (besides maybe a better error message on the update-engine code to verify if the older systems can fit the new initrd before actually trying to copy it).

@t-lo
Copy link
Member

t-lo commented Jun 18, 2025

I think both approaches have some merit, and it's great to have a good pro/con discussion.

Re: active instances; the vast majority of Flatcar instances out there appears to use in-place updates for upgrading. All these, even the ones newly deployed today, would be affected if we only implement boot partition resizing.

Looking at the benefits of both approaches on the other hand, I believe they are complementary: It would be great to have more flexibility re: partition layout and sizes in future versions of Flatcar, and it would be good to have a more robust bootloader process like the one the kernel move implicitly includes.

So I would not look at the two approaches as being contradictory, or even competitive - quite the opposite, they enable each other.

@ader1990
Copy link
Contributor Author

@t-lo I find the workflow proposed in https://hackmd.io/@flatcar/H1MDJuu7lg -> very complex and thus prone to issues down the road and worried on the security aspect of Flatcar. Adding complexity is prone to adding bugs or security issues. I also see some limitations to the proposal. Once the change proposed in https://hackmd.io/@flatcar/H1MDJuu7lg will be done, it cannot be reverted and we have to stick to this new workflow. Well, this MR change also cannot be reverted, but the implications of this MR change are very clear.

I am also thinking about the security profile being changed as proposed in https://hackmd.io/@flatcar/H1MDJuu7lg -> this might mean that users need to re-profile / re-certify the new Flatcar booting process from the perspective of security compliance. I suggest also to bring these changes in the weekly meetings and maybe ask user feedback before actually merging them.

This MR change is simple and can be done today, the longer we wait, more Flatcar instances will get deployed with the 128MB /boot partition.

I see the change https://hackmd.io/@flatcar/H1MDJuu7lg as more of a last resort change and can be done when it really needs to be done.

@chewi
Copy link
Contributor

chewi commented Jun 18, 2025

I have tracked the remaining space in /boot, looking at how much is taken up by the non-kernel files when initially deployed together with two copies of the kernel from each release. The situation was worst in 3975, before I made some adjustments to buy us a little more time. If you initially deploy that on amd64 and then add two kernel images from the 4368 nightly, that only leaves you with 1.7MB free. The amount the kernel is allowed to increase is only half that. That can disappear very quickly, especially if we enable more of the things we'd actually like or stop going far out of our way to keep the size down.

That leaves very little time for systems that started on 3975 to have remedial action applied. Even if you assume that only a small number of systems will have started on 3975, the others won't have much longer. I also imagine that users with very many deployments that began on a range of versions would prefer to see them behave consistently. These users really won't appreciate being told they cannot upgrade their fleet from say, 2 months time, and even a year or so from now would be an unwelcome inconvenience. I have been working under the assumption that we absolutely must not burn this bridge unless we have to.

@t-lo
Copy link
Member

t-lo commented Jun 18, 2025

Both good points, I welcome the discussion.
@ader1990 We cannot make changes that sacrifices compatibility with active deployments, that's one of the foundational guarantees we give to our users. "We don't break your deployments; ever" is one of the basic promises of the project, we've been through great lengths to uphold it - years-long cgroupsv1 backwards compatibility is a good example - and violating this would have significant impact to user trust.

Introducing only the new partition format would have limited impact as we would still need to test with the smaller partition sizes, and releases failing this test won't be greenlit. There is an immediate benefit for custom-built images though, they can easily activate kernel options and increase initrd sizes w/o messing with the partitioning themselves.

The scheme discussed in the "kernel move" document will allow us to transition without any user impact, and at the same time improve bootloader robustness. The security concepts introduced in that process also work towards our signing / trusted boot efforts (to which Chewi has made significant contributions) - if we doubt any of these, we should absolutely, and openly, discuss.

I do second your impression that we're proposing a significant change that needs to be thoroughly discussed. We brought it up in the DevSync and announced the write-up in the latest Office Hours - https://www.youtube.com/live/IXx2ZI963_Q?si=6fCyDtv3xDoBHQqP&t=899 - and we will continue to provide opportunities to further discuss. Your proposal of getting user feedback is awesome, we should definitely take a stab at this.

@ader1990
Copy link
Contributor Author

@t-lo I see a middle way, but quite complicated though: to have this PR change introduced sooner than later, and introduce the work presented in https://hackmd.io/@flatcar/H1MDJuu7lg in sleeper mode, that activates only when the update_engine sees that there is not enough space in /boot. After time, the Flatcar deployments will converge to be using only this PR's change. There is a best case scenario when the work presented here https://hackmd.io/@flatcar/H1MDJuu7lg will never be needed to activate during upgrades.

I was also thinking that the kernel move might also bring some complexity in how the ARM64 / and maybe RISC-V current / future work might be impacted: #2556 #2485 - but I need to check them case by case to see how the usage of uboot + grub + DTBs might be impacted. The nice part on this is that Flatcar does not officially support these workflows.

Also, there is the case of the fallback to be tested and added as a Mantle functional test: Flatcar supports fallback to the good partition if the upgraded version fails to boot. If there is a Flatcar already installed, let s say stable-2024, and then it is upgraded to stable-2026 (with the kernel move), and the stable-2026 fails to boot for any reason, then the stable-2024 should still be able to boot.

Flatcar initrd (early boot) is already quite complicated, documentation would be needed for new / potential Flatcar maintainers to better understand the workflow of initrd and bootengine, with the new changes. Both scenarios - basic new instance, and upgrades should have a better documentation. I will be glad to work on such documentation, as I found it very hard at first to understand what happens there, and now, the only way to understand it is to look in the boot logs / systemd logs and bootengine repo.

Thanks.

@ader1990
Copy link
Contributor Author

When looking at the overall things we are trying to achieve, it seems quite similar to what the industry is doing for some time: https://wiki.gentoo.org/wiki/Unified_kernel_image.

Maybe we should be looking at this in more depth, see if the upstream implementations regarding UKIs fit the Flatcar workflow (things like https://github.com/systemd/mkosi), and have a broader discussion and decision going further.

As noted by @chewi in the https://hackmd.io/@flatcar/H1MDJuu7lg Thilo suggested that USR-A/USR-B could be entire disk images, which might tie in well with systemd. Probably too big a change at this point, maybe later. -> we can go directly to UKIs if possible instead of having a temporary workaround.

@chewi
Copy link
Contributor

chewi commented Jun 19, 2025

#2556 is actually one of my big motivators for doing this. If we were to merge that today, it would immediately push us over the limit. Postponing the migration to when it's absolutely required is just delaying the inevitable, and not even for very long. It would also make upgrades fairly unpredictable for users. Will it do the migration this time or not?

I don't believe these changes will make arm64 or RISC-V support any harder. If anything, allowing GRUB upgrades and more flexibility with command line arguments could make it easier.

The ability to switch to a pre-migration slot is an essential part of the work. The new GRUB configuration will know how to boot the older kernel. With the new configuration being more flexible, that's not difficult to do. For UEFI systems, the old GRUB image will be installed as a fallback to be invoked by the shim or manually. I also aim to have a menu entry in the new GRUB pointing to the old GRUB. I'm not planning to allow for an actual downgrade (as opposed to just switching the slot) but I gather we don't support that anyway.

My document is fairly long because I went into some detail explaining how we'll get there and why I've taken this approach. The actual amount of change may be less than you expect. Most of it concerns the load-a script. Much of it is literally changing the kernel path or just reordering existing parts of the build process.

I know there has been interest in UKIs, so I did say early on that having the kernel in /usr would rule them out because EFI firmware cannot load from btrfs. Maybe you can load them from GRUB, but then what's the point? I'm not convinced that Flatcar needs to go down the UKI route. They can simplify the security model, but at a cost of flexibility that I don't think Flatcar can afford. Not using UKIs doesn't make things inherently insecure. Given all that, I don't see my proposal as a temporary workaround.

Sorry, I'm not sure what having USR-A/USR-B as entire disk images has to do with UKIs.

@t-lo
Copy link
Member

t-lo commented Jun 23, 2025

@ader1990 would you be available for discussing this (open ended! No bias from our side) in the dev sync on Wednesday? Would be awesome to chat about this more broadly, with the occasional deep dive.

@ader1990
Copy link
Contributor Author

@ader1990 would you be available for discussing this (open ended! No bias from our side) in the dev sync on Wednesday? Would be awesome to chat about this more broadly, with the occasional deep dive.

Hello, a discussion is always good.

@ader1990 ader1990 force-pushed the ader1990/increase_boot_partition branch from d4d9739 to a997b05 Compare July 3, 2025 13:01
@ader1990 ader1990 deployed to development July 3, 2025 13:01 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants