Perry Myers
2009-Jan-22 04:16 UTC
[Ovirt-devel] [PATCH node] Refactoring of o-c-storage and logging in general to correct some bugs
* Allow o-c-storage to be reentrant by properly wiping out old partitions and lvm after they have been created. Needed to fix firstboot scripts to use /tmp/ovirt.log to prevent open file descriptor when unmounting/ destroying /var/log partition/lvm. * Correct size calculation problems (1000 vs 1024 based MB) so that the LVM partition actually would use up the remainder of the disk * Cleanup of output for size configuration prompting including calculation of size remaining after each entry * If invalid size entries are entered, user is prompted until a valid entry is entered * set +e is done at end of perform_partitioning to undo set -e at top of function * MEM_SIZE_MB fixed (awk doesn't need file cat'd to it, can just open file directly) Signed-off-by: Perry Myers <pmyers at redhat.com> --- scripts/ovirt-config-setup | 6 ++- scripts/ovirt-config-storage | 103 +++++++++++++++++++++++------------------- scripts/ovirt-firstboot | 4 +- scripts/ovirt-functions | 25 +++++++++- 4 files changed, 86 insertions(+), 52 deletions(-) diff --git a/scripts/ovirt-config-setup b/scripts/ovirt-config-setup index c39c76a..270ce3d 100755 --- a/scripts/ovirt-config-setup +++ b/scripts/ovirt-config-setup @@ -47,7 +47,11 @@ while true; do printf "\nERROR: $OPTION FAILED. " printf "See $OVIRT_LOGFILE\n\n" fi - } 2>&1 | $TEE; + } 2>&1 | tee -a $OVIRT_TMP_LOGFILE; + if [ -f $OVIRT_TMP_LOGFILE ]; then + cat $OVIRT_TMP_LOGFILE >> $OVIRT_LOGFILE + rm -f $OVIRT_TMP_LOGFILE + fi break ;; esac done diff --git a/scripts/ovirt-config-storage b/scripts/ovirt-config-storage index a34203b..3a49523 100755 --- a/scripts/ovirt-config-storage +++ b/scripts/ovirt-config-storage @@ -32,21 +32,22 @@ swap_min_size=5 get_selected_drive_size() { start_log + local size local udi=$(hal-find-by-property --key block.device --string $DRIVE) if [ -z "$udi" ]; then # If hal didn't find the device, it could be a virtio block device # In this case, use sfdisk -s to get the size size=$(sfdisk -s $DRIVE) - SPACE=$(echo "scale=0; $size / 1024" | bc -l) + size=$(echo "scale=0; $size * 1024" | bc -l) else size=$(hal-get-property --udi "$udi" --key storage.size) if [ $size -eq 0 ]; then # disk is probably hot-swappable, use different HAL key size=$(hal-get-property --udi "$udi" --key storage.removable.media_size) fi - SPACE=$(echo "scale=0; $size / (1024 * 1024)" | bc -l) fi + SPACE=$(echo "scale=0; $size / (1024 * 1024)" | bc -l) log "Selected Device: $DRIVE ($SPACE MB)" stop_log } @@ -68,7 +69,7 @@ check_partition_sizes() "+ $CONFIG_SIZE + $LOGGING_SIZE + $min_data_size" | bc -l) if [ $need_size -gt $disk_size ]; then - gap_size=$(echo "scale=0; $need_size-$disk_size;" | bc -l) + local gap_size=$(echo "scale=0; $need_size-$disk_size;" | bc -l) printf "\n" printf "=============================================================\n" printf "The target storage device is too small for the desired sizes:\n" @@ -150,31 +151,49 @@ do_configure() get_selected_drive_size printf "\n\nPlease configure storage partitions.\n\n" - printf "Enter partition sizes in MB.\n" - printf "A value of 0 indicates the partition should be disabled.\n" - printf "If the partition is enabled, it will have a minimum valid size.\n" - printf "For the Data partition, a size of -1 indicates that the\n" - printf "partition should use up the remaining space on the disk.\n\n" - - for i in boot swap root config logging data ; do + printf "* Enter partition sizes in MB.\n" + printf "* A value of 0 indicates the partition should be disabled.\n" + printf "* If the partition is enabled, it will have a minimum valid size.\n" + printf "* Size remaining value is approximate due to cylinder rounding\n" + printf " during partitioning.\n" + printf "* For the Data partition, a size of -1 indicates that the\n" + printf " partition should use up the remaining space on the disk.\n\n" + + local space_left=$SPACE + for part in boot swap root config logging data ; do part_regexp="^0$" - if [ "$i" = "data" ]; then + if [ "$part" = "data" ]; then part_regexp="^\-1|0$" fi - uc=$(echo $i|tr '[[:lower:]]' '[[:upper:]]') + uc=$(echo $part|tr '[[:lower:]]' '[[:upper:]]') size_var=${uc}_SIZE eval "size=\$$size_var" - min_size_var=${i}_min_size + min_size_var=${part}_min_size eval "min_size=\$$min_size_var" - read -ep "Change $i partition size. (Current $size MB, Minimum $min_size MB)? " - r=$REPLY - test -z "$r" && r=$size - if [[ $r =~ ^-*[0-9]+$ ]] && [[ $r -ge $min_size || - $r =~ $part_regexp ]] ; then - eval "$size_var=$r" - else - printf "invalid $i size: '$r' retaining $size MB.\n" - fi + + while true; do + printf "\nChange $part partition size. (Def. $size MB), " + printf "Min. $min_size MB, " + printf "Max. ~$space_left MB)\n" + read -ep "? " + mb_input=$REPLY + test -z "$mb_input" && mb_input=$size + local size_used=0 + if [[ $mb_input =~ ^-*[0-9]+$ ]]; then + if [[ $mb_input -ge $min_size || $mb_input =~ $part_regexp ]] \ + && [[ $mb_input -le $space_left ]] ; then + eval "$size_var=$mb_input" + size_used=$mb_input + break; + else + printf "invalid $part size: $mb_input. " + printf "Does not fall into specified range.\n" + fi + else + printf "invalid $part size: '$mb_input'.\n" + fi + done + space_left=$(echo "scale=0;$space_left - $size_used" | bc -l) done if ! check_partition_sizes; then @@ -230,13 +249,17 @@ EOF # - remove LVM volumes and groups wipe_lvm_on_disk() { + unmount_logging for vg in $(pvdisplay -c $DRIVE* 2>/dev/null|awk -F: '{print $2}'|sort -u); do for d in $(grep $vg /proc/mounts|awk '{print $2}'); do + log "Unmounting $d" umount $d done for lv in $(lvdisplay -c $vg|awk -F: '{print $1}'); do + log "Removing $lv" lvremove -f $lv done + log "Removing $vg" vgremove -f $vg done } @@ -248,40 +271,27 @@ perform_partitioning() return fi - DRIVE_FILE=$(echo $DRIVE | tr '/' '_') - if [ -f /tmp/ovirt-config-storage-$DRIVE_FILE ]; then - printf "\n\nERROR:\n" - printf "Storage Configuration has already been run for $DRIVE.\n" - printf "To run it again, please reboot the Node from USB/cdrom/PXE\n" - printf "in stand-alone mode.\n\n\n" - return 1 - fi - - touch /tmp/ovirt-config-storage-$DRIVE_FILE - start_log log "Starting partitioning of $DRIVE" - log "Removing old LVM partitions" - wipe_lvm_on_disk - # Exit upon any failure. set -e + log "Removing old LVM partitions" + wipe_lvm_on_disk + # FIXME: save a backup copy, just in case? log "Wiping old boot sector" dd if=/dev/zero of=$DRIVE bs=1024K count=1 blockdev --rereadpt $DRIVE partprobe -s $DRIVE - if [ "$BOOT_SIZE" -lt 10 ]; then - # ensure minimal BOOT partition - BOOT_SIZE=10 - fi log "Creating boot partition" + MEM_SIZE_MB=$(echo "scale=0; $MEM_SIZE_MB / 1024;" | bc -l) + local boot_size_si=$(echo "scale=0; $BOOT_SIZE * (1024 * 1024) / (1000 * 1000)" | bc -l) parted $DRIVE -s "mklabel ${LABEL_TYPE}" - parted $DRIVE -s "mkpartfs primary ext2 0M ${BOOT_SIZE}M" - parted $DRIVE -s "mkpart primary ext2 ${BOOT_SIZE}M ${SPACE}M" + parted $DRIVE -s "mkpartfs primary ext2 0M ${boot_size_si}M" + parted $DRIVE -s "mkpart primary ext2 ${boot_size_si}M -1" parted $DRIVE -s "set 1 boot on" parted $DRIVE -s "set 2 lvm on" parted $DRIVE -s "print" @@ -307,19 +317,19 @@ perform_partitioning() if [ "$SWAP_SIZE" -gt 0 ]; then log "Creating swap partition" - lvcreate --name Swap --size ${SWAP_SIZE}M /dev/HostVG + lvcreate --name Swap --size ${SWAP_SIZE}M /dev/HostVG mkswap -L "SWAP" /dev/HostVG/Swap echo "/dev/HostVG/Swap swap swap defaults 0 0" >> /etc/fstab fi if [ "$ROOT_SIZE" -gt 0 ]; then log "Creating root partition" - lvcreate --name Root --size ${ROOT_SIZE}M /dev/HostVG + lvcreate --name Root --size ${ROOT_SIZE}M /dev/HostVG mke2fs -j /dev/HostVG/Root -L "ROOT" tune2fs -c 0 -i 0 /dev/HostVG/Root fi if [ "$CONFIG_SIZE" -gt 0 ]; then log "Creating config partition" - lvcreate --name Config --size ${CONFIG_SIZE}M /dev/HostVG + lvcreate --name Config --size ${CONFIG_SIZE}M /dev/HostVG mke2fs -j /dev/HostVG/Config -L "CONFIG" tune2fs -c 0 -i 0 /dev/HostVG/Config fi @@ -359,6 +369,7 @@ perform_partitioning() mount_logging log "Completed!" + set +e stop_log } @@ -402,7 +413,7 @@ do_confirm() done } -MEM_SIZE_MB=$(cat /proc/meminfo | awk '/MemTotal:/ { print $2 }') +MEM_SIZE_MB=$(awk '/MemTotal:/ { print $2 }' /proc/meminfo) case $MEM_SIZE_MB in ''|*[^0-9]*) die failed to get system memory size;; esac diff --git a/scripts/ovirt-firstboot b/scripts/ovirt-firstboot index 575fa89..403f66a 100755 --- a/scripts/ovirt-firstboot +++ b/scripts/ovirt-firstboot @@ -60,9 +60,7 @@ start () fi disable_firstboot - start_log - ovirt_store_firstboot_config - stop_log + ovirt_store_firstboot_config > $OVIRT_LOGFILE 2>&1 } case "$1" in diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions index 7f97bb9..fa2d025 100644 --- a/scripts/ovirt-functions +++ b/scripts/ovirt-functions @@ -1,7 +1,7 @@ # -*-Shell-script-*- OVIRT_LOGFILE=/var/log/ovirt.log -TEE="tee -a $OVIRT_LOGFILE" +OVIRT_TMP_LOGFILE=/tmp/ovirt.log _log_status=1 # label of the oVirt partition @@ -37,7 +37,7 @@ start_log() { if [ "$_log_status" = 1 ]; then exec 6>&1 exec 7>&2 - exec 1>>$OVIRT_LOGFILE + exec 1>>$OVIRT_TMP_LOGFILE exec 2>&1 _log_status=0 fi @@ -278,6 +278,27 @@ mount_logging() { fi } +unmount_logging() { + if ! grep -q " /var/log ext3" /proc/mounts; then + return 0 + fi + + log "Unmounting log partition" + service rsyslog stop + if [ -e /var/log.bak ]; then + rm -rf /var/log.bak + fi + cp -av /var/log /var/log.bak + + umount /var/log + cp -av /var/log.bak/* /var/log + restorecon -rv /var/log + rm -Rf /var/log.bak + service rsyslog start + + return 0 +} + # mount data partition mount_data() { if grep -q " /data ext3" /proc/mounts; then -- 1.6.0.6