[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#384532: partman-crypto: implement on-demand loading



Package: partman-crypto
Version: 10
Severity: normal
Tags: patch

As discussed on debian-devel, we should implement on-demand-loading for partman-crypto so that most of the packages are only loaded if/when the functionality is needed. This will reduce the memory requirements for an average install by several MB's.

I've attached the latest version of the patch. This one adds all the suggestions that the last one received on debian-boot (lowmem check, progress bar, anna-install only executed once per package).

I've tested the patch to the best of my ability, but since all crypto packages are currently included, it is hard to test the downloading of components properly.

Anyways, unless I get some feedback to the contrary, I plan to commit this patch soonish (probably during the weekend).

Regards,
David
Index: choose_method/crypto/do_option
===================================================================
--- choose_method/crypto/do_option	(revision 40192)
+++ choose_method/crypto/do_option	(working copy)
@@ -11,14 +11,7 @@
 rm -f $part/use_filesystem
 rm -f $part/format
 
-# Set defaults
-if [ -d /lib/partman/ciphers/dm-crypt ]; then
-	echo dm-crypt > $part/crypto_type
-	crypto_set_defaults $part dm-crypt
-elif [ -d /lib/partman/ciphers/loop-AES ]; then
-	echo loop-AES > $part/crypto_type
-	crypto_set_defaults $part loop-AES
-else
-	exit 1
-fi
+# Set defaults (this also downloads additional components)
+crypto_prepare_method $part dm-crypt || exit 1
+echo dm-crypt > $part/crypto_type
 echo crypto > $part/method
Index: debian/control
===================================================================
--- debian/control	(revision 40192)
+++ debian/control	(working copy)
@@ -8,17 +8,18 @@
 Package: partman-crypto
 XC-Package-Type: udeb
 Architecture: any
-Depends: partman-base (>= 87), partman-crypto-dm, partman-crypto-loop, cdebconf-newt-entropy (>= 0.3), ${shlibs:Depends}, ${misc:Depends}
+Priority: standard
+Depends: partman-base (>= 87), ${shlibs:Depends}, ${misc:Depends}
 Description: Add to partman support for block device encryption
 
 Package: partman-crypto-dm
 XC-Package-Type: udeb
 Architecture: all
-Depends: partman-crypto, crypto-modules, cryptsetup-udeb
+Depends: partman-crypto, crypto-modules, cryptsetup-udeb, cdebconf-newt-entropy (>= 0.3)
 Description: Add to partman support for dm-crypt encryption
 
 Package: partman-crypto-loop
 XC-Package-Type: udeb
 Architecture: all
-Depends: partman-crypto, loop-aes-modules, mount-aes-udeb, gnupg-udeb
+Depends: partman-crypto, loop-aes-modules, mount-aes-udeb, gnupg-udeb, cdebconf-newt-entropy (>= 0.3)
 Description: Add to partman support for loop-AES encryption
Index: debian/partman-crypto.templates
===================================================================
--- debian/partman-crypto.templates	(revision 40192)
+++ debian/partman-crypto.templates	(working copy)
@@ -363,6 +363,18 @@
  be destroyed upon each reboot. This should only be used for
  swap partitions.
 
+Template: partman-crypto/install_udebs_failure
+Type: error
+_Description: Failed to download crypto components
+ An error occurred trying to download additional crypto components.
+
+Template: partman-crypto/install_udebs_low_mem
+Type: boolean
+_Description: Proceed to install crypto components despite insufficient memory?
+ There does not seem to be sufficient memory available to install
+ additional crypto components. Would you like to go ahead and try
+ anyway? Note that this may crash the installation process.
+
 Template: partman-crypto/warning_experimental_nonaudit
 Type: boolean
 Default: false
Index: active_partition/crypto_type/do_option
===================================================================
--- active_partition/crypto_type/do_option	(revision 40192)
+++ active_partition/crypto_type/do_option	(working copy)
@@ -25,19 +25,30 @@
 		done
 	)
 
+	if [ -z "$choices" ]; then
+		return 1
+	fi
+
 	template="partman-crypto/crypto_type"
 	if ! debconf_select critical $template "$choices" ""; then
-		return
+		return 1
 	fi
 	type=$RET
+
 	echo $type > $part/crypto_type
