#!/bin/sh
#170818 sfs
#=====================================================================
# TOOLS
#=====================================================================
msg2() { ###sfs
    [ "${quiet}" != "y" ] && echo $@
    echo "$@" >>/log-rootaufs2
    if [ "${debug}" = "y" ] || [ "${step}" = "y" ] ;then
	[ "${quiet}" = "y" ] && echo $@
#        echo -e "[1;33m"":: Debugging shell started.\n: Type your desired commands, hit Ctrl+D to continue booting\n: or press Ctrl+Alt+Del to reboot.""[0m" 
        echo -e "[1;33m"":: Debugging shell started. Ctrl+D: continue booting. Ctrl+Alt+Del: reboot""[0m" 
#        launch_interactive_shell
        sh 2>/dev/null #; echo -e "\n\n"
    fi
}

# args: source, mountpoint
_mnt_aufs_init() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Creating aufs mount ${src} in ${mnt}"
    mkdir -p "${mnt}"
    /bin/mount -t aufs -o br:"${src}" rootaufs "${mnt}"
}

# args: source, mountpoint
_mnt_aufs_add() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Adding new aufs branch ${src} in ${mnt}"
    /bin/mount -t aufs -o remount,append:"${src}" none "${mnt}"
}

# args: source, mountpoint
_mnt_dev() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Mounting device ${src} to ${mnt}"
    mkdir -p "${mnt}"
    /bin/mount "${src}" "${mnt}"
}

# args: source, mountpoint
_mnt_bind() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Binding ${src} to ${mnt}"
    mkdir -p "${mnt}"
    /bin/mount --bind "${src}" "${mnt}"
}

# args: source, mountpoint
_mnt_move() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Moving ${src} to ${mnt}"
    mkdir -p "${mnt}"
    /bin/mount --move "${src}" "${mnt}"
}

# args: file, mountpoint
_mnt_loop() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Mounting file ${src} to ${mnt}"
    mkdir -p "${mnt}"
    /bin/mount -o loop "${src}" "${mnt}"
}

# args: size, mountpoint
_mnt_tmpfs() {
    size="${1}"
    mnt="${2}"
    msg2 "::: Mounting tmpfs, size=${size} to ${mnt}"
    mkdir -p "${mnt}"
    /bin/mount -t tmpfs -o "size=${size}" tmpfs "${mnt}"
}

# args: mountpoint
_mnt_rerw() {
    mnt="${1}"
    msg2 "::: Re-mounting rw ${mnt}"
    /bin/mount -o "remount,rw" "${mnt}"
}

#=====================================================================
# HOOK
#=====================================================================
run_hook () {
    rootaufs="${changes}" ###sfs
    tmpfs_size="${ramsize}"
    step2="$step"
    [ "${dir}" ] && roothide=y && msg2 ":: dir= detected. Autoaddition 'roothide'"
    [ "${dir}" ] && [ ! "${rootaufs}" ] && rootaufs=y && msg2 ":: dir= detected. 'changes' not defined. Autoaddition 'changes' (mounts a tmpfs RW filesystem)"
    #check if wanted
    if [ "x${rootaufs}" = "x" ]; then
        return
    fi

    #defaults
    if [ "${rootaufs}" == "y" ]; then
        export rootaufs=tmpfs
    fi
    if [ "x${tmpfs_size}" = "x" ]; then
#        tmpfs_size="75%"
        tmpfs_size="60%"
    fi
    #...
    
    #load modules
   if [ ! -d /sys/fs/aufs ] ;then ###sfs 
    /sbin/modprobe aufs
    if [ $? != 0 ]; then
        msg2 ":: rootaufs2: Could NOT load aufs module, bailing out"
        launch_interactive_shell
        return
    fi
   fi
    /sbin/modprobe loop
    /sbin/modprobe squashfs

    # set mount handler for rootaufs
    mount_handler="rootaufs_mount_handler"
    export mount_handler
#    msg2 "-------rootaufs=${rootaufs} rwopt=$rw"
}

#=====================================================================
# MOUNT HANDLER
#=====================================================================

