#!/bin/sh

############################
# script description:
# umount clear and re-make disk partions
#
# disk partions:
# | -- swap area -- | -- base area -- | -- user area -- |
#
# auth: fork
# time: 2015-06-12
# copyright: terra-master tec
#
############################

# exit code list:
# 1: script already running
# 2: script service stop failed
# 3: script with invalid block device
# 4: script make GPT  partion failed
# 5: script make core partion failed
# 6: script make swap partion failed
# 7: script make user partion failed
# 8: script make core RAID failed
# 9: script mount core RAID failed
# 10: script tar system.bz2 failed

# 1001: invalid parameters

# include global functions and variables
. /etc/tos/scripts/scripts
. /etc/tos/scripts/service

script_get_lock
[ $? -ne 0 ] && exit 1

echo $TOS_SCRIPTS_PATH
echo $TOS_SETUP_URL
echo $TOS_RAID_CORE
echo $TOS_RAID_SWAP
echo $TOS_CORE_SIGN

disks=""
disksnum=0
coresize=0
swapsize=0
bootsize=0
initlog=/tmp/diskinit.log

#tar -xf /mnt/system/system.ins --overwrite -C /mnt/target/ ./usr/sbin/mdadm
#cp -a /mnt/target/usr/sbin/mdadm /sbin >/dev/null 2>&1

N5_UEFI=$(awk '/model name/' /proc/cpuinfo | uniq | grep -E "N[45913]| C3558R ")

echo "start init system. Process:0" >$initlog
[ ! -f ${TOS_RAID_CONF} ] && /usr/bin/tosconf

# parameters check
coresize=8192 #md9 8G
swapsize=2048 #md8 2G
bootsize=300  #bootload 300M
TOS_SWAP_SIGN=UTOSSWAP-X86-S64

for sd in $@; do
  [ ! -b $sd ] && continue
  disks="${disks} ${sd}"
  disksnum=$((disksnum + 1))
done

if [ $disksnum -lt 1 ]; then
  echo "invalid disk numb:$disksnum, must not less than 1. Error:1001" >$initlog
  script_put_lock
  exit 255
fi

echo "start init system. Process:10" >$initlog
sleep 2

# stop system service
ter_service all stop
if [ $? -ne 0 ]; then
  echo "service all stop failed. Error:2" >$initlog
  script_put_lock
  exit 2
else
  echo "service all stop. Process:20" >$initlog
fi

# stop system raid
for md in /dev/md*; do
  df | grep $md
  [ $? -eq 0 ] && umount $md
  [ -f $md -o -b $md ] && mdadm -S $md >/dev/null 2>&1
done

syspath=/mnt/system/system.ins
if [ ! -e $syspath ]; then
  echo "$syspath is invlaid file. Error:11" >$initlog
  script_put_lock
  exit 11
fi

if [ ! -e /boot/bzImage ]; then
  # extract dir to /boot/
  tar -xf $syspath -C / ./boot
  if [ $? -ne 0 ]; then
    echo "tar $syspath failed. Error:10" >$initlog
    script_put_lock
    exit 10
  fi
  tar -xf $syspath -C / ./EFI >/dev/null 2>&1
fi

# Do you need to repartition
IsNeedParted() {
  local blk=$1
  local blkname=$(basename $blk)
  local count=$(ls -1d /sys/block/$blkname/$blkname[0-9] | wc -l)
  if [ $count -lt 4 ]; then
    return 1
  fi
  blkid ${blk}1 2>/dev/null | grep "UTOSDISK" >/dev/null
  if [ $? -ne 0 ]; then
    return 1
  fi
  mdadm -E ${blk}2 2>/dev/null | grep "UTOSCORE-X86-S64" >/dev/null
  if [ $? -ne 0 ]; then
    return 1
  fi
  mdadm -E ${blk}3 2>/dev/null | grep "UTOSSWAP-X86-S64" >/dev/null
  if [ $? -ne 0 ]; then
    return 1
  fi
  mdadm -E ${blk}4 2>/dev/null | grep "UTOSUSER-X86-S64" >/dev/null
  if [ $? -ne 0 ]; then
    return 1
  fi
  return 0
}

# repartition
PartedDisk() {
  local blk=$1
  local offset=0
  local offend=0
  # earse gpt info
  dd if=/dev/zero of=$blk bs=1024 count=1
  parted -s $blk mktable gpt
  if [ $? -ne 0 ]; then
    echo make gpt partion on $blk failed
    echo "make gpt partion on $blk failed. Error:4" >$initlog
    script_put_lock
    exit 4
  fi
  # bootsize...
  offset=0
  offend=$((offset + bootsize))
  parted -s $blk mkpart primary ext2 0% $offend
  if [ $? -ne 0 ]; then
    echo "make core on $blk with offset:$offset size:$bootsize failed. Error:5" >$initlog
    script_put_lock
    exit 5
  fi
  # coresize...
  offset=$((offset + bootsize))
  offend=$((offset + coresize))
  parted -s $blk mkpart primary ext2 $offset $offend
  if [ $? -ne 0 ]; then
    echo "make swap on $blk with offset:$offset size:$coresize failed. Error:6" >$initlog
    script_put_lock
    exit 6
  fi
  # swapsize...
  offset=$((offset + coresize))
  offend=$((offset + swapsize))
  parted -s $blk mkpart primary ext2 $offset $offend
  if [ $? -ne 0 ]; then
    echo "make swap on $blk with offset:$offset size:$swapsize failed. Error:6" >$initlog
    script_put_lock
    exit 6
  fi
  # usersize...
  offset=$((offset + swapsize))
  offend=-1
  parted -s $blk mkpart primary ext2 $offset 100%
  if [ $? -ne 0 ]; then
    echo "make user on $blk with offset:$offset size:lastspace failed. Error:7" >$initlog
    script_put_lock
    exit 7
  fi

  # wait for block device appears
  sleep 1
  
  mdadm --zero-superblock ${blk}1 >/dev/null 2>&1
  mdadm --zero-superblock ${blk}2 >/dev/null 2>&1
  mdadm --zero-superblock ${blk}3 >/dev/null 2>&1
  mdadm --zero-superblock ${blk}4 >/dev/null 2>&1
}

# clear other disk ...
clearLabel() {
  local blk=$1
  if [ -b ${blk}1 ]; then
    blkid ${blk}1 2>/dev/null | grep "UTOSDISK" >/dev/null
    [ $? -eq 0 ] && tune2fs -L "" ${blk}1
  fi
  if [ -b ${blk}2 ]; then
    mdadm -E ${blk}2 2>/dev/null | grep "UTOSCORE" >/dev/null
    [ $? -eq 0 ] && mdadm --zero-superblock ${blk}2
  fi
  if [ -b ${blk}3 ]; then
    mdadm -E ${blk}3 2>/dev/null | grep "UTOSSWAP" >/dev/null
    [ $? -eq 0 ] && mdadm --zero-superblock ${blk}3
  fi
}

for ablk in $(ls /dev/sd[a-z] 2>/dev/null); do
  echo "$disks" | grep "$ablk" >/dev/null
  [ $? -ne 0 ] && clearLabel "${ablk}"
done

echo "make part start. Process:30" >$initlog
# part system disk
for blk in $disks; do
  if [ ! -b $blk ]; then
    echo "$blk is invlaid block device. Error:3" >$initlog
    script_put_lock
    exit 3
  fi

  IsNeedParted $blk
  if [ $? -ne 0 ]; then
    PartedDisk $blk
  fi

  mdev -s # refresh block device
  coreparts="${coreparts} ${blk}2"
  swapparts="${swapparts} ${blk}3"
  userparts="${userparts} ${blk}4"

  #init blk2
  if [ -b "${blk}2" ]; then
    echo -e "y\n" | mke2fs -t ext4 "${blk}2"
  fi
  wait $!
done
echo "make part success. Process:40" >$initlog
sleep 1

# make core raid
echo "make core raid1 now"
echo -e "y\n" >/tmp/mdadm.io

mdadm -C $TOS_RAID_SWAP -l1 -n$disksnum -N$TOS_SWAP_SIGN $swapparts --force </tmp/mdadm.io
sleep 1
if [ ! -b $TOS_RAID_SWAP ]; then
  mdadm -C $TOS_RAID_SWAP -l1 -n$disksnum -N$TOS_SWAP_SIGN $swapparts --force </tmp/mdadm.io
  if [ $? -ne 0 ]; then
    echo "make swap raid1 failed. Error:8" >$initlog
    script_put_lock
    exit 8
  fi
fi
[ -b $TOS_RAID_SWAP ] && mdadm --grow $TOS_RAID_SWAP --raid-devices=72 --force
echo "make swap raid1 success. Process:50" >$initlog

mdadm -C $TOS_RAID_CORE -l1 -n$disksnum -N$TOS_CORE_SIGN $coreparts --force </tmp/mdadm.io
sleep 1
if [ ! -b $TOS_RAID_CORE ]; then
  mdadm -C $TOS_RAID_CORE -l1 -n$disksnum -N$TOS_CORE_SIGN $coreparts --force </tmp/mdadm.io
  if [ $? -ne 0 ]; then
    echo "make core raid1 failed. Error:8" >$initlog
    script_put_lock
    exit 8
  fi
fi
[ -b $TOS_RAID_CORE ] && mdadm --grow $TOS_RAID_CORE --raid-devices=72 --force
echo "make core raid1 success. Process:60" >$initlog

echo -e "y\n" | mke2fs -t ext4 $TOS_RAID_CORE
wait $!
process=60
TOS_CORE_NAME=$(basename $TOS_RAID_CORE)
while [ 1 ]; do
  sleep 20 #等待md9同步，md9
  sync_action=$(cat /sys/block/$TOS_CORE_NAME/md/sync_action)
  if [ "$sync_action" == "idle" ]; then
    break
  fi
  [ $process -lt 80 ] && process=$((process + 1))
  echo "wait core raid1 sync. Process:$process" >$initlog
done

mkdir -p $TOS_RAID_CORE_PATH
umount $TOS_RAID_CORE_PATH >/dev/null 2>&1
mount $TOS_RAID_CORE $TOS_RAID_CORE_PATH
if [ $? -ne 0 ]; then
  echo "mount ${TOS_RAID_CORE} to ${TOS_RAID_CORE_PATH} failed. Error:9" >$initlog
  script_put_lock
  exit 9
fi
echo "mount ${TOS_RAID_CORE} to ${TOS_RAID_CORE_PATH}. Process:86" >$initlog

# remove old rootfs
rm -fr $TOS_RAID_CORE_PATH/*
# extract new rootfs
tar -xf $syspath -C $TOS_RAID_CORE_PATH
if [ $? -ne 0 ]; then
  echo "tar $syspath to $TOS_RAID_CORE_PATH failed. Error:10" >$initlog
  script_put_lock
  exit 10
elif [ ! -e $TOS_RAID_CORE_PATH/boot/bzImage ]; then
  echo "packget $syspath is invalid. Error:11" >$initlog
  script_put_lock
  exit 11
fi
echo "tar $syspath to $TOS_RAID_CORE_PATH. Process:90" >$initlog
sync

for blk in $disks; do
    #grub-install
    mkdir -p /mnt/bootparts
    if [ ! -z "$N5_UEFI" ]; then
      # 查看mkfs.vfat是否存在
      mkfs.vfat --help >/dev/null 2>&1
      [ $? -ne 0 ] && echo "mkfs.vfat nonentity Error:44" >$initlog && script_put_lock && exit 44
      mkfs.vfat ${blk}1 -n "${TOS_DISK_SIGN}"
    else
      echo -e "y\n" | mke2fs -t ext4 ${blk}1 -L "${TOS_DISK_SIGN}"
    fi
    # 直接尝试卸载，不管是否挂载
    umount /mnt/bootparts >/dev/null 2>&1
    mount ${blk}1 /mnt/bootparts
    [ $? -ne 0 ] && echo "mount ${blk}1 /mnt/bootparts failed Error:33" >$initlog && script_put_lock && exit 33
    # 安装grub时使用大系统内的grub环境
    if [ ! -z "$N5_UEFI" ]; then
      # 使用大系统内的环境安装的话就不需要从system.ins中解压获取了
      # if [ ! -d /lib/grub/x86_64-efi ]; then
      #     tar -xf /mnt/system/system.ins --overwrite -C /mnt/target/ ./lib/grub/x86_64-efi ./lib/libefivar.so.1 ./lib/libefiboot.so.1 ./lib/libefivar.so.1.37 ./lib/libefiboot.so.1.37 ./sbin/efibootmgr ./share/locale
      #     cp -a /mnt/target/sbin/efibootmgr /sbin
      #     mv /mnt/target/lib/libefivar.so.1 /lib
      #     mv /mnt/target/lib/libefiboot.so.1 /lib
      #     mv /mnt/target/lib/libefivar.so.1.37 /lib
      #     mv /mnt/target/lib/libefiboot.so.1.37 /lib
      #     mkdir /share
      #     cp -a /mnt/target/share/locale /share
      #     mkdir -p /lib/grub
      #     cp -a /mnt/target/lib/grub/x86_64-efi /lib/grub
      # fi
      # /sbin/grub-install --target=x86_64-efi --efi-directory=/mnt/bootparts/ --boot-directory=/mnt/bootparts/boot --bootloader-id=boot $blk --force
      /sbin/grub-install --target=x86_64-efi --directory="$TOS_RAID_CORE_PATH/lib/grub/x86_64-efi" --locale-directory="/usr/share/locale" --efi-directory=/mnt/bootparts/ --boot-directory="/mnt/bootparts/boot" --bootloader-id=boot "$blk" --force
    else
      /sbin/grub-install --root-directory=/mnt/bootparts "$blk" --force
    fi
    cp -a /boot/bzImage /mnt/bootparts/boot/
    tar -xf /boot/grub.bz2 -C /mnt/bootparts/
    [ -e /boot/.tosloader ] && cp -a /boot/.tosloader /mnt/bootparts/boot/
    sync
    umount /mnt/bootparts
    wait $!
done

if [ -x $TOS_RAID_CORE_PATH/usr/sbin/CheckSystem ]; then
  $TOS_RAID_CORE_PATH/usr/sbin/CheckSystem -init
fi
sync
chown -R root:root $TOS_RAID_CORE_PATH/*
#add rws for sudo & busybox
chmod 4755 $TOS_RAID_CORE_PATH/usr/bin/sudo
chmod 4755 $TOS_RAID_CORE_PATH/bin/busybox
[ "$INSTALLAUTO" = "1" ] && touch $TOS_RAID_CORE_PATH/.autoInstall
touch $TOS_RAID_CORE_PATH/.eraseAcl
# setup gurb bootup config
mdadm --detail --scan > $TOS_RAID_CORE_PATH/etc/mdadm/mdadm.conf
echo "disk init done. Process:100" >$initlog
script_put_lock
exit 0

