[2/2] Always try resizing the fs in expand on first boot

Message ID 20221108112837.435213-3-tobias.schaffner@siemens.com
State Under Review
Headers show
Series expand-on-first-boot: try fs resize on expanded partitions | expand

Commit Message

Tobias Schaffner Nov. 8, 2022, 11:28 a.m. UTC
From: Tobias Schaffner <tobias.schaffner@siemens.com>

If the filesystem resize fails or gets interrupted we have no way to recover
from this as the script always exits if the partition was already resized.

Check if we have to resize the partition but alway run the chosen fs resize
tool. Leave the decision if the filesystem has to be resized to resize2fs /
systemd-growfs.
If the filesystem was already expanded the resize2fs / systemd-growfs call is a
noop.

Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
 .../files/expand-last-partition.sh            | 35 +++++++++----------
 1 file changed, 16 insertions(+), 19 deletions(-)

Comments

Henning Schild Nov. 9, 2022, 8:52 a.m. UTC | #1
Hi,

if the scripts runs into a problem that is likely severe and should not
have happened in the first place. Making it more robust and so that it
can be run multiple times still does not hurt.

But really what one would need to do is make a copy of the original
partition table and restore that when the fs resize fails, in some exit
hook.

What you are doing here would only skip the partition resize on a
second call and maybe run into the same error again later on. Whatever
that error might have been. So we better understand the nature of such
errors instead of making that script so that we try over and over ...
and maybe always fail.

In fact the longer term plan was to move this to use systemds
first-boot semantics instead of that self-disabling trick.

Henning

Am Tue, 8 Nov 2022 12:28:37 +0100
schrieb "T. Schaffner" <tobias.schaffner@siemens.com>:

> From: Tobias Schaffner <tobias.schaffner@siemens.com>
> 
> If the filesystem resize fails or gets interrupted we have no way to
> recover from this as the script always exits if the partition was
> already resized.
> 
> Check if we have to resize the partition but alway run the chosen fs
> resize tool. Leave the decision if the filesystem has to be resized
> to resize2fs / systemd-growfs.
> If the filesystem was already expanded the resize2fs / systemd-growfs
> call is a noop.
> 
> Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
> ---
>  .../files/expand-last-partition.sh            | 35
> +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-)
> 
> diff --git
> a/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
> b/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
> index 0d662cc..b21b958 100755 ---
> a/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
> +++
> b/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
> @@ -35,26 +35,23 @@ LAST_PART_START="$(cat
> /sys/class/block/"${LAST_PART_NAME}"/start)" GPT_BACKUP_SIZE=33 if [
> $((LAST_PART_START + LAST_PART_SIZE + GPT_BACKUP_SIZE)) -lt
> "${DISK_SIZE}" ]; then
> -	echo "Disk is practically already full, doing nothing." >&2
> -	exit 0
> -fi
> +	# Transform the partition table as follows:
> +	#
> +	# - Remove any 'last-lba' header so sfdisk uses the entire
> available space.
> +	# - If this partition table is MBR and an extended partition
> container (EBR)
> +	#   exists, we assume this needs to be expanded as well;
> remove its size
> +	#   field so sfdisk expands it.
> +	# - For the previously fetched last partition, also remove
> the size field so
> +	#   sfdisk expands it.
> +	sfdisk -d "${BOOT_DEV}" 2>/dev/null | \
> +		grep -v last-lba | \
> +		sed 's|^\(.*, \)size=[^,]*, \(type=[f5]\)$|\1\2|' | \
> +		sed 's|^\('"${LAST_PART}"' .*, \)size=[^,]*, |\1|' |
> \
> +		sfdisk --force "${BOOT_DEV}"
>  
> -# Transform the partition table as follows:
> -#
> -# - Remove any 'last-lba' header so sfdisk uses the entire available
> space. -# - If this partition table is MBR and an extended partition
> container (EBR) -#   exists, we assume this needs to be expanded as
> well; remove its size -#   field so sfdisk expands it.
> -# - For the previously fetched last partition, also remove the size
> field so -#   sfdisk expands it.
> -sfdisk -d "${BOOT_DEV}" 2>/dev/null | \
> -	grep -v last-lba | \
> -	sed 's|^\(.*, \)size=[^,]*, \(type=[f5]\)$|\1\2|' | \
> -	sed 's|^\('"${LAST_PART}"' .*, \)size=[^,]*, |\1|' | \
> -	sfdisk --force "${BOOT_DEV}"
> -
> -# Inform the kernel about the partitioning change
> -partx -u "${LAST_PART}"
> +	# Inform the kernel about the partitioning change
> +	partx -u "${LAST_PART}"
> +fi
>  
>  # this is for debian stretch or systemd < 236
>  if [ ! -x /lib/systemd/systemd-growfs ]; then
Tobias Schaffner Nov. 9, 2022, 10:11 a.m. UTC | #2
On 09.11.22 09:52, Schild, Henning (T CED SES-DE) wrote:
> Hi,
> 
> if the scripts runs into a problem that is likely severe and should not
> have happened in the first place. Making it more robust and so that it
> can be run multiple times still does not hurt.
> 
> But really what one would need to do is make a copy of the original
> partition table and restore that when the fs resize fails, in some exit
> hook.
> 
> What you are doing here would only skip the partition resize on a
> second call and maybe run into the same error again later on. Whatever
> that error might have been. So we better understand the nature of such
> errors instead of making that script so that we try over and over ...
> and maybe always fail.
> 
> In fact the longer term plan was to move this to use systemds
> first-boot semantics instead of that self-disabling trick.
> 
> Henning

I like the idea of restoring the partition table after a failed resize. 
That covers the usecase that sfdisk did something wrong which I have not 
considered yet.

What this patch tried to fix in the first place where these two scenarios:
* The script gets interrupted for e.g. because of power cycle after 
repartitioning.
* The uevent after the partx -u takes longer than expected and the 
resize resizes to the old partition size or fails because of that.

Rare cases but may happen with many devices in the field.

> Am Tue, 8 Nov 2022 12:28:37 +0100
> schrieb "T. Schaffner" <tobias.schaffner@siemens.com>:
> 
>> From: Tobias Schaffner <tobias.schaffner@siemens.com>
>>
>> If the filesystem resize fails or gets interrupted we have no way to
>> recover from this as the script always exits if the partition was
>> already resized.
>>
>> Check if we have to resize the partition but alway run the chosen fs
>> resize tool. Leave the decision if the filesystem has to be resized
>> to resize2fs / systemd-growfs.
>> If the filesystem was already expanded the resize2fs / systemd-growfs
>> call is a noop.
>>
>> Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
>> ---
>>   .../files/expand-last-partition.sh            | 35
>> +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-)
>>
>> diff --git
>> a/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
>> b/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
>> index 0d662cc..b21b958 100755 ---
>> a/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
>> +++
>> b/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
>> @@ -35,26 +35,23 @@ LAST_PART_START="$(cat
>> /sys/class/block/"${LAST_PART_NAME}"/start)" GPT_BACKUP_SIZE=33 if [
>> $((LAST_PART_START + LAST_PART_SIZE + GPT_BACKUP_SIZE)) -lt
>> "${DISK_SIZE}" ]; then
>> -	echo "Disk is practically already full, doing nothing." >&2
>> -	exit 0
>> -fi
>> +	# Transform the partition table as follows:
>> +	#
>> +	# - Remove any 'last-lba' header so sfdisk uses the entire
>> available space.
>> +	# - If this partition table is MBR and an extended partition
>> container (EBR)
>> +	#   exists, we assume this needs to be expanded as well;
>> remove its size
>> +	#   field so sfdisk expands it.
>> +	# - For the previously fetched last partition, also remove
>> the size field so
>> +	#   sfdisk expands it.
>> +	sfdisk -d "${BOOT_DEV}" 2>/dev/null | \
>> +		grep -v last-lba | \
>> +		sed 's|^\(.*, \)size=[^,]*, \(type=[f5]\)$|\1\2|' | \
>> +		sed 's|^\('"${LAST_PART}"' .*, \)size=[^,]*, |\1|' |
>> \
>> +		sfdisk --force "${BOOT_DEV}"
>>   
>> -# Transform the partition table as follows:
>> -#
>> -# - Remove any 'last-lba' header so sfdisk uses the entire available
>> space. -# - If this partition table is MBR and an extended partition
>> container (EBR) -#   exists, we assume this needs to be expanded as
>> well; remove its size -#   field so sfdisk expands it.
>> -# - For the previously fetched last partition, also remove the size
>> field so -#   sfdisk expands it.
>> -sfdisk -d "${BOOT_DEV}" 2>/dev/null | \
>> -	grep -v last-lba | \
>> -	sed 's|^\(.*, \)size=[^,]*, \(type=[f5]\)$|\1\2|' | \
>> -	sed 's|^\('"${LAST_PART}"' .*, \)size=[^,]*, |\1|' | \
>> -	sfdisk --force "${BOOT_DEV}"
>> -
>> -# Inform the kernel about the partitioning change
>> -partx -u "${LAST_PART}"
>> +	# Inform the kernel about the partitioning change
>> +	partx -u "${LAST_PART}"
>> +fi
>>   
>>   # this is for debian stretch or systemd < 236
>>   if [ ! -x /lib/systemd/systemd-growfs ]; then
>