rootaufs_mount_handler() {
#    msg2 "-------rootaufs=${rootaufs} rw=$rw roothide=$roothide"
    newroot="${1}"
    
    if [ "${break}" = "pre" ]; then
        msg2 ":: '${break}' Break requested, type 'exit' to resume operation"
        launch_interactive_shell
    fi

    #-----------------------------------
    #aufs tree
###sfs    aufs_base="/aufs/"
    aufs_base="/mnt/"
#    aufs_root="${aufs_base}root"
    aufs_root="${aufs_base}home"
#    aufs_rw="${aufs_base}rw"
    aufs_rw="${aufs_base}live/memory/changes"
    aufs_rwtype=""
    #overlay: "${aufs_base}${img##*/}"    
    
    #=======================================================
    # Mount filesystems
    #=======================================================
    #TODO
    # replace "_mnt_loop" with versatile mount handler:
    # * enable passing options: fstype, rw, loop, copy2ram...
    # * check file systems
    # * use default_mount_handler ?

    #-----------------------------------
    #mount default root to "ro"
    msg2 ":: Mounting root..."
    mkdir -p "${aufs_root}"

##subdir sfs(
if [ ! -z "$rootdir" ]; then
    mkdir -p "${aufs_root}1" 
    default_mount_handler "${aufs_root}1"
    mount --bind "${aufs_root}1/$rootdir" "${aufs_root}"
else
#    mkdir -p ${aufs_root}1 
    default_mount_handler "${aufs_root}"
#	        mount --bind "${aufs_root}"1 "${aufs_root}"
fi
##subdir)

    #-----------------------------------
    #mount "rw":
    msg2 ":: Mounting rw ${rootaufs}..."
    if [ "${rootaufs}" == "tmpfs" ]; then
        #tmpfs
        aufs_rwtype="tmpfs"
        _mnt_tmpfs "${tmpfs_size}" "${aufs_rw}"

    elif [ -b $rootaufs ]; then
        #block device
        aufs_rwtype="block"
        #FIXME: add options...
        _mnt_dev "${rootaufs}" "${aufs_rw}"
    
    else
        #sub mount inside root

        #remount root rw
        _mnt_rerw "${aufs_root}"

        #source real path
        src="${aufs_root}/${rootaufs#/}"
	[ ! -f $src ] && [ ! -d $src ] && mkdir -p $src && msg2 "::: changes= not fount. Create $src" ###sfs
        #mount based on $src type
        if [ -d $src ]; then
            #dir: use this as rw
            aufs_rwtype="dir"
            aufs_rw="${src}"
            
            #FIXME: bind doesn't seem to work with aufs2: overlapped
            #aufs_rwtype="bind"
            #_mnt_bind "${src}" "${aufs_rw}"

        elif [ -f $src ]; then
            #file: loop
            aufs_rwtype="loop"
            _mnt_loop "${src}" "${aufs_rw}"

        else
            #error
            msg2 "ERROR: rootaufs '${src}' not found, fallback to tmpfs"
            aufs_rwtype="tmpfs"
            _mnt_tmpfs "${tmpfs_size}" "${aufs_rw}"
            launch_interactive_shell
        fi
    fi

    #-----------------------------------
    #mount overlays
    overlay_mnt=""
###sfs dir 
  LOAD=`echo   "${load}" | sed 's/;/|/g'`; [ $LOAD ] || LOAD=._null
NOLOAD=`echo "${noload}" | sed 's/;/|/g'`; [ $NOLOAD ] || NOLOAD=._null
RAMMOD=`echo "${rammod}" | sed 's/;/|/g'`
PTH="${aufs_root}/${dir}"
#find $PTH/base $PTH/modules -name "*.pfs" 2>/dev/null | grep -v "$NOLOAD" | sort >/tmp/modules
#find $PTH/optional -name "*.pfs" 2>/dev/null | grep "$LOAD" | sort >>/tmp/modules
ls -1 "$PTH"/base/*.pfs "$PTH"/modules/*.pfs 2>/dev/null | grep -v "$NOLOAD" >/tmp/modules
ls -1 "$PTH"/optional/*.pfs 2>/dev/null | grep "$LOAD"  >>/tmp/modules

###sfs( Перенос номерных модулей в верхний слой aufs с сортировкой
#SORT=2-9 
#SORT=`value sort'`
if [ "$SORT" ];then
    sort2="/0[$SORT][0-9]-|"
    if [ "`echo "$SORT" |grep -v "^[0-9-]\+$"`" ];then
	echo -e "[31m""!!Ошибка!!\nВ параметре sort= можно указывать только цифры.\n
Например : sort=456789 или sort=4-9
Модули, начинающиеся с 0xy- , будут загружены верхний слой
AUFS по алфавиту (т.е. перекроют остальные модули)
   x - указанное Вами маска в sort=; y - любая цифра
Модули 089(исправления) и 09x(сохранения) всегда в верхнем слое.

Например :
/mnt/sda1/pra3/base/000-kernel.pfs
/mnt/sda1/pra3/base/001-Pra03arch12nos.pfs
/mnt/sda1/pra3/base/040-jwm-pra3c.pfs
/mnt/sda1/pra3/base/070-Pra-151119.pfs
/mnt/sda1/pra3/base/089-pra-up.pfs
/mnt/sda1/pra3/base/090-save-150921net-pra.pfs
/mnt/sda1/pra3/modules/042-cow-notify-s04.pfs
/mnt/sda1/pra3/optional/075-Systemd-217-8-s03.pfs

с sort=4-9 :
/mnt/sda1/pra3/base/000-kernel.pfs
/mnt/sda1/pra3/base/001-Pra03arch12nos.pfs
/mnt/sda1/pra3/base/040-jwm-pra3c.pfs
/mnt/sda1/pra3/modules/042-cow-notify-s04.pfs
/mnt/sda1/pra3/base/070-Pra-151119.pfs
/mnt/sda1/pra3/optional/075-Systemd-217-8-s03.pfs
/mnt/sda1/pra3/base/089-pra-up.pfs
/mnt/sda1/pra3/base/090-save-150921net-pra.pfs

Нажмите Ctrl+Alt+Del для перезагрузки.""[0m" >> /dev/null
	#exit
	msg2 ":: rootaufs sort=: Could NOT use letter. Exanple sort=456789 or sort=4-9"
        launch_interactive_shell
    fi
fi
grep -Ev ''$sort2'/089-|/09[0-9]-' /tmp/modules >/tmp/modules1
grep -E  ''$sort2'/089-|/09[0-9]-' /tmp/modules | while read i; do
    i1=${i##*/}
    i2=${i%/*}
    echo "$i1$i2"
done | sort -n | while read i; do
    i1=${i#*/}
    i2=${i%%/*}
    echo "/$i1/$i2"
done >/tmp/modules2
#089 и 09х в верхний слой aufs
cat /tmp/modules1 /tmp/modules2 >/tmp/modules
[ "${base_only}" = "y" ] && grep /base/0 /tmp/modules > /tmp/mod && mv /tmp/mod /tmp/modules

###sfs)
step=
    if [ "x${dir}" != "x" ]; then
        msg2 ":: dir= Mounting overlays from ${dir}..."
#        for img in `ls -1 "${aufs_root}"/${dir}/[bm][ao]*/*.pfs |sort -r`; do
#        for img in `ls -1 "${aufs_root}"/"${dir}"/modules/*.pfs |sort -r` `ls -1 "${aufs_root}"/${dir}/base/*.pfs |sort -r`; do
        for img in `tac /tmp/modules`; do
###sfs            mnt="${aufs_base}${img##*/}"
            mnt="${aufs_base}live/memory/images/${img##*/}"
            overlay_mnt="${overlay_mnt} ${mnt}"
