#!/usr/local/bin/cbsd
#v11.0.6
globalconf="${workdir}/cbsd.conf"
MYARG="jname dstdir media"
MYOPTARG="dstname name label product publisher prunelist freesize host_hostname ip4_addr gw4 timezone nameserver nic inter quiet efi nobase swapsize fromfile vm_guestfs"
MYDESC="Convert jail into cd9660 ISO or memstick image"
ADDHELP="dstdir= destination dir for storing jname.iso\n\
dstname= for alternative image name\n\
name= for alternative kernel name (GENERIC is default)\n\
label= label for media\n\
media= iso,memstick or bhyve\n\
prunelist= path to prunelist, default is \${sharedir}/jail2iso-prunelist. 0 for disable.\n\
freesize= reserved (expand to) X size of image free space (100m, 1g)\n\
host_hostname= set hostname in rc.conf image (freebsd only)\n\
ip4_addr= set ip4 addr or 'DHCP' in rc.conf image (freebsd only\n\
gw4= gateway for IPv4\n\
timezone= set timezone in image (freebsd only)\n\
nameserver= set nameserver in image (freebsd only)\n\
nic= specify network nic for ip4_addr\n\
efi= - set 0 to disable efi by default (if efiboot.img exist its preffered boot method)\n\
swapsize= - Allocate/configure SWAP partition to X size\n\
fromfile= - Read arguments from file\n\
vm_guestfs= ufs or zfs. Default is: ufs\n"
EXTHELP="wf_jail2iso.html"

set -e
. ${globalconf}
set +e

. ${subr}
. ${system}
. ${zfstool}
. ${strings}
readconf buildworld.conf
. ${tools}
. ${workdir}/universe.subr
. ${workdir}/bhyve.subr

readconf jail2iso.conf
init $*

. ${buildconf}
. ${jrcconf}
[ $? -eq 1 ] && err 1 "${MAGENTA}No such jail: ${GREEN}${jname}${NORMAL}"

[ -r "${fromfile}" ] && . ${fromfile}
[ -z "${quiet}" ] && quiet=0
[ -z "${efi}" ] && efi=1
[ -z "${swapsize}" ] && swapsize=0
[ -z "${vm_guestfs}" ] && vm_guestfs="ufs"

[ "${media}" = "bhyve" -a -z "${freesize}" ] && err 1 "${MAGENTA}For media=bhyve please set freesize= value. For example: ${GREEN}freesize=1g${NORMAL}"

init_target_arch
init_srcdir
init_supported_arch
init_basedir
init_kerneldir

[ -n "${label}" ] && LABEL="${label}"
[ -n "${product}" ] && PRODUCT="${product}"
[ -n "${publisher}" ] && PUBLISHER="${publisher}"

TMP_DIR="${tmpdir}/$jname-iso.$$"
DST_DIR="${tmpdir}/tmpmfsroot.$$"

TRAP=""

clear_tmp_dir()
{
	[ -d "${TMP_DIR}" -o -f "${TMP_DIR}" ] && ${CHFLAGS_CMD} -R noschg ${TMP_DIR} && /bin/rm -rf ${TMP_DIR}
}

# Prepare MFSRoot part
prepare_dir()
{
	local rcscript="/etc/rc.d/preparedir"

	/bin/cp -rP ${path}/etc ${DST_DIR}/

	case "${media}" in
	"iso")
		MOUNTROOT="/sbin/mount -oro -t cd9660 /dev/iso9660/${LABEL} /mnt"
		;;
	"memstick")
		MOUNTROOT="/sbin/mount -oro /dev/ufs/${LABEL} /mnt"
		;;
	esac

	/bin/cat > ${DST_DIR}${rcscript} <<EOF
#!/bin/sh
#
# Copyright (c) 2015 Oleg Ginzburg <olevole@olevole.ru>

# PROVIDE: preparedir
# KEYWORD: nojail
# BEFORE: sysctl

MOUNTOK=0
maxretry=10
retry=0

if [ ! -d /mnt/bin ]; then
	printf "Waiting \${maxretry}s for mount root..."
	while [ \$MOUNTOK -ne 1 ]; do
		${MOUNTROOT}
		if [ \$? -ne 0 ]; then
			printf " \${retry} "
			sleep 1
			retry=\$((retry+1))
		else
			echo
			MOUNTOK=1
		fi
		if [ \$retry -ge \${maxretry} ]; then
			echo
			echo "Unsuccess. Drop to single mode"
			exit 0
		fi
	done
fi

if [ ! -d /usr/bin ]; then
EOF
	echo 'MD=$( /sbin/mdconfig -o readonly -a -t vnode -f /mnt/usr.uzip )' >> ${DST_DIR}${rcscript}
	echo '/sbin/mount -oro /dev/${MD}.uzip /mnt/usr' >> ${DST_DIR}${rcscript}
	echo '/sbin/mount -oro -t nullfs /mnt/usr /usr' >> ${DST_DIR}${rcscript}
	echo '/sbin/mount -oro -t nullfs /mnt/boot /boot' >> ${DST_DIR}${rcscript}
	echo 'hash -r' >> ${DST_DIR}${rcscript}
	echo 'fi' >>${DST_DIR}${rcscript}

	/bin/chmod 0555 ${DST_DIR}${rcscript}

	[ -f "${path}/etc/rc.conf" ] && /bin/cp ${path}/etc/rc.conf ${DST_DIR}/etc/rc.conf

	# Here is mfsroot location
	if [ -f "${jailsysdir}/${jname}/tmpfsdir" ]; then
		/bin/cp ${miscdir}/tmpfsdir ${DST_DIR}/etc/rc.d/
	fi
}

prunelist()
{
	[ ! -f "${prunelist}" ] && return 0 # no prune
	[ -z "${1}" ] && return 0 # sanity

	${ECHO} "${MAGENTA}Prune file by list: ${GREEN}${prunelist}${NORMAL}"

	for FILE in $( /bin/cat ${prunelist} ); do
		[ -z "${FILE}" ] && continue
		case ":${FILE}" in
			:#* | :)
				continue
				;;
		esac
		/bin/rm -rf ${1}/${FILE} 2>/dev/null
	done
}

# $1 - rootdir
epilogue_img()
{
	local _rootfs="${1}"
	[ -z "${_rootfs}" -a ! -d "${_rootfs}" ] && return 0
	[ -z "${nic}" ] && nic="vtnet0"

	${ECHO} "${MAGENTA}Epilogue for ${GREEN}${_rootfs}${NORMAL}"

	${SYSRC_CMD} -qf ${_rootfs}/etc/rc.conf fsck_y_enable="YES" >/dev/null

	[ -n "${host_hostname}" ] && ${SYSRC_CMD} -qf ${_rootfs}/etc/rc.conf hostname="${host_hostname}" >/dev/null

	if [ -n "${ip4_addr}" -a "${ip4_addr}" != "0" ]; then
		case "${ip4_addr}" in
			[Dd][Hh][Cc][Pp])
				${SYSRC_CMD} -qf ${_rootfs}/etc/rc.conf ifconfig_${nic}="DHCP" >/dev/null
				;;
			*)
				${SYSRC_CMD} -qf ${_rootfs}/etc/rc.conf ipv4_addrs_${nic}="${ip4_addr}" >/dev/null
		esac
	fi

	[ -n "${gw4}" ] && ${SYSRC_CMD} -qf ${_rootfs}/etc/rc.conf defaultrouter="${gw4}" >/dev/null

	if [ -n "${nameserver}" ]; then
		IFS=","
		for i in ${nameserver}; do
			echo "nameserver ${i}" >> ${_rootfs}/etc/resolv.conf
		done
		IFS=" "
	fi

	[ -n "${timezone}" ] && [ -f "/usr/share/zoneinfo/${timezone}" ] && /bin/cp /usr/share/zoneinfo/${timezone} ${_rootfs}/etc/localtime
}


makemfsroot()
{
	local _filelist _ver
	local _tmpdir=$( /usr/bin/mktemp -d )

	mfsrootfile="${tmpdir}/mfsroot.$$"

	_ver=${ver%%.*}

	_filelist="${sharedir}/${platform}-filemin_${_ver}.txt.xz"

	copy-binlib filelist=${_filelist} dstdir=${_tmpdir} basedir=${BASE_DIR} chaselibs=1

	local _size=0

#	_size=$(/usr/bin/find ${_tmpdir} | while read _myfile; do
#		_size=$((_size + `/usr/bin/stat -f %z ${_myfile}`))
#		echo ${_size}
#	done |/usr/bin/tail -n1 )

#	_size=$(( _size / 1024 / 1024 ))
#	_size=$(( _size + 10 ))
#	_size=$(( _size * 1024 ))

#	echo "$_size"

	# NOT REL
	_size=80000
#	_size=230000

	/bin/dd if=/dev/zero of=${mfsrootfile} count=${_size} bs=1k

	DEV=$( /sbin/mdconfig -a -t vnode -f ${mfsrootfile} )
	/sbin/bsdlabel -w /dev/${DEV} auto
	/sbin/newfs -n -i ${BS} -m 0 -o space /dev/${DEV}
	/bin/mkdir -p ${DST_DIR}
	/sbin/mount /dev/${DEV} ${DST_DIR}

	echo "cd ${_tmpdir} && find -E ${_tmpdir} \( -type f -or -type d -or -type l \) -print |/usr/bin/sed s:${_tmpdir}:./:g |/usr/bin/cpio -pdmu ${DST_DIR}"
	cd ${_tmpdir} && find -E ${_tmpdir} \( -type f -or -type d -or -type l \) -print |/usr/bin/sed s:${_tmpdir}:./:g |/usr/bin/cpio -pdmu ${DST_DIR}

	/bin/chflags -R noschg ${_tmpdir}
	/bin/rm -rf ${_tmpdir}

	prepare_dir
	[ "${prunelist}" != "0" ] && prunelist ${DST_DIR}
	cd /
	# make flags for preparedir script
	[ -d "${DST_DIR}/usr/bin" ] && /bin/rm -rf ${DST_DIR}/usr/bin
	/sbin/umount -f ${DST_DIR} && /bin/rmdir ${DST_DIR}
	/sbin/mdconfig -d -u ${DEV}
}


show_bhyve_message()
{
	$ECHO "${MAGENTA}Completed. Image ready for bhyve, example:${NORMAL}"
	/bin/cat << EOF
 % kldload vmm
 % kldload if_tap
 % sysctl -w net.link.tap.up_on_open=1
 % ifconfig tap0 create
 % ifconfig bridge0 create
EOF
    ${ECHO} " % ifconfig bridge0 addm ${mynic} addm tap0    ${GREEN}<< -- where ${mynic} is uplink${NORMAL}"
    /bin/cat << EOF
 % ifconfig bridge0 up
 % sh /usr/share/examples/bhyve/vmrun.sh -d ${dstdir}/${dstname} ${jname}
EOF
}

# $1 - source dir
# $2 - dst file image
create_img_for_dir()
{
	local base_size minfree1 minfree2
	local _res _msg

	[ -z "${freesize}" ] && freesize=0
	[ -z "${imgfreesize}" ] && imgfreesize=0

	if [ -d "${1}" ]; then
		base_size=$( /usr/bin/du -sk ${1} | /usr/bin/awk '{printf $1"k"}' )
	else
		base_size=0
	fi

	if is_number ${freesize}; then
		if conv2bytes ${freesize}; then
			freesize="${convval}"
		fi
	fi

	if is_number ${swapsize}; then
		if conv2bytes ${swapsize}; then
			swapsize="${convval}"
		fi
	fi

	if is_number ${imgfreesize}; then
		if conv2bytes ${imgfreesize}; then
			imgfreesize="${convval}"
		fi
	fi

	if is_number ${base_size}; then
		if conv2bytes ${base_size}; then
			base_size="${convval}"
		fi
	fi

	# we need calculate 8% minfree from base_size
	# minfree=$(( base_size * 8 / 100 ))
	minfree1=$(( base_size * 9 / 100 )) # 9% - du -sk and conv2bytes fault compensation
	minfree2=$(( freesize * 9 / 100 )) # 9% - du -sk and conv2bytes fault compensation

	all_size=$(( base_size + freesize + minfree1 + minfree2 + imgfreesize + swapsize ))
	fs_size=$(( base_size + freesize + minfree1 + minfree2 ))

	_msg=$( bhyve_create_dsk -p ${2} -s ${all_size} -f 0 )
	_res=$?
	if [ ${_res} -ne 0 ]; then
		err 1 "Error: Couldn't create the image file. ${_msg}"
	fi
}


bhyve_zfs_install()
{
	local mnttmp tmpjname
	/sbin/kldstat -qm zfs || /sbin/kldload zfs
	mnttmp=$( /usr/bin/mktemp -d )

	local poolname="tank"
	local freepool=0
	local poolnum=0
	local mypool="${poolname}" # first version of poolname, without index

	mypool=$( while [ ${freepool} -eq 0 ]; do
		/sbin/zpool status ${mypool} > /dev/null 2>&1
		[ $? -eq 1 ] && freepool=1 && echo "${mypool}" && exit 0  # No such pool here, so take it
		[ ${poolnum} -gt 10 ] && err 1 "${mypool}"
		poolnum=$(( poolnum + 1 ))
		mypool="${poolname}${poolnum}"
	done )

	[ $? -ne 0 ] && err 1 "${MAGENTA}Can't find free pool name: ${GREEN}${mypool}${NORMAL}"

	echo "zfsinstall devs=${unit} srcdata=${path} mnt=${mnttmp} pool=${mypool} swap=\"${swapsize}\" quiet=1"
	zfsinstall devs=${unit} srcdata=${path} mnt=${mnttmp} pool=${mypool} swap="${swapsize}" quiet=1
	[ $? -ne 0 ] && err 1 "${MAGENTA}Error for zfsinstall${NORMAL}"

	# hack for remove all dirty zpool 
	/bin/cat > ${mnttmp}/etc/rc.local <<EOF
/sbin/zpool list | ${GREP_CMD} UNAVAIL |/usr/bin/awk '{printf \$1"\n"}' |while read _zpool; do
/sbin/zpool destroy \${_zpool} >/dev/null 2>&1
done

# detect for swap
FSWAP=\$( /sbin/gpart list | ${GREP_CMD} -B50 "type: freebsd-swap" | ${GREP_CMD} Name: | /usr/bin/tail -n1 |/usr/bin/awk '/Name:/{print \$3}' )

if [ -n "\$FSWAP" ]; then
	echo "/dev/\${FSWAP} none swap sw 0 0" > /etc/fstab
	/sbin/swapon -a
fi

/bin/rm -f /etc/rc.local
EOF
	epilogue_img ${mnttmp}

	_post_module_action ${mnttmp}

	/sbin/umount ${mnttmp}/var > /dev/null 2>&1
	/sbin/umount ${mnttmp}/tmp > /dev/null 2>&1
	/sbin/umount ${mnttmp} > /dev/null 2>&1
	/bin/rmdir ${mnttmp} > /dev/null 2>&1
	/sbin/zpool export -f ${mypool}
}


make_ufs()
{
	# move to kernel init?
	get_kernel

	[ ! -d "${KERNEL_DIR}" ] && err 1 "No such ${KERNEL_DIR}"
	[ "$media" = "iso" -o "$media" = "memstick" -o "${media}" = "bhyve" ] || err 1 "${MAGENTA}Unknown media type. Must be: ${GREEN}iso${MAGENTA},${GREEN} memstick ${MAGENTA}or${GREEN} bhyve${NORMAL}"

	mountbase -o "" -p "" -d "" -c "" -s ""
	[ "${ver}" != "empty" ] && mountfstab jroot=${path} fstab=${mount_fstab} jname="${jname}" > /dev/null 2>&1

	BS=8192

	[ "${media}" != "bhyve" ] && makemfsroot

	TRAP="${TRAP} clear_tmp_dir;"
	trap "${TRAP}" HUP INT ABRT BUS TERM EXIT
	/bin/mkdir -p ${TMP_DIR}
	cd ${path} && /bin/pax -p eme -rw . ${TMP_DIR}

	[ "${media}" != "bhyve" ] && /bin/rm -rf ${TMP_DIR}/rescue
	[ "${prunelist}" != "0" ] && prunelist ${TMP_DIR}

	# remove archive
	# BAD FOR packages
	#[ "${media}" != "bhyve" ] && /usr/bin/find ${TMP_DIR} -type f -name \*.a -delete

	/bin/cp -a ${KERNEL_DIR}/boot/kernel ${TMP_DIR}/boot

	if [ "${media}" != "bhyve" ]; then
		/bin/rm -f ${TMP_DIR}/boot/kernel/*.symbols
		cd ${TMP_DIR}/boot/kernel && /usr/bin/gzip -9 ./kernel
	fi

	[ -f "${jailsysdir}/${jname}/loader.conf" ] && /bin/cp ${jailsysdir}/${jname}/loader.conf ${TMP_DIR}/boot/loader.conf

	if [ "${media}" != "bhyve" ]; then
		/bin/cat >> ${TMP_DIR}/boot/loader.conf << EOF
#hw.vga.textmode=1
geom_uzip_load="YES"
tmpfs_load="YES"
nullfs_load="YES"

mfs_load="YES"
mfs_type="mfs_root"
mfs_name="/mfsroot"
vfs.root.mountfrom="ufs:/dev/md0"

net.inet.ip.fw.default_to_accept=1
EOF
else
/bin/cat >> ${TMP_DIR}/boot/loader.conf <<EOF
#hw.vga.textmode=1
console="userboot"
#virtio_load="YES"
#virtio_pci_load="YES"
#virtio_blk_load="YES"
#if_vtnet_load="YES"
EOF
	fi

	case "${media}" in
		"iso")
			ROOTFS="/dev/iso9660/${LABEL} /mnt cd9660 ro 0 0"
			;;
		"memstick")
			ROOTFS="/dev/ufs/${LABEL} /mnt ufs ro,noatime 1 1"
			;;
		"bhyve")
	#		ROOTFS="/dev/ufs/${LABEL} / ufs rw 1 1"
			ROOTFS="/dev/gpt/${LABEL} / ufs rw 1 1"
			;;
	esac

	if [ "${media}" != "bhyve" ]; then
/bin/cat > ${TMP_DIR}/etc/fstab << EOF
tmpfs /tmp tmpfs rw 0 0
${ROOTFS}
/mnt/boot /boot ${NULLFS} ro 0 0
tmpfs /boot/zfs tmpfs rw 0 0
EOF
	else
/bin/cat > ${TMP_DIR}/etc/fstab <<EOF
${ROOTFS}
EOF

		[ "${swap_size}" != "0" ] && /bin/cat >> ${TMP_DIR}/etc/fstab <<EOF
/dev/gpt/swap	none	swap	sw	0	0
EOF
	fi

	echo "Welcome to ${PRODUCT}" > ${TMP_DIR}/etc/motd

	if [ "${media}" != "bhyve" ]; then
		/bin/mv ${mfsrootfile} ${TMP_DIR}/mfsroot
		cd ${TMP_DIR}
		/usr/bin/gzip -9 ${TMP_DIR}/mfsroot
		TRAP="${TRAP} /bin/rm -f /tmp/usr.img.$$ ;"
		trap "${TRAP}" HUP INT ABRT BUS TERM EXIT
		/usr/sbin/makefs -o optimization=space -t ffs /tmp/usr.img.$$ ${TMP_DIR}/usr
		/usr/bin/mkuzip -o ${TMP_DIR}/usr.uzip /tmp/usr.img.$$
		${CHFLAGS_CMD} -R noschg ${TMP_DIR}/usr && /bin/rm -rf ${TMP_DIR}/usr && /bin/mkdir ${TMP_DIR}/usr
		#

		# LiveCD location
		[ -f "$jailsysdir/${jname}/tmpfsdir" ] && /bin/cp ${jailsysdir}/${jname}/tmpfsdir ${TMP_DIR}/etc/
	fi

	if [ "${media}" = "bhyve" ]; then
/bin/cat > ${TMP_DIR}/etc/ttys <<EOF
console "/usr/libexec/getty std.9600"   vt100   on secure
EOF
	fi

	# post action inside image
	epilogue_img ${TMP_DIR}
}


# rootpath
_post_module_action()
{
	local TMPFILE
	local rootpath
	local tmpjname

	[ -n "${1}" ] && rootpath="${1}"

	[ ! -d "${rootpath}" ] && return 0

	tmpjname=$( path2jail root=${rootpath} )

	# create temporary jail for post-action
	. ${workdir}/jcreate.subr
	TMPFILE=$( /usr/bin/mktemp )

	if [ -r "${fromfile}" ]; then
		/bin/cp -a ${fromfile} ${TMPFILE}
		${SYSRC_CMD} -qf ${TMPFILE} -x jname
		${SYSRC_CMD} -qf ${TMPFILE} path="${rootpath}"
		${SYSRC_CMD} -qf ${TMPFILE} data="${rootpath}"
	else

		# additional area
		[ -n "${user_pw_root}" ] && /bin/cat >> ${TMPFILE} <<EOF
user_pw_root='${user_pw_root}';
EOF

		[ -n "${pkglist}" ] && echo "pkglist=\"${pkglist}\";" >> ${TMPFILE}
		if [ -n "${srvlist}" -a -r "${srvlist}" ]; then
			/bin/cat ${srvlist} >> ${TMPFILE}
			/bin/rm -f ${srvlist}
		fi
	fi

	# end of additional area
	# pkg bootstrap && user accounting
	postcreate_module_action ${tmpjname} ${TMPFILE}

	/bin/rm -f ${TMPFILE}
	jcleanup jname=${tmpjname}

	JAILRCCONF="${jailrcconfdir}/rc.conf_${tmpjname}"
	# make sure jail is offline 
	jstop jname=${tmpjname} > /dev/null 2>&1
	junregister jname=${tmpjname}
	[ -f "${JAILRCCONF}" ] && /bin/rm -f ${JAILRCCONF}
}

# MAIN
clear_tmp_dir
[ $baserw -eq 1 ] && path=$data

[ "${prunelist}" != "0" ] && prunelist="${sharedir}/jail2iso-prunelist"
[ "${nobase}" != "1" ] && [ ! -d "${BASE_DIR}" ] && err 1 "${MAGENTA}No base data on: ${GREEN}${BASE_DIR}${NORMAL}"

case "${media}" in
	"iso")
		make_ufs
		[ -z "${dstname}" ] && dstname="${jname}-${ver}_${arch}.iso"
		/usr/local/cbsd/release/mkisoimages.sh -l ${LABEL} -n ${dstdir}/${dstname} -d ${TMP_DIR} -e ${efi}
		;;
	"memstick")
		make_ufs
		[ -z "${dstname}" ] && dstname="${jname}-${ver}_${arch}.img"
		/usr/sbin/makefs -B little -o version=2 -o label=${LABEL} ${dstdir}/${dstname}.part ${TMP_DIR}
		[ $? -ne 0 ] && err 1 "makefs failed"

		# use mkimg on 10.1+ and gpart+mbr for 10.0-
		if [ ${freebsdhostversion} -lt 1000730 ]; then
			##
			unit=$( /sbin/mdconfig -a -t vnode -f ${dstdir}/${dstname} )
			[ $? -ne 0 ] && err 1 "mdconfig failed"
			/sbin/gpart create -s BSD ${unit}
			/sbin/gpart bootcode -b ${TMP_DIR}/boot/boot ${unit}
			/sbin/gpart add -t freebsd-ufs ${unit}
			/sbin/mdconfig -d -u ${unit}
		else
			if [ ${efi} -eq 1 ]; then
				/usr/bin/mkimg -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${TMP_DIR}/boot/boot1.efifat -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-swap::1M -o ${dstdir}/${dstname}
			else
				/usr/bin/mkimg -s gpt -b ${TMP_DIR}/boot/pmbr -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-swap::1M -o ${dstdir}/${dstname}
			fi
			/bin/rm -f ${dstdir}/${dstname}.part
		fi

		${ECHO} "${MAGENTA}Now you can burn image to USB memstick via\n ${GREEN}dd if=${dstdir}/${dstname} of=/dev/da${RED}X${GREEN} bs=\"10240\" conv=\"sync\"${NORMAL}"
		;;
	"bhyve")
		[ -z "${dstname}" ] && dstname="${jname}-${ver}_${arch}.img"
		# bad behaviour of makefs: http://www.freebsd.org/cgi/query-pr.cgi?pr=188762
		#	makefs -o version=2 -o label="${LABEL}" ${dstdir}/${dstname} ${TMP_DIR}

		if [ "${vm_guestfs}" = "ufs" ]; then
			create_img_for_dir ${TMP_DIR} ${dstdir}/${dstname}
		else
			create_img_for_dir ${data} ${dstdir}/${dstname}
		fi

		if [ "${swapsize}" != "0" ]; then
			if conv2human "${swapsize}"; then
				swapsize=${convval}
			fi
		fi

		if [ "${fs_size}" != "0" ]; then
			if conv2human "${fs_size}"; then
				fs_size=${convval}
			fi
		fi

		unit=$( /sbin/mdconfig -a -t vnode -f ${dstdir}/${dstname} )

		[ $? -ne 0 ] && err 1 "mdconfig failed"

		case "${vm_guestfs}" in
			"ufs")
				make_ufs
				/sbin/gpart create -s gpt ${unit}
				/sbin/gpart add -t freebsd-boot -l gpboot -b 40 -s 512K ${unit}
				/sbin/gpart bootcode -b ${TMP_DIR}/boot/pmbr -p ${TMP_DIR}/boot/gptboot -i 1 ${unit}
				# bug? not more than 9g?
				ufspart=$( /sbin/gpart add -t freebsd-ufs -l ${LABEL} -b 1M -s ${fs_size} ${unit} |/usr/bin/awk '/ added/{print $1}' )

				if [ "${swapsize}" != "0" ]; then
					/sbin/gpart add -t freebsd-swap -l swap ${unit}
				fi

				if [ -z "${ufspart}" ]; then
					/sbin/mdconfig -d -u ${unit}
					err 1 "Can't create UFS part for ${unit}"
				fi

				/sbin/newfs -U -n -L "${LABEL}" /dev/${ufspart}
				tdir=$( /usr/bin/mktemp -d )

				/sbin/mount /dev/${ufspart} ${tdir}
				cd ${TMP_DIR} && /bin/pax -p eme -rw . ${tdir}

				/sbin/umount ${tdir} && /bin/rmdir ${tdir}
				# mkimg -s gpt -b ${1}/boot/pmbr -p efi:=${1}/boot/boot1.efifat -p freebsd-boot:=${1}/boot/gptboot -p freebsd-ufs:=${2}.part -p freebsd-swap::1M -o ${2}
				# mkimg -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${TMP_DIR}/boot/boot1.efifat -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname} -p freebsd-swap::1M -o /tmp/test.img
				;;
			"zfs")
				bhyve_zfs_install
				;;
		esac

		mynic=$( getnics-by-ip ip=0.0.0.0 2>/dev/null )
		[ -z "${mynic}" ] && mynic="em0"
		[ ${quiet} -eq 0 ] && show_bhyve_message
		/sbin/mdconfig -d -u ${unit}
	;;
esac

[ "${ver}" != "empty" ] && unmountfstab jroot=${path} fstab=${mount_fstab} > /dev/null 2>&1

jcleanup jname=${jname}
