#!/bin/sh
ROOTAUFS2(){
ver=250402 #sfs
verr=$ver
msg2() { ###sfs
    [ "${quiet}" != "y" ] && echo "[1m""$*""[0m"
    echo "$@" >>/log-rootaufs3
    if [ "${debug}" = "y" ] || [ "${step}" = "y" ] ;then
	[ "${quiet}" = "y" ] && echo "[1m""$*""[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
}
#export -f msg2
#=====================================================================
# TOOLS
#=====================================================================
# args: source, mountpoint
_mnt_aufs_init() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Creating aufs mount ${src} in ${mnt}"
    #/bin/mount -t aufs -o br:"${src}" rootaufs "${mnt}"
    # https://github.com/util-linux/util-linux/issues/2309
    [ `mount -V |awk '{print $4}' |awk -F. '{print $1$2}'` -gt 238 ] && a2="=" || a2=":"

    mkdir -p "${mnt}"
    /bin/mount -t aufs -o x-initrd.mount,nowarn_perm,br${a2}"${src}" rootaufs "${mnt}"
		if [ $? != 0 ]; then
	            err 'rootaufs3: mount -t aufs -o nowarn_perm,br${a2}"${src}" rootaufs "${mnt}"'
	            launch_interactive_shell
	        fi
}

# 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}"
    /bin/mount -t aufs -o x-initrd.mount,remount,append${a2}"${src}"=rr+wh none "${mnt}"
}

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

# args: source, mountpoint
_mnt_bind() {
    src="${1}"
    mnt="${2}"
    msg2 "::: Binding ${src} to ${mnt}"
    mkdir -p "${mnt}"
    /bin/mount -o x-initrd.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}"
    loopdev="$(losetup --find --show --read-only -- "${src}" 2>/dev/null)"
    if [ "${loopdev}" ]; then
        mkdir -p "${mnt}"
        /bin/mount -o x-initrd.mount,ro "${loopdev}" "${mnt}" || { losetup -d "${loopdev}" 2>/dev/null; return 1; }
    else
        mkdir -p "${mnt}"
        /bin/mount -o x-initrd.mount,ro,loop "${src}" "${mnt}"
    fi
}

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

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

#autodetect func
# Функции поиска:
param() { grep -E -qo " $1( |\$)" /proc/cmdline; }
value() { grep -E -o "(^| )$1=[^ ]+" /proc/cmdline | cut -d= -f2- | tail -n 1; }

_rootaufs_resolve_device() {
    spec="${1}"
    case "${spec}" in
        UUID:*) spec="UUID=${spec#UUID:}" ;;
        LABEL:*) spec="LABEL=${spec#LABEL:}" ;;
        PARTUUID:*) spec="PARTUUID=${spec#PARTUUID:}" ;;
        PARTLABEL:*) spec="PARTLABEL=${spec#PARTLABEL:}" ;;
    esac

    case "${spec}" in
        /dev/*) [ -b "${spec}" ] && printf '%s\n' "${spec}"; return ;;
        UUID=*|LABEL=*|PARTUUID=*|PARTLABEL=*) ;;
        *) return 1 ;;
    esac

    if command -v resolve_device >/dev/null 2>&1; then
        resolve_device "${spec}" 2>/dev/null && return
    fi
    for devpath in $(blkid -t "${spec}" -o device 2>/dev/null); do
        [ -b "${devpath}" ] && { printf '%s\n' "${devpath}"; return; }
    done
    return 1
}

_rootaufs_wait_device() {
    spec="${1}"
    wait_left="${rootdelay:-6}"
    while [ "${wait_left}" -gt 0 ]; do
        devpath="$(_rootaufs_resolve_device "${spec}")"
        [ "${devpath}" ] && { printf '%s\n' "${devpath}"; return 0; }
        nap
        wait_left=$((wait_left - 1))
    done
    return 1
}

_rootaufs_list_devices() {
    if command -v lsblk >/dev/null 2>&1; then
        if ! param nocd; then
            lsblk -no PATH -Q 'TYPE == "rom"' 2>/dev/null
            lsblk -no PATH -Q 'TYPE == "part" && RM == 1' 2>/dev/null
        fi
        if ! param nohd; then
            lsblk -no PATH -Q 'TYPE == "part" && RM == 0' 2>/dev/null
        fi
    else
        param nocd || for x in /dev/sr*; do [ -b "$x" ] && printf '%s\n' "$x"; done
        param nohd || blkid | grep -E -v '/dev/sr|/dev/loop|/dev/mapper' | cut -d: -f1
    fi
}

_rootaufs_path_exists() {
    mode="${1}"
    path="${2}"
    case "${mode}" in
        -d) [ -d "${path}" ] ;;
        -f) [ -f "${path}" ] ;;
        *) false ;;
    esac
}

_rootaufs_accept_path() {
    mode="${1}"
    relpath="${2}"
    rootaufs_found_path="${aufs_root}/${relpath}"
    _rootaufs_path_exists "${mode}" "${rootaufs_found_path}" || return 1
    if [ "${sgnfile}" ]; then
        [ -e "${rootaufs_found_path}/${sgnfile#/}" ] || return 2
    fi
    return 0
}

_rootaufs_probe_device() {
    mode="${1}"
    relpath="${2}"
    devnode="${3}"
    x="${devnode##*/}"
    mnt=
    fs=`blkid "${devnode}" | grep -E -o ' TYPE=[^ ]+' | cut -d'"' -f2`
    [ "${fs}" ] || return 1
    msg2 ":::: mount $x $fs"
    mkdir -p ${aufs_root}
    if [ $fs = ntfs ]; then
        modprobe ntfs3 && sleep 1
        if [ -d /sys/module/ntfs3 ];then
            mount -t ntfs3 "${devnode}" ${aufs_root} && mnt=y
        else ntfs-3g "${devnode}" ${aufs_root} && mnt=y
        fi
    else
        mount "${devnode}" ${aufs_root} 2>/dev/null && mnt=y || { modprobe $fs 2>/dev/null && mount -n "${devnode}" ${aufs_root} 2>/dev/null && mnt=y ; }
    fi
    msg2 "::::: Mounted: `mount |grep -E '^/dev'`"
    if _rootaufs_accept_path "${mode}" "${relpath}"; then
        if [ "${sgnfile}" ]; then
            msg2 "::::: Finded: ${aufs_root}/${relpath} and sgnfile ${sgnfile}"
        else
            msg2 "::::: Finded: ${aufs_root}/${relpath}"
        fi
        DEV=$x; FND=y; return 0
    fi
    if [ "${sgnfile}" ] && _rootaufs_path_exists "${mode}" "${aufs_root}/${relpath}"; then
        msg2 "::::: Not Finded sgnfile: ${aufs_root}/${relpath}/${sgnfile#/}"
    else
        msg2 "::::: Not Finded: ${aufs_root}/${relpath}"
    fi
    [ "$mnt" ] && umount "${devnode}" && rmdir ${aufs_root} && msg2 ":::: umount ${devnode}"
    return 1
}