##            src="${aufs_root}/${img#/}"
            src="${img#/}"
            
            #FIXME: copy2ram
#            if [ "${copy2ram}" = "y" ] && [ "${aufs_rwtype}" == "tmpfs" ]; then
            if [ "${copy2ram}" = "y" ] && [ "${aufs_rwtype}" == "tmpfs" ] && [ "`echo "${img}" |grep "$RAMMOD"`"  ] ; then
                src_rw="${aufs_rw}/${img##*/}"
                msg2 -n "::: Copying image file to ${src_rw}..."
                /bin/cp "${src}" "${src_rw}"
                msg2 "done."
                src="$src_rw"
            fi
            
            _mnt_loop ${src} ${mnt}
        done
    fi

    if [ "x${overlay}" != "x" ]; then
        msg2 ":: Mounting overlays..."
###sfs        for img in ${overlay/,/ }; do
        for img in `echo ${overlay} |sed 's/,/ /g'`; do
###sfs            mnt="${aufs_base}${img##*/}"
            mnt="${aufs_base}live/memory/images/${img##*/}"
            overlay_mnt="${overlay_mnt} ${mnt}"
            src="${aufs_root}/${img#/}"
            
            #FIXME: copy2ram
            if [ "${copy2ram}" = "y" ] && [ "${aufs_rwtype}" == "tmpfs" ]; then
                src_rw="${aufs_rw}/${img##*/}"
                msg2 -n "::: Copying image file to ${src_rw}..."
                /bin/cp "${src}" "${src_rw}"
                msg2 "done."
                src="$src_rw"
            fi
            
            _mnt_loop ${src} ${mnt}
        done
    fi
    
    
    #=======================================================
    # Build aufs new root
    #=======================================================
    msg2 ":: Mounting aufs..."

    #-----------------------------------
    #aufs merge: rw + overlays + ro
    if [ "${break}" = "aufs" ]; then
        msg2 ":: '${break}' Break requested, type 'exit' to resume operation"
        launch_interactive_shell
    fi

    _mnt_aufs_init ${aufs_rw} "${newroot}"
    for mnt in ${overlay_mnt}; do
        _mnt_aufs_add ${mnt} "${newroot}"
    done
    if [ "x${roothide}" = "x" ]; then
        _mnt_aufs_add ${aufs_root} "${newroot}"
###subdir2 sfs(
	#[ "x${rootaufs}" != "x" ] && 
	[ "${root}" ] &&
	    root2="${newroot}${aufs_base}`basename ${root}`" &&
	    mkdir -p "${root2}" && 
    	    default_mount_handler "${root2}" &&
            msg2 "::: Mount ${root} in ${root2}"
###subdir2 sfs)
    fi
    #-----------------------------------
    #move aufs mount points into the live system
    _mnt_move "${aufs_root}" "${newroot}${aufs_root}"
    if [ "${aufs_rwtype}" != "dir" ]; then
        #if rw is a dir in root: no link
        _mnt_move "${aufs_rw}" "${newroot}${aufs_rw}"
    fi
    for mnt in ${overlay_mnt}; do
        _mnt_move "${mnt}" "${newroot}${mnt}"
    done

    
    #=======================================================
    # Fix new root
    #=======================================================
step="$step2"
    msg2 ":: Setting aufs root..."

    #-----------------------------------
    #fix etc/fstab: remove root, swap & tmpfs if possible
    sed -e '/ \/ /d' -e '/ swap /d' -i ${newroot}/etc/fstab
    if [ "${aufs_rwtype}" == "tmpfs" ]; then
        sed -e '/ tmpfs /d' -i ${newroot}/etc/fstab
        #FIXME...
        echo chmod 1777 /dev/shm >> ${newroot}/etc/rc.local
    fi


    #-----------------------------------
    #avoid root fs remount/check in rc.sysinit...    
    if [ ! -e /run/initramfs/root-fsck ]; then
        msg2 "WARNING: missing 'fsck' hook, root fs will NOT be checked"
        msg2 "WARNING: please add fsck to HOOKS in mkinitcpio.conf"
        echo 0 > /run/initramfs/root-fsck
    fi
    #arch FCK
    cp /run/initramfs/root-fsck /run/initramfs/fsck-root

    #-----------------------------------
    #fix etc/rc.sysinit: checkable root is now "/aufs/rw", not "/"
    #no root check if tmpfs
    if [ "${aufs_rwtype}" != "tmpfs" -a  "${aufs_rwtype}" != "dir" ]; then
        rm /run/initramfs/*fsck*
        sed -e 's/\(mount -o remount\(,ro\)* \/\)$/\1aufs\/rw/' \
            -i ${newroot}/etc/rc.sysinit
    fi

    #-----------------------------------
    #build remountrw
    file="${newroot}/bin/remountrw"
    echo \#!/bin/sh >$file
    echo mount -o remount,rw ${aufs_root} >>$file
    chmod 0700 $file

    #build remountro
    file="${newroot}/bin/remountro"
    echo \#!/bin/sh >$file
    echo mount -o remount,ro ${aufs_root} >>$file
    chmod 0700 $file

###sfs(
# Копирование папки /rootcopy:
#ROOTCOPY="${rootcopy}"
if [ "${norootcopy}" = "y" -a "${dir}" ]; then
    ROOTCOPY=none
    #echo $i"пропуск директории /rootcopy"
    msg2 ":: Skip /rootcopy ..."
else
#    if [ $ROOTCOPY ]; then
#	locate -d $ROOTCOPY
#	if [ $? -eq 0 ]; then echo $i"копирование содержимого директории $ROOTCOPY"; cp -af /mnt/$DEV/$LPTH/. /union/. 2>/dev/null; else fail $ROOTCOPY; ROOTCOPY=none; fi
#    else
	ROOTCOPY=none
	#echo $i"копирование содержимого директории $PTH/rootcopy"
        msg2 ":: Copy ${newroot}${PTH}/rootcopy ..."
	#msg2 "noroot=$norootcopy"
	#cp -af $PTH/rootcopy/. /union/. 2>/dev/null
	#cp -af "${newroot}${PTH}"/rootcopy/. "${newroot}". 2>/dev/null
	cp -af "${newroot}${PTH}"/rootcopy/. "${newroot}${aufs_rw}/". 2>/dev/null
        #launch_interactive_shell
#    fi
fi
#	cp -af "${newroot}/${PTH}"/rootcopy/. "${newroot}". ; sleep 7 #2>/dev/null

NOAUTAxxx(){
if [ "${noauto}" != "y" ];then
mp="${newroot}/mnt"
    msg2 ":: AutoMount ${id} ..."
#blkid |grep -E 'sr|ext|vfat|ntfs' |grep -Ev '^/dev/loop' | grep "$1"|
blkid |grep -E 'sr|ext|vfat|ntfs' |grep -Ev '^/dev/loop' |
 while read id;do
    d=`echo $id |awk -F: '{print $1}'| sed 's/\/dev\///'`
    [ "${mopt}" ] && MOPT="-o ${mopt}" || MOPT="-o noatime,nodiratime,suid,dev,exec,async"
#    [ "`blkid -o value -s TYPE "/dev/$d"`" = vfat ] && MOPT="$MOPT,umask=0,check=s,utf8=true,quiet,codepage=866,iocharset=utf8" 
#    [ "`blkid -o value -s TYPE "/dev/$d"`" = ntfs ] && MOPT="$MOPT,allow_other" 
    if [ "`mount |grep "/dev/$d"`" = "" ];then
	mkdir -p "$mp"/"$d" #&&  \
	##echo "id=$id fs=$fs"
	msg2 ":: mount /dev/"$d" "$mp"/"$d" $MOPT" #>> /log-rootaufs2
#	mount /dev/"$d" "$mp"/"$d" $MOPT 2>&1> /log-rootaufs2
	mount /dev/"$d" "$mp"/"$d" $MOPT 2>> /log-rootaufs2
    else
	#[ "$mp" = "/new_root/mnt" ] || 
	ln -s "`mount |awk '/^\/dev\/'"$d"'/ {print $3}' |sed 's#'${newroot}'##'`" "$mp"/"$d"
    fi
 done
fi
}
    msg2 ":: rootaufs2 end"

    mkdir -p "${newroot}/var/log" && mv /log-rootaufs2 "${newroot}/var/log/initrd.log" && 
	echo -e "\n===Top layer AUFS:===" >> "${newroot}/var/log/initrd.log" &&
	tac /tmp/modules >> "${newroot}/var/log/initrd.log" &&
	echo -e "===Lower layer AUFS===" >> "${newroot}/var/log/initrd.log" &&
###sfs)

    if [ "${break}" = "post" ]; then
        msg2 ":: '${break}' Break requested, type 'exit' to resume operation"
        launch_interactive_shell
    fi
}

# vim:ft=sh:ts=4:sw=4:et:
