#!/bin/sh -efu

#
# For keys description see:
# http://www.opengroup.org/onlinepubs/009695399/utilities/set.html
#
# Copyright (C) 2007  Andrew V. Stepanov <stanv@altlinux.org>
# Correct (C)2008 Hihin Ruslamn <ruslandh@altlinux.ru>
#
# Get Every Archive from git package Repository.
#
# This file 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#


# Notes XXX:
#	* Assume that all device drivers already loaded (not need do modprobe, or init LVM, raid, or anything else)
#	* What will be if LILO installed to /dev/hda1, not at /dev/hda ?

PROG="${0##*/}"
PROG_VERSION='1.0.3'
PARTITIONS="/proc/partitions"
LILO_CONFIG="/etc/lilo.conf"
RM_DIRS=( ) # init empty array, will be contains directory that should be deleted at exit_handler
UMOUNT_DIRS=( ) # init empty array, will be contains directory that should be umounted at exit_handler
BLKID=/sbin/blkid
MNT=/mnt/partitions
CHROOT=/sbin/chroot
EDIT=
P_UMOUNT=

LC_ALL=C
export LC_ALL

if [ -f /usr/bin/mcedit ];then
EDIT=/usr/bin/mcedit
else 
    if [ -f /usr/bin/vim ];then
    	EDIT=/usr/bin/vim
	else
	    if [ -f /usr/bin/vi ];then
		EDIT=/bin/vi
	    fi
    fi
fi


show_help()
{
    cat <<EOF
    $PROG - restore MBR erased by Microsoft Windows (TM)

    Usage: $PROG [options]

    Options:
    --lilo			restore LILO MBR;
    --grub			restore GRUB MBR;
    -e, --edit=[mcedit|vim|vi]	current edit
    -r, --root=DEVICE		device containing /etc directory
    -q, --quiet, --silent	try to be more quiet;
    -v, --verbose		print a message for each action;
    -V, --version		print program version and exit;
    -h, --help			show this text and exit.
    -d, --debug			debug mode 
    -x			      	set -x

    Report bugs to http://bugs.altlinux.ru/

EOF
    exit
}

print_version()
{
    cat <<EOF
    $PROG version $PROG_VERSION
    Written by Andrew V. Stepanov <stanv/altlinux.org>
    Copyright (C) 2007  Andrew V. Stepanov <stanv/altlinux.org>
			Hihin Ruslan 	   <ruslandh/altlinux.ru>
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
    exit
}

info()
{
    printf "%s\n" "$*"
}

msg_info()
{
    printf '%s\n' "$PROG: $*" >&2
}

fatal()
{
    msg_info "$@"
    exit 1
}

show_usage()
{
    [ -z "$*" ] || msg_info "$*"
    echo "Try \`$PROG --help' for more information." >&2
    exit 1
}

verbose()
{
    [ -n "$verbose" ] || return 0
    msg_info "$@"
}


who_mount()
{
local tmp
local dev=( )
local mont_p=( )
local ptype=( )
local options=( )
local pri=( )
local nom=( )
if [ -z "$tmpdir" ];then
    tmp="$(mktemp -dt "$PROG.XXXXXXXX")" || fatal "Could not create temporary directory"
else
    tmp="$tmpdir"
fi

local ind=${#dev[@]}
local index=0

mount > $tmp/mount.txt

printf "Part\t mount\t Type\t Options:\n"
while read dev[$index] on mount_p[$index] type ptype[$index] options[$index] pri[$index] nom[$index]
do 
if [ -z ${mount_p[$index]} ];then
    continue
fi

printf "%s\t%s\t %s\t%s\t%s\n" \
${dev[$index]} \
${mount_p[$index]} \
${ptype[$index]} \
${options[$index]}

done < $tmp/mount.txt
}




whois_fstab()
{
local dev=( )
local mont_p=( )
local ptype=( )
local options=( )
local pri=( )
local nom=( )

if [ -z "$2" ];then
    verbose "error Call whois_fstab $*"
    return 1
fi    

local ind=${#dev[@]}
local index=0
local file_fstab
local src

file_fstab=$1;  shift
src=$1;  shift

if [ !  -f "$file_fstab" ];then
    verbose "$file_fstab no exist"
    return -1 
fi


while read dev[$index] mount_p[$index] ptype[$index] options[$index] pri[$index] nom[$index]
do 
if [ -z ${mount_p[$index]} ];then
    continue
fi

if [ "$src" = "${dev[$index]}" ];then
    echo ${mount_p[$index]}
fi
if [ "$src" = "${mount_p[$index]}" ];then
    echo ${dev[$index]}
fi

done < $file_fstab
}

all_mount()
{
local dev=( )
local mont_p=( )
local ptype=( )
local options=( )
local pri=( )
local nom=( )
local rdisk
local rpoint

local ind=${#dev[@]}
local index=0
local file_fstab

verbose all_mount $*

if [ "$#" -ne "1" ];then
    verbose error all_mount $*
    return
fi

mpoint=$1; shift
file_fstab="$mpoint/etc/fstab"

if [ !  -f "$file_fstab" ];then
    verbose "$file_fstab no exist"
    return -1 
fi


while read dev[$index] mount_p[$index] ptype[$index] options[$index] pri[$index] nom[$index]
do 
if [ -z "${mount_p[$index]}" ];then
    continue
fi

local poptions=${options[$index]} 
local poptions=`echo $poptions | grep -v noauto`
if [ -z "$poptions" ];then
    continue
fi
if [  "${ptype[$index]}" = "proc"   -o  "${ptype[$index]}" = "devpts"   -o  "${ptype[$index]}" = "tmpfs"  -o  "${ptype[$index]}" = "swap"  ];then
    continue
fi

mountpoint -q "$mpoint${mount_p[$index]}" || mount "${dev[$index]}" "$mpoint${mount_p[$index]}" &> /dev/null ||
verbose "mount ${dev[$index]}" "$mpoint ${mount_p[$index]}"


done < $file_fstab

if ! mount | grep -q "$mpoint/dev"; then
    mount --bind /dev  "$mpoint/dev" || fatal "Could not mount (bind) /dev to chroot $mpoint/dev"
    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mpoint/dev"
fi    

if ! mount | grep -q "$mpoint/proc"; then
    mount --bind /proc "$mpoint/proc" || fatal "Could not mount (bind) /proc to chroot $mpoint/proc"
    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mpoint/proc"
fi    
if [ -d "$mpoint/sys" ]; then
	if ! mount | grep -q "$mpoint/sys"; then
    	    mount --bind /sys "$mpoint/sys" || fatal "Could not mount (bind) /sys to chroot $mpoint/sys"
	    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mpoint/sys"
	fi    
fi
}



all_fstab()
{
local dev=( )
local mont_p=( )
local ptype=( )
local options=( )
local pri=( )
local nom=( )


local ind=${#dev[@]}
local index=0
local file_fstab

if [ -z "$*" ];then
    file_fstab=/etc/fstab
    else 
    file_fstab=$1 && shift
fi

if [ !  -f "$file_fstab" ];then
    verbose "$file_fstab no exist"
    return -1 
fi


printf "Part\t mount\t Type\t Options:\n"
while read dev[$index] mount_p[$index] ptype[$index] options[$index] pri[$index] nom[$index]
do 
if [ -z ${mount_p[$index]} ];then
    continue
fi

printf "%s\t%s\t %s\t%s\t%s\n" \
${dev[$index]} \
${mount_p[$index]} \
${ptype[$index]} \

done < $file_fstab
}

uuid2dev()
{
    local uuid=$1 && shift # in form UUID=e280469a-d06f-4c0b-b068-44f3b576029e or LABEL=root
    local ldev=`echo $uuid | grep UUID`
    if [ -z "$ldev" ]; then
	echo $uuid
	return
    fi 
    ldev=$($BLKID -o device -t "$uuid" | sort -r | sed -e '1!d')
    verbose "uuid2dev: transform $uuid to $ldev"
    echo $ldev
}

is_root()
{
    local disk=$1 && shift
    verbose "is_root() $disk"
    [ -d "$disk/etc" ] &&
    [ -d "$disk/boot" ] &&
    [ -d "$disk/home" ] &&
    [ -d "$disk/var" ] &&
    [ -d "$disk/bin" ] &&
    [ -d "$disk/lib" ] &&
    [ -d "$disk/sys" ] &&
    [ -d "$disk/proc" ] && verbose is_root $disk  && return 0
    verbose is_not_rot $disk && return 1
}

is_etc()
{
    local dir=$1 && shift
    [ -f "$dir/inittab" ] &&
    [ -f "$dir/fstab" ] &&
    [ -f "$dir/group" ] &&
    [ -f "$dir/passwd" ] &&
    [ -f "$dir/mtab" ] && verbose is_etc && return 0
    verbose is_not_etc && return 1
}

good_lilo()
{
    boot_str="`cat $disk/etc/lilo.conf | grep -v '^#' | grep '^boot'`"
    boot_str1=$( echo $(expr match "$boot_str" ".*\([s,h]d[a-f][ 1-9]*\)") )
    boot_str2=$( echo $(expr match "$boot_str" ".*\([s,h]d[a-f][ ]*\)") )
    if [ -n "$boot_str2" ] && [ "$boot_str1" = "$boot_str2" ];then
	verbose good boot_str1=$boot_str1
	return 0
    else 
	verbose "bad boot_str1=$boot_str1 boot_str2=$boot_str2"
	return 1
    fi
}

good_grub()
{
    return 0
}

is_mbr()
{
  verbose "is_mbr()"

        if [ -f "$disk/etc/lilo.conf" ] ; then
            verbose "found LILO boot loader"
            good_lilo 
            itog=$?
            verbose "itog=$itog"
                if [ "$itog" -eq 0 ]; then
        	    verbose  "good_lilo"
        	    return 0
        	else 
        	    verbose "bad_lilo"
        	    return 1
    	    fi
        elif [ -f "$disk/boot/grub/menu.lst" ]; then
            verbose "found GRUB boot loader"
            good_grub 
            itog=$?
            verbose "itog=$itog"
            if [ -z "$itog" ]; then 
        	    return 0 
        	else 
        	    return 1
	    fi
	fi
return 1
}


is_mbr_boot()
{
  local disk=$1 && shift
  is_root "$disk"  && is_mbr "$disk" && verbose "mbr $disk good" && return 0
  verbose "mbr $disk is bad" && return 1
}

find_etc()
{
    local active_root=
    local active_etc=

    verbose "try to find devices with / or /etc directories, have to examine folowing file systems:"
    verbose "FS: $(cat "$tmpdir/available.disks" | paste -s -d ' ')"

    verbose "check already mounted file systems"
    cat "$tmpdir/available.disks" |
    {
        while read disk; do
            if (mount | grep -q "$disk"); then
                sed -i "\@$disk@d" "$tmpdir/available.disks"
                local mounted_at="$( mount | grep "$disk" | cut -d ' ' -f 3 | sed 1!d )" || mounted_at=none
		verbose "check $mounted_at mount point it is a root partition"
        	verbose  "mounted_at=$mounted_at"
	        if is_root "$mounted_at" && is_etc "$mounted_at/etc" && is_mbr_boot "$mounted_at" ;then
                    verbose "$disk mounted at $mounted_at is root partition, continue..."
                    echo "$disk" >> $tmpdir/found.disks
                else
                    verbose "$disk isn't a root partition, skip"
                fi
            fi
        done
    }

    verbose "check not mounted file systems, by mounting them to $mnt_point"
    verbose "umounted FS: $(cat "$tmpdir/available.disks" | paste -s -d ' ')"
    cat "$tmpdir/available.disks" |
    {
        while read disk; do
            verbose "mount $disk to $mnt_point"
            mount -o ro "$disk" "$mnt_point" || 
            {
                verbose "can't mount $disk to $mnt_point"
                continue
            }
            verbose "mount done"
            if is_root "$mnt_point" && is_etc "$mnt_point"/etc && is_mbr_boot "$mnt_point"; then
                verbose "temporary mounted $disk at $mnt_point is root or /etc partition, continue..."
                echo "$disk" >> "$tmpdir/found.disks"
                verbose "disk=$disk"
            else
                verbose "$disk is not a root or etc partition, skip"
    		verbose "bad disk = $disk"
            fi

            verbose "umount $disk from $mnt_point"
            umount "$disk" || fatal "can't umount $disk from $mnt_point"
        done
    }
}


restore_mbr()
{
    local root=$1 && shift
    local bootloader=$1 && shift
    local device=$1 && shift

    verbose restore_mbr $root $device 
    if [ ! -d "$root" ]; then
        fail "bad root $root"
    fi

    mdisk=$root 

    
    P_UMOUNT=1
    

    verbose "bootloader=$bootloader"
    
    if [ "$bootloader" = "unknown" ]; then
        verbose "try to detect current boot loader"
        if [ -f "$root/etc/lilo.conf" ]; then
            verbose "found LILO boot loader"
            bootloader="lilo"
        elif [ -f "$root/boot/grub/menu.lst" ];then
    	    $CHROOT "$root" which grub-install >/dev/null 2>&1 && bootloader="grub" && verbose "found GRUB boot loader"
        else 
    	    fatal "can't guess what boot loader should be used"
        fi
    fi

    info "bootloader=$bootloader"
    info "---------------------------------------"
        
    verbose $mdisk


    case  "$bootloader"  in
        lilo)
        {
            verbose "runing LILO in chroot $root"
            $CHROOT $root lilo -V >/dev/null 2>&1 || fatal "can't find LILO on the chroot $root, maybe try to restore GRUB MBR instead?"
	    local itog=0
            if [ -n "$verbose" ]; then
        	$CHROOT $root lilo -v -P ignore $verbose || itog=$?
            else
                $CHROOT $root lilo -P ignore || itog=$?
            fi
            verbose  "itog=$itog"
                if [ "$itog" -eq 0 ]; then
        	    verbose  "good_bootloader"
        	    return 0
        	else 
		        #echo
            		info "Please edit lilo.conf"
		        sleep 5
		    if [ -n "$EDIT" ];then
		        $EDIT "$root/etc/lilo.conf"
			sleep 1
		    else
			cat "$root/etc/lilo.conf"
		    fi
        	    return 1
    	    fi

        }
        ;;
        grub)
        {
            verbose "runing GRUB in chroot $root for device $device"
            $CHROOT "$root" which grub-install >/dev/null 2>&1 || fatal "can't find GRUB on the chroot $root, maybe try to restore LILO MBR instead?"
            $CHROOT "$root" grub-install "$device"
        }
        ;;
        *)
        {
            fatal "unsupported bootloader: $bootloader"
        }
        ;;
	esac
}


exit_handler()
{
    local rc=$?
    trap - EXIT

    #info
    info "---------------------------------------"
    verbose "call exit_handler with $rc exit code"
    verbose mdisk = $mdisk
    verbose "dev_root=$dev_root"

    local rm_num=${#RM_DIRS[@]}
    local umount_num=${#UMOUNT_DIRS[@]}

    verbose "done umount directories"
    verbose "P_UMOUNT=$P_UMOUNT"
	if [ ! "$mdisk" == "/" ];then
	  verbose "whois_fstab $mdisk/etc/fstab /"
	  rdev=$(whois_fstab $mdisk/etc/fstab /)
	  rdev=$( uuid2dev $rdev )
	  verbose rdev=$rdev
	fi

#    P_UMOUNT=
#    if [ ! "$P_UMOUNT" ];then
    while [ "$umount_num" -ne "0" ]; do
        local index=$((umount_num - 1))
        local dir="${UMOUNT_DIRS[$index]}"
        verbose "umount directory $dir"
        mountpoint -q $dir && umount $dir || :
        umount_num=$((umount_num - 1))
    done
#    fi

    local fd=$(mount | grep mdisk)
    if [ -z "$fd" ];then
    verbose "done removing directories"

    while [ "$rm_num" -ne "0" ]; do
        local index=$((rm_num - 1))
        local dir="${RM_DIRS[$index]}"
        verbose "remove directory $dir"
        mountpoint -q $dir || rmdir $dir || ls $dir :
        rm_num=$((rm_num - 1))
    done
    else
	verbose $(ls $mdisk) && exit  15
    fi
    
    
    if [ "$rc" -eq "0" ]; then
        msg_info " Bootloader successfully restored!"
#        exit $rc
    else
	msg_info " Exit $rc"
    fi

    if [ ! "$mdisk" == "/" ];then
	  umount $mdisk &> /dev/null ||
	  sleep 1
	  mountpoint -q $mdisk || rmdir $mdisk
    fi
    
    if [ ! -d "$MNT/system" ];then
	  mkdir -p "$MNT/system" 
    fi
    recursiv_mount $rdev $MNT/system

    verbose " Exit $rc\n"
    exit $rc
}

recursiv_mount()
{
  verbose "recursiv_mount $1 $2"    
  if [ "$#" -ne "2" ];then
    verbose "error recursiv_mount $1 $2"
    return
  fi

  local rdisk=$1 && shift
  local rpoint=$1 && shift
  if [ ! -d "$rpoint" ];then
    verbose "$rpoint is not directory"
    return
  fi
  mountpoint -q $rpoint || mount $rdisk $rpoint &> /dev/null 
  all_mount "$rpoint"
}

scan_disks()
{
    local uuid=
    local disk=
    verbose "remove duplicates disks (same disk may have several names, eg dm-0 or hda)"
    $BLKID | grep -o 'UUID=[^[:space:]]*' | sort -r | uniq |
    {
        while read uuid; do
            disk=$($BLKID -o device -t "$uuid" 2>/dev/null | sort -r | sed -e '1!d')
            echo "$disk" >> $tmpdir/available.disks
            verbose "add $disk to further look what it is"
        done
    }
}

# =======================
# Program start from here
# =======================

# Parse command line options

OPT=`getopt -n $PROG -o e:,r:,h,q,v,V,x,d -l lilo,grub,root:,edit:,quiet,silent,verbose,version,help,debug -- "$@"` ||
show_usage
eval set -- "$OPT"

# Options
lilo=
grub=
mnt_point=
root=
boot_dev=
dev_root=
do_nothing=
quiet=
verbose=
mdisk=
DEBUG=

# Other variables
tmpdir=
del_mnt_point=

#EDIT=


while :; do
    case $1 in
        --) shift; break
        ;;
        --lilo)
        {
            lilo="lilo"
            [ -z "$grub" ] ||
            show_usage 'Options --lilo, --grub are mutually exclusive.'
        }
        ;;
        --grub)
        {
            grub="grub"
            [ -z "$lilo" ] ||
            show_usage 'Options --lilo, --grub are mutually exclusive.'
        }
        ;;
        -r|--root)
        {
            shift; dev_root=$1
        }
        ;;
        -e|--edit)
        {
            shift; Ed=$1
	    if [ "$Ed" = "vim" -o "$Ed" = "vi" -o "$Ed" = "mcedit" ];then
		case "$Ed" in
		mc)
                    if [ -x "/usr/bin/mc"  ];then
			EDIT="/usr/bin/mc"
                    fi
		    ;;
		vim)
                    if [ -x "/usr/bin/vim"  ];then
			EDIT="/usr/bin/vim"
                    fi
		    ;;
		vi)
                    if [ -x "/bin/vi"  ];then
			EDIT="/bin/vi"
                    fi
		    ;;
                *)
                esac
	    else
                show_help
	    fi
        }
        ;;
        -q|--quiet|--silent)
        {
            quiet=yes
        }
        ;;
        -v|--verbose)
        {
            verbose=-v
        }
        ;;
        -x)
        {
            set -x
        }
        ;;
        -V|--version)
        {
            print_version
        }
        ;;
        -h|--help)
        {
            show_help
        }
        ;;
        -d|--debug)
        {
            DEBUG=1
            verbose=-v
            set -x
        }
        ;;
        *)
        {
            info "unrecognized argument: " $1
            show_usage
        }
        ;;
    esac

    shift
done


if [ "$UID" != "0" ]; then
    fatal "$PROG requires root privileges"
fi

verbose $PROG

which $BLKID > /dev/null 2>&1 || fatal "$PROG requires $BLKID from e2fsprogs package"

if [ -n "$quiet" ]; then
    exec > /dev/null 2>&1
fi

mkdir -p "$MNT"
workdir="`mktemp -dt "$PROG.XXXXXXXXXX"`"

mountpoint -q "$MNT" || mount -o rw -t tmpfs tmpfs "$MNT"


mnt_point="$( (unset TMPDIR; mktemp -dp $MNT) )"

[ -d "$mnt_point" ] || fatal "Could not create temporary directory for mounting file systems"
RM_DIRS[${#RM_DIRS[*]}]="$mnt_point"

tmpdir="$(mktemp -dt "$PROG.XXXXXXXX")" || fatal "Could not create temporary directory"
verbose "tmpdir=$tmpdir"
verbose "$tmpdir directory created for store temporary files"

trap exit_handler EXIT SIGHUP SIGINT SIGQUIT SIGTERM

scan_disks # result in $tmpdir/available.disks

# Skip active root
active_root=$(grep < /etc/fstab -v "^[ \t]*#" | grep "[[:space:]]/[[:space:]]" | grep "UUID="  |  sed -e "s/^[ \t]*//" -e "s/[ \t].*//")
verbose "active_root=$active_root"

#if [ -n "$active_root" ]; then
#    active_root=$(uuid2dev "$active_root")
#    verbose $active_root
#else
#    active_root=`mount | grep "[[:space:]]/[[:space:]]" | grep -v rootfs -v /dev/loop` ||
#    [ -n "$active_root" ] && active_root=$( echo `expr match "$active_root" '.*\(/dev/[^[:space:]]*\)'` )
#fi

#verbose "active_root=$active_root"


#if [ -n "$active_root" ]; then
#    verbose "skip active root $active_root from concerned disks"
#    rw=`cat $tmpdir/available.disks | grep "$active_root"`
#    [ -z "$rw" ] ||  sed -i "\@$active_root@d" "$tmpdir/available.disks"
#else
#    verbose "can't find active mounted root partition, it's ok, continue..." # for example squashfs
#fi
#verbose `cat "$tmpdir/available.disks"`

# Skip active /etc
##active_etc=$(grep </etc/fstab -v "^[ \t]*#" | grep "[[:space:]]/etc[[:space:]]" | sed -e "s/^[ \t]*//" -e "s/[ \t].*//")
##if [ -n "$active_etc" ]; then
##    active_etc=$(uuid2dev "$active_etc")
##else
##    active_etc=`mount | grep " on /etc type" | sed "s/ .*//"`
##fi
##if [ -n "$active_etc" ]; then
##    verbose "skip active /etc $active_etc from concerned disks"
##    sed -i "\@$active_etc@d" "$tmpdir/available.disks"
##fi

verbose "skip non supported file systems. Keep only: ext2, ext3, reiserfs, xfs, jfs"
cat "$tmpdir/available.disks" |
{
    while read disk; do
        $BLKID "$disk" |  grep -iq -e ext2 -e ext3 -e reiser -e xfs -e jfs ||
        {
            verbose "disk $disk has not supported file system, remove him from concerned disks"
            sed -i "\@$disk@d" "$tmpdir/available.disks"
        }
    done
}
if [ -n "$dev_root" ]; then
    grep -q "$dev_root" "$tmpdir/available.disks" || fatal "can't operate on $dev_root device"
    [ -b "$dev_root" ] || fatal "bad etc-dev \`$dev_root', it is not a block device"
else
    verbose "no device containing /etc files specified, try to find it by self"
    verbose "create temporary directory $mnt_point for mounting unknown file systems"
    mkdir -p "$mnt_point"
    find_etc # result in  $tmpdir/found.disks
    all_root=`cat $tmpdir/found.disks`
    verbose "allroot=$all_root"

    [ -f "$tmpdir/found.disks" ] || show_usage "can't find any disk contain /etc files, try to specify it with --etc-dev=DEVICE option"
#    [ "$(wc -l "$tmpdir/found.disks" | cut -f 1 -d ' ')" = "1" ] || show_usage "Found to many devices with /etc directories, try to specify one with --root=DEVICE option"
    dev_root=$(head -n 1 "$tmpdir/found.disks")
fi

verbose $(cat  "$tmpdir/found.disks")

#info
info root $dev_root
#echo

# At this stage $dev_root may be mounted or unmounted
if (mount | grep -q "$dev_root"); then
    # Already mounted
    mounted_at=$(mount | grep "$dev_root" | cut -f 3 -d ' ' | sed 1!d )
    if ! is_root "$mounted_at" && is_etc "$mounted_at/etc" && is_mbr_boot "$mounted_at"; then
        # maybe user via --etc-dev give us real etc device, not root device
        mounted_at=$(realpath "$mounted_at/..")
        if [ ! is_root "$mnt_point" -o ! is_etc "$mnt_point/etc" -o ! is_mbr_boot "$mounted_at" ]; then
            fatal "disk $dev_root doesn't contains /etc files"
        fi
    fi
    verbose "target device $dev_root already mounted at $mounted_at"
    boot_dev=$(grep <"$mounted_at/etc/fstab" -v "^[ \t]*#" | grep "[[:space:]]/boot[[:space:]]" | sed -e "s/^[ \t]*//" -e "s/[ \t].*//")
    verbose  "boot_dev=$boot_dev"
    if [ -n "$boot_dev" ] ; then
        boot_dev=$(uuid2dev "$boot_dev")
        verbose "boot_dev=$boot_dev"
        if ! mount | grep -q "$boot_dev"; then
            verbose "mount /boot device $boot_dev to $mounted_at/boot"
            mount "$boot_dev" "$mounted_at/boot" || fatal "Could not mount $boot_dev to $mounted_at/boot"
            UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mounted_at/boot"
        fi
    fi


    verbose "disk is mounted"
    if [ "$mounted_at" != "/" ];then
	if ! mount | grep -q "$mounted_at/dev"; then
	    mount --bind /dev  "$mounted_at/dev" || fatal "Could not mount (bind) /dev to chroot $mounted_at/dev"
	    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mounted_at/dev"
	fi    

	if ! mount | grep -q "$mounted_at/proc"; then
	    mount --bind /proc "$mounted_at/proc" || fatal "Could not mount (bind) /proc to chroot $mounted_at/proc"
	    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mounted_at/proc"
	fi    
	if [ -d "$mounted_at/sys" ]; then
		if ! mount | grep -q "$mounted_at/sys"; then
	    	    mount --bind /sys "$mounted_at/sys" || fatal "Could not mount (bind) /sys to chroot $mounted_at/proc"
		    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mounted_at/sys"
		fi    
	fi
    fi
    
    restore_mbr "$mounted_at" $([ -n "${lilo}${grub}" ] && echo "${lilo}${grub}" || echo "unknown") "$dev_root"


else
    # Mount by self
    verbose "mount device $dev_root to $mnt_point"
    mount "$dev_root" "$mnt_point" || show_usage "Could not mount $dev_root to $mnt_point"
    verbose "mount $dev_root $mnt_point"


    if (is_etc "$mnt_point"/etc); then
        root_dev=$(grep <"$mnt_point/etc/fstab" -v "^[ \t]*#" | grep "[[:space:]]/[[:space:]]" | sed -e "s/^[ \t]*//" -e "s/[ \t].*//")
        root_dev=$(uuid2dev "$root_dev")
        verbose "real root is $root_dev, while $dev_root is disk wich contains /etc directory"
        umount "$mnt_point" || fatal "Could not umount $dev_root from $mnt_point"
        verbose "mount / device $root_dev to $mnt_point"
        mount "$root_dev" "$mnt_point" || fatal "Could not mount $root_dev to $mnt_point"
    #    verbose "mount /etc device $dev_root to $mnt_point"
    #    mount "$dev_root" "$mnt_point" || fatal "Could not mount $dev_root to $mnt_point"
    fi
    
    boot_dev=$(grep <"$mnt_point/etc/fstab" -v "^[ \t]*#" | grep "[[:space:]]/boot[[:space:]]" | sed -e "s/^[ \t]*//" -e "s/[ \t].*//")

    verbose $mnt_point
    verbose "disk is not mounted"

    if [ "$mnt_point" != "/" ];then
    	    
	if ! mount | grep -q "$mnt_point/dev"; then
	    mount --bind /dev  "$mnt_point/dev" || fatal "Could not mount (bind) /dev to chroot $mnt_point/dev"
	    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mnt_point/dev"
	fi

	if ! mount | grep -q "$mnt_point/proc"; then
	    mount --bind /proc "$mnt_point/proc" || fatal "Could not mount (bind) /proc to chroot $mnt_point/proc"
	    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mnt_point/proc"
	fi
	if [ -d "$mnt_point/sys" ];then
	    if ! mount | grep -q "$mnt_point/sys"; then
		mount --bind /sys "$mnt_point/sys" || fatal "Could not mount (bind) /proc to chroot $mnt_point/proc"
		UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mnt_point/sys"
	    fi
	fi
    fi
    verbose  "boot_dev=$boot_dev"
    if [ -n "$boot_dev" ] ; then
        boot_dev=$(uuid2dev "$boot_dev")
        verbose "mount /boot device $boot_dev to $mnt_point/boot"
	if ! mount | grep -q "$boot_dev"; then
            mount "$boot_dev" "$mnt_point/boot" || fatal "Could not mount $boot_dev to $mnt_point"
    	    UMOUNT_DIRS[${#UMOUNT_DIRS[*]}]="$mnt_point/boot"
	fi    
    fi

    restore_mbr "$mnt_point" $([ -n "${lilo}${grub}" ] && echo "${lilo}${grub}" || echo "unknown") "$dev_root"
fi

exit 0 # Go to exit handler

# vim:ts=4:sw=4:expandtab