_rootaufs_locate_explicit() {
    mode="${1}"
    path="${2}"
    case "${path}" in
        /dev/*/*)
            devspec="/dev/$(printf '%s' "${path#/dev/}" | cut -d/ -f1)"
            LPTH="$(printf '%s' "${path#/dev/}" | cut -d/ -f2-)"
            ;;
        UUID:*/*|LABEL:*/*|PARTUUID:*/*|PARTLABEL:*/*)
            devspec="$(printf '%s' "${path}" | cut -d/ -f1)"
            LPTH="$(printf '%s' "${path}" | cut -d/ -f2-)"
            ;;
        UUID=*/*|LABEL=*/*|PARTUUID=*/*|PARTLABEL=*/*)
            devspec="$(printf '%s' "${path}" | cut -d/ -f1)"
            LPTH="$(printf '%s' "${path}" | cut -d/ -f2-)"
            ;;
        *) return 1 ;;
    esac
    devnode="$(_rootaufs_wait_device "${devspec}")" || return 1
    _rootaufs_probe_device "${mode}" "${LPTH}" "${devnode}"
}

_rootaufs_changes_posix_ok() {
    target="${1}"
    test1="${target}/._rootaufs_posix_test1"
    test2="${target}/._rootaufs_posix_test2"
    rm -f "${test1}" "${test2}"
    touch "${test1}" 2>/dev/null &&
        ln -s "${test1}" "${test2}" 2>/dev/null &&
        chmod +x "${test1}" 2>/dev/null && [ -x "${test1}" ] &&
        chmod -x "${test1}" 2>/dev/null && [ ! -x "${test1}" ]
    ok=$?
    rm -f "${test1}" "${test2}"
    return "${ok}"
}

_rootaufs_use_tmpfs_changes() {
    msg2 "::: changes target is not POSIX compatible. Fallback to tmpfs changes."
    [ "${aufs_rw}" ] && umount "${aufs_rw}" 2>/dev/null
    aufs_rw="${aufs_rw_base}"
    aufs_rwtype="tmpfs"
    _mnt_tmpfs "${tmpfs_size}" "${aufs_rw}"
}

_rootaufs_copy_module_to_ram() {
    src="${1}"
    rootaufs_copy_dst=
    mkdir -p "${aufs_cr}" 2>/dev/null || {
        msg2 "::: Cannot create copy2ram target ${aufs_cr}. Keeping remaining modules on media."
        return 1
    }
    dst="${aufs_cr}/${src##*/}"
    [ "${rootaufs_copy2ram_left}" ] && msg2 "::: Copy2ram ${src##*/} (${rootaufs_copy2ram_left} modules left)"
    [ "${rootaufs_copy2ram_left}" ] && rootaufs_copy2ram_left=$((rootaufs_copy2ram_left - 1))
    /bin/cp -L "${src}" "${dst}" 2>/dev/null || {
        rm -f "${dst}"
        msg2 "::: Not enough memory to copy ${src##*/}. Keeping remaining modules on media."
        return 1
    }
    rootaufs_copy_dst="${dst}"
}

fstab() { 
msg2 "::: fstab $*"
FND=none
rm -f /tmp/devices
for devnode in $(_rootaufs_list_devices); do
    blkid "${devnode}" >>/tmp/devices 2>/dev/null
    _rootaufs_probe_device "$1" "$2" "${devnode}" && break
done
}

lazy() { 
msg2 "::: lazy $*"
[ "${rootdelay}" ] && SLEEP="${rootdelay}" || SLEEP=6
while [ $SLEEP -gt 0 -a $FND = none ]; do 
    #fstab; search $* && break
    fstab $* && break
    nap; let SLEEP=SLEEP-1
done 
}

located(){ msg2 "::: located $*" ; LPTH=$2; FND=none ; _rootaufs_locate_explicit "$@" || lazy $* ; }
nap() { msg2 "::: Media is not ready. Wait $SLEEP sec."; sleep 1; }

_root_find(){
#start autodetect
    msg2 "::: root= not specified. Autosearch $rootaufs_media_dir" 
    [ "$rootaufs_media_dir" ] && located -d "${rootaufs_media_dir}" 
    [ "$rootdir" ] && located -d "${rootdir}" 
#    msg2 "::: root= not specified. Autosearch $dir" && lazy -d "${dir}" || lazy -d "${rootdir}" 
#    if [ "$DEV" ] ;then
    if [ "$FND" = y ] ;then
	#root="/dev/$DEV" ; ln -sf "/mnt/$DEV" /mnt/home ; msg2 ":::: root=/dev/$DEV"
	root="/dev/$DEV" ; msg2 ":::: root=/dev/$DEV"
    #else err " root= not defined" && launch_interactive_shell 
    fi
######### end autodetect
}


}
#=====================================================================
# HOOK
#=====================================================================
run_hook () {
    rootaufs_backend=aufs
    rootaufs_media_dir="${dir}"
    rootaufs_changes="${changes}"
    rootaufs_rw_dir_type=dir
    if [ "x${diro}${changeso}${ofs}" != "x" ]; then
        rootaufs_backend=overlay
        rootaufs_media_dir="${diro}"
        rootaufs_changes="${changeso}"
        rootaufs_rw_dir_type=diro
        [ "x${dir}" = "x" ] || return
        changes="${changeso}"
    else
        [ "x${aufs}" = "x" ] || return
    fi
ROOTAUFS2
    [ "${sgnfile}" ] || sgnfile="$(value sgnfile)"
    [ "$ro" ] 	 || rwopt=rw
    [ "$mopt" ]  && rootflag="$mopt"
    [ "$delay" ] && rootdelay="$delay"
#msg2 "===============sdsds" ; sleep 5

    rootaufs="${rootaufs_changes}" ###sfs
    tmpfs_size="${ramsize}"
    step2="$step"
    [ "${rootaufs_media_dir}" ] && roothide=y && msg2 ":: ${rootaufs_rw_dir_type}= detected. Autoaddition 'roothide'"
    [ "${rootaufs_media_dir}" ] && [ ! "${rootaufs}" ] && rootaufs=y && msg2 ":: ${rootaufs_rw_dir_type}= detected. Autoaddition changes tmpfs"
    #check if wanted
    [ "x${rootaufs}" = "x" ] && return
    #defaults
    [ "${rootaufs}" == "y" ] && export rootaufs=tmpfs
    [ "x${tmpfs_size}" = "x" ] && tmpfs_size="60%"
    #        tmpfs_size="75%"
    
    #load modules
   if [ "${rootaufs_backend}" = "overlay" ]; then
    /sbin/modprobe overlay 2>/dev/null
   elif [ ! -d /sys/fs/aufs ] ;then ###sfs 
    /sbin/modprobe aufs 2>/dev/null
    if [ $? != 0 ]; then
        err "Could NOT load aufs module, bailing out"
        launch_interactive_shell
        return
    fi
   fi
    ls /usr/lib/modules/*/modules.dep.bin  2>/dev/null 1>&2 && /sbin/modprobe loop 2>/dev/null #kernel-pf 
    ls /usr/lib/modules/*/modules.dep.bin  2>/dev/null 1>&2 && /sbin/modprobe squashfs 2>/dev/null

    # set mount handler for rootaufs
    mount_handler="rootaufs_mount_handler"
    export mount_handler


    #-----------------------------------
    #aufs tree
###sfs    aufs_base="/aufs/"
#    aufs_base="/mnt/"
    aufs_base="/run/archroot/"
#    aufs_root="${aufs_base}root"
#    aufs_root="${aufs_base}home"
    aufs_root="${aufs_base}root_ro"
    aufs_home="${aufs_base}home"
#    aufs_rw="${aufs_base}rw"
    aufs_rw="${aufs_base}live/memory/changes"
    aufs_rw_base="${aufs_rw}"
    aufs_ro="${aufs_base}live/memory/images"
    aufs_cr="${aufs_base}live/memory/copy2ram"
    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"


#if [ ! "${root}" ] ;then
if [ ! "${root}${from}" ] ;then
    [ ! "`cat /proc/cmdline |grep rdinit=/vtoy/vtoy`" ] && _root_find  #start autodetect
fi
}

