240 lines
4.9 KiB
Bash
Executable File
240 lines
4.9 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# This script creates partman cryptdisks for the encrypted devices
|
|
# setup in choose_partition/crypto/do_option.
|
|
|
|
. /lib/partman/lib/base.sh
|
|
. /lib/partman/lib/lvm-base.sh
|
|
|
|
# Avoid warnings from lvm2 tools about open file descriptors
|
|
export LVM_SUPPRESS_FD_WARNINGS=1
|
|
|
|
if [ -x /sbin/vgdisplay ]; then
|
|
vgroups=$(/sbin/vgdisplay 2>/dev/null | grep '^[ ]*VG Name' | \
|
|
sed -e 's/.*[[:space:]]\(.*\)$/\1/' | sort)
|
|
else
|
|
vgroups=''
|
|
fi
|
|
|
|
dev_to_devdir () {
|
|
echo $DEVICES/$(echo $1 | tr / =)
|
|
}
|
|
|
|
create_disk () {
|
|
device=$1
|
|
model=$2
|
|
size=$3
|
|
|
|
devdir=$(dev_to_devdir $device)
|
|
mkdir $devdir || return 1
|
|
cd $devdir
|
|
|
|
echo $device > $devdir/device
|
|
echo $model > $devdir/model
|
|
echo $size > $devdir/size
|
|
|
|
open_dialog OPEN $device
|
|
read_line response
|
|
close_dialog
|
|
if [ "$response" = failed ]; then
|
|
rm -rf $devdir
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
create_partition () {
|
|
local id num size type fs path name free_space free_size filesystem
|
|
filesystem=$2
|
|
|
|
cd $(dev_to_devdir $1)
|
|
|
|
open_dialog NEW_LABEL loop
|
|
close_dialog
|
|
|
|
# find the free space
|
|
open_dialog PARTITIONS
|
|
free_space=''
|
|
while { read_line num id size type fs path name; [ "$id" ]; }; do
|
|
case $fs in
|
|
free|unknown)
|
|
free_space=$id
|
|
free_size=$size
|
|
free_fs=$fs
|
|
# we can't break here
|
|
;;
|
|
esac
|
|
done
|
|
close_dialog
|
|
|
|
# create partition in the free space
|
|
if [ "$free_space" ]; then
|
|
if [ "$free_fs" = unknown ]; then
|
|
# parted >= 3.2 gives us a partition automatically.
|
|
id=$free_space
|
|
else
|
|
# With parted < 3.2 we must create a partition
|
|
# manually.
|
|
open_dialog NEW_PARTITION primary $filesystem $free_space full $free_size
|
|
read_line num id size type fs path name
|
|
close_dialog
|
|
fi
|
|
if [ -z "$id" ]; then
|
|
log "error: NEW_PARTITION returned no id"
|
|
return
|
|
fi
|
|
fi
|
|
open_dialog DISK_UNCHANGED
|
|
close_dialog
|
|
|
|
mkdir -p $id
|
|
echo $id
|
|
}
|
|
|
|
create_cryptdisk () {
|
|
local dev id num size path cryptdev cipher file vg vgs
|
|
dev=$1
|
|
id=$2
|
|
num=$3
|
|
size=$4
|
|
path=$5
|
|
|
|
cipher=$(cat $id/cipher)
|
|
keytype=$(cat $id/keytype)
|
|
method=$(cat $id/method)
|
|
|
|
templ="partman-crypto/text/cryptdev_description"
|
|
db_subst $templ CIPHER $cipher
|
|
db_subst $templ KEYTYPE $keytype
|
|
db_metaget $templ description || RET=''
|
|
model="$RET"
|
|
if [ -z "$model" ]; then
|
|
model="${cipher} ${keytype}"
|
|
fi
|
|
|
|
# Tell partman about the crypt disk
|
|
cryptdev=$(cat $id/crypt_active)
|
|
cryptdir=$(dev_to_devdir $cryptdev)
|
|
if [ ! -d $cryptdir ]; then
|
|
if ! create_disk $cryptdev "$model" $size; then
|
|
return 2
|
|
fi
|
|
fi
|
|
|
|
db_get partman/default_filesystem
|
|
default_fs="$RET"
|
|
|
|
case $keytype in
|
|
random)
|
|
filesystem=linux-swap
|
|
;;
|
|
keyfile|*)
|
|
filesystem="$default_fs"
|
|
;;
|
|
esac
|
|
|
|
# Create a new partition in there
|
|
cryptid=$(create_partition $cryptdev $filesystem)
|
|
if [ -z $cryptid ]; then
|
|
return 3
|
|
fi
|
|
cryptpart=$cryptdir/$cryptid
|
|
|
|
# Make sure partition hasn't been processed already
|
|
if [ -e $cryptpart/method ]; then
|
|
return 0
|
|
fi
|
|
|
|
# Select defaults
|
|
case $filesystem in
|
|
linux-swap)
|
|
echo swap > $cryptpart/method
|
|
if [ "$method" = crypto ]; then
|
|
>$cryptpart/format
|
|
else
|
|
rm -f $cryptpart/format
|
|
fi
|
|
;;
|
|
|
|
$default_fs)
|
|
if [ "$method" = crypto ]; then
|
|
echo format > $cryptpart/method
|
|
>$cryptpart/format
|
|
>$cryptpart/use_filesystem
|
|
echo $filesystem > $cryptpart/filesystem
|
|
else
|
|
echo keep > $cryptpart/method
|
|
rm -f $cryptpart/format
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# To avoid ordering problems between init.d/crypto and init.d/lvm,
|
|
# we need to duplicate a bit of the latter here, in case an existing
|
|
# crypto device contains an LVM PV.
|
|
if [ "$method" = crypto_keep ]; then
|
|
if pvdisplay "$cryptdev" >/dev/null 2>&1; then
|
|
for file in acting_filesystem filesystem format \
|
|
formatable use_filesystem; do
|
|
rm -f $cryptpart/$file
|
|
done
|
|
echo lvm > $cryptpart/method
|
|
if [ ! -e $cryptpart/locked ]; then
|
|
vg="$(pv_get_vg "$cryptdev")"
|
|
for vgs in $vgroups; do
|
|
if [ "$vg" = "$vgs" ]; then
|
|
vg_lock_pvs "$vg" "$cryptdev"
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
update_partition $cryptdir $cryptid
|
|
|
|
echo $path:$num:$dev/$id > $cryptdir/crypt_realdev
|
|
return 0
|
|
}
|
|
|
|
db_register partman-crypto/confirm partman-crypto/confirm_nooverwrite
|
|
|
|
for dev in /var/lib/partman/devices/*; do
|
|
[ -d "$dev" ] || continue
|
|
cd $dev
|
|
partitions=
|
|
open_dialog PARTITIONS
|
|
while { read_line num id size type fs path name; [ "$id" ]; }; do
|
|
if [ "$fs" != free ]; then
|
|
partitions="$partitions $id:$num:$size:$path"
|
|
fi
|
|
done
|
|
close_dialog
|
|
|
|
for p in $partitions; do
|
|
set -- $(IFS=: && echo $p)
|
|
id=$1
|
|
num=$2
|
|
size=$3
|
|
path=$4
|
|
|
|
cd $dev
|
|
|
|
[ -f $id/method ] || continue
|
|
[ -f $id/crypto_type ] || continue
|
|
[ -f $id/cipher ] || continue
|
|
[ -f $id/crypt_active ] || continue
|
|
|
|
method=$(cat $id/method)
|
|
[ $method = crypto ] || [ $method = crypto_keep ] || continue
|
|
|
|
if ! create_cryptdisk $dev $id $num $size $path; then
|
|
db_fset partman-crypto/init_failed seen false
|
|
db_input critical partman-crypto/init_failed
|
|
db_go || true
|
|
continue
|
|
fi
|
|
done
|
|
done
|
|
|