Patch

diff --git a/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh b/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
index 0d662cc..b21b958 100755
--- a/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
+++ b/meta/recipes-support/expand-on-first-boot/files/expand-last-partition.sh
@@ -35,26 +35,23 @@  LAST_PART_START="$(cat /sys/class/block/"${LAST_PART_NAME}"/start)"
 GPT_BACKUP_SIZE=33
 
 if [ $((LAST_PART_START + LAST_PART_SIZE + GPT_BACKUP_SIZE)) -lt "${DISK_SIZE}" ]; then
-	echo "Disk is practically already full, doing nothing." >&2
-	exit 0
-fi
+	# Transform the partition table as follows:
+	#
+	# - Remove any 'last-lba' header so sfdisk uses the entire available space.
+	# - If this partition table is MBR and an extended partition container (EBR)
+	#   exists, we assume this needs to be expanded as well; remove its size
+	#   field so sfdisk expands it.
+	# - For the previously fetched last partition, also remove the size field so
+	#   sfdisk expands it.
+	sfdisk -d "${BOOT_DEV}" 2>/dev/null | \
+		grep -v last-lba | \
+		sed 's|^\(.*, \)size=[^,]*, \(type=[f5]\)$|\1\2|' | \
+		sed 's|^\('"${LAST_PART}"' .*, \)size=[^,]*, |\1|' | \
+		sfdisk --force "${BOOT_DEV}"
 
-# Transform the partition table as follows:
-#
-# - Remove any 'last-lba' header so sfdisk uses the entire available space.
-# - If this partition table is MBR and an extended partition container (EBR)
-#   exists, we assume this needs to be expanded as well; remove its size
-#   field so sfdisk expands it.
-# - For the previously fetched last partition, also remove the size field so
-#   sfdisk expands it.
-sfdisk -d "${BOOT_DEV}" 2>/dev/null | \
-	grep -v last-lba | \
-	sed 's|^\(.*, \)size=[^,]*, \(type=[f5]\)$|\1\2|' | \
-	sed 's|^\('"${LAST_PART}"' .*, \)size=[^,]*, |\1|' | \
-	sfdisk --force "${BOOT_DEV}"
-
-# Inform the kernel about the partitioning change
-partx -u "${LAST_PART}"
+	# Inform the kernel about the partitioning change
+	partx -u "${LAST_PART}"
+fi
 
 # this is for debian stretch or systemd < 236
 if [ ! -x /lib/systemd/systemd-growfs ]; then