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: