diff mbox series

[isar-cip-core,v2] initramfs-crypt-hook: Optimize disk encryption in combination with expansion of last partition

Message ID 20250122142811.106525-1-alexander.heinisch@siemens.com (mailing list archive)
State New, archived
Headers show
Series [isar-cip-core,v2] initramfs-crypt-hook: Optimize disk encryption in combination with expansion of last partition | expand

Commit Message

Heinisch, Alexander Jan. 22, 2025, 2:28 p.m. UTC
From: Alexander Heinisch <alexander.heinisch@siemens.com>

In the current implementation (since: 284175c3) disk expansion logic
is done before the actual disk encryption.

This results in reencrypting the full expanded size of the disk, instead
of only reencrypting the sections containing the actual data. This results
in a drastic increase of time (approx 20x on our systems ) needed for reencryption!

Since relevant disk contents are only available in the sections of the disk
available before the expansion, it is sufficient to reencrypt them only.

This patch changes order of encryption and disk expansion resulting in
faster encryption (since only the necessary parts are encrypted).
The resize operation does not reencrypt the added disk parts but just
extends the LUKS container (cryptsetup resize) to reflect the maximum
available disk space.

Signed-off-by: Alexander Heinisch <alexander.heinisch@siemens.com>
---

Changes v2:
- Reuse get_fstype from mkinitramfs scripts/functions. 
  Therefore, we could also get rid of mounting the partition
- Dropped support for btrfs (compared to v1) since crypt hook
  does not support btrfs anyways

 .../files/local-top-complete                  | 28 ++++++++++++++++---
 1 file changed, 24 insertions(+), 4 deletions(-)

Comments

Jan Kiszka Jan. 22, 2025, 3:41 p.m. UTC | #1
On 22.01.25 15:28, alexander.heinisch@siemens.com wrote:
> From: Alexander Heinisch <alexander.heinisch@siemens.com>
> 
> In the current implementation (since: 284175c3) disk expansion logic
> is done before the actual disk encryption.
> 
> This results in reencrypting the full expanded size of the disk, instead
> of only reencrypting the sections containing the actual data. This results
> in a drastic increase of time (approx 20x on our systems ) needed for reencryption!
> 
> Since relevant disk contents are only available in the sections of the disk
> available before the expansion, it is sufficient to reencrypt them only.
> 
> This patch changes order of encryption and disk expansion resulting in
> faster encryption (since only the necessary parts are encrypted).
> The resize operation does not reencrypt the added disk parts but just
> extends the LUKS container (cryptsetup resize) to reflect the maximum
> available disk space.
> 
> Signed-off-by: Alexander Heinisch <alexander.heinisch@siemens.com>
> ---
> 
> Changes v2:
> - Reuse get_fstype from mkinitramfs scripts/functions. 
>   Therefore, we could also get rid of mounting the partition
> - Dropped support for btrfs (compared to v1) since crypt hook
>   does not support btrfs anyways

Will likely return soon: I'm playing with a/b /var using btrfs as a
first option (should not remain the only one, but you need to start
somewhere).

> 
>  .../files/local-top-complete                  | 28 ++++++++++++++++---
>  1 file changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> index 8adc4e5..0146f58 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> @@ -153,6 +153,26 @@ expand_partition() {
>  	# Inform the kernel about the partitioning change
>  	partx -u "${last_part}"
>  
> +	last_part_device_name=${last_part#\/dev/}
> +
> +	mapping_name=$(cat /sys/class/block/"$last_part_device_name"/holders/*/dm/name)
> +	cryptsetup resize "$mapping_name"
> +	last_part_mapped=/dev/mapper/"$mapping_name"
> +	fs_type=$(get_fstype ${last_part_mapped})
> +
> +	case ${fs_type} in
> +	ext*)
> +
> +		# Do not fail resize2fs if no mtab entry is found, e.g.,
> +		# when using systemd mount units.
> +		export EXT2FS_NO_MTAB_OK=1
> +		resize2fs "${last_part_mapped}"
> +		;;
> +	*)
> +		log_warning_msg "Unrecognized filesystem type ${fs_type} - no resize performed"
> +		;;
> +	esac
> +
>  	log_end_msg
>  }
>  
> @@ -215,10 +235,6 @@ for partition_set in $partition_sets; do
>  		echo "ROOT=$decrypted_part" >/conf/param.conf
>  	fi
>  
> -	if [ "$partition_expand" = "expand" ]; then
> -		expand_partition $part_device
> -	fi
> -
>  	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>  			| grep -q "luks2"; then
>  		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
> @@ -259,6 +275,10 @@ for partition_set in $partition_sets; do
>  	esac
>  
>  	finalize_tpm2_encryption "$part_device"
> +
> +	if [ "$partition_expand" = "expand" ]; then
> +		expand_partition $part_device
> +	fi
>  done
>  
>  if [ -n "$watchdog_pid" ]; then

Thanks, will apply (once I cleaned up my local tree from the
ab-var-snapshot hacks).

Jan
Stephen Ecker Jan. 22, 2025, 6:13 p.m. UTC | #2
You will have to modify the encrypt_partition.script to add btrfs support,
but it's not that difficult.  There should be a way to add support for
other filesystems with directives that provide resize commands

On Wed, Jan 22, 2025, 9:41 AM Jan Kiszka via lists.cip-project.org
<jan.kiszka=siemens.com@lists.cip-project.org> wrote:

> On 22.01.25 15:28, alexander.heinisch@siemens.com wrote:
> > From: Alexander Heinisch <alexander.heinisch@siemens.com>
> >
> > In the current implementation (since: 284175c3) disk expansion logic
> > is done before the actual disk encryption.
> >
> > This results in reencrypting the full expanded size of the disk, instead
> > of only reencrypting the sections containing the actual data. This
> results
> > in a drastic increase of time (approx 20x on our systems ) needed for
> reencryption!
> >
> > Since relevant disk contents are only available in the sections of the
> disk
> > available before the expansion, it is sufficient to reencrypt them only.
> >
> > This patch changes order of encryption and disk expansion resulting in
> > faster encryption (since only the necessary parts are encrypted).
> > The resize operation does not reencrypt the added disk parts but just
> > extends the LUKS container (cryptsetup resize) to reflect the maximum
> > available disk space.
> >
> > Signed-off-by: Alexander Heinisch <alexander.heinisch@siemens.com>
> > ---
> >
> > Changes v2:
> > - Reuse get_fstype from mkinitramfs scripts/functions.
> >   Therefore, we could also get rid of mounting the partition
> > - Dropped support for btrfs (compared to v1) since crypt hook
> >   does not support btrfs anyways
>
> Will likely return soon: I'm playing with a/b /var using btrfs as a
> first option (should not remain the only one, but you need to start
> somewhere).
>
> >
> >  .../files/local-top-complete                  | 28 ++++++++++++++++---
> >  1 file changed, 24 insertions(+), 4 deletions(-)
> >
> > diff --git
> a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> > index 8adc4e5..0146f58 100644
> > --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> > +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> > @@ -153,6 +153,26 @@ expand_partition() {
> >       # Inform the kernel about the partitioning change
> >       partx -u "${last_part}"
> >
> > +     last_part_device_name=${last_part#\/dev/}
> > +
> > +     mapping_name=$(cat
> /sys/class/block/"$last_part_device_name"/holders/*/dm/name)
> > +     cryptsetup resize "$mapping_name"
> > +     last_part_mapped=/dev/mapper/"$mapping_name"
> > +     fs_type=$(get_fstype ${last_part_mapped})
> > +
> > +     case ${fs_type} in
> > +     ext*)
> > +
> > +             # Do not fail resize2fs if no mtab entry is found, e.g.,
> > +             # when using systemd mount units.
> > +             export EXT2FS_NO_MTAB_OK=1
> > +             resize2fs "${last_part_mapped}"
> > +             ;;
> > +     *)
> > +             log_warning_msg "Unrecognized filesystem type ${fs_type} -
> no resize performed"
> > +             ;;
> > +     esac
> > +
> >       log_end_msg
> >  }
> >
> > @@ -215,10 +235,6 @@ for partition_set in $partition_sets; do
> >               echo "ROOT=$decrypted_part" >/conf/param.conf
> >       fi
> >
> > -     if [ "$partition_expand" = "expand" ]; then
> > -             expand_partition $part_device
> > -     fi
> > -
> >       if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
> >                       | grep -q "luks2"; then
> >               open_tpm2_partition "$part_device" "$crypt_mount_name"
> "$tpm_device"
> > @@ -259,6 +275,10 @@ for partition_set in $partition_sets; do
> >       esac
> >
> >       finalize_tpm2_encryption "$part_device"
> > +
> > +     if [ "$partition_expand" = "expand" ]; then
> > +             expand_partition $part_device
> > +     fi
> >  done
> >
> >  if [ -n "$watchdog_pid" ]; then
>
> Thanks, will apply (once I cleaned up my local tree from the
> ab-var-snapshot hacks).
>
> Jan
>
> --
> Siemens AG, Foundational Technologies
> Linux Expert Center
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#17596):
> https://lists.cip-project.org/g/cip-dev/message/17596
> Mute This Topic: https://lists.cip-project.org/mt/110753272/9242556
> Group Owner: cip-dev+owner@lists.cip-project.org
> Unsubscribe:
> https://lists.cip-project.org/g/cip-dev/leave/13820419/9242556/92422264/xyzzy
> [stephenecker240@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
>
Jan Kiszka Feb. 4, 2025, 1:42 p.m. UTC | #3
On 22.01.25 15:28, alexander.heinisch@siemens.com wrote:
> From: Alexander Heinisch <alexander.heinisch@siemens.com>
> 
> In the current implementation (since: 284175c3) disk expansion logic
> is done before the actual disk encryption.
> 
> This results in reencrypting the full expanded size of the disk, instead
> of only reencrypting the sections containing the actual data. This results
> in a drastic increase of time (approx 20x on our systems ) needed for reencryption!
> 
> Since relevant disk contents are only available in the sections of the disk
> available before the expansion, it is sufficient to reencrypt them only.
> 
> This patch changes order of encryption and disk expansion resulting in
> faster encryption (since only the necessary parts are encrypted).
> The resize operation does not reencrypt the added disk parts but just
> extends the LUKS container (cryptsetup resize) to reflect the maximum
> available disk space.
> 
> Signed-off-by: Alexander Heinisch <alexander.heinisch@siemens.com>
> ---
> 
> Changes v2:
> - Reuse get_fstype from mkinitramfs scripts/functions. 
>   Therefore, we could also get rid of mounting the partition
> - Dropped support for btrfs (compared to v1) since crypt hook
>   does not support btrfs anyways
> 
>  .../files/local-top-complete                  | 28 ++++++++++++++++---
>  1 file changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> index 8adc4e5..0146f58 100644
> --- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> +++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
> @@ -153,6 +153,26 @@ expand_partition() {
>  	# Inform the kernel about the partitioning change
>  	partx -u "${last_part}"
>  
> +	last_part_device_name=${last_part#\/dev/}
> +
> +	mapping_name=$(cat /sys/class/block/"$last_part_device_name"/holders/*/dm/name)
> +	cryptsetup resize "$mapping_name"
> +	last_part_mapped=/dev/mapper/"$mapping_name"
> +	fs_type=$(get_fstype ${last_part_mapped})
> +
> +	case ${fs_type} in
> +	ext*)
> +
> +		# Do not fail resize2fs if no mtab entry is found, e.g.,
> +		# when using systemd mount units.
> +		export EXT2FS_NO_MTAB_OK=1

Why do we need this here but not during shrinking in
reencrypt_existing_partition?

> +		resize2fs "${last_part_mapped}"
> +		;;
> +	*)
> +		log_warning_msg "Unrecognized filesystem type ${fs_type} - no resize performed"

By now, we need support for btrfs here as well.

> +		;;
> +	esac
> +
>  	log_end_msg
>  }
>  
> @@ -215,10 +235,6 @@ for partition_set in $partition_sets; do
>  		echo "ROOT=$decrypted_part" >/conf/param.conf
>  	fi
>  
> -	if [ "$partition_expand" = "expand" ]; then
> -		expand_partition $part_device
> -	fi
> -
>  	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
>  			| grep -q "luks2"; then
>  		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
> @@ -259,6 +275,10 @@ for partition_set in $partition_sets; do
>  	esac
>  
>  	finalize_tpm2_encryption "$part_device"
> +
> +	if [ "$partition_expand" = "expand" ]; then
> +		expand_partition $part_device
> +	fi
>  done
>  
>  if [ -n "$watchdog_pid" ]; then

Jan
diff mbox series

Patch

diff --git a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
index 8adc4e5..0146f58 100644
--- a/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
+++ b/recipes-initramfs/initramfs-crypt-hook/files/local-top-complete
@@ -153,6 +153,26 @@  expand_partition() {
 	# Inform the kernel about the partitioning change
 	partx -u "${last_part}"
 
+	last_part_device_name=${last_part#\/dev/}
+
+	mapping_name=$(cat /sys/class/block/"$last_part_device_name"/holders/*/dm/name)
+	cryptsetup resize "$mapping_name"
+	last_part_mapped=/dev/mapper/"$mapping_name"
+	fs_type=$(get_fstype ${last_part_mapped})
+
+	case ${fs_type} in
+	ext*)
+
+		# Do not fail resize2fs if no mtab entry is found, e.g.,
+		# when using systemd mount units.
+		export EXT2FS_NO_MTAB_OK=1
+		resize2fs "${last_part_mapped}"
+		;;
+	*)
+		log_warning_msg "Unrecognized filesystem type ${fs_type} - no resize performed"
+		;;
+	esac
+
 	log_end_msg
 }
 
@@ -215,10 +235,6 @@  for partition_set in $partition_sets; do
 		echo "ROOT=$decrypted_part" >/conf/param.conf
 	fi
 
-	if [ "$partition_expand" = "expand" ]; then
-		expand_partition $part_device
-	fi
-
 	if /usr/sbin/cryptsetup luksDump --batch-mode "$part_device" \
 			| grep -q "luks2"; then
 		open_tpm2_partition "$part_device" "$crypt_mount_name" "$tpm_device"
@@ -259,6 +275,10 @@  for partition_set in $partition_sets; do
 	esac
 
 	finalize_tpm2_encryption "$part_device"
+
+	if [ "$partition_expand" = "expand" ]; then
+		expand_partition $part_device
+	fi
 done
 
 if [ -n "$watchdog_pid" ]; then