From 2c5994e359da4299ffb0a9e7f3f338002677a904 Mon Sep 17 00:00:00 2001 From: Dieter Plaetinck Date: Sun, 5 Dec 2010 19:49:56 +0100 Subject: code cleanup: use bash4 associative arrays for filesystem stuff now the information about which setup programs for filesystems, label programs, which FS'es can go on which blockdevices, need/can have labels, can be mounted and FS friendly names are in a central place in libs/lib-blockdevices-filesystems.sh. This simplifies the code somewhat where you actually want to work with the filesystems. Also, we only check the available filesystem utilities once at program startup, causing a performance improvement. --- src/core/libs/lib-blockdevices-filesystems.sh | 155 +++++++++++++++----------- src/core/libs/lib-ui-interactive.sh | 61 +++------- src/core/libs/lib-ui.sh | 4 + src/core/procedures/automatic | 1 + src/core/procedures/base | 1 + src/core/procedures/interactive | 1 + 6 files changed, 112 insertions(+), 111 deletions(-) (limited to 'src/core') diff --git a/src/core/libs/lib-blockdevices-filesystems.sh b/src/core/libs/lib-blockdevices-filesystems.sh index 4038edb..6e792f7 100644 --- a/src/core/libs/lib-blockdevices-filesystems.sh +++ b/src/core/libs/lib-blockdevices-filesystems.sh @@ -36,6 +36,56 @@ TMP_FILESYSTEMS=$RUNTIME_DIR/aif-filesystems # Only used internally by this libr TMP_BLOCKDEVICES=$RUNTIME_DIR/aif-blockdata +declare -A filesystem_programs=(["swap"]="mkswap" ["reiserfs"]="mkreiserfs" ["lvm-pv"]="pvcreate" ["lvm-vg"]="vgcreate" ["lvm-lv"]="lvcreate" ["dm_crypt"]="cryptsetup") +for simple in ext2 ext3 ext4 nilfs2 xfs jfs vfat +do + filesystem_programs+=([$simple]=mkfs.$simple) +done + +declare -A label_programs=(["xfs"]="xfs_admin" ["jfs"]="jfs_tune" ["reiserfs"]="reiserfstune" ["nilfs2"]="nilfs-tune" ["vfat"]="dosfslabel") +for ext in ext2 ext3 ext4 +do + label_programs+=([$ext]=tune2fs) +done + +# names for filesystems (which are shown to users in dialogs etc, don't use spaces!) +declare -A filesystem_names=(["nilfs2"]="Nilfs2_EXPERIMENTAL" ["vfat"]="vFat") +for i in ext2 ext3 ext4 reiserfs xfs jfs +do + name=$(echo $i | capitalize) + filesystem_names+=([$i]=$name) +done + +# specify which filesystems can be stored on which blockdevices +fs_on_raw=(swap ext2 ext3 ext4 reiserfs nilfs2 xfs jfs vfat dm_crypt lvm-pv) +fs_on_lvm_lv=(swap ext2 ext3 ext4 reiserfs nilfs2 xfs jfs vfat dm_crypt) +fs_on_dm_crypt=(swap ext2 ext3 ext4 reiserfs nilfs2 xfs jfs vfat lvm-pv) +fs_on_lvm_pv=(lvm-vg) +fs_on_lvm_vg=(lvm-lv) + +# the following is useful to do checks like check_is_in $fs_type ${fs_on[$part_type]} (or iterate it) +# bash does not allow lists (array) in associative arrays, but this seems to work. +# maybe it stores them as strings, which in this case is ok (no spaces in elements) +declare -A fs_on +fs_on[raw]=${fs_on_raw[@]} +fs_on[lvm-lv]=${fs_on_lvm_lv[@]} +fs_on[lvm-pv]=${fs_on_lvm_pv[@]} +fs_on[lvm-vg]=${fs_on_lvm_vg[@]} +fs_on[dm_crypt]=${fs_on_dm_crypt[@]} + +fs_mountable=(ext2 ext3 ext4 nilfs2 xfs jfs vfat reiserfs) +fs_label_mandatory=('lvm-vg' 'lvm-lv' 'dm_crypt') +fs_label_optional=('ext2' 'ext3' 'ext4' 'reiserfs' 'nilfs2' 'xfs' 'jfs' 'vfat') + +# returns which filesystems you can create based on the locally available utilities +get_possible_fs () { + possible_fs= + for fs in "${!filesystem_programs[@]}" + do + which ${filesystem_programs[$fs]} &>/dev/null && possible_fs=("${possible_fs[@]}" fs) + done +} + # procedural code from quickinst functionized and fixed. # there were functions like this in the setup script too, with some subtle differences. see below @@ -728,7 +778,7 @@ process_filesystem () # Create the FS if [ "$fs_create" = yes ] then - if ! program=`get_filesystem_program $fs_type` + if ! check_is_in $fs_type "${!filesystem_programs[@]}" then show_warning "process_filesystem error" "Cannot determine filesystem program for $fs_type on $part. Not creating this FS" return 1 @@ -736,31 +786,35 @@ process_filesystem () [ -z "$fs_label" ] && [ "$fs_type" = lvm-vg -o "$fs_type" = lvm-pv ] && fs_label=default #TODO. implement the incrementing numbers label for lvm vg's and lv's #TODO: health checks on $fs_params etc + program="${filesystem_programs[$fs_type]}" case ${fs_type} in - xfs) mkfs.xfs -f $part $fs_opts >$LOG 2>&1; ret=$? ;; - jfs) yes | mkfs.jfs $part $fs_opts >$LOG 2>&1; ret=$? ;; - reiserfs) yes | mkreiserfs $part $fs_opts >$LOG 2>&1; ret=$? ;; - ext2) mke2fs "$part" $fs_opts >$LOG 2>&1; ret=$? ;; - ext3) mke2fs -j $part $fs_opts >$LOG 2>&1; ret=$? ;; - ext4) mkfs.ext4 $part $fs_opts >$LOG 2>&1; ret=$? ;; #TODO: installer.git uses mke2fs -t ext4 -O dir_index,extent,uninit_bg , which is best? - nilfs2) mkfs.nilfs2 "$part" $fs_opts >$LOG 2>&1; ret=$? ;; - vfat) mkfs.vfat $part $fs_opts >$LOG 2>&1; ret=$? ;; - swap) if [ -z "$fs_label" ]; then - mkswap $part $fs_opts >$LOG 2>&1; ret=$? - else - mkswap -L $fs_label $part $fs_opts >$LOG 2>&1; ret=$? - fi - ;; - dm_crypt) [ -z "$fs_params" ] && fs_params='-c aes-xts-plain -y -s 512'; - inform "Please enter your passphrase to encrypt the device (with confirmation)" - cryptsetup $fs_params $fs_opts luksFormat -q $part >$LOG 2>&1 < /dev/tty ; ret=$? #hack to give cryptsetup the approriate stdin. keep in mind we're in a loop (see process_filesystems where something else is on stdin) - inform "Please enter your passphrase to unlock the device" - cryptsetup luksOpen $part $fs_label >$LOG 2>&1 < /dev/tty; ret=$? || ( show_warning 'cryptsetup' "Error luksOpening $part on /dev/mapper/$fs_label" ) ;; - lvm-pv) pvcreate $fs_opts $part >$LOG 2>&1; ret=$? ;; - lvm-vg) # $fs_params: list of PV's - vgcreate $fs_opts $fs_label $fs_params >$LOG 2>&1; ret=$? ;; - lvm-lv) # $fs_params = size string (eg '5G') - lvcreate -L $fs_params $fs_opts -n $fs_label `sed 's#/dev/mapper/##' <<< $part` >$LOG 2>&1; ret=$? ;; #$fs_opts is usually something like -L 10G # Strip '/dev/mapper/' part because device file may not exist. TODO: do i need to activate them? + xfs) + $program -f $part $fs_opts >$LOG 2>&1; ret=$? ;; + jfs|reiserfs) + yes | $program $part $fs_opts >$LOG 2>&1; ret=$? ;; + ext2|ext3|ext4|nilfs2|vfat) + $program $part $fs_opts >$LOG 2>&1; ret=$? ;; + swap) + if [ -z "$fs_label" ]; then + $program $part $fs_opts >$LOG 2>&1; ret=$? + else + $program -L $fs_label $part $fs_opts >$LOG 2>&1; ret=$? + fi + ;; + dm_crypt) + [ -z "$fs_params" ] && fs_params='-c aes-xts-plain -y -s 512'; + inform "Please enter your passphrase to encrypt the device (with confirmation)" + $program $fs_params $fs_opts luksFormat -q $part >$LOG 2>&1 < /dev/tty ; ret=$? #hack to give cryptsetup the approriate stdin. keep in mind we're in a loop (see process_filesystems where something else is on stdin) + inform "Please enter your passphrase to unlock the device" + $program luksOpen $part $fs_label >$LOG 2>&1 < /dev/tty; ret=$? || ( show_warning 'cryptsetup' "Error luksOpening $part on /dev/mapper/$fs_label" ) ;; + lvm-pv) + $program $fs_opts $part >$LOG 2>&1; ret=$? ;; + lvm-vg) + # $fs_params: list of PV's + $program $fs_opts $fs_label $fs_params >$LOG 2>&1; ret=$? ;; + lvm-lv) + # $fs_params = size string (eg '5G') + $program -L $fs_params $fs_opts -n $fs_label `sed 's#/dev/mapper/##' <<< $part` >$LOG 2>&1; ret=$? ;; #$fs_opts is usually something like -L 10G # Strip '/dev/mapper/' part because device file may not exist. TODO: do i need to activate them? # don't handle anything else here, we will error later esac # The udevadm settle is a workaround for a bug/racecondition in cryptsetup. See: @@ -772,27 +826,17 @@ process_filesystem () sleep 2 fi - if [ -n "$fs_label" ] + if [ -n "$fs_label" ] && check_is_in $fs_type "${!label_programs[@]}" then - if [ "$fs_type" = xfs ] - then - xfs_admin -L $fs_label $part >$LOG 2>&1; ret=$? - elif [ "$fs_type" = jfs ] - then - jfs_tune -L $fs_label $part >$LOG 2>&1; ret=$? - elif [ "$fs_type" = reiserfs ] - then - reiserfstune -l $fs_label $part >$LOG 2>&1; ret=$? - elif [ "$fs_type" = nilfs2 ] - then - nilfs-tune -L $fs_label $part >$LOG 2>&1; ret=$? - elif [ "$fs_type" = ext2 -o "$fs_type" = ext3 -o "$fs_type" = ext4 ] - then - tune2fs -L $fs_label $part >$LOG 2>&1; ret=$? - elif [ "$fs_type" = vfat ] - then - dosfslabel $part $fs_label >$LOG 2>&1; ret=$? - fi + program="${label_programs[$fs_type]}" + case ${fs_type} in + xfs|jfs|nilfs2|ext2|ext3|ext4) + $program -L $fs_label $part >$LOG 2>&1; ret=$?;; + reiserfs) + $program -l $fs_label $part >$LOG 2>&1; ret=$?;; + vfat) + $program $part $fs_label >$LOG 2>&1; ret=$?;; + esac [ "$ret" -gt 0 ] && { show_warning "process_filesystem error" "Error setting label $fs_label on $part." ; return 1; } fi @@ -850,27 +894,6 @@ process_filesystem () } -# $1 filesystem type -get_filesystem_program () -{ - [ -z "$1" ] && die_error "get_filesystem_program needs a filesystem id as \$1" - [ $1 = swap ] && echo mkswap && return 0 - [ $1 = ext2 ] && echo mkfs.ext2 && return 0 - [ $1 = ext3 ] && echo mkfs.ext3 && return 0 - [ $1 = ext4 ] && echo mkfs.ext4 && return 0 - [ $1 = reiserfs ] && echo mkreiserfs && return 0 - [ $1 = nilfs2 ] && echo mkfs.nilfs2 && return 0 - [ $1 = xfs ] && echo mkfs.xfs && return 0 - [ $1 = jfs ] && echo mkfs.jfs && return 0 - [ $1 = vfat ] && echo mkfs.vfat && return 0 - [ $1 = lvm-pv ] && echo pvcreate && return 0 - [ $1 = lvm-vg ] && echo vgcreate && return 0 - [ $1 = lvm-lv ] && echo lvcreate && return 0 - [ $1 = dm_crypt ] && echo cryptsetup && return 0 - return 1 -} - - # $1 blockdevice # $2 unit: B, KiB, kB, MiB, MB, GiB or GB. defaults to B (we follow IEEE 1541-2002 ) # output will be in $BLOCKDEVICE_SIZE diff --git a/src/core/libs/lib-ui-interactive.sh b/src/core/libs/lib-ui-interactive.sh index 6ac2478..92fc236 100644 --- a/src/core/libs/lib-ui-interactive.sh +++ b/src/core/libs/lib-ui-interactive.sh @@ -256,14 +256,10 @@ interactive_autoprepare() get_blockdevice_size $DISC MiB FSOPTS= - which `get_filesystem_program ext2` &>/dev/null && FSOPTS="$FSOPTS ext2 Ext2" - which `get_filesystem_program ext3` &>/dev/null && FSOPTS="$FSOPTS ext3 Ext3" - which `get_filesystem_program ext4` &>/dev/null && FSOPTS="$FSOPTS ext4 Ext4" - which `get_filesystem_program reiserfs` &>/dev/null && FSOPTS="$FSOPTS reiserfs Reiser3" - which `get_filesystem_program xfs` &>/dev/null && FSOPTS="$FSOPTS xfs XFS" - which `get_filesystem_program jfs` &>/dev/null && FSOPTS="$FSOPTS jfs JFS" - which `get_filesystem_program vfat` &>/dev/null && FSOPTS="$FSOPTS vfat VFAT" - which `get_filesystem_program nilfs2` &>/dev/null && FSOPTS="$FSOPTS nilfs2 Nilfs2_EXPERIMENTAL" + for fs in ext2 ext3 ext4 reiserfs xfs jfs vfat nilfs2 + do + check_is_in $fs $possible_fs && FSOPTS="$FSOPTS $fs ${filesystem_names[$fs]}" + done ask_number "Enter the size (MiB) of your /boot partition. Recommended size: 100MiB\n\nDisk space left: $BLOCKDEVICE_SIZE MiB" 16 $BLOCKDEVICE_SIZE 100 || return 1 BOOT_PART_SIZE=$ANSWER_NUMBER @@ -394,44 +390,17 @@ interactive_filesystem () if [ "$NEW_FILESYSTEM" != no_fs ] then - # Possible filesystems/software layers on partitions/block devices - # name on top of mountpoint? label? DM device? theoretical device? opts? special params? - - # swap raw/lvm-lv/dm_crypt no no no no no no - # ext 2 raw/lvm-lv/dm_crypt optional optional no no optional no - # ext 3 raw/lvm-lv/dm_crypt optional optional no no optional no - # ext 4 raw/lvm-lv/dm_crypt optional optional no no optional no - # reiserFS raw/lvm-lv/dm_crypt optional optional no no optional no - # Nilfs2 raw/lvm-lv/dm_crypt optional optional no no optional no - # xfs raw/lvm-lv/dm_crypt optional optional no no optional no - # jfs raw/lvm-lv/dm_crypt optional optional no no optional no - # vfat raw/lvm-lv/dm_crypt optional opt i guess no no optional no - # lvm-pv raw/dm_crypt no no no. $pv = $part $part+ (+ is to differentiate from $part) optional no - # lvm-vg lvm-pv no yes /dev/mapper/$label =dm device optional PV's to use - # lvm-lv lvm-vg no yes /dev/mapper/$part_label-$label =dm device optional LV size - # dm_crypt raw/rvm-lv no yes /dev/mapper/$label =dm device optional no - - # Determine which filesystems/blockdevices are possible for this blockdevice FSOPTS= - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program swap` &>/dev/null && FSOPTS="$FSOPTS swap Swap" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program ext2` &>/dev/null && FSOPTS="$FSOPTS ext2 Ext2" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program ext3` &>/dev/null && FSOPTS="$FSOPTS ext3 Ext3" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program ext4` &>/dev/null && FSOPTS="$FSOPTS ext4 Ext4" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program reiserfs` &>/dev/null && FSOPTS="$FSOPTS reiserfs Reiser3" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program nilfs2` &>/dev/null && FSOPTS="$FSOPTS nilfs2 Nilfs2_EXPERIMENTAL" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program xfs` &>/dev/null && FSOPTS="$FSOPTS xfs XFS" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program jfs` &>/dev/null && FSOPTS="$FSOPTS jfs JFS" - [ $part_type = raw -o $part_type = lvm-lv -o $part_type = dm_crypt ] && which `get_filesystem_program vfat` &>/dev/null && FSOPTS="$FSOPTS vfat VFAT" - [ $part_type = raw -o $part_type = dm_crypt ] && which `get_filesystem_program lvm-pv` &>/dev/null && FSOPTS="$FSOPTS lvm-pv LVM_Physical_Volume" - [ $part_type = lvm-pv ] && which `get_filesystem_program lvm-vg` &>/dev/null && FSOPTS="$FSOPTS lvm-vg LVM_Volumegroup" - [ $part_type = lvm-vg ] && which `get_filesystem_program lvm-lv` &>/dev/null && FSOPTS="$FSOPTS lvm-lv LVM_Logical_Volume" - [ $part_type = raw -o $part_type = lvm-lv ] && which `get_filesystem_program dm_crypt` &>/dev/null && FSOPTS="$FSOPTS dm_crypt DM_crypt_Volume" + for fs in ${fs_on[$part_type]} + do + check_is_in $fs $possible_fs && FSOPTS="$FSOPTS $fs ${filesystem_names[$fs]}" + done fs_create=no ask_yesno "Do you want to have this filesystem (re)created ? If not, make sure there already is a filesystem!" && fs_create=yes - # determine FS + # determine FS choice fsopts=($FSOPTS); if [ ${#fsopts[*]} -lt 4 ] # less then 4 words in the $FSOPTS string. eg only one option then @@ -447,7 +416,7 @@ interactive_filesystem () fi # ask mountpoint, if relevant - if [[ $fs_type != lvm-* && "$fs_type" != dm_crypt && $fs_type != swap ]] + if check_is_in $fs_type "${fs_mountable[@]}" then default=no [ -n "$fs_mountpoint" ] && default="$fs_mountpoint" @@ -461,8 +430,6 @@ interactive_filesystem () fi # ask label, if relevant - fs_label_mandatory=('lvm-vg' 'lvm-lv' 'dm_crypt') - fs_label_optional=('ext2' 'ext3' 'ext4' 'reiserfs' 'nilfs2' 'xfs' 'jfs' 'vfat') if [ "$fs_create" == yes ] && check_is_in "$fs_type" "${fs_label_mandatory[@]}" then default= @@ -478,6 +445,8 @@ interactive_filesystem () fi # ask special params, if relevant + # lvm-vg: PV's to use + # lvm-lv: LV size if [ "$fs_create" == yes ] && [ "$fs_type" = lvm-vg ] then # add $part to $fs_params if it's not in there because the user wants this enabled by default. TODO: we should find something out so you can't disable $part. (would be weird to have a vg listed on $part and not have $part it fs_params) @@ -485,7 +454,7 @@ interactive_filesystem () if ! egrep -q "$pv(\$| )" <<< "$fs_params"; then [ -n "$fs_params" ] && fs_params="$fs_params " fs_params="$fs_params$pv" - fi + fi list= for pv in $fs_params @@ -527,7 +496,7 @@ interactive_filesystem () then default= [ -n "$fs_opts" ] && default="$fs_opts" - program=`get_filesystem_program $fs_type` + program="${filesystem_programs[$fs_type]}" ask_string "Enter any additional opts for $program" "$default" 0 fs_opts="$ANSWER_STRING" fi @@ -540,6 +509,8 @@ interactive_filesystem () NEW_FILESYSTEM="$fs_type;$fs_create;$fs_mountpoint;target;${fs_opts// /__};$fs_label;${fs_params// /__}" # add new theoretical blockdevice, if relevant + # these are just the resulting DM devices, + # exception for lvm-pv: we create $part+ to represent the PV (+ is to differentiate from $part itself) new_device= [ "$fs_type" = lvm-vg ] && new_device="/dev/mapper/$fs_label $fs_type $fs_label" [ "$fs_type" = lvm-pv ] && new_device="$part+ $fs_type no_label" diff --git a/src/core/libs/lib-ui.sh b/src/core/libs/lib-ui.sh index ac842bb..8b886fe 100644 --- a/src/core/libs/lib-ui.sh +++ b/src/core/libs/lib-ui.sh @@ -51,6 +51,10 @@ _getavaildisks() done } +# captitalize first character +function capitalize () { + sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g'; +} set_keymap () { diff --git a/src/core/procedures/automatic b/src/core/procedures/automatic index 596aed3..6fdc1d8 100644 --- a/src/core/procedures/automatic +++ b/src/core/procedures/automatic @@ -82,6 +82,7 @@ worker_runtime_network () worker_prepare_disks () { + get_possible_fs echo "$var_PARTITIONS" > $TMP_PARTITIONS echo "$var_BLOCKDATA" > $TMP_BLOCKDEVICES process_disks || die_error "Could not process_disks" diff --git a/src/core/procedures/base b/src/core/procedures/base index f357908..98a816b 100644 --- a/src/core/procedures/base +++ b/src/core/procedures/base @@ -139,6 +139,7 @@ worker_interactive_time () worker_prepare_disks () { partition # use lib-archboot function by default + get_possible_fs # in official installer: autoprepare or diy first partitions, then mountpoints } diff --git a/src/core/procedures/interactive b/src/core/procedures/interactive index b64101b..5673347 100644 --- a/src/core/procedures/interactive +++ b/src/core/procedures/interactive @@ -101,6 +101,7 @@ worker_configure_system() worker_prepare_disks() { + get_possible_fs interactive_prepare_disks } -- cgit v1.2.3-54-g00ecf