## Shared code for all guided partitioning components auto_init_disks() { local dev # Create new disk label; don't prompt for label . /lib/partman/lib/disk-label.sh prepare_new_labels "$@" || return 1 for dev in "$@"; do create_new_label "$dev" no || return 1 done } get_last_free_partition_infos() { local dev dev="$1" cd $dev free_space='' open_dialog PARTITIONS while { read_line num id size type fs path name; [ "$id" ]; }; do if [ "$fs" = free ]; then free_space=$id free_size=$size free_type=$type fi done close_dialog } # Mark a partition as LVM and add it to vgpath mark_partition_as_lvm() { local id id=$1 shift open_dialog GET_FLAGS $id flags=$(read_paragraph) close_dialog open_dialog SET_FLAGS $id write_line "$flags" write_line lvm write_line NO_MORE close_dialog } # Each disk must have at least one primary partition after autopartitioning. ensure_primary() { if echo "$scheme" | grep -q '\$primary{'; then # Recipe provides one primary partition return fi cd $dev open_dialog USES_EXTENDED read_line uses_extended close_dialog if [ "$uses_extended" = no ]; then # No need for this on this partition table type return fi open_dialog PARTITIONS local have_primary= local id type while { read_line x1 id x2 type x3 x4 x5; [ "$id" ]; }; do if [ "$type" = primary ]; then have_primary=1 fi done close_dialog if [ "$have_primary" ]; then # Existing disk provides one primary partition return fi # Neither disk nor recipe provides a primary partition. Force the # first partition in the recipe (arbitrarily chosen) to be primary. scheme="$( local first=1 foreach_partition ' if [ "$first" ]; then echo "$* \$primary{ }" first= else echo "$*" fi' )" } reuse_partitions() { cd $dev local scheme scheme="$scheme_reused" foreach_partition ' id="$(echo " $*" | sed -n '\''s/.* \$reuse{ \([^}]*\) }.*/\1/p'\'')" if [ -z "$id" ]; then db_progress STOP autopartitioning_failed fi setup_partition $id $* # Hack to stop EFI partitions showing up as formatted when # they will actually not be. We do not have a good # interface for this yet. if [ -f $id/method ] && [ "$(cat $id/method)" = efi ] && \ [ -f $id/detected_filesystem ]; then rm -f $id/format fi' } create_primary_partitions() { cd $dev while [ "$free_type" = pri/log ] && \ echo $scheme | grep -q '\$primary{'; do pull_primary set -- $primary if [ -z "$scheme_rest" ]; then open_dialog NEW_PARTITION primary $4 $free_space full ${1}000001 else open_dialog NEW_PARTITION primary $4 $free_space beginning ${1}000001 fi read_line num id size type fs path name close_dialog if [ -z "$id" ]; then db_progress STOP autopartitioning_failed fi neighbour=$(partition_after $id) if [ "$neighbour" ]; then open_dialog PARTITION_INFO $neighbour read_line x1 new_free_space x2 new_free_type fs x3 x4 close_dialog fi if [ -z "$scheme_rest" ]; then # If this is the last partition to be created, it does # not matter if we have space left for more partitions : elif [ -z "$neighbour" ] || [ "$fs" != free ] || \ [ "$new_free_type" = primary ] || \ [ "$new_free_type" = unusable ]; then open_dialog DELETE_PARTITION $id close_dialog open_dialog NEW_PARTITION primary $4 $free_space end ${1}000001 read_line num id size type fs path name close_dialog if [ -z "$id" ]; then db_progress STOP autopartitioning_failed fi neighbour=$(partition_before $id) if [ "$neighbour" ]; then open_dialog PARTITION_INFO $neighbour read_line x1 new_free_space x2 new_free_type fs x3 x4 close_dialog fi if [ -z "$neighbour" ] || [ "$fs" != free ] || [ "$new_free_type" = unusable ]; then open_dialog DELETE_PARTITION $id close_dialog break fi fi shift; shift; shift; shift if echo "$*" | grep -q "method{ lvm }"; then pv_devices="$pv_devices $path" mark_partition_as_lvm $id $* elif echo "$*" | grep -q "method{ crypto }"; then pv_devices="$pv_devices /dev/mapper/${path##*/}_crypt" fi setup_partition $id $* primary='' scheme="$scheme_rest" free_space=$new_free_space free_type="$new_free_type" done } create_partitions() { foreach_partition ' if [ -z "$free_space" ]; then db_progress STOP autopartitioning_failed fi open_dialog PARTITION_INFO $free_space read_line x1 free_space x2 free_type fs x3 x4 close_dialog if [ "$fs" != free ]; then free_type=unusable fi case "$free_type" in primary|logical) type="$free_type" ;; pri/log) type=logical ;; unusable) db_progress STOP autopartitioning_failed ;; esac if [ "$last" = yes ]; then open_dialog NEW_PARTITION $type $4 $free_space full ${1}000001 else open_dialog NEW_PARTITION $type $4 $free_space beginning ${1}000001 fi read_line num id size type fs path name close_dialog if [ -z "$id" ]; then db_progress STOP autopartitioning_failed fi shift; shift; shift; shift if echo "$*" | grep -q "method{ lvm }"; then pv_devices="$pv_devices $path" mark_partition_as_lvm $id $* elif echo "$*" | grep -q "method{ crypto }"; then pv_devices="$pv_devices /dev/mapper/${path##*/}_crypt" fi setup_partition $id $* free_space=$(partition_after $id)' } is_wholedisk_mdraid () { local device="`echo $1 | sed -e 's!/\([0-9]*\)$!\1!'`" local mddisk=${device#/dev/} local ret=0 local d [ -d /sys/block/$mddisk/md ] || return 1 for d in /sys/block/$mddisk/slaves/*; do case "$d" in dm-*|md*) ;; *p[0-9]|*p[0-9][0-9]) ret=1 break ;; esac done return $ret } get_auto_disks() { local dev device dmtype for dev in $DEVICES/*; do [ -d "$dev" ] || continue device=$(cat $dev/device) # Skip software RAID (mdadm) devices (/dev/md/X and /dev/mdX) # unless it's a whole-disk partitionable array if echo "$device" | grep -Eq "/dev/md/?[0-9]*$"; then if ! is_wholedisk_mdraid "$device"; then continue fi fi # Skip installer disk $(mount | grep -qF "$device on /cdrom ") && continue # Skip device mapper devices (/dev/mapper/), # except for multipath devices if echo $device | grep -q "^/dev/mapper/"; then if ! is_multipath_dev $device; then continue fi fi printf "$dev\t$(device_name $dev)\n" done } select_auto_disk() { local DEVS DEVS=$(get_auto_disks) [ -n "$DEVS" ] || return 1 debconf_select critical partman-auto/select_disk "$DEVS" "" || return 1 echo "$RET" return 0 } # Maps a devfs name to a partman directory dev_to_partman () { local dev_name="$1" local mapped_dev_name="$(mapdevfs $dev_name)" if [ -n "$mapped_dev_name" ]; then dev_name="$mapped_dev_name" fi for dev in $DEVICES/*; do # mapdevfs both to allow for different ways to refer to the # same device using devfs, and to allow user input in # non-devfs form if [ "$(mapdevfs $(cat $dev/device))" = "$dev_name" ]; then echo $dev fi done }