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

Bug#462396: Multiple disks support for partman-auto-lvm



Hi,

Here are the patches concerning the functional changes. I also modified the 
error strings to follow Christian Perrier's advices. Please note that this 
patch adds a new string, "Multiple disks", that should be translated.

Cheers,
Grégory
diff -ruN --exclude=.svn --exclude=debian debian-installer.refactor/packages/partman/partman-auto-crypto/autopartition-crypto debian-installer.fchanges/packages/partman/partman-auto-crypto/autopartition-crypto
--- debian-installer.refactor/packages/partman/partman-auto-crypto/autopartition-crypto	2008-07-31 21:11:32.000000000 +0200
+++ debian-installer.fchanges/packages/partman/partman-auto-crypto/autopartition-crypto	2008-07-31 23:38:21.000000000 +0200
@@ -3,10 +3,10 @@
 . /lib/partman/lib/auto-lvm.sh
 . /lib/partman/lib/crypto-base.sh
 
-dev="$1"
+targetdev="$1"
 method=crypto
 
-auto_lvm_prepare $dev $method || exit $?
+auto_lvm_prepare $targetdev $method || exit $?
 
 found=no
 for dev in $DEVICES/*; do
@@ -28,15 +28,13 @@
 
 		echo dm-crypt > $id/crypto_type
 		crypto_prepare_method "$dev/$id" dm-crypt || exit 1
-		found=yes
-		break
 	done
-	[ $found = yes ] && break
 done
 
 crypto_check_setup || exit 1
 crypto_setup no || exit 1
 
+pv_devices=''
 # This is a kludge to workaround parted's refusal to allow dm devices
 # to be used for LVM
 for dev in $DEVICES/*; do
@@ -45,7 +43,7 @@
 	[ -f "$dev/device" ] || continue
 
 	# Found it
-	pv_devices=$(cat $dev/device)
+	pv_devices="$pv_devices $(cat $dev/device)"
 
 	# We should have only one partition, but lets be thorough
 	cd $dev
@@ -65,7 +63,7 @@
 	done
 done
 
-auto_lvm_perform || exit 1
+auto_lvm_perform $targetdev || exit 1
 
 # partman likes to believe that the virtual devices have a changed
 # partition table
diff -ruN --exclude=.svn debian-installer.refactor/packages/partman/partman-auto-lvm/autopartition-lvm debian-installer.fchanges/packages/partman/partman-auto-lvm/autopartition-lvm
--- debian-installer.refactor/packages/partman/partman-auto-lvm/autopartition-lvm	2008-07-31 21:11:28.000000000 +0200
+++ debian-installer.fchanges/packages/partman/partman-auto-lvm/autopartition-lvm	2008-08-02 12:24:30.000000000 +0200
@@ -13,4 +13,4 @@
 	pv_devices="$pv_devices $realpath"
 done
 
-auto_lvm_perform || exit 1
+auto_lvm_perform $dev || exit 1
diff -ruN --exclude=.svn debian-installer.refactor/packages/partman/partman-auto-lvm/debian/partman-auto-lvm.templates debian-installer.fchanges/packages/partman/partman-auto-lvm/debian/partman-auto-lvm.templates
--- debian-installer.refactor/packages/partman/partman-auto-lvm/debian/partman-auto-lvm.templates	2008-07-31 21:11:28.000000000 +0200
+++ debian-installer.fchanges/packages/partman/partman-auto-lvm/debian/partman-auto-lvm.templates	2008-08-05 16:15:47.000000000 +0200
@@ -42,3 +42,28 @@
  the volume group.
  .
  Check /var/log/syslog or see virtual console 4 for the details.
+
+Template: partman-auto-lvm/text/multiple_disks
+Type: text
+# :sl1:
+_Description: Multiple disks (%s)
+
+Template: partman-auto-lvm/no_such_pv
+Type: error
+# :sl3:
+_Description: Non-existing physical volume
+ A volume group definition contains a reference to a non-existing
+ physical volume.
+ .
+ Please check that all devices are properly connected.
+ Alternatively, please check the automatic partitioning recipe.
+
+Template: partman-auto-lvm/no_pv_in_vg
+Type: error
+# :sl3:
+_Description: No physical volume defined in volume group
+ The automatic partitioning recipe contains the definition of a
+ volume group that does not contain any physical volume.
+ .
+ Please check the automatic partitioning recipe.
+
diff -ruN --exclude=.svn debian-installer.refactor/packages/partman/partman-auto-lvm/lib/auto-lvm.sh debian-installer.fchanges/packages/partman/partman-auto-lvm/lib/auto-lvm.sh
--- debian-installer.refactor/packages/partman/partman-auto-lvm/lib/auto-lvm.sh	2008-08-03 18:45:50.000000000 +0200
+++ debian-installer.fchanges/packages/partman/partman-auto-lvm/lib/auto-lvm.sh	2008-08-03 20:55:46.000000000 +0200
@@ -50,7 +50,7 @@
 	local dev free_size
 	dev=$1
 	
-	get_disk_infos $dev;
+	get_last_free_partition_infos $dev
 	free_size=$(expr 0000000"$free_size" : '0*\(..*\)......$') # convert to megabytes
 
 	expand_scheme
@@ -60,13 +60,24 @@
 }
 
 auto_lvm_prepare() {
-	local dev method size free_size normalscheme target
+	local dev method size free_size normalscheme target extra_devices tmpdev tmpdevdir physdev
 	dev=$1
 	method=$2
 
 	[ -f $dev/size ] || return 1
 	size=$(cat $dev/size)
 
+	extra_devices=''
+	if db_get partman-auto-lvm/extra_devices && [ "$RET" ]; then
+		for tmpdev in "$RET"; do
+			tmpdevdir="$(dev_to_partman $tmpdev)"
+			if [ -d "$tmpdevdir" ]; then
+				size=$(($size + $(cat $tmpdevdir/size)))
+				extra_devices="$extra_devices $tmpdevdir"
+			fi
+		done
+	fi
+
 	# Be sure the modules are loaded
 	modprobe dm-mod >/dev/null 2>&1 || true
 	modprobe lvm-mod >/dev/null 2>&1 || true
@@ -75,21 +86,34 @@
 		log-output -t update-dev update-dev
 	fi
 
-	target="$(humandev $(cat $dev/device)) - $(cat $dev/model)"
+	if [ $extra_devices ]; then
+		for extradev in $dev $extra_devices; do
+			extradev_str="$extradev_str $(cat $extradev/device)"
+		done
+		db_metaget partman-auto-lvm/text/multiple_disks
+		printf "$RET" ${idenum} ${linux}
+		target=$(printf "$RET" $extradev_str)
+	else
+		target="$(humandev $(cat $dev/device)) - $(cat $dev/model)"
+	fi
 	target="$target: $(longint2human $size)"
 	free_size=$(expr 0000000"$size" : '0*\(..*\)......$') # convert to megabytes
 
 	choose_recipe lvm "$target" "$free_size" || return $?
 
-	auto_init_disk "$dev" || return $?
-
-	# Check if partition is usable; use existing partman-auto template as we depend on it
-	if [ "$free_type" = unusable ]; then
-		db_input critical partman-auto/unusable_space || true
-		db_go || true
-		return 1
-	fi
-	free_size=$(expr 0000000"$free_size" : '0*\(..*\)......$') # convert to megabytes
+	size=0
+	for tmpdev in $dev $extra_devices; do
+		auto_init_disk "$tmpdev" || return $?
+		size=$(($size + $free_size))
+
+		# Check if partition is usable; use existing partman-auto template as we depend on it
+		if [ "$free_type" = unusable ]; then
+			db_input critical partman-auto/unusable_space || true
+			db_go || true
+			return 1
+		fi
+	done
+	free_size=$(expr 0000000"$size" : '0*\(..*\)......$') # convert to megabytes
 
 	decode_recipe $recipe lvm
 
@@ -102,6 +126,9 @@
 	if echo "$scheme" | grep lvmok | grep -q "[[:space:]]/boot[[:space:]]"; then
 		bail_out unusable_recipe
 	fi
+	
+	# Save the scheme in a temporary file to reuse it in auto_lvm_perform
+	echo "$scheme" >> /tmp/auto_lvm_scheme
 
 	### Situation
 	### We have a recipe foo from arch bar. we don't know anything other than what
@@ -137,11 +164,6 @@
 		;;
 	esac
 
-	# Creating envelope
-	scheme="$normalscheme${NL}100 1000 1000000000 ext3 \$primary{ } method{ $method }"
-
-	expand_scheme
-
 	clean_method
 
 	# This variable will be used to store the partitions that will be LVM
@@ -149,28 +171,50 @@
 	# It will be used later to provide real paths to partitions to LVM.
 	# (still one atm)
 	devfspv_devices=''
+	physdev=$(cat $dev/device)
 
-	create_primary_partitions
+	# Creating envelope if needed
+	normalscheme=$(auto_lvm_create_envelope "$normalscheme" $physdev $method)
 
-	create_partitions
+	# Creating the partitions that have no device declared on the default device
+	# and partitions declared on it
+	scheme=$(echo "$normalscheme" | grep -v 'device{')
+	scheme=${scheme}${NL}$(echo "$normalscheme" | grep "device{ $physdev[[:digit:]]* }" )
+	auto_lvm_create_partitions $dev
+
+	# Creating the partitions declared on each of the extra devices
+	for tmpdev in $extra_devices; do
+		physdev=$(cat $tmpdev/device)
+		scheme=$(echo "$normalscheme" | grep "device{ $physdev[[:digit:]]* }" )
+		[ -z "$scheme" ] && scheme="100 1000 1000000000 ext3 \$primary{ } method{ $method } device{ $device }"
+		auto_lvm_create_partitions $tmpdev
+	done
 
 	if ! confirm_changes partman-lvm; then
 		return 255
 	fi
 
-	# Write the partition tables
 	disable_swap
-	cd $dev
-	open_dialog COMMIT
-	close_dialog
+	# Write the partition tables
+	for tmpdev in $dev $extra_devices; do
+		cd $tmpdev
+		open_dialog COMMIT
+		close_dialog
+		device_cleanup_partitions
+	done
 
-	device_cleanup_partitions
 	update_all
 }
 
 auto_lvm_perform() {
+	local IFS physdev defvgname schemeline schemevg schemedev targetdir targetvg pvdevice
+	[ -n $1 ] || return 1
+	
+	physdev=$(cat $1/device)
+	targetdir="/tmp/auto_lvm_perform"
+	mkdir $targetdir || exit 1
+	
 	# Use hostname as default vg name (if available)
-	local defvgname pv
 	db_get partman-auto-lvm/new_vg_name
 	if [ -z "$RET" ]; then
 		if [ -s /etc/hostname ]; then
@@ -199,12 +243,92 @@
 		db_register partman-auto-lvm/new_vg_name_exists partman-auto-lvm/new_vg_name
 	done
 
-	if vg_create "$VG_name" $pv_devices; then
-		perform_recipe_by_lvm $VG_name $recipe
-	else
-		bail_out vg_create_error
-	fi
-	vg_lock_pvs "$VG_name" $pv_devices
+	# The scheme contains all the necessary informations about eventuals
+	# extra VGs to create
+	# The VGs to create are :
+	#   - the default one if some partitions don't have the invg{ } tag
+	#   - the ones present in vgname{ } tags of PVs
+	scheme=$(< /tmp/auto_lvm_scheme)
+	
+	# Recreating the envelope if needed
+	scheme=$(auto_lvm_create_envelope "$scheme" $physdev $method)
+
+	# Extracting the VGs to create, and on which devices
+	# Physical devices will be stored in /tmp/auto_lvm_perform/$VGNAME, one per line
+	IFS="$NL"
+	for schemeline in $scheme; do
+		restore_ifs
+		# Type of the line : PV or partition
+		if echo $schemeline | grep -q '\$lvmok{'; then
+			# It's a partition
+			# Check if a VG name is given
+			schemevg=$(echo $schemeline | grep 'invg{' | sed -e 's!.*invg{ *\([^ }]*\) *}.*!\1!g')
+			# If not, it will be in the default VG
+			# The file are touch()'ed to have an error generated later
+			# if they are empty
+			if [ -z "$schemevg" ]; then
+				touch $targetdir/$VG_name
+			else
+				touch $targetdir/$schemevg
+			fi
+		elif echo $schemeline | grep -v -q 'mountpoint{'; then
+			# It's a PV
+			# Check if a VG name is given
+			schemevg=$(echo $schemeline | grep -E 'method\{ (lvm|crypto) \}' | grep 'vgname{' | sed -e 's!.*vgname{ *\([^ }]*\) *}.*!\1!g')
+			# Check if a device is given
+			schemedev=$(echo $schemeline | grep -E 'method\{ (lvm|crypto) \}' | grep 'device{' | sed -e 's!.*device{ *\([^ }]*\) *}.*!\1!g')
+
+			# If no VG is given, then it will be in the default one
+			if [ -z "$schemevg" ]; then
+				tmpschemename=$VG_name
+			else
+				tmpschemename=$schemevg
+			fi
+
+			# If no physical device is given, then it is created on the default one
+			if [ -z "$schemedev" ]; then
+				tmpdevname=$physdev
+			else
+				tmpdevname=$schemedev
+			fi
+
+			# Getting the partition name from $pv_devices
+			pvdev_found=''
+			for pvdevice in $pv_devices; do
+				tmppvdev=$(echo $pvdevice | sed -re 's/[[:digit:]]+$//g')
+				if [ $tmpdevname = $tmppvdev ] || [ $tmpdevname = $pvdevice ]; then
+					tmpdevname=$(mapdevfs $pvdevice)
+					pvdev_found='yes'
+					break
+				fi
+			done
+
+			if [ "$pvdev_found" = yes ]; then
+				echo $tmpdevname >> $targetdir/$tmpschemename
+			else
+				bail_out no_such_pv
+			fi
+		fi
+	done
+	
+	# If a device listed in $pv_devices is not used, then add it to the
+	# default VG
+	for pvdevice in $pv_devices; do
+		if ! grep -q $pvdevice $targetdir/*; then
+			echo $pvdevice >> $targetdir/$VG_name
+		fi
+	done
+	
+	for targetvg in $targetdir/*; do
+		pv_devices=$(cat $targetvg)
+		[ -z "$pv_devices" ] && bail_out no_pv_in_vg
+		if vg_create "$(basename $targetvg)" $pv_devices; then
+			perform_recipe_by_lvm $(basename $targetvg) $recipe
+		else
+			bail_out vg_create_error
+		fi
+		vg_lock_pvs "$VG_name" $pv_devices
+	done
 
 	# Default to accepting the autopartitioning
 	menudir_default_choice /lib/partman/choose_partition finish finish || true
diff -ruN --exclude=.svn debian-installer.refactor/packages/partman/partman-auto-lvm/perform_recipe_by_lvm debian-installer.fchanges/packages/partman/partman-auto-lvm/perform_recipe_by_lvm
--- debian-installer.refactor/packages/partman/partman-auto-lvm/perform_recipe_by_lvm	2008-07-31 21:11:28.000000000 +0200
+++ debian-installer.fchanges/packages/partman/partman-auto-lvm/perform_recipe_by_lvm	2008-08-03 19:01:57.000000000 +0200
@@ -7,9 +7,17 @@
 VG_name=$1
 recipe=$2
 
-decode_recipe $recipe lvm
+db_get partman-auto-lvm/new_vg_name
+default_vgname="$RET"
 
-scheme=$(echo "$scheme" | grep lvmok)
+decode_recipe $recipe lvm
+tmpscheme=$(echo "$scheme" | grep lvmok)
+scheme=$(echo "$tmpscheme" | grep "invg{ *$VG_name *}")
+if [ $VG_name = $default_vgname ]; then
+	# Adding in the scheme the partitions that have no VG declared
+	extraschemelines=$(echo "$tmpscheme" | grep -v 'invg{')
+	scheme="${scheme:+$scheme$NL}$extraschemelines"
+fi
 
 partstep=$(echo "$scheme" | wc -l)
 partstep=$(expr $partstep + 3)
@@ -48,7 +56,11 @@
 
 name_number=1
 foreach_partition '
-	if echo $* | grep -q "mountpoint{"; then
+	if echo $* | grep -q "lvname{"; then
+		lvname=$(echo $* | sed \
+			-e "s/.*lvname{  *\([^ }]*\) *}.*/\1/g"
+		)
+	elif echo $* | grep -q "mountpoint{"; then
 		lvname=$(echo $* | sed \
 			-e "s/.*mountpoint{  *\([^ }]*\) *}.*/\1/g" \
 			-e "s!//!/!g" \

Reply to: