From e08b74f3eee5e5eb91ffac967e2bbd0754aa1add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Tue, 22 Mar 2016 09:18:14 +0100 Subject: [PATCH] Preserve hybrid GPT status on boot Added createHybridGPT method and setup the hybrid GPT/MBR table if requested by the XML configuration. In addition move the partition activation call also into the partition table finalize method. This is related to Issue #17 --- kiwi/boot/arch/arm/oemboot/suse-repart | 8 +-- kiwi/boot/arch/ppc/oemboot/suse-repart | 8 +-- kiwi/boot/arch/s390/oemboot/suse-repart | 8 +-- kiwi/boot/arch/x86_64/oemboot/rhel-repart | 8 +-- kiwi/boot/arch/x86_64/oemboot/suse-repart | 8 +-- kiwi/boot/functions.sh | 87 +++++++++++++++-------- kiwi/boot/image/base.py | 1 + kiwi/partitioner/gpt.py | 15 +++- kiwi/system/profile.py | 2 + test/unit/partitioner_gpt_test.py | 2 +- test/unit/profile_test.py | 1 + 11 files changed, 86 insertions(+), 62 deletions(-) diff --git a/kiwi/boot/arch/arm/oemboot/suse-repart b/kiwi/boot/arch/arm/oemboot/suse-repart index 01c13588..4697b133 100755 --- a/kiwi/boot/arch/arm/oemboot/suse-repart +++ b/kiwi/boot/arch/arm/oemboot/suse-repart @@ -607,7 +607,7 @@ function OEMRepart { #====================================== # Prepare partition table #-------------------------------------- - preparePartitionTable $imageDiskDevice + preparePartitionTable #====================================== # Initialize #-------------------------------------- @@ -626,13 +626,9 @@ function OEMRepart { fi sleep 1 #====================================== - # activate boot partition - #-------------------------------------- - activateBootPartition - #====================================== # Finalize partition table #-------------------------------------- - finalizePartitionTable $imageDiskDevice + finalizePartitionTable #====================================== # setup luks maps #-------------------------------------- diff --git a/kiwi/boot/arch/ppc/oemboot/suse-repart b/kiwi/boot/arch/ppc/oemboot/suse-repart index 94930190..fcd2d100 100755 --- a/kiwi/boot/arch/ppc/oemboot/suse-repart +++ b/kiwi/boot/arch/ppc/oemboot/suse-repart @@ -607,7 +607,7 @@ function OEMRepart { #====================================== # Prepare partition table #-------------------------------------- - preparePartitionTable $imageDiskDevice + preparePartitionTable #====================================== # Initialize #-------------------------------------- @@ -626,13 +626,9 @@ function OEMRepart { fi sleep 1 #====================================== - # activate boot partition - #-------------------------------------- - activateBootPartition - #====================================== # Finalize partition table #-------------------------------------- - finalizePartitionTable $imageDiskDevice + finalizePartitionTable #====================================== # setup luks maps #-------------------------------------- diff --git a/kiwi/boot/arch/s390/oemboot/suse-repart b/kiwi/boot/arch/s390/oemboot/suse-repart index 556a7978..2f8aec48 100755 --- a/kiwi/boot/arch/s390/oemboot/suse-repart +++ b/kiwi/boot/arch/s390/oemboot/suse-repart @@ -608,7 +608,7 @@ function OEMRepart { #====================================== # Prepare partition table #-------------------------------------- - preparePartitionTable $imageDiskDevice + preparePartitionTable #====================================== # Initialize #-------------------------------------- @@ -627,13 +627,9 @@ function OEMRepart { fi sleep 1 #====================================== - # activate boot partition - #-------------------------------------- - activateBootPartition - #====================================== # Finalize partition table #-------------------------------------- - finalizePartitionTable $imageDiskDevice + finalizePartitionTable #====================================== # setup luks maps #-------------------------------------- diff --git a/kiwi/boot/arch/x86_64/oemboot/rhel-repart b/kiwi/boot/arch/x86_64/oemboot/rhel-repart index 1adff59e..1f782b43 100755 --- a/kiwi/boot/arch/x86_64/oemboot/rhel-repart +++ b/kiwi/boot/arch/x86_64/oemboot/rhel-repart @@ -607,7 +607,7 @@ function OEMRepart { #====================================== # Prepare partition table #-------------------------------------- - preparePartitionTable $imageDiskDevice + preparePartitionTable #====================================== # Initialize #-------------------------------------- @@ -626,13 +626,9 @@ function OEMRepart { fi sleep 1 #====================================== - # activate boot partition - #-------------------------------------- - activateBootPartition - #====================================== # Finalize partition table #-------------------------------------- - finalizePartitionTable $imageDiskDevice + finalizePartitionTable #====================================== # setup luks maps #-------------------------------------- diff --git a/kiwi/boot/arch/x86_64/oemboot/suse-repart b/kiwi/boot/arch/x86_64/oemboot/suse-repart index 94930190..fcd2d100 100755 --- a/kiwi/boot/arch/x86_64/oemboot/suse-repart +++ b/kiwi/boot/arch/x86_64/oemboot/suse-repart @@ -607,7 +607,7 @@ function OEMRepart { #====================================== # Prepare partition table #-------------------------------------- - preparePartitionTable $imageDiskDevice + preparePartitionTable #====================================== # Initialize #-------------------------------------- @@ -626,13 +626,9 @@ function OEMRepart { fi sleep 1 #====================================== - # activate boot partition - #-------------------------------------- - activateBootPartition - #====================================== # Finalize partition table #-------------------------------------- - finalizePartitionTable $imageDiskDevice + finalizePartitionTable #====================================== # setup luks maps #-------------------------------------- diff --git a/kiwi/boot/functions.sh b/kiwi/boot/functions.sh index 078f523a..8eba3750 100644 --- a/kiwi/boot/functions.sh +++ b/kiwi/boot/functions.sh @@ -9361,6 +9361,21 @@ function cleanPartitionTable { fi } #====================================== +# partitionTableType +#-------------------------------------- +function partitionTableType { + # /.../ + # get partition table type + # ---- + local device=$(getDiskDevice $imageDiskDevice) + if ! parted -m -s $device unit s print > /tmp/table;then + systemException \ + "Failed to retrieve current partition table" \ + "reboot" + fi + cat /tmp/table | grep ^$device: | cut -f6 -d: +} +#====================================== # preparePartitionTable #-------------------------------------- function preparePartitionTable { @@ -9369,15 +9384,6 @@ function preparePartitionTable { # for a new disk geometry # ---- local IFS=$IFS_ORIG - local device=$(getDiskDevice $1) - local diskhd - local plabel - local line - local partn - local begin - local stopp - local label - local pflag #====================================== # check for hybrid iso #-------------------------------------- @@ -9389,19 +9395,11 @@ function preparePartitionTable { return fi #====================================== - # store a temp copy of the table - #-------------------------------------- - if ! parted -m -s $device unit s print > /tmp/table;then - systemException \ - "Failed to store current partition table" \ - "reboot" - fi - #====================================== # get table type #-------------------------------------- - plabel=$(cat /tmp/table | grep ^$device: | cut -f6 -d:) + local plabel=$(partitionTableType) #====================================== - # update table + # prepare table #-------------------------------------- if [[ "$plabel" =~ gpt ]];then #====================================== @@ -9420,7 +9418,28 @@ function finalizePartitionTable { # lost during repartition steps # ---- local IFS=$IFS_ORIG - local device=$(getDiskDevice $1) + #====================================== + # activate boot partition + #-------------------------------------- + if [[ $arch =~ i.86|x86_64 ]];then + activateBootPartition + fi + #====================================== + # get table type + #-------------------------------------- + local plabel=$(partitionTableType) + #====================================== + # finalize table + #-------------------------------------- + if [[ "$plabel" =~ gpt ]];then + #====================================== + # check if GPT needs to be hybrid + #-------------------------------------- + if [ "$kiwi_gpt_hybrid_mbr" = "true" ];then + createHybridGPT + fi + fi + return 0 } #====================================== # resetBootBind @@ -9541,11 +9560,6 @@ function setupKernelLinks { # activateBootPartition #-------------------------------------- function activateBootPartition { - if [[ ! $arch =~ i.86|x86_64 ]];then - # activation of a partition is only needed on - # x86 legacy BIOS implementations - return - fi local IFS=$IFS_ORIG local device=$imageBootDevice if [ ! -e $device ];then @@ -9564,26 +9578,39 @@ function activateBootPartition { #-------------------------------------- function relocateGPTAtEndOfDisk { local IFS=$IFS_ORIG - local device=$1 local input=/part.input if ! lookup gdisk &>/dev/null;then Echo "Warning, gdisk tool not found" Echo "This could break the resize of the image" fi rm -f $input - if [ ! -e "$device" ];then - device=$imageDiskDevice - fi for cmd in x e w y; do echo $cmd >> $input done - gdisk $device < $input 1>&2 + gdisk $imageDiskDevice < $input 1>&2 if [ ! $? = 0 ]; then Echo "Failed to write backup GPT at end of disk !" Echo "This could break the resize of the image" fi } #====================================== +# createHybridGPT +#-------------------------------------- +function createHybridGPT { + local IFS=$IFS_ORIG + local partition_count=$( + sgdisk -p $imageDiskDevice | grep -E '^\s+[0-9]+' | wc -l + ) + if [ $partition_count -gt 3 ]; then + # The max number of partitions to embed is 3 + # see man sgdisk for details + partition_count=3 + fi + if ! sgdisk -h $(seq -s : 1 $partition_count) $imageDiskDevice; then + Echo "Failed to create hybrid GPT/MBR !" + fi +} +#====================================== # FBOK #-------------------------------------- function FBOK { diff --git a/kiwi/boot/image/base.py b/kiwi/boot/image/base.py index 8e13eff0..5fbe743b 100644 --- a/kiwi/boot/image/base.py +++ b/kiwi/boot/image/base.py @@ -162,6 +162,7 @@ class BootImageBase(object): 'bootprofile', 'boottimeout', 'btrfs_root_is_snapshot', + 'gpt_hybrid_mbr', 'devicepersistency', 'filesystem', 'firmware', diff --git a/kiwi/partitioner/gpt.py b/kiwi/partitioner/gpt.py index 4a1291d7..ef77512d 100644 --- a/kiwi/partitioner/gpt.py +++ b/kiwi/partitioner/gpt.py @@ -77,7 +77,20 @@ class PartitionerGpt(PartitionerBase): def set_hybrid_mbr(self): partition_ids = [] - for number in range(1, self.partition_id + 1): + partition_number_to_embed = self.partition_id + if partition_number_to_embed > 3: + # the max number of partitions to embed is 3 + # for details see man sgdisk + log.debug( + 'maximum number of GPT hybrid MBR partitions is 3, got %d', + partition_number_to_embed + ) + partition_number_to_embed = 3 + log.debug( + 'reduced GPT hybrid MBR partition count to %d', + partition_number_to_embed + ) + for number in range(1, partition_number_to_embed + 1): partition_ids.append(format(number)) Command.run( ['sgdisk', '-h', ':'.join(partition_ids), self.disk_device] diff --git a/kiwi/system/profile.py b/kiwi/system/profile.py index 4d59ce2e..ca87c824 100644 --- a/kiwi/system/profile.py +++ b/kiwi/system/profile.py @@ -280,6 +280,8 @@ class Profile(object): type_section.get_bootloader() self.dot_profile['kiwi_btrfs_root_is_snapshot'] = \ type_section.get_btrfs_root_is_snapshot() + self.dot_profile['kiwi_gpt_hybrid_mbr'] = \ + type_section.get_gpt_hybrid_mbr() self.dot_profile['kiwi_devicepersistency'] = \ type_section.get_devicepersistency() self.dot_profile['kiwi_installboot'] = \ diff --git a/test/unit/partitioner_gpt_test.py b/test/unit/partitioner_gpt_test.py index 078c9506..ad43bed4 100644 --- a/test/unit/partitioner_gpt_test.py +++ b/test/unit/partitioner_gpt_test.py @@ -57,7 +57,7 @@ class TestPartitionerGpt(object): @patch('kiwi.partitioner.gpt.Command.run') def test_set_hybrid_mbr(self, mock_command): - self.partitioner.partition_id = 3 + self.partitioner.partition_id = 5 self.partitioner.set_hybrid_mbr() mock_command.assert_called_once_with( ['sgdisk', '-h', '1:2:3', '/dev/loop0'] diff --git a/test/unit/profile_test.py b/test/unit/profile_test.py index 85a356a6..44f8282a 100644 --- a/test/unit/profile_test.py +++ b/test/unit/profile_test.py @@ -90,6 +90,7 @@ class TestProfile(object): 'kiwi_profiles': '', 'kiwi_ramonly': None, 'kiwi_btrfs_root_is_snapshot': None, + 'kiwi_gpt_hybrid_mbr': None, 'kiwi_showlicense': None, 'kiwi_splash_theme': 'openSUSE', 'kiwi_strip_delete': '',