#!/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