#=====================================================================
# MOUNT HANDLER
#=====================================================================
rootaufs_mount_handler() {
    msg2 ":: Ventoy detect: `cat /proc/cmdline |grep rdinit=/vtoy/vtoy |echo NO`"
[ "`cat /proc/cmdline |grep rdinit=/vtoy/vtoy`" ] && root=/dev/mapper/ventoy && msg2 "::::: Ventoy detected"
    if [ "$from" ] ;then
        msg2 ":: from=$from"
	#DEV=sda1
	located -f "$from"
	[ "$FND" = none ]  && err "::: from=$from not defined" && launch_interactive_shell 
	FND=none
	umount $aufs_root
	from_path="/mnt/$DEV/$LPTH"
	[ -e "${from_path}" ] || from_path="/mnt/$DEV$from"
	root="$(losetup --find --show --read-only -- "${from_path}" 2>/dev/null)"
	[ "${root}" ] && msg2 "::::: $from_path losetup in root=$root" || { err "::: from=$from loop setup failed"; launch_interactive_shell; }
    fi
    msg2 ":: Mounting rootaufs3 ${rootaufs_backend} root $root..."
msg2 "rootaufs$verr"
    if [ "${break}" = "pre" ]; then
        msg2 ":: '${break}' Break requested, type 'exit' to resume operation"
        launch_interactive_shell
    fi
    newroot="${1}"
[ ! "$root" ] && err "::: root= not defined" && launch_interactive_shell 
    mkdir -p "${aufs_root}"

mnt_ntfs(){
    [ "${rootdelay}" ] && sleep ${rootdelay} && msg2 "::Wait rootdelay=${rootdelay}..."
    #[ "$FND" != y ] && msg2 "::: default_mount_handler ${aufs_root}" && default_mount_handler "${aufs_root}" 
    fsn=`blkid |grep -w ${root} | grep -E -o ' TYPE=[^ ]+' | cut -d'"' -f2`
    msg2 "::: $root fs is $fsn"
    if [ "$fsn" = ntfs ] ;then
#	[ "$FND" != y ] && ntfs-3g $root ${1} && msg2 "::: Mount $root as ntfs"
	if [ "$FND" != y ] ;then
	    modprobe ntfs3 && sleep 1
	    if [ -d /sys/module/ntfs3 ] ;then
		mount -t ntfs3  	$root ${1} && msg2 "::: Mount $root as ntfs3"
	    else ntfs-3g 		$root ${1} && msg2 "::: Mount $root as ntfs"
	    fi
	fi
    else 
	[ "$FND" != y ] && default_mount_handler "${1}"  && msg2 "::: default_mount_handler ${1}"
    fi
}

if [ "$rootdir" ]; then
#    mkdir -p "${aufs_root}1" 
    mkdir -p "${aufs_home}" 
#    default_mount_handler "${aufs_home}"
    mnt_ntfs ${aufs_home}
    mount --bind "${aufs_home}/$rootdir" "${aufs_root}"
    #umount "${aufs_root}1" && msg2 "::: umount ${aufs_root}1" 
else
    ln -s "${aufs_root}" "${aufs_home}"
    mnt_ntfs ${aufs_root}
fi

#    [ -L "${aufs_home}/$rootdir/${aufs_root}" ] && rm "${aufs_home}/$rootdir/${aufs_root}" && msg2 "::: rm simlink ${aufs_home}/$rootdir/${aufs_root}" 
#    [ -d "${aufs_home}/$rootdir/${aufs_root}" ] && umount "${aufs_home}/$rootdir/${aufs_root}" 
    #-----------------------------------
    #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}"
        _rootaufs_changes_posix_ok "${aufs_rw}" || _rootaufs_use_tmpfs_changes
    
    else
        #sub mount inside root

        #remount root rw
        _mnt_rerw "${aufs_root}"

        #source real path
    	    src="${aufs_root}/${rootaufs#/}"
	    mkdir -p ${src}

        #mount based on $src type
        if [ -f $src ]; then
            #file: loop
            aufs_rwtype="loop"
            _mnt_loop "${src}" "${aufs_rw}"
            _rootaufs_changes_posix_ok "${aufs_rw}" || _rootaufs_use_tmpfs_changes

        elif [ -d $src ]; then
#	if [ ! -f ${src} ] ;then ###sfs
	    [ ! -d ${src} ] && msg2 "::: changes=dir not fount. Create $src"
    	    src="${aufs_root}/${rootaufs#/}/changes"
	    mkdir -p ${src}
#	fi
            #dir: use this as rw
            aufs_rwtype="${rootaufs_rw_dir_type}" #; ln -sf $src "${aufs_base}live/memory/changes"
            aufs_rw="${src}"
            _rootaufs_changes_posix_ok "${aufs_rw}" || _rootaufs_use_tmpfs_changes
            
            #FIXME: bind doesn't seem to work with aufs2: overlapped
            #aufs_rwtype="bind"
            #_mnt_bind "${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
    msg2 ":: aufs_rwtype ${rootaufs} : $aufs_rwtype ..."

    #-----------------------------------
    #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'`
rootaufs_copy2ram_left=
PTH="${aufs_root}/${rootaufs_media_dir}"
#find $PTH/base $PTH/modules -name "*.pfs" 2>/dev/null | grep -E -v "$NOLOAD" | sort >/tmp/modules
#find $PTH/optional -name "*.pfs" 2>/dev/null | grep -E "$LOAD" | sort >>/tmp/modules

#ls -1 "$PTH"/base/*.*[xpsh][fz][sm] "$PTH"/modules/*.*[xpsh][fz][sm] 2>/dev/null | grep -E -v "$NOLOAD" >/tmp/modules
#find "$PTH"/base/ "$PTH"/modules/ -name "*.[xpsh][fz][sm]" 2>/dev/null | grep -E -v "$NOLOAD" >/tmp/modules
[ "${xzm}" ] || xzm=pfs #xzm=[ps][fb]s?
#find "$PTH"/base/ "$PTH"/modules/ -type f -regex .*'\.'$xzm'' 2>/dev/null | grep -E -v "$NOLOAD" >/tmp/modules
find "$PTH"/base/ "$PTH"/modules/ -type f -regex .*'\.'$xzm''  | grep -E -v "$NOLOAD" |sort >/tmp/modules
msg2 ":: find "$PTH"/base/ "$PTH"/modules/ -type f -regex .*'\.'$xzm''"
msg2 ":: Search *.$xzm (noload=$NOLOAD) in $PTH base modules >>/tmp/modules ..."
#ls -1 "$PTH"/optional/*.*[xpsh][fz][sm] 2>/dev/null | grep -E "$LOAD"  >>/tmp/modules
find "$PTH"/optional/ -type f -regex .*'\.'$xzm'' 2>/dev/null | grep -E "$LOAD"  |sort >>/tmp/modules
msg2 ":: Search *.$xzm (load=$LOAD) in $PTH optional >>/tmp/modules ..."
    if [ "$extramod" ]; then
	EXTRAMOD1=`echo "$extramod" | sed 's/;/ /g'`
	for folder in $EXTRAMOD1; do
	    msg2 ":: search extramod : ${aufs_root}/${folder} ..."
#	    locate -d $folder && { find /mnt/$DEV/$LPTH -name "*.$xzm" 2>/dev/null | egrep -v "$NOLOAD" | sort >>/tmp/modules; } || fail $folder
#	    locate -d $folder && { find /mnt/$DEV/$LPTH -name "*.$xzm" 2>/dev/null | egrep -ve "$NOLOAD" | sort >>/tmp/modules; } || fail $folder
	    #ls -1 "${aufs_root}/${extramod}"/*.*[xpsh][fz][sm] 2>/dev/null | grep -E -v "$NOLOAD"  >>/tmp/modules
	    if [ -d "${aufs_root}/$folder" ] ;then
		find "${aufs_root}/${folder}"/ -type f -regex .*'\.'$xzm'' 2>/dev/null | grep -E -v "$NOLOAD" |sort >>/tmp/modules
	    else
		err " not found extramod dir : ${aufs_root}/${folder} ... skip"
	    fi
	done
    fi

###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
        err " rootaufs3 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

#km="$(basename `grep "/000-kernel-`uname -r`$unm" /tmp/modules`)" 
km="$(grep "/000-kernel-`uname -r`$unm" /tmp/modules)"
km="`basename "$km"`"
    if [ "$km" ] ; then
	[ "`uname -m`" = "x86_64" ] && unm=_64
	sed -i "/000-kernel-`uname -r`$unm/p; /000-kernel-/d;" /tmp/modules &&
	        msg2 ":: ${km} found : skip other 000-kernel-*.$xzm ..."
    fi

[ "${base_only}" = "y" ] && grep /base/0 /tmp/modules > /tmp/mod && mv /tmp/mod /tmp/modules
if [ "${copy2ram}" = "y" ]; then
    [ "${RAMMOD}" ] || RAMMOD=.
    grep -E "${RAMMOD}" /tmp/modules >/tmp/rammod 2>/dev/null
    rootaufs_copy2ram_left="$(grep -c . /tmp/rammod 2>/dev/null)"
fi
###sfs)
step=
    if [ "x${rootaufs_media_dir}" != "x" ]; then
        msg2 ":: ${rootaufs_rw_dir_type}= Mounting overlays from ${rootaufs_media_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_ro}/${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 -E "$RAMMOD"`"  ] ; then
                _rootaufs_copy_module_to_ram "${src}" && src="${rootaufs_copy_dst}"
            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_ro}/${img##*/}"
            overlay_mnt="${overlay_mnt} ${mnt}"
            src="${aufs_root}/${img#/}"
            
            #FIXME: copy2ram
            if [ "${copy2ram}" = "y" ] && [ "${aufs_rwtype}" == "tmpfs" ]; then
                _rootaufs_copy_module_to_ram "${src}" && src="${rootaufs_copy_dst}"
            fi
            
            _mnt_loop ${src} ${mnt}
        done
    fi
    
    
    #=======================================================
    # Build aufs new root
    #=======================================================
    msg2 ":: Mounting ${rootaufs_backend}..."

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

    if [ "${rootaufs_backend}" = "overlay" ]; then
        mkdir -p "${newroot}"
        ROOT_MNT="/new_root"
        OFS_DIRS="/run/archroot"
        OFS_COWSPACE2="${OFS_DIRS}/live/memory/changes"
        [ "$changes" ] && OFS_COWSPACE2="${aufs_root}/$changes/changes"
        OFS_LOWER=""
        for mnt in ${overlay_mnt}; do
            OFS_LOWER="${OFS_LOWER}:${mnt}"
        done
        OFS_LOWER="`echo ${OFS_LOWER} |sed 's/^://'`"
        OFS_UPPER="${OFS_COWSPACE2}/upper"
        OFS_WORK="${OFS_COWSPACE2}/work"
        mkdir -p "${OFS_WORK}" "${OFS_UPPER}"
        LIBMOUNT_FORCE_MOUNT2=always mount -t overlay -o x-initrd.mount,redirect_dir=on,metacopy=off,index=on,lowerdir=${OFS_LOWER},upperdir=${OFS_UPPER},workdir=${OFS_WORK} overlay ${ROOT_MNT}
        if [ $? != 0 ]; then
            err "rootaufs3: mount -t overlay -o x-initrd.mount,redirect_dir=on,metacopy=off,lowerdir=${OFS_LOWER},upperdir=${OFS_UPPER},workdir=${OFS_WORK} overlay ${ROOT_MNT}"
            launch_interactive_shell
        fi
    else
        _mnt_aufs_init ${aufs_rw} "${newroot}"
        msg2 ":: _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}"
	    msg2 ":: _mnt_aufs_add ${aufs_root} ${newroot}"
        fi
    fi
sdx(){
###subdir2 sfs(
	#[ "x${rootaufs}" != "x" ] && 
	#[ ! "$DEV" ] && [ "${root}" ] &&
	[ ! "${root}" ] && err " root= not defined" && launch_interactive_shell
	[ "$FND" != y ] && [ "${root}" ] &&
	    root2="${newroot}${aufs_base}`basename ${root}`" &&
	    mkdir -p "${root2}" && 
    	    default_mount_handler "${root2}" &&
            msg2 "::: Mount ${root} in ${root2} (default_mount_handler)"
###subdir2 sfs)
}
#sdx
XX(){
    #-----------------------------------
    #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..."
	msg2 "::::: Mounted: `mount |grep -E '^/dev'`"
    #-----------------------------------
#[ "${noswap}" = "y" ] && FSTAB
[ "${aufs_rwtype}" = "dir" ] && ln -sf "${aufs_root}/$dir/changes" "${newroot}/${aufs_base}live/memory/changes"
[ "${aufs_rwtype}" = "diro" ] && ln -sf "${aufs_root}/$diro/changes" "${newroot}/${aufs_base}live/memory/changes"
cp ${newroot}/etc/fstab ${newroot}/etc/fstab.old
if [ "${noswap}" = "y" ] ;then
    sed '/^[^\s]\+\s*swap\s/s/^/#/' -i ${newroot}/etc/fstab #add#
else
    sed '/^[^\s]\+\s*swap\s/s/^#\+//'  -i ${newroot}/etc/fstab #rempve#
    grep " swap " ${newroot}/etc/fstab || for x in `blkid |grep 'TYPE="swap"'  | cut -d: -f1`; do echo "$x none swap sw,pri=1 0 0" >>${newroot}/etc/fstab; done
fi

if [ ! "${rootaufs_media_dir}${overlay}" ] ;then 
    sed '/^[^\s]\+\s*\/\s/s/^/#/' -i ${newroot}/etc/fstab #frugal
else
    sed '/^[^\s]\+\s*\/\s/s/^#\+//'  -i ${newroot}/etc/fstab #full
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" -a "${aufs_rwtype}" != "diro" ]; 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:
if [ "${norootcopy}" = "y" -a "${rootaufs_media_dir}" ]; then
    ROOTCOPY=none
    #echo $i"пропуск директории /rootcopy"
    msg2 ":: Skip /rootcopy ..."
else
    if [ -d "${PTH}/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 to ${aufs_rw}/ ..."
	#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
	cp -af "${PTH}"/rootcopy/. "${newroot}/". 2>/log-rootaufs3 #/dev/null
		if [ $? != 0 ]; then
	            err 'rootaufs3: cp -af "${PTH}"/rootcopy/. "${newroot}/". '
	            launch_interactive_shell
	        fi
        #launch_interactive_shell
    fi
fi
#	cp -af "${newroot}/${PTH}"/rootcopy/. "${newroot}". ; sleep 7 #2>/dev/null

	msg2 "::::: Mounted: `mount |grep -E '^/dev'`"
    msg2 ":: rootaufs3 end"

	mkdir -p "${newroot}/var/log" && mv /log-rootaufs3 "${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" &&

#porteus initrd support
LNK(){
	    rmdir "${2}" 2>/dev/null
	    [ -L "${2}" ] && rm "${2}"
	    mkdir -p "`dirname "$2"`"
	    [ -d "$1" ] && ln -sf "${1}" "${2}"
}
LNK "${aufs_home}" "${newroot}/mnt/home"
if [ "${rootaufs_backend}" = "overlay" ]; then
    LNK "${OFS_COWSPACE2}/upper" "${newroot}/mnt/live/memory/changes"
else
    LNK "${aufs_rw}" "${newroot}/mnt/live/memory/changes"
fi
LNK "${aufs_ro}" "${newroot}/mnt/live/memory/images"
LNK "${aufs_cr}" "${newroot}/mnt/live/memory/copy2ram"
###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:
