OSInside / kiwi

KIWI - Appliance Builder Next Generation
https://osinside.github.io/kiwi
GNU General Public License v3.0
300 stars 152 forks source link

dracut resizing: on GPT don't assume resize #2576

Closed tamara-schmitz closed 3 months ago

tamara-schmitz commented 3 months ago

When the script in the dracut module checks if a resize should take place, it checks if the partition table was expanded to cover the entirety of the disk. If the check says that this has happened, partitions are not resized either. This check only exists for GPT.

There is hardware with UEFI firmware that on reboot "fixes up" the GPT table and expands it to the entirety of the disk. This causes partition expansion to be skipped.

Fixes # .

Changes proposed in this pull request:

schaefi commented 3 months ago

There is hardware with UEFI firmware that on reboot "fixes up" the GPT

why does EFI mess with the storage disks partition table ? I consider this a pretty bad bug in the firmware.

Well there was a reason for this code, to prevent any unneccessary block IO on the device when it has already been resized. Simply deleting that code doesn't look like a proper solution to me.

I would say we allow to skip the check with a new rd.kiwi.no_gpt_backup_check, document it properly and add this option to the kernelcmdline="..." attribute in the respective image configuration. This makes it explicit, clear, documented and does not change the current behavior just because there is some broken EFI firmware out there.

Thoughts ?

mairda commented 3 months ago

FYI on the reported UEFI firmware fixup of the GPT. It's been tested on three types of x86 PC based hardware. Two hardware PoS terminals and qemu. In all cases the same kiwi image is deployed using kiwi tools and the physical disk is larger than the image so the image primary GPT header is short of whole disk and there is no valid backup GPT at end of disk that matches the primary GPT. In qemu and one of the poS terminals that is still true on first boot of the image and the GPT then file-systems are adjusted automatically by kiwi. In the other PoS terminal after placing image blocks onto physical disk blocks and rebooting, no file-system adjust is performed and the kiwi log shows that no need to grow file-systems was detected. If repeated and booted instead into a recovery shell console sgdisk --verify confirms that the GPT already covers the whole disk and has no field errors. For example, placing an 8GB image onto a 20GB physical disk, there are unpartitioned blocks but there is NO gap between the GPT Last partitionable block field and the end of expected partitionable space on the physical disk plus primary and backup GPTs match. This happened between the completion of placing image sectors onto disk sectors and reaching the recovery shell console. Executed code may not be limited to but include any post image laydown behavior; the reboot method; the PoS terminal firmware (self-claimed UEFI); boot loader and OS boot (linux). The only one of these that is not known to be identical in all three test cases is the UEFI firmware. As a further test case that GPT design should be expected to prevent, two tests were performed after laying a short image onto a disk using qemu and placing a "lingering" backup GPT at the end of physical disk blocks (emulating one of multiple previous completion and GPT/file-system correction of repeated image installs). Whether the same GPT as the image or a whole disk corrected GPT was used as the simulated "lingering" GPT from a previous install the primary GPT was always detected as not reaching the end of disk. Whether the observed GPT fixup was performed by what might be claimed to be the PoS terminal's UEFI firmware, or some other firmware (BBIOSTLUEFID: badly built in operating system that launches UEFI directly) on this PoS terminal, laying an 8GB image on a 20GB disk and rebooting does not result in kiwi detecting any need for GPT correction on first boot of the image and file-systems are not adjusted but are still their original image size in the presence of large numbers of unpartitioned blocks in the GPT. Review of the GPT after linux boot shows it is already expanded to fill the disk and kiwi logging shows it was detected as such during first boot. While it is a fact that GPT expansion is expected when laying a short image on a larger disk it is incomplete to assume that a whole-disk GPT is evidence of successful file-system expansion. A short OR whole disk GPT with suitable free sectors is evidence that file-system expansion is practical. We could take the easy way out and forget how this PoS terminal had it's GPT adjusted between image laydown and first boot. A system power-failure occurs just after successful completion of using sgdisk -e but before any file-systems were adjusted. It's not a heavy load to re-deploy the image with a short GPT (though it doesn't scale well with image size) but it's also not necessary if the availability of suitable free sectors is detectable anyway even if the GPT covers the whole disk.

mairda commented 3 months ago

FYI on the reported UEFI firmware fixup of the GPT....

For the record, I have no problem with handling this via a switch option available when testing the need for file-system expansion (agreed it appears bad UEFI firmware as the plausible cause but it is there behaving as described).

tamara-schmitz commented 3 months ago

okay. how is the check option going to be implemented then?

I also think the topic of the issue is not quite correct. We do not assume a resize, we check the location of the backup table, which is a valuable implementation that I don't want to loose.

But that is the assumption that the code makes right now: resize_wanted returns no, even if oem-resize-once is false, just because GPT table and backup table are set correctly until the end. And so after that the script just exits after logging without checking partition sizes or anything.

If you want to keep the check, then I think it is done in the wrong spot of the code. sgdisk --verify could be done as precheck for relocate_gpt_at_end_of_disk.

I would say we allow to skip the check with a new rd.kiwi.no_gpt_backup_check, document it properly and add this option to the kernelcmdline="..." attribute in the respective image configuration. This makes it explicit, clear, documented and does not change the current behavior just because there is some broken EFI firmware out there.

Has kiwi implemented cmdline options like this before? That would make implementing this solution easier.

Well there was a reason for this code, to prevent any unneccessary block IO on the device when it has already been resized.

A GPT table is in the 10KB magnitude of size unless I am mistaken. If you believe it affects performance and you see that the script runs faster when timed, sure then there is a good reason to do this extra stuff.

schaefi commented 3 months ago

okay. how is the check option going to be implemented then?

I opened #2579 for review and follow-up

Has kiwi implemented cmdline options like this before? That would make implementing this solution easier.

sure it's regularly used and exists since day one of kiwi. Also some documentation about the kiwi dracut options can be found here: https://osinside.github.io/kiwi/concept_and_workflow/customize_the_boot_process.html#boot-image-parameters

I'm closing this one on behalf of the new PR and hope this is ok, I'd like to move forward with the bug because if we agree on the code it still needs to be ported to SLES15 as this is the source of the customer report.

Thanks