#!/bin/sh

PROG="${0##*/}"
stage2=/root

message() {
	printf %s\\n "$PROG: $*"
}

# get /proc/cmdline parameter
# if key is specified, parse key1:value1,key2:value2... parameter argument
# and select corresponded key value
# returns:
#       0 if there is a parameter (also print it's value if "-p" is used)
#       1 if there is no such parameter
get_cmdline() { # [-p] parameter [key]
  local SEDFLAG=""
  local SEARCH=""
  local REPLACE=""
  local CMDLINE="${PROC_CMDLINE:-/proc/cmdline}"

  case "$1" in
    -p) SEDFLAG="p"; shift ;;
  esac

  case "$#" in
    1) SEARCH="$1(=([^ ]*)|()( |$))"; REPLACE="\3";;
    *) SEARCH="$1=(.*,|)$2(:([^, ]+)|()(,.*| |\$))"; REPLACE="\4";;
  esac

  sed -nr "
  s/(^|.* )$SEARCH.*/$REPLACE/$SEDFLAG
  t
  q 1
  " < "$CMDLINE"
}

# check if get_cmdline -p $2 [$3] is equal to $1 pattern
equal_cmdline() {  # value <get_cmdline parameter> [<get_cmdline parameter2>]
  local V="$1"; shift
  case `get_cmdline -p "$@"` in
      $V) return 0;;
      *) return 1;;
  esac
}

nfs_slice(){
local profile
local overlays=/srv/public/netinst/overlays-live
if equal_cmdline nfs automatic method; then
	# mount overlays from nfs 
	ip=$(netstat -t --numeric-hosts --numeric-ports | grep :2049 | head -n1 | \
		sed 's/  */ /g' | cut -d' ' -f5 | cut -d: -f1)
	profile=$(get_cmdline -p profile || : )
	mkdir -p $stage2/tmp/images
	message "Mounting NFS overlays from $ip:$overlays"
	if nfsmount -o nolock $ip:$overlays $stage2/tmp/images > /dev/null 2>&1 ; then
		local msg
		ls -l $stage2/tmp/images/ > /dev/null || :
		for image in $(find $stage2/tmp/images/$profile -name "*.iso" | sort) ; do
			msg="${msg} $(basename "$image" .iso)"
			imgdir=$stage2/tmp/overlays/$(basename "$image")
			mkdir -p $imgdir
			mount -o loop $image $imgdir \
			&& { mount -t aufs -o "remount,add:1:$imgdir/=rr+wh" none $stage2 || msg="$msg!"; } || msg="$msg?"
		done
		test -n "$msg" && message "$msg" || message "No overlays found"
	else
		message "NFS mount failed"
	fi
fi
}

mount_options="noatime,nodiratime,commit=30,min_batch_time=100000,barrier=0,data=writeback,delalloc"

create_disk_slice() {
	[ -f /sys/dev/block/$(mountpoint -d /image)/partition ] || return 0
	[ -h /dev/disk/by-label/alt-live-storage ] && return 0

	partition=$(mountpoint -d /image)
	major=${partition%:*}
	minor=$((${partition#*:}& ~0xf))
	devlink=$(readlink /sys/dev/block/$major:$minor)
	device=/dev/${devlink##*/}
	before=$(fdisk -l $device | grep "^$device" | wc -l)
	partpath=/sys/dev/block/$partition
	newstart=$(($(cat $partpath/start)+$(cat $partpath/size)+1))
	fdisk $device << _EOF_ 2>&1 | grep "^Created"
n
p

$newstart

w
_EOF_
	after=$(fdisk -l $device | grep "^$device" | wc -l)
	if [ $after -gt $before ] ; then 
		partline=$(fdisk -l $device | grep "^$device" | tail -n1)
		start=$(echo $partline | sed 's/  */ /g' | cut -d' ' -f2)
		length=$(($(echo $partline | sed 's/  */ /g' | cut -d' ' -f3)-$start))
		number=$(echo $partline | cut -d' ' -f1| sed 's/[^0-9]*//')
		partdev=$device$number
		udevd --daemon >/dev/null 2>&1
		addpart $device $number $start $length && udevadm trigger
		# wait for $device$number
		for n in seq 1 10; do
			[ -b $partdev ] && break
			sleep 1
		done
		( mke2fs -t ext4 -O ^has_journal -L alt-live-storage $partdev &&
			mount -o $mount_options $partdev $stage2.rw ) 2>&1 |
				grep "^Filesystem label"
		udevadm control --exit
	fi
}

disk_slice(){
# Automaitc rw live on flash
# NB: may severely degrade first boot performance due to heavier I/O
case "$(get_cmdline -p automatic method)" in
disk|cdrom)
	if get_cmdline automatic label || get_cmdline live_rw; then
		create_disk_slice
	fi
	;;
esac

if [ -h /dev/disk/by-label/alt-live-storage ]; then
	grep -qs "[[:space:]]$stage2.rw[[:space:]]" /proc/mounts ||
		mount -o $mount_options /dev/disk/by-label/alt-live-storage $stage2.rw
fi
}

#
# Enter point
#

if cat /proc/mounts | grep "[[:space:]]$stage2[[:space:]]" | grep -s -q '[[:space:]]squashfs[[:space:]]'; then
    message "Root fs is squashfs"
    RO_ROOT="yes"
elif equal_cmdline live stagename; then
    message "Running live"
    RO_ROOT="yes"
elif equal_cmdline rescue stagename; then
    message "Running rescue"
    RO_ROOT="yes"
else
    message "Unknown root fs"
    RO_ROOT="no"
fi

if [ "$RO_ROOT" = "yes" ]; then
    message "Remounting / with aufs"
    [ -L /etc/mtab ] || ln -sf /proc/mounts /etc/mtab
    /bin/mkdir -p $stage2.rw $stage2.ro
    if equal_cmdline live stagename || equal_cmdline rescue stagename; then
	    disk_slice
    fi
    /bin/mountpoint -q $stage2.rw || /bin/mount -t tmpfs none $stage2.rw -o mode=755
    /bin/mount $stage2 $stage2.ro --move
    /bin/mount -t aufs none $stage2 -o dirs=$stage2.rw=rw:$stage2.ro=rr
    if equal_cmdline live stagename; then
	    nfs_slice
    fi
    /bin/mkdir -p $stage2/.ro $stage2/.rw
    /bin/mount $stage2.ro $stage2/.ro --move
    /bin/mount $stage2.rw $stage2/.rw --move
    /bin/rmdir $stage2.rw $stage2.ro

    message "Root FS overlayed with aufs"
fi
    
if get_cmdline propagator-debug ; then
    /bin/openvt -s -w -- /bin/sh
fi
