diff options
author | Dieter Plaetinck <dieter@plaetinck.be> | 2008-12-06 19:54:33 +0100 |
---|---|---|
committer | Dieter Plaetinck <dieter@plaetinck.be> | 2008-12-06 19:54:33 +0100 |
commit | 43b7fbbced07f2ad3ea941d66d0aaa65a1a99f30 (patch) | |
tree | c2bccbfb9f1804c30da6900000ba8d65628bd95d | |
parent | a576218155ca5b631e5e4074a0a47e9a0773564b (diff) |
partial implementation of process_filesystems + necessary refactoring in lib-ui-interactive
-rw-r--r-- | src/core/libs/lib-blockdevices-filesystems.sh | 105 | ||||
-rw-r--r-- | src/core/libs/lib-ui-interactive.sh | 37 |
2 files changed, 112 insertions, 30 deletions
diff --git a/src/core/libs/lib-blockdevices-filesystems.sh b/src/core/libs/lib-blockdevices-filesystems.sh index d285580..a06aa6f 100644 --- a/src/core/libs/lib-blockdevices-filesystems.sh +++ b/src/core/libs/lib-blockdevices-filesystems.sh @@ -9,7 +9,7 @@ modprobe aes-i586 || show_warning modprobe 'Could not modprobe aes-i586. no supp TMP_DEV_MAP=/home/arch/aif/runtime/dev.map TMP_FSTAB=/home/arch/aif/runtime/.fstab TMP_PARTITIONS=/home/arch/aif/runtime/.partitions -TMP_FILESYSTEMS=/home/arch/aif/runtime/.filesystems +TMP_FILESYSTEMS=/home/arch/aif/runtime/.filesystems # Only used internally by this library. Do not even think about using this as interface to this library. it won't work # procedural code from quickinst functionized and fixed. # there were functions like this in the setup script too, with some subtle differences. see below @@ -38,7 +38,7 @@ target_special_fs () # taken from setup # Disable swap and all mounted partitions for the destination system. Unmount -# the destination root partition last! +# the destination root partition last! TODO: only taking care of / is not enough, we can have the same problem on another level (eg /a/b/c and /a/b) target_umountall() { infofy "Disabling swapspace, unmounting already mounted disk devices..." @@ -407,13 +407,81 @@ process_disk () } -# go over each filesystem in $TMP_FILESYSTEMS, reorder them so that each entry has it's correspondent block device available (eg if you need /dev/mapper/foo which only becomes available after some other entry is processed) and process them +generate_filesystem_list () +{ + echo -n > $TMP_FILESYSTEMS + while read part type label fs_string + do + if [ "$fs_string" != no_fs ] + then + for fs in `sed 's/|/ /g' <<< $fs_string` # this splits multiple fs'es up, or just takes the one if there is only one (lvm vg's can have more then one lv) + do + fs_type=` cut -d ';' -f 1 <<< $fs` + fs_create=` cut -d ';' -f 2 <<< $fs` + fs_mountpoint=` cut -d ';' -f 3 <<< $fs` + fs_mount=` cut -d ';' -f 4 <<< $fs` + fs_opts=` cut -d ';' -f 5 <<< $fs` + fs_label=` cut -d ';' -f 6 <<< $fs` + fs_params=` cut -d ';' -f 7 <<< $fs` + echo "$part $part_type $part_label $fs_type $fs_create $fs_mountpoint $fs_mount $fs_opts $fs_label $fs_params" >> $TMP_FILESYSTEMS + done + fi + done < $BLOCK_DATA + +} + + +# process all entries in $BLOCK_DATA, create all blockdevices and filesystems and mount them correctly, destroying what's necessary first. process_filesystems () { - #TODO: reorder file by strlen of mountpoint (or alphabetically), so that we don't get 'overridden' mountpoints (eg you don't mount /a/b/c and then /a/b. checking whether the parent dir exists is not good -> sort -t \ -k 2 - #TODO: we must make sure we have created all PV's, then reate a vg and the lv's. - #TODO: 'deconstruct' the mounted filesystems, pv's, lv's,vg's,dm_crypt's.. in the right order before doing this (opposite order of construct) and swapoff. - debug "process_filesystems Called. checking all entries in $TMP_FILESYSTEMS" + generate_filesystem_list + + # phase 1: deconstruct all mounts in the vfs that are about to be reconstructed. (and also swapoff where appropriate) + # re-order list so that we umount in the correct order. eg first umount /a/b/c, then /a/b. we sort alphabetically, which has the side-effect of sorting by stringlength, hence by vfs dependencies. + + sort -t \ -k 2 test $TMP_FILESYSTEMS | tac | while read part part_type part_label fs_type fs_create fs_mountpoint fs_mount fs_opts fs_label fs_params + do + if [ "$fs_type" = swap ] + then + swapoff $part + elif [ "$fs_mountpoint" != no_mount ] + then + [ "$fs_mount" = target ] && fs_mountpoint=$var_TARGET_DIR$fs_mountpoint + umount $fs_mountpoint + fi + done + + # TODO: phase 2: deconstruct blockdevices if they would exist already (destroy any lvm things, dm_crypt devices etc in the correct order) + # in theory devices with same names could be stacked on each other with different dependencies. I hope that's not the case for now. In the future maybe we should deconstruct things we need and who are in /etc/mtab or something. + # targets for deconstruction: /dev/mapper devices and lvm PV's who contain no fs, or a non-lvm/dm_crypt fs. TODO: improve regexes + # after deconstructing. the parent must be updated to reflect the vanished child. + +# TODO: as long as devices in this list remains and exist physically +# TODO: abort when there still are physical devices listed, but we tried to deconstruct them already, give error + + egrep '\+|mapper' $BLOCK_DATA | egrep -v ' lvm-pv;| lvm-vg;| lvm-lv;| dm_crypt;' | while read part part_type part_label fs + do + real_part=${part/+/} + if [ -b "$real_part" ] + then + debug "Attempting deconstruction of device $part (type $part_type)" + [ "$part_type" = lvm-pv ] && ( pvremove $part || show_warning "process_filesystems blockdevice deconstruction" "Could not pvremove $part") + [ "$part_type" = lvm-vg ] && ( vgremove -f $part || show_warning "process_filesystems blockdevice deconstruction" "Could not vgremove -f $part") + [ "$part_type" = lvm-lv ] && ( lvremove -f $part || show_warning "process_filesystems blockdevice deconstruction" "Could not lvremove -f $part") + [ "$part_type" = dm_crypt ] && ( cryptsetup luksClose $part || show_warning "process_filesystems blockdevice deconstruction" "Could not cryptsetup luksClose $part") + else + debug "Skipping deconstruction of device $part (type $part_type) because it doesn't exist" + fi + done + + # TODO: phase 3: create all blockdevices in the correct order (for each fs, the underlying block device must be available so dependencies must be resolved. for lvm:first pv's, then vg's, then lv's etc, but all device mapper devices need attention) + + # TODO: phase 4: mount all filesystems in the vfs in the correct order. (also swapon where appropriate) + # reorder file by strlen of mountpoint (or alphabetically), so that we don't get 'overridden' mountpoints (eg you don't mount /a/b/c and then /a/b. checking whether the parent dir exists is not good -> sort -t \ -k 2 + sort -t \ -k 2 test + + + debug "process_filesystems Called. checking all entries in $BLOCK_DATA" rm -f $TMP_FSTAB devs_avail=1 while [ $devs_avail = 1 ] @@ -421,25 +489,36 @@ process_filesystems () devs_avail=0 for part in `findpartitions` do - if entry=`grep ^$part $TMP_FILESYSTEMS` + if entry=`grep ^$part $BLOCK_DATA` then - process_filesystem "$entry" && sed -i "/^$part/d" $TMP_FILESYSTEMS && debug "$part processed and removed from $TMP_FILESYSTEMS" + process_filesystem "$entry" && sed -i "/^$part/d" $BLOCK_DATA && debug "$part processed and removed from $BLOCK_DATA" devs_avail=1 fi done done - entries=`wc -l $TMP_FILESYSTEMS` + entries=`wc -l $BLOCK_DATA` if [ $entries -gt 0 ] then - die_error "Could not process all entries because not all available blockdevices became available. Unprocessed:`awk '{print \$1}' $TMP_FILESYSTEMS`" + die_error "Could not process all entries because not all available blockdevices became available. Unprocessed:`awk '{print \$1}' $BLOCK_DATA`" else debug "All entries processed..." fi } +# NOTE: beware, the 'mount?' for now just matters for the location (if 'target', the target path gets prepended) + +# FORMAT DEFINITION: + +# MAIN FORMAT FOR $BLOCK_DATA (format used to interface with this library): one line per blockdevice, multiple fs'es in 1 'fs-string' +# $BLOCK_DATA entry. +# <blockdevice> type label/no_label <FS-string>/no_fs +# FS-string: +# type;recreate(yes/no);mountpoint;mount?(target,runtime,no);opts;label;params[|FS-string|...] where opts have _'s instead of whitespace + + +# ADDITIONAL INTERNAL FORMAT FOR $TMP_FILESYSTEMS: each filesystem on a separate line, so block devices can be on multiple lines +# part part_type part_label fs_type fs_create fs_mountpoint fs_mount fs_opts fs_label fs_params -#TMP_FILESYSTEMS beware, the 'mount?' for now just matters for the location (if 'target', the target path gets prepended) -#blockdevice:filesystem:mountpoint:recreate FS?(yes/no):mount?(target,runtime,no)[:extra options for specific filesystem] # make a filesystem on a blockdevice and mount if requested. process_filesystem () diff --git a/src/core/libs/lib-ui-interactive.sh b/src/core/libs/lib-ui-interactive.sh index e120385..735fc00 100644 --- a/src/core/libs/lib-ui-interactive.sh +++ b/src/core/libs/lib-ui-interactive.sh @@ -104,7 +104,7 @@ interactive_set_clock() } -interactive_autoprepare() +interactive_autoprepare() #TODO: port this to use the $BLOCK_DATA format { DISCS=$(finddisks) if [ $(echo $DISCS | wc -w) -gt 1 ]; then @@ -227,7 +227,7 @@ interactive_partition() { # create new, delete, or edit a filesystem -interactive_filesystem () +interactive_filesystem () #TODO: make it possible to edit 1 specific aspect of a FS (eg mountpoint, type etc) { part=$1 # must be given and (scheduled to become) a valid device -> don't do [ -b "$1" ] because the device might not exist *yet* part_type=$2 # a part should always have a type @@ -237,7 +237,7 @@ interactive_filesystem () if [ -z "$fs" ] then fs_type= - fs_mount= + fs_mountpoint= fs_opts= fs_label= fs_params= @@ -249,18 +249,20 @@ interactive_filesystem () NEW_FILESYSTEM=empty return 0 else - fs_type=` cut -d ';' -f 1 <<< $fs` - fs_mount=` cut -d ';' -f 2 <<< $fs` - fs_opts=` cut -d ';' -f 3 <<< $fs` - fs_label=` cut -d ';' -f 4 <<< $fs` - fs_params=`cut -d ';' -f 5 <<< $fs` + fs_type=` cut -d ';' -f 1 <<< $fs` + fs_create=` cut -d ';' -f 2 <<< $fs` #not asked for to the user. this is always 'yes' for now + fs_mountpoint=` cut -d ';' -f 3 <<< $fs` + fs_mount=` cut -d ';' -f 4 <<< $fs` #we dont need to ask this to the user. this is always 'target' for 99.99% of the users + fs_opts=` cut -d ';' -f 5 <<< $fs` + fs_label=` cut -d ';' -f 6 <<< $fs` + fs_params=` cut -d ';' -f 7 <<< $fs` [ "$fs_type" = no_type ] && fs_type= - [ "$fs_mount" = no_mount ] && fs_mount= + [ "$fs_mountpoint" = no_mount ] && fs_mountpoint= [ "$fs_opts" = no_opts ] && fs_opts= [ "$fs_label" = no_label ] && fs_label= [ "$fs_params" = no_params ] && fs_params= old_fs_type=$fs_type - old_fs_mount=$fs_mount + old_fs_mountpoint=$fs_mountpoint old_fs_opts=$fs_opts old_fs_label=$fs_label old_fs_params=$fs_params @@ -314,9 +316,9 @@ interactive_filesystem () if [[ $fs_type != lvm-* && "$fs_type" != dm_crypt ]] then default= - [ -n "$fs_mount" ] && default="$fs_mount" + [ -n "$fs_mountpoint" ] && default="$fs_mountpoint" ask_string "Enter the mountpoint for $part" "$default" || return 1 - fs_mount=$ANSWER_STRING + fs_mountpoint=$ANSWER_STRING fi # ask label, if relevant @@ -369,11 +371,11 @@ interactive_filesystem () fs_opts=$(sed 's/ /_/g' <<< "$ANSWER_STRING") #TODO: clean up all whitespace (tabs and shit) [ -z "$fs_type" ] && fs_type=no_type - [ -z "$fs_mount" ] && fs_mount=no_mount + [ -z "$fs_mountpoint" ] && fs_mountpoint=no_mount [ -z "$fs_opts" ] && fs_opts=no_opts [ -z "$fs_label" ] && fs_label=no_label [ -z "$fs_params" ] && fs_params=no_params - NEW_FILESYSTEM="$fs_type;$fs_mount;$fs_opts;$fs_label;$fs_params" + NEW_FILESYSTEM="$fs_type;yes;$fs_mountpoint;target;$fs_opts;$fs_label;$fs_params" #TODO: make re-creation yes/no asking available in this UI. # add new theoretical blockdevice, if relevant if [ "$fs_type" = lvm-vg ] @@ -410,7 +412,7 @@ interactive_filesystems() { # $BLOCK_DATA entry. easily parsable.: # <blockdevice> type label/no_label <FS-string>/no_fs # FS-string: - # type;mountpoint;opts;label;params[|FS-string|...] where opts have _'s instead of whitespace + # type;recreate;mountpoint;mount?(target,runtime,no);opts;label;params[|FS-string|...] where opts have _'s instead of whitespace findpartitions 0 'no_fs' ' raw no_label' > $BLOCK_DATA while [ "$USERHAPPY" = 0 ] @@ -443,7 +445,7 @@ interactive_filesystems() { list= if [ -n "$fs" ] then - for lv in `sed '/|/ /' <<< $fs` + for lv in `sed 's/|/ /g' <<< $fs` do label=$(cut -d ';' -f 4 <<< $lv) mountpoint=$(cut -d ';' -f 2 <<< $lv) @@ -492,7 +494,7 @@ interactive_filesystems() { done - # If the user has forgotten one or more fundamental ones, ask him now + #TODO: If the user has forgotten one or more fundamental ones, send him back to the main editor ALLOK=true # TODO: check all conditions that would make ALLOK untrue again while [ "$ALLOK" != "true" ]; do @@ -549,6 +551,7 @@ interactive_filesystems() { # TODO: prepend $var_TARGET_DIR before handing over # TODO: convert our format to what process_filesystems will understand + process_filesystems && notify "Partitions were successfully created." && return 0 show_warning "Something went wrong while processing the filesystems" return 1 |