#!/bin/ksh

#
# This script will clone the current root file system 
# and update menu.lst so you can boot from it. If you
# specify the flag "default" it will make the new 
# filesystem the default to boot from
# 
#

export PATH="/usr/bin:/usr/sbin:/sbin"

if [ "x$1" = "x" ]; then
	echo "Usage: clone_root.sh <new_name>"
	exit 1
fi

#
# get the name of our root file system
#
rootfs=`mount | grep "^/ " | awk '{ print $3 }'`
#
# name of the zpool for this file system
#
rootpool=`dirname $rootfs`
#
# and the name of file system without the pool
#
rootzfs=`basename $rootfs`
#
# this is what the snapshot will be called
#
newsnapshot="$rootfs@$1_snapshot"
#
# and this is what the new cloned file system will be called
#
newrootfs="$rootpool/$1"

#
# first make sure that the mount type is set to legacy for the pool
#
if [ `zfs get -H -o value mountpoint $rootpool` != "legacy" ]; then
	echo "You need to set the mountpoint for the pool to 'legacy' for this script to work."
	echo "You can do that using this command: zfs set mountpoint=legacy $rootpool"
	echo "Exiting."
	exit 1
fi

#
# we will create a directory where we will mount the new file system
# as well as the pool
#
tmpmountpoint="/.mount$$"
if [ ! -d $tmpmountpoint ]; then
	if ! mkdir $tmpmountpoint; then
		echo "Can't create temporary mountpoint for the root pool."
		exit 1
	fi
fi

#
# first create a snapshot of the current root file system
#
if ! zfs snapshot $newsnapshot; then
	echo "Can't create $newsnapshot snapshot."
	rmdir $tmpmountpoint
	exit 1
fi

#
# then we clone it to the new name
#
if ! zfs clone $newsnapshot $newrootfs; then
	echo "Can't create $newrootfs clone."
	zfs destroy $newsnapshot
	rmdir $tmpmountpoint
	exit 1
fi

#
# set the necessary options for the new root
#
zfs set mountpoint=legacy $newrootfs

#
# now mount the new root 
#
if ! mount -F zfs $newrootfs $tmpmountpoint; then
	echo "Can't mount $newrootfs on $tmpmountpoint."
	echo "Won't be available to edit /etc/vfstab on that file system."
	echo "Cloning won't be complete."
	echo "Exiting."
	exit 1
fi

#
# and lets modify the new vfstab to point to the right zfs file system
#
tmpfile=/tmp/vfstab.$$.$RANDOM
touch $tmpmountpoint/$1
cat $tmpmountpoint/etc/vfstab | sed "s/$rootzfs/$1/" >$tmpfile
mv $tmpfile $tmpmountpoint/etc/vfstab

umount $tmpmountpoint

if ! mount -F zfs $rootpool $tmpmountpoint; then
	echo "Can't mount $rootpool on $tmpmountpoint."
	echo "Exiting."
	exit 1
fi

if [ ! -f $tmpmountpoint/boot/grub/menu.lst ]; then
	echo "Can't find /boot/grub/menu.lst on the file system $rootpool."
	echo "This should not happen."
else
	cat >>$tmpmountpoint/boot/grub/menu.lst << EOF
title NexentaCP $1 [Auto-detect 32-bit/64-bit]
	bootfs $newrootfs
	kernel\$ /platform/i86pc/kernel/\$ISADIR/unix -B $ZFS-BOOTFS 
	module\$ /platform/i86pc/\$ISADIR/boot_archive
title NexentaCP $1 [32-bit]
	bootfs $newrootfs
	kernel\$ /platform/i86pc/kernel/unix -B \$ZFS-BOOTFS
	module\$ /platform/i86pc/boot_archive
EOF
fi

umount $tmpmountpoint
rmdir $tmpmountpoint

exit 0