-	crypto_set_defaults $part $type
+	crypto_prepare_method $part $type || return 1
+
+	return 0
 }
 
 [ -f $part/method ] || exit 0
 method=$(cat $part/method)
 
 if [ $method = crypto ]; then
-	select_crypto_type
+	# Load all known crypto types
+	crypto_load_udebs partman-crypto-dm
+	crypto_load_udebs partman-crypto-loop
+
+	select_crypto_type || return 1
 fi
 
Index: crypto_tools.sh
===================================================================
--- crypto_tools.sh	(revision 40192)
+++ crypto_tools.sh	(working copy)
@@ -381,7 +381,7 @@
 		for module in $(cat $modulefile); do
 			if [ -f $moduledir/$module ]; then
 				# Already loaded
-				continue;
+				continue
 			fi
 	
 			if modprobe -q $module; then
@@ -396,9 +396,56 @@
 	return 0
 }
 
-# Does initial setup for a crypto method:
-#  1) sets default values
-#  2) loads default modules
+# Loads additional crypto udebs
+crypto_load_udebs() {
+	local packages udebdir package memfree
+	packages="$1"
+	udebdir=/var/run/partman-crypto/udebs
+
+	if [ -z "$packages" ]; then
+		return 0
+	fi
+
+	if [ ! -d $udebdir ]; then
+		mkdir -p $udebdir
+	fi
+
+
+	for package in $packages; do
+		if [ -f $udebdir/$package ]; then
+			continue
+		fi
+
+		if [ -e /proc/meminfo ]; then
+			memfree=$(grep MemFree /proc/meminfo | head -1 | \
+				  sed 's/.*:[[:space:]]*\([0-9]*\).*/\1/')
+			# A more or less arbitrary limit
+			if [ "$memfree" -lt 10000 ]; then
+				db_set partman-crypto/install_udebs_low_mem false
+				db_fset partman-crypto/install_udebs_low_mem seen false
+				db_input critical partman-crypto/install_udebs_low_mem
+				db_go || true
+				db_get partman-crypto/install_udebs_low_mem
+				if [ "$RET" != true ]; then
+					return 1
+				fi
+			fi
+		fi
+
+		if ! anna-install $package; then
+			db_fset partman-crypto/install_udebs_failure seen false
+			db_input critical partman-crypto/install_udebs_failure
+			db_go || true
+			return 1
+		fi
+
+		touch $udebdir/$package
+	done
+
+	return 0
+}
+
+# Sets the defaults for a given crypto type
 crypto_set_defaults () {
 	local part type
 	part=$1
@@ -422,9 +469,53 @@
 		rm -f $part/keyhash
 		;;
 	esac
+	return 0
+}
 
-	# Also load the modules needed for the chosen type/cipher
-	crypto_load_modules $type "$(cat $part/cipher)"
+# Does initial setup for a crypto method:
+#  1) Loads the appropriate udebs
+#  2) Loads the appropriate kernel modules
+#  3) Sets default values
+crypto_prepare_method () {
+	local part type package
+	part=$1
+	type=$2
+	package=''
+
+	[ -d $part ] || return 1
+	case $type in
+	dm-crypt)
+		package="partman-crypto-dm"
+		;;
+	loop-AES)
+		package="partman-crypto-loop"
+		;;
+	*)
+		return 1
+		;;
+	esac
+
+	# 1A - Pull in the method package and additional dependencies
+	if ! crypto_load_udebs $package; then
+		return 1
+	fi
+
+	# 1B - Verify that it worked
+	if ! crypto_check_required_tools $type; then
+		return 1
+	fi
+
+	# 2 - Also load the kernel modules needed for the chosen type/cipher
+	if ! crypto_load_modules $type $(cat $part/cipher); then
+		return 1
+	fi
+
+	# 3 - Finally, set the defaults for the chosen type
+	if ! crypto_set_defaults $part $type; then
+		return 1
+	fi
+
+	return 0
 }
 
 crypto_check_required_tools() {
@@ -438,6 +529,8 @@
 	loop-AES)
 		tools="/bin/blockdev-keygen /usr/bin/gpg /bin/base64"
 		;;
+	*)
+		return 1
 	esac
 
 	for tool in $tools; do

Reply to: