ubuntu-22.04.3-desktop-amd64/casper/filesystem/usr/lib/partman/init.d/52crypto

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