#!/bin/bash

#Preupgrade Assistant performs system upgradability assessment
#and gathers information required for successful operating system upgrade.
#Copyright (C) 2013 Red Hat Inc.
#Ondrej Vasik <ovasik@redhat.com>
#
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.
. /usr/share/preupgrade/common.sh
#END GENERATED SECTION

###########################################################
is_removable() {
  [ -e "/sys/block/$1/removable" ] && {
    cat "/sys/block/$1/removable"
    return 0
  }

  ttmp=$( echo "$1" | sed "s/[0-9-]*$//" )
  [ -e "/sys/block/$1/$ttmp/removable" ] && {
    cat "/sys/block/$1/$ttmp/removable"
    return 0
  }

  # shouldn't be there more these files but....
  ttmp=$(find "/sys/block/" -name "$1" -type d)
  [ -z "$ttmp" ] && {
    echo 0
    echo "DEBUG: cannot find $1" >&2
    return 1
  }

  while [ "$ttmp" != "/sys/block" ]; do
    # in some cases we need to go up to disk
    [ -e "$ttmp/removable" ] && break
    ttmp=$(dirname $ttmp)
  done
  [ "$ttmp" == "/sys/block" ] && {
    echo 0
    echo "DEBUG: still cannot find $1" >&2
    return 1
  }
  cat "$ttmp/removable"
  return $?
}
###########################################################
is_ro() {
  mount | grep -qE "^([^[:space:]]*/)?${1}.*\(.*,?ro,?.*\)" && echo 1 && return 0
  echo 0
  return 1
}
###########################################################
get_type() {
  dmsetup ls --target crypt | grep -qE "^($1|$2)[[:space:]]" && {
    echo crypt
    return 0
  }

  lvdisplay -c 2>/dev/null | grep -q ":$3:$4$" && {
    echo lvm
    return 0
  }

  tmp_class=""
  line=
  while IFS= read line || [ -n "$line" ]; do
  echo "$line" | grep -q "^class" && {
    tmp_class=$(echo "$line" | awk '{print $2}')
    continue
  }

  echo $line | grep -q "^device:[[:space:]]*${1}$" && {
    [ "$tmp_class" == "HD" ] && echo "disk" && return 0
    [ "$tmp_class" == "CDROM" ] && echo "rom" && return 0
    # other cases... ok we will pretend it's partition - I can't imagine
    # now this situation
  }

  done < /etc/sysconfig/hwconf

  # yes, it's partition, anything else isn't supported now
  echo "part"
}

###########################################################
###########################################################

export LVM_SUPPRESS_FD_WARNINGS=1
cp /proc/partitions $VALUE_TMP_PREUPGRADE/kickstart/
cp /etc/fstab $VALUE_TMP_PREUPGRADE/kickstart/
pvs --noheadings --separator ':' > $VALUE_TMP_PREUPGRADE/kickstart/pvs_list
vgs --noheadings --separator ':' > $VALUE_TMP_PREUPGRADE/kickstart/vgs_list
lvdisplay -C --noheadings --separator ':' > $VALUE_TMP_PREUPGRADE/kickstart/lvdisplay
rm -f "$VALUE_TMP_PREUPGRADE/kickstart/lsblk_list"

# replace lsblk - which is not available on RHEL-5 system
#lsblk -r --noheadings > $VALUE_TMP_PREUPGRADE/kickstart/lsblk_list
line=
while IFS= read line || [ -n "$line" ]; do
orig_name=$(echo "$line" | awk '{print $4}')
maj_num=$(echo "$line" | awk '{print $1}')
min_num=$(echo "$line" | awk '{print $2}')
blocks=$(echo "$line" | awk '{print $3}')
[ "${maj_num}:${min_num}" == "major:minor" ] || [ -z "$line" ] && continue

# some utilities need orig_name and others need name:   dm-1 vs LogVol00.....
name=$(dmsetup info -co name --noheadings -j $maj_num -m $min_num 2>/dev/null ||\
       echo "$line" | awk '{print $4}')
# is mounted?
mnt_line=$(grep -E "^([^[:space:]]*/)?$name[[:space:]]" /etc/mtab)
mnt_point=$(echo "$mnt_line" | cut -d " " -f2)
[ -z "$mnt_point" ] && {
  grep -v "^Filename" /proc/swaps \
    | grep -qE "^([^[:space:]]*/)?($name|$orig_name)[[:space:]]" \
    && mnt_point="[SWAP]"
}

size=$(( $(blockdev --getsize64 "/dev/$orig_name") / 2**20 )) # size in MB
# 1 -> True; 0 -> False
removable=$(is_removable $orig_name)
isro=$(is_ro $name) # is read-only? - not used by kickstart but to be less ugly
  mount | grep -qE "^([^[:space:]]*/)?${1}.*\(ro\)" && echo 1 && return 0

tmp_type=$(get_type "$orig_name" "$name" $maj_num $min_num)
echo "$name ${maj_num}:${min_num} $removable ${size}M $isro $tmp_type $mnt_point" >> $VALUE_TMP_PREUPGRADE/kickstart/lsblk_list
done < /proc/partitions

##########################################################
echo " * partitions - a copy of the /proc/partitions system file, which can be used in Kickstart for a disk layout" >>"$VALUE_TMP_PREUPGRADE/kickstart/README"
echo " * fstab - a copy of automated system mountpoints from the /etc/fstab file" >>"$VALUE_TMP_PREUPGRADE/kickstart/README"
echo " * lsblk_list - a list of block devices generated by the 'lsblk --list' command" >>"$VALUE_TMP_PREUPGRADE/kickstart/README"
echo " * pvs_list - a list of physical volumes generated by the 'pvs' command " >>"$VALUE_TMP_PREUPGRADE/kickstart/README"
echo " * vgs_list - a list of volume groups generated by the 'vgs' command " >>"$VALUE_TMP_PREUPGRADE/kickstart/README"

grep "[[:space:]]ext3[[:space:]]" /etc/fstab >/dev/null && exit $RESULT_INFORMATIONAL

exit $RESULT_PASS
